Enhanced block building

Much easier to build bridges, bases etc. now. Especially under fire.
This commit is contained in:
Dany0 2013-01-21 21:23:42 +01:00
parent d4f68b6f92
commit a0dd8ea25a
8 changed files with 1310 additions and 1272 deletions

View File

@ -392,6 +392,8 @@ mdl_test = client.model_load_pmf("pkg/base/pmf/test.pmf")
mdl_test_bone = client.model_bone_find(mdl_test, "test") mdl_test_bone = client.model_bone_find(mdl_test, "test")
mdl_cube = client.model_load_pmf("pkg/base/pmf/cube.pmf") mdl_cube = client.model_load_pmf("pkg/base/pmf/cube.pmf")
mdl_cube_bone = client.model_bone_find(mdl_cube, "bncube") mdl_cube_bone = client.model_bone_find(mdl_cube, "bncube")
mdl_Xcube = client.model_load_pmf("pkg/base/pmf/Xcube.pmf")
mdl_Xcube_bone = client.model_bone_find(mdl_cube, "bnXcube")
mdl_spade, mdl_spade_bone = client.model_load_pmf("pkg/base/pmf/spade.pmf"), 0 mdl_spade, mdl_spade_bone = client.model_load_pmf("pkg/base/pmf/spade.pmf"), 0
mdl_block, mdl_block_bone = client.model_load_pmf("pkg/base/pmf/block.pmf"), 0 mdl_block, mdl_block_bone = client.model_load_pmf("pkg/base/pmf/block.pmf"), 0
weapon_models[WPN_RIFLE] = client.model_load_pmf("pkg/base/pmf/rifle.pmf") weapon_models[WPN_RIFLE] = client.model_load_pmf("pkg/base/pmf/rifle.pmf")

View File

@ -1,434 +1,435 @@
--[[ --[[
This file is part of Ice Lua Components. This file is part of Ice Lua Components.
Ice Lua Components is free software: you can redistribute it and/or modify Ice Lua Components is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Ice Lua Components is distributed in the hope that it will be useful, Ice Lua Components is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>. along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
]] ]]
print("base dir:",common.base_dir) print("base dir:",common.base_dir)
dofile("pkg/base/version.lua") dofile("pkg/base/version.lua")
-- base dir stuff -- base dir stuff
DIR_PKG_ROOT = DIR_PKG_ROOT or "pkg/base" DIR_PKG_ROOT = DIR_PKG_ROOT or "pkg/base"
DIR_PKG_LIB = DIR_PKG_LIB or DIR_PKG_ROOT DIR_PKG_LIB = DIR_PKG_LIB or DIR_PKG_ROOT
DIR_PKG_PMF = DIR_PKG_PMF or DIR_PKG_ROOT.."/pmf" DIR_PKG_PMF = DIR_PKG_PMF or DIR_PKG_ROOT.."/pmf"
DIR_PKG_GFX = DIR_PKG_GFX or DIR_PKG_ROOT.."/gfx" DIR_PKG_GFX = DIR_PKG_GFX or DIR_PKG_ROOT.."/gfx"
DIR_PKG_WAV = DIR_PKG_WAV or DIR_PKG_ROOT.."/wav" DIR_PKG_WAV = DIR_PKG_WAV or DIR_PKG_ROOT.."/wav"
DIR_PKG_MAP = DIR_PKG_MAP or "pkg/maps" DIR_PKG_MAP = DIR_PKG_MAP or "pkg/maps"
MAP_DEFAULT = MAP_DEFAULT or DIR_PKG_MAP.."/mesa.vxl" MAP_DEFAULT = MAP_DEFAULT or DIR_PKG_MAP.."/mesa.vxl"
LIB_LIST = LIB_LIST or { LIB_LIST = LIB_LIST or {
DIR_PKG_LIB.."/icegui/widgets.lua", DIR_PKG_LIB.."/icegui/widgets.lua",
DIR_PKG_LIB.."/lib_bits.lua", DIR_PKG_LIB.."/lib_bits.lua",
DIR_PKG_LIB.."/lib_collect.lua", DIR_PKG_LIB.."/lib_collect.lua",
DIR_PKG_LIB.."/lib_gui.lua", DIR_PKG_LIB.."/lib_gui.lua",
DIR_PKG_LIB.."/lib_map.lua", DIR_PKG_LIB.."/lib_map.lua",
DIR_PKG_LIB.."/lib_namegen.lua", DIR_PKG_LIB.."/lib_namegen.lua",
DIR_PKG_LIB.."/lib_pmf.lua", DIR_PKG_LIB.."/lib_pmf.lua",
DIR_PKG_LIB.."/lib_sdlkey.lua", DIR_PKG_LIB.."/lib_sdlkey.lua",
DIR_PKG_LIB.."/lib_util.lua", DIR_PKG_LIB.."/lib_util.lua",
DIR_PKG_LIB.."/lib_vector.lua", DIR_PKG_LIB.."/lib_vector.lua",
DIR_PKG_LIB.."/obj_player.lua", DIR_PKG_LIB.."/obj_player.lua",
DIR_PKG_LIB.."/obj_intent.lua", DIR_PKG_LIB.."/obj_intent.lua",
DIR_PKG_LIB.."/obj_nade.lua", DIR_PKG_LIB.."/obj_nade.lua",
} }
-- load libs -- load libs
local i local i
for i=1,#LIB_LIST do for i=1,#LIB_LIST do
local asdf_qwerty = i local asdf_qwerty = i
i = nil i = nil
dofile(LIB_LIST[asdf_qwerty]) dofile(LIB_LIST[asdf_qwerty])
i = asdf_qwerty i = asdf_qwerty
end end
i = nil i = nil
-- mode stuff -- mode stuff
MODE_DEBUG_SHOWBOXES = false MODE_DEBUG_SHOWBOXES = false
MODE_CHEAT_FLY = false MODE_CHEAT_FLY = false
MODE_AUTOCLIMB = true MODE_AUTOCLIMB = true
MODE_AIRJUMP = false MODE_AIRJUMP = false
MODE_SOFTCROUCH = true MODE_SOFTCROUCH = true
MODE_NADE_SPEED = 30.0 MODE_NADE_SPEED = 30.0
MODE_NADE_STEP = 0.1 MODE_NADE_STEP = 0.1
MODE_NADE_FUSE = 3.0 MODE_NADE_FUSE = 3.0
MODE_NADE_ADAMP = 0.5 MODE_NADE_ADAMP = 0.5
MODE_NADE_BDAMP = 1.0 MODE_NADE_BDAMP = 1.0
MODE_NADE_RANGE = 8.0 MODE_NADE_RANGE = 8.0
MODE_NADE_DAMAGE = 500.0 MODE_NADE_DAMAGE = 500.0
MODE_MINIMAP_RCIRC = false MODE_MINIMAP_RCIRC = false
MODE_ENABLE_MINIMAP = true MODE_ENABLE_MINIMAP = true
MODE_MAP_TRACERS = false -- TODO! MODE_MAP_TRACERS = false -- TODO!
MODE_TILT_SLOWDOWN = false -- TODO! MODE_TILT_SLOWDOWN = false -- TODO!
MODE_TILT_DOWN_NOCLIMB = false -- TODO! MODE_TILT_DOWN_NOCLIMB = false -- TODO!
MODE_DRUNKCAM_VELOCITY = false -- keep this off unless you want to throw up MODE_DRUNKCAM_VELOCITY = false -- keep this off unless you want to throw up
MODE_DRUNKCAM_LOCALTURN = true -- this is the one you're looking for. MODE_DRUNKCAM_LOCALTURN = true -- this is the one you're looking for.
MODE_DRUNKCAM_CORRECTSPEED = 10.0 MODE_DRUNKCAM_CORRECTSPEED = 10.0
MODE_DELAY_SPADE_DIG = 1.0 MODE_DELAY_SPADE_DIG = 1.0
MODE_DELAY_SPADE_HIT = 0.25 MODE_DELAY_SPADE_HIT = 0.25
MODE_DELAY_BLOCK_BUILD = 0.5 MODE_DELAY_BLOCK_BUILD = 0.5
MODE_DELAY_TOOL_CHANGE = 0.2 MODE_DELAY_TOOL_CHANGE = 0.2
MODE_DELAY_NADE_THROW = 0.5 MODE_DELAY_NADE_THROW = 0.5
MODE_BLOCK_HEALTH = 100 MODE_BLOCK_HEALTH = 100
MODE_BLOCK_DAMAGE_SPADE = 34 MODE_BLOCK_DAMAGE_SPADE = 34
MODE_BLOCK_DAMAGE_RIFLE = 34 MODE_BLOCK_DAMAGE_RIFLE = 34
MODE_BLOCK_REGEN_TIME = 15.0 MODE_BLOCK_REGEN_TIME = 15.0
MODE_BLOCK_PLACE_IN_AIR = false --TODO: make this a server config variable, maybe godmode?
MODE_RCIRC_LINGER = 60.0
MODE_RESPAWN_TIME = 8.0 MODE_RCIRC_LINGER = 60.0
MODE_RESPAWN_TIME = 8.0
MODE_CHAT_LINGER = 15.0
MODE_CHAT_MAX = 10 MODE_CHAT_LINGER = 15.0
MODE_CHAT_STRMAX = 102 MODE_CHAT_MAX = 10
MODE_CHAT_STRMAX = 102
-- scoring
SCORE_INTEL = 10 -- scoring
SCORE_KILL = 1 SCORE_INTEL = 10
SCORE_TEAMKILL = -1 SCORE_KILL = 1
SCORE_SUICIDE = -1 SCORE_TEAMKILL = -1
SCORE_SUICIDE = -1
-- tools
TOOL_SPADE = 0 -- tools
TOOL_BLOCK = 1 TOOL_SPADE = 0
TOOL_GUN = 2 TOOL_BLOCK = 1
TOOL_NADE = 3 TOOL_GUN = 2
TOOL_NADE = 3
-- sounds
if client then -- sounds
client.wav_cube_size(0.5) if client then
wav_rifle_shot = common.wav_load(DIR_PKG_WAV.."/rifle-shot.wav") client.wav_cube_size(0.5)
wav_rifle_reload = common.wav_load(DIR_PKG_WAV.."/rifle-reload.wav") wav_rifle_shot = common.wav_load(DIR_PKG_WAV.."/rifle-shot.wav")
wav_whoosh = common.wav_load(DIR_PKG_WAV.."/whoosh.wav") wav_rifle_reload = common.wav_load(DIR_PKG_WAV.."/rifle-reload.wav")
wav_buld = common.wav_load(DIR_PKG_WAV.."/buld.wav") wav_whoosh = common.wav_load(DIR_PKG_WAV.."/whoosh.wav")
wav_grif = common.wav_load(DIR_PKG_WAV.."/grif.wav") wav_buld = common.wav_load(DIR_PKG_WAV.."/buld.wav")
wav_hammer = common.wav_load(DIR_PKG_WAV.."/hammer.wav") wav_grif = common.wav_load(DIR_PKG_WAV.."/grif.wav")
wav_jump_up = common.wav_load(DIR_PKG_WAV.."/jump-up.wav") wav_hammer = common.wav_load(DIR_PKG_WAV.."/hammer.wav")
wav_jump_down = common.wav_load(DIR_PKG_WAV.."/jump-down.wav") wav_jump_up = common.wav_load(DIR_PKG_WAV.."/jump-up.wav")
wav_pin = common.wav_load(DIR_PKG_WAV.."/pin.wav") wav_jump_down = common.wav_load(DIR_PKG_WAV.."/jump-down.wav")
wav_steps = {} wav_pin = common.wav_load(DIR_PKG_WAV.."/pin.wav")
local i wav_steps = {}
for i=1,8 do local i
wav_steps[i] = common.wav_load(DIR_PKG_WAV.."/step"..i..".wav") for i=1,8 do
end wav_steps[i] = common.wav_load(DIR_PKG_WAV.."/step"..i..".wav")
end end
end
-- weapons
WPN_RIFLE = 1 -- weapons
WPN_RIFLE = 1
weapon_models = {}
weapon_models = {}
weapons = {
[WPN_RIFLE] = function (plr) weapons = {
local this = {} this.this = this [WPN_RIFLE] = function (plr)
local this = {} this.this = this
this.cfg = {
dmg = { this.cfg = {
head = 100, dmg = {
body = 49, head = 100,
legs = 33, body = 49,
}, legs = 33,
},
ammo_clip = 10,
ammo_reserve = 50, ammo_clip = 10,
time_fire = 1/2, ammo_reserve = 50,
time_reload = 2.5, time_fire = 1/2,
time_reload = 2.5,
recoil_x = 0.0001,
recoil_y = -0.05, recoil_x = 0.0001,
recoil_y = -0.05,
name = "Rifle"
} name = "Rifle"
}
function this.restock()
this.ammo_clip = this.cfg.ammo_clip function this.restock()
this.ammo_reserve = this.cfg.ammo_reserve this.ammo_clip = this.cfg.ammo_clip
end this.ammo_reserve = this.cfg.ammo_reserve
end
function this.reset()
this.t_fire = nil function this.reset()
this.t_reload = nil this.t_fire = nil
this.reloading = false this.t_reload = nil
this.restock() this.reloading = false
end this.restock()
end
this.reset()
this.reset()
local function prv_fire(sec_current)
local xlen, ylen, zlen local function prv_fire(sec_current)
xlen, ylen, zlen = common.map_get_dims() local xlen, ylen, zlen
xlen, ylen, zlen = common.map_get_dims()
if client then
tracer_add(plr.x,plr.y,plr.z, if client then
plr.angy,plr.angx) tracer_add(plr.x,plr.y,plr.z,
plr.angy,plr.angx)
client.wav_play_global(wav_rifle_shot, plr.x, plr.y, plr.z)
end client.wav_play_global(wav_rifle_shot, plr.x, plr.y, plr.z)
end
local sya = math.sin(plr.angy)
local cya = math.cos(plr.angy) local sya = math.sin(plr.angy)
local sxa = math.sin(plr.angx) local cya = math.cos(plr.angy)
local cxa = math.cos(plr.angx) local sxa = math.sin(plr.angx)
local fwx,fwy,fwz local cxa = math.cos(plr.angx)
fwx,fwy,fwz = sya*cxa, sxa, cya*cxa local fwx,fwy,fwz
fwx,fwy,fwz = sya*cxa, sxa, cya*cxa
-- perform a trace
local d,cx1,cy1,cz1,cx2,cy2,cz2 -- perform a trace
d,cx1,cy1,cz1,cx2,cy2,cz2 local d,cx1,cy1,cz1,cx2,cy2,cz2
= trace_map_ray_dist(plr.x+sya*0.4,plr.y,plr.z+cya*0.4, fwx,fwy,fwz, 127.5) d,cx1,cy1,cz1,cx2,cy2,cz2
d = d or 127.5 = trace_map_ray_dist(plr.x+sya*0.4,plr.y,plr.z+cya*0.4, fwx,fwy,fwz, 127.5)
d = d or 127.5
-- see if there's anyone we can kill
local hurt_idx = nil -- see if there's anyone we can kill
local hurt_part = nil local hurt_idx = nil
local hurt_part_idx = 0 local hurt_part = nil
local hurt_dist = d*d local hurt_part_idx = 0
local i,j local hurt_dist = d*d
local i,j
for i=1,players.max do
local p = players[i] for i=1,players.max do
if p and p ~= plr and p.alive then local p = players[i]
local dx = p.x-plr.x if p and p ~= plr and p.alive then
local dy = p.y-plr.y+0.1 local dx = p.x-plr.x
local dz = p.z-plr.z local dy = p.y-plr.y+0.1
local dz = p.z-plr.z
for j=1,3 do
local dd = dx*dx+dy*dy+dz*dz for j=1,3 do
local dd = dx*dx+dy*dy+dz*dz
local dotk = dx*fwx+dy*fwy+dz*fwz
local dot = math.sqrt(dd-dotk*dotk) local dotk = dx*fwx+dy*fwy+dz*fwz
if dot < 0.55 and dd < hurt_dist then local dot = math.sqrt(dd-dotk*dotk)
hurt_idx = i if dot < 0.55 and dd < hurt_dist then
hurt_dist = dd hurt_idx = i
hurt_part_idx = j hurt_dist = dd
hurt_part = ({"head","body","legs"})[j] hurt_part_idx = j
hurt_part = ({"head","body","legs"})[j]
break
end break
dy = dy + 1.0 end
end dy = dy + 1.0
end end
end end
end
if hurt_idx then
if server then if hurt_idx then
players[hurt_idx].gun_damage( if server then
hurt_part, this.cfg.dmg[hurt_part], plr) players[hurt_idx].gun_damage(
else hurt_part, this.cfg.dmg[hurt_part], plr)
common.net_send(nil, common.net_pack("BBB" else
, 0x13, hurt_idx, hurt_part_idx)) common.net_send(nil, common.net_pack("BBB"
end , 0x13, hurt_idx, hurt_part_idx))
else end
if client then else
common.net_send(nil, common.net_pack("BBB" if client then
, 0x13, 0, 0)) common.net_send(nil, common.net_pack("BBB"
end , 0x13, 0, 0))
end
if cx2 and cy2 <= ylen-3 then
bhealth_damage(cx2,cy2,cz2,MODE_BLOCK_DAMAGE_RIFLE) if cx2 and cy2 <= ylen-3 then
end bhealth_damage(cx2,cy2,cz2,MODE_BLOCK_DAMAGE_RIFLE)
end end
end
-- TODO: fire a tracer
-- TODO: fire a tracer
-- apply recoil
-- attempting to emulate classic behaviour provided i have it right -- apply recoil
plr.recoil(sec_current, this.cfg.recoil_y, this.cfg.recoil_x) -- attempting to emulate classic behaviour provided i have it right
end plr.recoil(sec_current, this.cfg.recoil_y, this.cfg.recoil_x)
end
function this.reload()
if this.ammo_clip ~= this.cfg.ammo_clip then function this.reload()
if this.ammo_reserve ~= 0 then if this.ammo_clip ~= this.cfg.ammo_clip then
if not this.reloading then if this.ammo_reserve ~= 0 then
this.reloading = true if not this.reloading then
client.wav_play_global(wav_rifle_reload, plr.x, plr.y, plr.z) this.reloading = true
common.net_send(nil, common.net_pack("BB", 0x1D, 0)) client.wav_play_global(wav_rifle_reload, plr.x, plr.y, plr.z)
plr.zooming = false common.net_send(nil, common.net_pack("BB", 0x1D, 0))
this.t_reload = nil plr.zooming = false
end end end this.t_reload = nil
end end end end
end
function this.click(button, state)
if button == 1 then function this.click(button, state)
-- LMB if button == 1 then
if this.ammo_clip > 0 then -- LMB
this.firing = state if this.ammo_clip > 0 then
else this.firing = state
this.firing = false else
-- TODO: play sound this.firing = false
end -- TODO: play sound
elseif button == 3 then end
-- RMB elseif button == 3 then
if hold_to_zoom then -- RMB
plr.zooming = state if hold_to_zoom then
else plr.zooming = state
if state and not this.reloading then else
plr.zooming = not plr.zooming if state and not this.reloading then
end plr.zooming = not plr.zooming
end end
end end
end end
end
function this.get_model()
return weapon_models[WPN_RIFLE] function this.get_model()
end return weapon_models[WPN_RIFLE]
end
function this.draw(px, py, pz, ya, xa, ya2)
client.model_render_bone_global(this.get_model(), 0, function this.draw(px, py, pz, ya, xa, ya2)
px, py, pz, ya, xa, ya2, 3) client.model_render_bone_global(this.get_model(), 0,
end px, py, pz, ya, xa, ya2, 3)
end
function this.tick(sec_current, sec_delta)
if this.reloading then function this.tick(sec_current, sec_delta)
if not this.t_reload then if this.reloading then
this.t_reload = sec_current + this.cfg.time_reload if not this.t_reload then
end this.t_reload = sec_current + this.cfg.time_reload
end
if sec_current >= this.t_reload then
local adelta = this.cfg.ammo_clip - this.ammo_clip if sec_current >= this.t_reload then
if adelta > this.ammo_reserve then local adelta = this.cfg.ammo_clip - this.ammo_clip
adelta = this.ammo_reserve if adelta > this.ammo_reserve then
end adelta = this.ammo_reserve
this.ammo_reserve = this.ammo_reserve - adelta end
this.ammo_clip = this.ammo_clip + adelta this.ammo_reserve = this.ammo_reserve - adelta
this.t_reload = nil this.ammo_clip = this.ammo_clip + adelta
this.reloading = false this.t_reload = nil
plr.arm_rest_right = 0 this.reloading = false
else plr.arm_rest_right = 0
local tremain = this.t_reload - sec_current else
local telapsed = this.cfg.time_reload - tremain local tremain = this.t_reload - sec_current
local roffs = math.min(tremain,telapsed) local telapsed = this.cfg.time_reload - tremain
roffs = math.min(roffs,0.3)/0.3 local roffs = math.min(tremain,telapsed)
roffs = math.min(roffs,0.3)/0.3
plr.arm_rest_right = roffs
end plr.arm_rest_right = roffs
elseif this.firing and this.ammo_clip == 0 then end
this.firing = false elseif this.firing and this.ammo_clip == 0 then
elseif this.firing and ((not this.t_fire) or sec_current >= this.t_fire) then this.firing = false
prv_fire(sec_current) elseif this.firing and ((not this.t_fire) or sec_current >= this.t_fire) then
prv_fire(sec_current)
this.t_fire = this.t_fire or sec_current
this.t_fire = this.t_fire + this.cfg.time_fire this.t_fire = this.t_fire or sec_current
if this.t_fire < sec_current then this.t_fire = this.t_fire + this.cfg.time_fire
this.t_fire = sec_current if this.t_fire < sec_current then
end this.t_fire = sec_current
end
this.ammo_clip = this.ammo_clip - 1
this.ammo_clip = this.ammo_clip - 1
-- TODO: poll: do we want to require a new click per shot?
-- nope - rakiru -- TODO: poll: do we want to require a new click per shot?
end -- nope - rakiru
end
if this.t_fire and this.t_fire < sec_current then
this.t_fire = nil if this.t_fire and this.t_fire < sec_current then
end this.t_fire = nil
end end
end
return this
end, return this
} end,
}
weapons_enabled = {}
weapons_enabled[WPN_RIFLE] = true weapons_enabled = {}
weapons_enabled[WPN_RIFLE] = true
-- teams
teams = { -- teams
[0] = { teams = {
name = "Blue Master Race", [0] = {
color_mdl = {16,32,128}, name = "Blue Master Race",
color_chat = {0,0,255}, color_mdl = {16,32,128},
}, color_chat = {0,0,255},
[1] = { },
name = "Green Master Race", [1] = {
color_mdl = {16,128,32}, name = "Green Master Race",
color_chat = {0,192,0}, color_mdl = {16,128,32},
}, color_chat = {0,192,0},
} },
}
cpalette_base = {
0x7F,0x7F,0x7F, cpalette_base = {
0xFF,0x00,0x00, 0x7F,0x7F,0x7F,
0xFF,0x7F,0x00, 0xFF,0x00,0x00,
0xFF,0xFF,0x00, 0xFF,0x7F,0x00,
0x00,0xFF,0x00, 0xFF,0xFF,0x00,
0x00,0xFF,0xFF, 0x00,0xFF,0x00,
0x00,0x00,0xFF, 0x00,0xFF,0xFF,
0xFF,0x00,0xFF, 0x00,0x00,0xFF,
} 0xFF,0x00,0xFF,
}
cpalette = {}
do cpalette = {}
local i,j do
for i=0,7 do local i,j
local r,g,b for i=0,7 do
r = cpalette_base[i*3+1] local r,g,b
g = cpalette_base[i*3+2] r = cpalette_base[i*3+1]
b = cpalette_base[i*3+3] g = cpalette_base[i*3+2]
for j=0,3 do b = cpalette_base[i*3+3]
local cr = math.floor((r*j)/3) for j=0,3 do
local cg = math.floor((g*j)/3) local cr = math.floor((r*j)/3)
local cb = math.floor((b*j)/3) local cg = math.floor((g*j)/3)
cpalette[#cpalette+1] = {cr,cg,cb} local cb = math.floor((b*j)/3)
end cpalette[#cpalette+1] = {cr,cg,cb}
for j=1,4 do end
local cr = r + math.floor(((255-r)*j)/4) for j=1,4 do
local cg = g + math.floor(((255-g)*j)/4) local cr = r + math.floor(((255-r)*j)/4)
local cb = b + math.floor(((255-b)*j)/4) local cg = g + math.floor(((255-g)*j)/4)
cpalette[#cpalette+1] = {cr,cg,cb} local cb = b + math.floor(((255-b)*j)/4)
end cpalette[#cpalette+1] = {cr,cg,cb}
end end
end end
end
damage_blk = {}
players = {max = 32, current = 1} damage_blk = {}
intent = {} players = {max = 32, current = 1}
nades = {head = 1, tail = 0} intent = {}
nades = {head = 1, tail = 0}
function sort_players()
players_sorted = {} function sort_players()
for k,v in ipairs(players) do players_sorted = {}
players_sorted[k] = v for k,v in ipairs(players) do
end players_sorted[k] = v
table.sort(players_sorted, end
function(x, y) table.sort(players_sorted,
if x.score == y.score then function(x, y)
if x.kills == y.kills then if x.score == y.score then
if x.deaths == y.deaths then if x.kills == y.kills then
return x.pid < y.pid if x.deaths == y.deaths then
end return x.pid < y.pid
return x.deaths < y.deaths end
end return x.deaths < y.deaths
return x.kills > y.kills end
end return x.kills > y.kills
return x.score > y.score end
end return x.score > y.score
) end
end )
end
local players_mt = {}
function players_mt.__newindex(self, key, value) local players_mt = {}
rawset(self, key, value) function players_mt.__newindex(self, key, value)
sort_players() rawset(self, key, value)
end sort_players()
end
setmetatable(players, players_mt) setmetatable(players, players_mt)

View File

@ -1,455 +1,473 @@
--[[ --[[
This file is part of Ice Lua Components. This file is part of Ice Lua Components.
Ice Lua Components is free software: you can redistribute it and/or modify Ice Lua Components is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Ice Lua Components is distributed in the hope that it will be useful, Ice Lua Components is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>. along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
]] ]]
-- returns a list consisting of {t,r,g,b} tuplets -- returns a list consisting of {t,r,g,b} tuplets
function map_pillar_raw_unpack(tpack) function map_pillar_raw_unpack(tpack)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
local t = {} local t = {}
local i,j,y local i,j,y
i = 1 i = 1
y = 0 y = 0
while true do while true do
-- fill with air -- fill with air
while y < tpack[i+1] do while y < tpack[i+1] do
t[y+1] = nil t[y+1] = nil
y = y + 1 y = y + 1
end end
-- fill with top data -- fill with top data
j = i + 4 j = i + 4
while y <= tpack[i+2] do while y <= tpack[i+2] do
t[y+1] = {tpack[j+3],tpack[j+2],tpack[j+1],tpack[j+0]} t[y+1] = {tpack[j+3],tpack[j+2],tpack[j+1],tpack[j+0]}
y = y + 1 y = y + 1
j = j + 4 j = j + 4
end end
-- check if end -- check if end
if tpack[i] == 0 then if tpack[i] == 0 then
-- fill the rest with invisible -- fill the rest with invisible
while y < ylen do while y < ylen do
t[y+1] = false t[y+1] = false
y = y + 1 y = y + 1
end end
-- that's it -- that's it
break break
end end
local ntr = tpack[i]-1-(tpack[i+2]-tpack[i+1]+1) local ntr = tpack[i]-1-(tpack[i+2]-tpack[i+1]+1)
i = i + 4*tpack[i] i = i + 4*tpack[i]
ntr = tpack[i+3] - ntr ntr = tpack[i+3] - ntr
-- fill with invisible -- fill with invisible
while y < ntr do while y < ntr do
t[y+1] = false t[y+1] = false
y = y + 1 y = y + 1
end end
-- fill with bottom data -- fill with bottom data
while y < tpack[i+3] do while y < tpack[i+3] do
t[y+1] = {tpack[j+3],tpack[j+2],tpack[j+1],tpack[j+0]} t[y+1] = {tpack[j+3],tpack[j+2],tpack[j+1],tpack[j+0]}
y = y + 1 y = y + 1
j = j + 4 j = j + 4
end end
end end
return t return t
end end
function map_pillar_raw_get(x,z) function map_pillar_raw_get(x,z)
return map_pillar_raw_unpack(common.map_pillar_get(x,z)) return map_pillar_raw_unpack(common.map_pillar_get(x,z))
end end
function map_pillar_raw_pack(t) function map_pillar_raw_pack(t)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
local tpack = {} local tpack = {}
local y,i local y,i
local rmode = 0 local rmode = 0
local n,s,e,a local n,s,e,a
a = 0 a = 0
i = nil i = nil
y = 0 y = 0
while true do while true do
-- skip air -- skip air
while t[y+1] == nil do while t[y+1] == nil do
y = y + 1 y = y + 1
if y >= ylen then break end if y >= ylen then break end
end end
if y >= ylen then break end if y >= ylen then break end
if i then tpack[i] = n end if i then tpack[i] = n end
-- allocate slot -- allocate slot
i = #tpack+1 i = #tpack+1
tpack[i+0] = 0 tpack[i+0] = 0
tpack[i+1] = y tpack[i+1] = y
tpack[i+2] = 0 tpack[i+2] = 0
tpack[i+3] = a tpack[i+3] = a
-- copy top run -- copy top run
n = 1 n = 1
while t[y+1] do while t[y+1] do
tpack[#tpack+1] = t[y+1][4] tpack[#tpack+1] = t[y+1][4]
tpack[#tpack+1] = t[y+1][3] tpack[#tpack+1] = t[y+1][3]
tpack[#tpack+1] = t[y+1][2] tpack[#tpack+1] = t[y+1][2]
tpack[#tpack+1] = t[y+1][1] tpack[#tpack+1] = t[y+1][1]
y = y + 1 y = y + 1
n = n + 1 n = n + 1
end end
tpack[i+2] = y-1 tpack[i+2] = y-1
-- skip dirt -- skip dirt
while t[y+1] == false do while t[y+1] == false do
y = y + 1 y = y + 1
if y >= ylen then break end if y >= ylen then break end
end end
if y >= ylen then break end if y >= ylen then break end
-- build bottom run -- build bottom run
while t[y+1] do while t[y+1] do
tpack[#tpack+1] = t[y+1][4] tpack[#tpack+1] = t[y+1][4]
tpack[#tpack+1] = t[y+1][3] tpack[#tpack+1] = t[y+1][3]
tpack[#tpack+1] = t[y+1][2] tpack[#tpack+1] = t[y+1][2]
tpack[#tpack+1] = t[y+1][1] tpack[#tpack+1] = t[y+1][1]
n = n + 1 n = n + 1
y = y + 1 y = y + 1
end end
a = y a = y
end end
return tpack return tpack
end end
function map_pillar_raw_set(x,z,t) function map_pillar_raw_set(x,z,t)
local tpack = map_pillar_raw_pack(t) local tpack = map_pillar_raw_pack(t)
common.map_pillar_set(x,z,tpack) common.map_pillar_set(x,z,tpack)
if img_overview and tpack[5] then if img_overview and tpack[5] then
-- TODO: check for wrapping -- TODO: check for wrapping
local r,g,b local r,g,b
b = tpack[5] b = tpack[5]
g = tpack[6] g = tpack[6]
r = tpack[7] r = tpack[7]
local c = argb_split_to_merged(r,g,b) local c = argb_split_to_merged(r,g,b)
common.img_pixel_set(img_overview, x, z, c) common.img_pixel_set(img_overview, x, z, c)
end end
end end
function map_block_aerate(x,y,z) function map_block_aerate(x,y,z)
return ({ return ({
1, 1,
64+math.sin((x+z-y)*math.pi/4)*8, 64+math.sin((x+z-y)*math.pi/4)*8,
32-math.sin((x-z+y)*math.pi/4)*8, 32-math.sin((x-z+y)*math.pi/4)*8,
0 0
}) })
end end
function map_pillar_aerate(x,z) function map_pillar_aerate(x,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
local t = map_pillar_raw_get(x,z) local t = map_pillar_raw_get(x,z)
local l = { local l = {
map_pillar_raw_get(x-1,z), map_pillar_raw_get(x-1,z),
map_pillar_raw_get(x+1,z), map_pillar_raw_get(x+1,z),
map_pillar_raw_get(x,z-1), map_pillar_raw_get(x,z-1),
map_pillar_raw_get(x,z+1), map_pillar_raw_get(x,z+1),
} }
local y local y
for y=1,ylen do for y=1,ylen do
if t[y] then if t[y] then
if l[1][y] ~= nil and l[2][y] ~= nil if l[1][y] ~= nil and l[2][y] ~= nil
and l[3][y] ~= nil and l[4][y] ~= nil and l[3][y] ~= nil and l[4][y] ~= nil
and t[y-1] ~= nil and (y == ylen or t[y+1] ~= nil) then and t[y-1] ~= nil and (y == ylen or t[y+1] ~= nil) then
t[y] = false t[y] = false
end end
elseif t[y] == false then elseif t[y] == false then
if l[1][y] == nil or l[2][y] == nil if l[1][y] == nil or l[2][y] == nil
or l[3][y] == nil or l[4][y] == nil or l[3][y] == nil or l[4][y] == nil
or t[y-1] == nil or (y ~= ylen and t[y+1] == nil) then or t[y-1] == nil or (y ~= ylen and t[y+1] == nil) then
t[y] = map_block_aerate(x,y-1,z) t[y] = map_block_aerate(x,y-1,z)
end end
end end
end end
map_pillar_raw_set(x,z,t) map_pillar_raw_set(x,z,t)
end end
function map_hashcoord3(x,y,z) function map_hashcoord3(x,y,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
return return
(y % ylen) + ylen*((x % xlen) + xlen*(z % zlen)) (y % ylen) + ylen*((x % xlen) + xlen*(z % zlen))
end end
function map_hashcoord2(x,z) function map_hashcoord2(x,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
return (x % xlen) return (x % xlen)
+xlen*(z % zlen) +xlen*(z % zlen)
end end
function map_chkdisbrk(x,y,z) function map_chkdisbrk(x,y,z)
-- A* ftw -- A* ftw
local loadq = { local loadq = {
{x-1,y,z}, {x-1,y,z},
{x+1,y,z}, {x+1,y,z},
{x,y-1,z}, {x,y-1,z},
{x,y+1,z}, {x,y+1,z},
{x,y,z-1}, {x,y,z-1},
{x,y,z+1}, {x,y,z+1},
} }
local tmap = {} local tmap = {}
local pmap = {} local pmap = {}
local plist = {} local plist = {}
local ptag = {} local ptag = {}
local ptaglist = {} local ptaglist = {}
local nukeq = {} local nukeq = {}
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
-- build chunks -- build chunks
local i,j local i,j
for i=1,#loadq do for i=1,#loadq do
local prio,tx,ty,tz local prio,tx,ty,tz
tx,ty,tz = loadq[i][1],loadq[i][2],loadq[i][3] tx,ty,tz = loadq[i][1],loadq[i][2],loadq[i][3]
if not pmap[map_hashcoord2(tx,tz)] then if not pmap[map_hashcoord2(tx,tz)] then
pmap[map_hashcoord2(tx,tz)] = map_pillar_raw_get(tx,tz) pmap[map_hashcoord2(tx,tz)] = map_pillar_raw_get(tx,tz)
plist[#plist+1] = {tx,tz} plist[#plist+1] = {tx,tz}
end end
if (not tmap[map_hashcoord3(tx,ty,tz)]) and pmap[map_hashcoord2(tx,tz)][ty+1] ~= nil then if (not tmap[map_hashcoord3(tx,ty,tz)]) and pmap[map_hashcoord2(tx,tz)][ty+1] ~= nil then
local pq = collect_new_prioq(function(p,q) local pq = collect_new_prioq(function(p,q)
return p[1] < q[1] return p[1] < q[1]
end) end)
tmap[map_hashcoord3(tx,ty,tz)] = { tmap[map_hashcoord3(tx,ty,tz)] = {
heur = -ty, heur = -ty,
dist = 0, dist = 0,
i = i, i = i,
} }
pq.push({-ty,tx,ty,tz}) pq.push({-ty,tx,ty,tz})
local nukeasm = {} local nukeasm = {}
while nukeasm and not pq.empty() do while nukeasm and not pq.empty() do
local c = pq.pop() local c = pq.pop()
prio,tx,ty,tz = c[1],c[2],c[3],c[4] prio,tx,ty,tz = c[1],c[2],c[3],c[4]
--print(prio,tx,ty,tz) --print(prio,tx,ty,tz)
local tm = tmap[map_hashcoord3(tx,ty,tz)] local tm = tmap[map_hashcoord3(tx,ty,tz)]
if prio <= tm.heur + tm.dist then if prio <= tm.heur + tm.dist then
--print(i,prio,tx,ty,tz) --print(i,prio,tx,ty,tz)
nukeasm[#nukeasm+1] = {tx,ty,tz} nukeasm[#nukeasm+1] = {tx,ty,tz}
if not pmap[map_hashcoord2(tx,tz)] then if not pmap[map_hashcoord2(tx,tz)] then
pmap[map_hashcoord2(tx,tz)] = map_pillar_raw_get(tx,tz) pmap[map_hashcoord2(tx,tz)] = map_pillar_raw_get(tx,tz)
plist[#plist+1] = {tx,tz} plist[#plist+1] = {tx,tz}
end end
local nb = { local nb = {
{tx-1,ty,tz}, {tx-1,ty,tz},
{tx+1,ty,tz}, {tx+1,ty,tz},
{tx,ty-1,tz}, {tx,ty-1,tz},
{tx,ty+1,tz}, {tx,ty+1,tz},
{tx,ty,tz-1}, {tx,ty,tz-1},
{tx,ty,tz+1}, {tx,ty,tz+1},
} }
local dist = tm.dist+1 local dist = tm.dist+1
for j=1,6 do for j=1,6 do
local cx,cy,cz = nb[j][1], nb[j][2], nb[j][3] local cx,cy,cz = nb[j][1], nb[j][2], nb[j][3]
local cm = tmap[map_hashcoord3(cx,cy,cz)] local cm = tmap[map_hashcoord3(cx,cy,cz)]
if cy == ylen or (cm and cm.i ~= i) then if cy == ylen or (cm and cm.i ~= i) then
--print("BAIL!") --print("BAIL!")
nukeasm = nil nukeasm = nil
break break
end end
if not pmap[map_hashcoord2(cx,cz)] then if not pmap[map_hashcoord2(cx,cz)] then
pmap[map_hashcoord2(cx,cz)] = map_pillar_raw_get(cx,cz) pmap[map_hashcoord2(cx,cz)] = map_pillar_raw_get(cx,cz)
plist[#plist+1] = {cx,cz} plist[#plist+1] = {cx,cz}
end end
if pmap[map_hashcoord2(cx,cz)][cy+1] ~= nil then if pmap[map_hashcoord2(cx,cz)][cy+1] ~= nil then
local heur = -cy local heur = -cy
if not cm then if not cm then
cm = { cm = {
heur = heur, heur = heur,
dist = dist, dist = dist,
i = i, i = i,
} }
tmap[map_hashcoord3(cx,cy,cz)] = cm tmap[map_hashcoord3(cx,cy,cz)] = cm
pq.push({heur+dist,cx,cy,cz}) pq.push({heur+dist,cx,cy,cz})
else else
if cm.heur+cm.dist > heur+dist then if cm.heur+cm.dist > heur+dist then
cm.heur = heur cm.heur = heur
cm.dist = dist cm.dist = dist
pq.push({heur+dist,cx,cy,cz}) pq.push({heur+dist,cx,cy,cz})
end end
end end
end end
end end
end end
end end
if nukeasm then if nukeasm then
nukeq[#nukeq+1] = nukeasm nukeq[#nukeq+1] = nukeasm
--print(#nukeq,#nukeasm) --print(#nukeq,#nukeasm)
end end
end end
end end
-- nuke it all -- nuke it all
-- TODO: assemble falling PMFs and drop the buggers -- TODO: assemble falling PMFs and drop the buggers
local brokestuff = false local brokestuff = false
for i=1,#nukeq do for i=1,#nukeq do
local tx,ty,tz local tx,ty,tz
local nl = nukeq[i] local nl = nukeq[i]
if #nl > 0 then brokestuff = true end if #nl > 0 then brokestuff = true end
for j=1,#nl do for j=1,#nl do
local c = nl[j] local c = nl[j]
tx,ty,tz = c[1],c[2],c[3] tx,ty,tz = c[1],c[2],c[3]
if not ptag[map_hashcoord2(tx,tz)] then if not ptag[map_hashcoord2(tx,tz)] then
ptag[map_hashcoord2(tx,tz)] = true ptag[map_hashcoord2(tx,tz)] = true
ptaglist[#ptaglist+1] = {tx,tz} ptaglist[#ptaglist+1] = {tx,tz}
end end
pmap[map_hashcoord2(tx,tz)][ty+1] = nil pmap[map_hashcoord2(tx,tz)][ty+1] = nil
end end
end end
if brokestuff and client then if brokestuff and client then
client.wav_play_global(wav_grif,x+0.5,y+0.5,z+0.5) client.wav_play_global(wav_grif,x+0.5,y+0.5,z+0.5)
end end
-- apply nukings -- apply nukings
local nptag = {} local nptag = {}
local nptaglist = {} local nptaglist = {}
for i=1,#ptaglist do for i=1,#ptaglist do
local tx,tz local tx,tz
local c = ptaglist[i] local c = ptaglist[i]
tx,tz = c[1], c[2] tx,tz = c[1], c[2]
map_pillar_raw_set(tx,tz,pmap[map_hashcoord2(tx,tz)]) map_pillar_raw_set(tx,tz,pmap[map_hashcoord2(tx,tz)])
if not nptag[map_hashcoord2(tx,tz)] then if not nptag[map_hashcoord2(tx,tz)] then
nptag[map_hashcoord2(tx,tz)] = true nptag[map_hashcoord2(tx,tz)] = true
nptaglist[#nptaglist+1] = {tx,tz} nptaglist[#nptaglist+1] = {tx,tz}
end end
end end
-- aerate -- aerate
for i=1,#nptaglist do for i=1,#nptaglist do
local tx,tz local tx,tz
local c = nptaglist[i] local c = nptaglist[i]
tx,tz = c[1], c[2] tx,tz = c[1], c[2]
map_pillar_aerate(tx,tz) map_pillar_aerate(tx,tz)
end end
end end
function map_block_get(x,y,z) function map_block_get(x,y,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
if y < 0 or y >= ylen then return end if y < 0 or y >= ylen then return end
local t = map_pillar_raw_get(x,z) local t = map_pillar_raw_get(x,z)
return t[y+1] return t[y+1]
end end
function map_block_set(x,y,z,typ,r,g,b) function map_block_set(x,y,z,typ,r,g,b)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
if y < 0 or y >= ylen then return end if y < 0 or y >= ylen then return end
local t = map_pillar_raw_get(x,z) local t = map_pillar_raw_get(x,z)
t[y+1] = {typ, r, g, b} t[y+1] = {typ, r, g, b}
map_pillar_raw_set(x,z,t) map_pillar_raw_set(x,z,t)
map_pillar_aerate(x,z) map_pillar_aerate(x,z)
map_pillar_aerate(x-1,z) map_pillar_aerate(x-1,z)
map_pillar_aerate(x+1,z) map_pillar_aerate(x+1,z)
map_pillar_aerate(x,z-1) map_pillar_aerate(x,z-1)
map_pillar_aerate(x,z+1) map_pillar_aerate(x,z+1)
end end
function map_block_paint(x,y,z,typ,r,g,b) function map_block_paint(x,y,z,typ,r,g,b)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
if y < 0 or y >= ylen then return end if y < 0 or y >= ylen then return end
local t = map_pillar_raw_get(x,z) local t = map_pillar_raw_get(x,z)
if t[y+1] then if t[y+1] then
t[y+1] = {typ, r, g, b} t[y+1] = {typ, r, g, b}
map_pillar_raw_set(x,z,t) map_pillar_raw_set(x,z,t)
end end
end end
function map_block_break(x,y,z) function map_block_break(x,y,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
if y < 0 or y >= ylen-1 then return false end if y < 0 or y >= ylen-1 then return false end
local t = map_pillar_raw_get(x,z) local t = map_pillar_raw_get(x,z)
if t[y+1] == nil then return false end if t[y+1] == nil then return false end
t[y+1] = nil t[y+1] = nil
map_pillar_raw_set(x,z,t) map_pillar_raw_set(x,z,t)
map_pillar_aerate(x,z) map_pillar_aerate(x,z)
map_pillar_aerate(x-1,z) map_pillar_aerate(x-1,z)
map_pillar_aerate(x+1,z) map_pillar_aerate(x+1,z)
map_pillar_aerate(x,z-1) map_pillar_aerate(x,z-1)
map_pillar_aerate(x,z+1) map_pillar_aerate(x,z+1)
map_chkdisbrk(x,y,z) map_chkdisbrk(x,y,z)
return true return true
end end
function map_block_delete(x,y,z) function map_block_delete(x,y,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
if y < 0 or y >= ylen-1 then return end if y < 0 or y >= ylen-1 then return end
local t = map_pillar_raw_get(x,z) local t = map_pillar_raw_get(x,z)
t[y+1] = nil t[y+1] = nil
map_pillar_raw_set(x,z,t) map_pillar_raw_set(x,z,t)
map_pillar_aerate(x,z) map_pillar_aerate(x,z)
map_pillar_aerate(x-1,z) map_pillar_aerate(x-1,z)
map_pillar_aerate(x+1,z) map_pillar_aerate(x+1,z)
map_pillar_aerate(x,z-1) map_pillar_aerate(x,z-1)
map_pillar_aerate(x,z+1) map_pillar_aerate(x,z+1)
end end
function map_block_pick(x,y,z) function map_block_pick(x,y,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
if x < 0 or x >= xlen then return end if x < 0 or x >= xlen then return end
if y < 0 or y >= ylen then return end if y < 0 or y >= ylen then return end
if z < 0 or z >= zlen then return end if z < 0 or z >= zlen then return end
local t = map_pillar_raw_get(x,z) local t = map_pillar_raw_get(x,z)
local c = t[y+1] local c = t[y+1]
return c[1],c[2],c[3],c[4] if c==nil then error(x..","..y..","..z) end
end
return c[1],c[2],c[3],c[4]
end
--checks for neighbors
function map_is_buildable(x, y, z)
local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims()
--warning! a long condition
if map_block_get(x,y,z) == nil then
if map_block_get(x + 1,y,z) ~= nil or map_block_get(x - 1,y,z) ~= nil or map_block_get(x,y + 1,z) ~= nil or map_block_get(x,y - 1,z) ~= nil or map_block_get(x,y,z - 1) ~= nil or map_block_get(x,y,z + 1) ~= nil then
if x >=0 and x < xlen and y >= 0 and y < ylen - 2 and z >= 0 and z < zlen then
return true;
end
end
else
return false;
end
end

View File

@ -1,365 +1,372 @@
--[[ --[[
This file is part of Ice Lua Components. This file is part of Ice Lua Components.
Ice Lua Components is free software: you can redistribute it and/or modify Ice Lua Components is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
Ice Lua Components is distributed in the hope that it will be useful, Ice Lua Components is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>. along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
]] ]]
function vcross(x1,y1,z1,x2,y2,z2) function vcross(x1,y1,z1,x2,y2,z2)
return y1*z2 - z1*y2 return y1*z2 - z1*y2
, z1*x2 - x1*z2 , z1*x2 - x1*z2
, x1*y2 - y1*x2 , x1*y2 - y1*x2
end end
function vdot(x1,y1,z1,x2,y2,z2) function vdot(x1,y1,z1,x2,y2,z2)
return x1*x2 + y1*y2 + z1*z2 return x1*x2 + y1*y2 + z1*z2
end end
function vlen2(x,y,z) function vlen2(x,y,z)
return x*x + y*y + z*z return x*x + y*y + z*z
end end
function vlen(x,y,z) function vlen(x,y,z)
return math.sqrt(vlen2(x,y,z)) return math.sqrt(vlen2(x,y,z))
end end
function vnorm(x,y,z) function vnorm(x,y,z)
local d = math.max(0.0000001,vlen(x,y,z)) local d = math.max(0.0000001,vlen(x,y,z))
return x/d, y/d, z/d return x/d, y/d, z/d
end end
function vrotate(theta,x,y,z,bx,by,bz) function vrotate(theta,x,y,z,bx,by,bz)
-- glRotate as specified by SGI :D -- glRotate as specified by SGI :D
bx,by,bz = vnorm(bx,by,bz) bx,by,bz = vnorm(bx,by,bz)
-- S = [ 0 -z y ] -- S = [ 0 -z y ]
-- [ z 0 -x ] -- [ z 0 -x ]
-- [ -y x 0 ] -- [ -y x 0 ]
-- R = uuT + cosO (I - uuT) + sinO S -- R = uuT + cosO (I - uuT) + sinO S
-- alternatively -- alternatively
-- R = uuT * (1 - cosO) + IcosO + sinO S -- R = uuT * (1 - cosO) + IcosO + sinO S
local ct = math.cos(theta) local ct = math.cos(theta)
local st = math.sin(theta) local st = math.sin(theta)
return return
x*(bx*bx*(1-ct)+ct) + y*(bx*by*(1-ct) + st*-bz) + z*(bx*bz*(1-ct) + st*by), x*(bx*bx*(1-ct)+ct) + y*(bx*by*(1-ct) + st*-bz) + z*(bx*bz*(1-ct) + st*by),
x*(by*bx*(1-ct) + st*bz) + y*(by*by*(1-ct)*(1-ct)+ct) + z*(by*bz*(1-ct) + st*-bx), x*(by*bx*(1-ct) + st*bz) + y*(by*by*(1-ct)*(1-ct)+ct) + z*(by*bz*(1-ct) + st*-bx),
x*(bz*bx*(1-ct) + st*-by) + y*(bz*by*(1-ct) + st*bx) + z*(bz*bz*(1-ct)+ct) x*(bz*bx*(1-ct) + st*-by) + y*(bz*by*(1-ct) + st*bx) + z*(bz*bz*(1-ct)+ct)
end end
function trace_gap(x,y,z) function trace_gap(x,y,z)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
local l = common.map_pillar_get(math.floor(x), math.floor(z)) local l = common.map_pillar_get(math.floor(x), math.floor(z))
i = 1 i = 1
local h1,h2 local h1,h2
h1 = nil h1 = nil
while true do while true do
h2 = l[i+1] h2 = l[i+1]
if h2 == ylen-1 then h2 = ylen end if h2 == ylen-1 then h2 = ylen end
if y < l[i+1] or l[i] == 0 then return h1, h2 end if y < l[i+1] or l[i] == 0 then return h1, h2 end
i = i + l[i]*4 i = i + l[i]*4
if y < l[i+3] then return h1, h2 end if y < l[i+3] then return h1, h2 end
h1 = l[i+3] h1 = l[i+3]
h2 = l[i+1] h2 = l[i+1]
end end
end end
function box_is_clear(x1,y1,z1,x2,y2,z2,canwrap) function box_is_clear(x1,y1,z1,x2,y2,z2,canwrap)
local x,z,i local x,z,i
x1 = math.floor(x1) x1 = math.floor(x1)
y1 = math.floor(y1) y1 = math.floor(y1)
z1 = math.floor(z1) z1 = math.floor(z1)
x2 = math.floor(x2) x2 = math.floor(x2)
y2 = math.floor(y2) y2 = math.floor(y2)
z2 = math.floor(z2) z2 = math.floor(z2)
local xlen,ylen,zlen local xlen,ylen,zlen
xlen,ylen,zlen = common.map_get_dims() xlen,ylen,zlen = common.map_get_dims()
if not canwrap then if not canwrap then
if x1 < 0 or z1 < 0 then if x1 < 0 or z1 < 0 then
return false return false
elseif x2 >= xlen or z2 >= zlen then elseif x2 >= xlen or z2 >= zlen then
return false return false
end end
end end
for z=z1,z2 do for z=z1,z2 do
for x=x1,x2 do for x=x1,x2 do
local l = common.map_pillar_get(x, z) local l = common.map_pillar_get(x, z)
i = 1 i = 1
while true do while true do
if l[i+1] == ylen-1 and y2 < ylen then break end if l[i+1] == ylen-1 and y2 < ylen then break end
if y2 < l[i+1] then break end if y2 < l[i+1] then break end
if l[i] == 0 then return false end if l[i] == 0 then return false end
i = i + l[i]*4 i = i + l[i]*4
if y1 < l[i+3] then return false end if y1 < l[i+3] then return false end
end end
end end
end end
return true return true
end end
function trace_map_ray_dist(x1,y1,z1, vx,vy,vz, maxdist) function trace_map_ray_dist(x1,y1,z1, vx,vy,vz, maxdist, nil_on_maxdist)
local function depsilon(d) if nil_on_maxdist == nil then nil_on_maxdist = true end
if d < 0.0000001 then
return 0.0000001 local function depsilon(d)
else if d < 0.0000001 then
return d return 0.0000001
end else
end return d
end
local xlen,ylen,zlen end
xlen,ylen,zlen = common.map_get_dims()
local xlen,ylen,zlen
-- offsets xlen,ylen,zlen = common.map_get_dims()
local fx,fy,fz
if vx < 0 then fx = bx1 else fx = bx2 end -- offsets
if vy < 0 then fy = by1 else fy = by2 end local fx,fy,fz
if vz < 0 then fz = bz1 else fz = bz2 end if vx < 0 then fx = bx1 else fx = bx2 end
if vy < 0 then fy = by1 else fy = by2 end
-- direction if vz < 0 then fz = bz1 else fz = bz2 end
local gx,gy,gz
if vx < 0 then gx = -1 else gx = 1 end -- direction
if vy < 0 then gy = -1 else gy = 1 end local gx,gy,gz
if vz < 0 then gz = -1 else gz = 1 end if vx < 0 then gx = -1 else gx = 1 end
vx = vx * gx if vy < 0 then gy = -1 else gy = 1 end
vy = vy * gy if vz < 0 then gz = -1 else gz = 1 end
vz = vz * gz vx = vx * gx
vy = vy * gy
-- cell vz = vz * gz
local cx,cy,cz
cx = math.floor(x1) -- cell
cy = math.floor(y1) local cx,cy,cz
cz = math.floor(z1) cx = math.floor(x1)
cy = math.floor(y1)
-- subpos cz = math.floor(z1)
local sx,sy,sz
sx = x1-cx -- subpos
sy = y1-cy local sx,sy,sz
sz = z1-cz sx = x1-cx
if gx >= 0 then sx = 1-sx end sy = y1-cy
if gy >= 0 then sy = 1-sy end sz = z1-cz
if gz >= 0 then sz = 1-sz end if gx >= 0 then sx = 1-sx end
if gy >= 0 then sy = 1-sy end
local dist = 0 if gz >= 0 then sz = 1-sz end
local pillar, npillar
npillar = common.map_pillar_get(cx,cz) local dist = 0
pillar = npillar local pillar, npillar
npillar = common.map_pillar_get(cx,cz)
while true do pillar = npillar
local tx = sx/depsilon(vx)
local ty = sy/depsilon(vy) while true do
local tz = sz/depsilon(vz) local tx = sx/depsilon(vx)
local t,d local ty = sy/depsilon(vy)
local ncx,ncy,ncz local tz = sz/depsilon(vz)
ncx,ncy,ncz = cx,cy,cz local t,d
local ncx,ncy,ncz
if tx < ty and tx < tz then ncx,ncy,ncz = cx,cy,cz
t = tx
d = 0 if tx < ty and tx < tz then
ncx = cx + gx t = tx
npillar = common.map_pillar_get(ncx,ncz) d = 0
elseif ty < tx and ty < tz then ncx = cx + gx
t = ty npillar = common.map_pillar_get(ncx,ncz)
d = 1 elseif ty < tx and ty < tz then
ncy = cy + gy t = ty
else d = 1
t = tz ncy = cy + gy
d = 2 else
ncz = cz + gz t = tz
npillar = common.map_pillar_get(ncx,ncz) d = 2
end ncz = cz + gz
npillar = common.map_pillar_get(ncx,ncz)
dist = dist + t end
if dist > maxdist then return nil, nil, nil, nil, nil, nil, nil end
dist = dist + t
local i=1
while true do if dist > maxdist and nil_on_maxdist then
if ncy < npillar[i+1] then break end return nil, nil, nil, nil, nil, nil, nil
if npillar[i] == 0 then return dist, cx, cy, cz, ncx, ncy, ncz end elseif dist > maxdist and not nil_on_maxdist then
i = i + npillar[i]*4 return dist, cx, cy, cz, ncx, ncy, ncz
if ncy < npillar[i+3] then return dist, cx, cy, cz, ncx, ncy, ncz end end
end
local i=1
sx = sx - vx*t while true do
sy = sy - vy*t if ncy < npillar[i+1] then break end
sz = sz - vz*t if npillar[i] == 0 then return dist, cx, cy, cz, ncx, ncy, ncz end
i = i + npillar[i]*4
cx,cy,cz = ncx,ncy,ncz if ncy < npillar[i+3] then return dist, cx, cy, cz, ncx, ncy, ncz end
end
if d == 0 then sx = 1
elseif d == 1 then sy = 1 sx = sx - vx*t
else sz = 1 end sy = sy - vy*t
sz = sz - vz*t
pillar = npillar
end cx,cy,cz = ncx,ncy,ncz
end
if d == 0 then sx = 1
function trace_map_box(x1,y1,z1, x2,y2,z2, bx1,by1,bz1, bx2,by2,bz2, canwrap) elseif d == 1 then sy = 1
local function depsilon(d) else sz = 1 end
if d < 0.0000001 then
return 0.0000001 pillar = npillar
else end
return d end
end
end function trace_map_box(x1,y1,z1, x2,y2,z2, bx1,by1,bz1, bx2,by2,bz2, canwrap)
local function depsilon(d)
-- delta if d < 0.0000001 then
local dx,dy,dz return 0.0000001
dx = x2-x1 else
dy = y2-y1 return d
dz = z2-z1 end
end
-- offsets
local fx,fy,fz -- delta
if dx < 0 then fx = bx1 else fx = bx2 end local dx,dy,dz
if dy < 0 then fy = by1 else fy = by2 end dx = x2-x1
if dz < 0 then fz = bz1 else fz = bz2 end dy = y2-y1
dz = z2-z1
-- direction
local gx,gy,gz -- offsets
if dx < 0 then gx = -1 else gx = 1 end local fx,fy,fz
if dy < 0 then gy = -1 else gy = 1 end if dx < 0 then fx = bx1 else fx = bx2 end
if dz < 0 then gz = -1 else gz = 1 end if dy < 0 then fy = by1 else fy = by2 end
dx = dx * gx if dz < 0 then fz = bz1 else fz = bz2 end
dy = dy * gy
dz = dz * gz -- direction
local gx,gy,gz
-- combined box size if dx < 0 then gx = -1 else gx = 1 end
local bcx,bcy,bcz if dy < 0 then gy = -1 else gy = 1 end
bcx = (bx2-bx1) if dz < 0 then gz = -1 else gz = 1 end
bcy = (by2-by1) dx = dx * gx
bcz = (bz2-bz1) dy = dy * gy
dz = dz * gz
-- top left offset (note, incorrect name!)
local tlx,tly,tlz -- combined box size
if gx >= 0 then tlx = 0.999 else tlx = 0.001 end local bcx,bcy,bcz
if gy >= 0 then tly = 0.999 else tly = 0.001 end bcx = (bx2-bx1)
if gz >= 0 then tlz = 0.999 else tlz = 0.001 end bcy = (by2-by1)
bcz = (bz2-bz1)
-- apply offset
x1 = x1 + fx -- top left offset (note, incorrect name!)
y1 = y1 + fy local tlx,tly,tlz
z1 = z1 + fz if gx >= 0 then tlx = 0.999 else tlx = 0.001 end
bx1 = bx1 - fx if gy >= 0 then tly = 0.999 else tly = 0.001 end
by1 = by1 - fy if gz >= 0 then tlz = 0.999 else tlz = 0.001 end
bz1 = bz1 - fz
bx2 = bx2 - fx -- apply offset
by2 = by2 - fy x1 = x1 + fx
bz2 = bz2 - fz y1 = y1 + fy
z1 = z1 + fz
-- cell bx1 = bx1 - fx
local cx,cy,cz by1 = by1 - fy
cx = math.floor(x1) bz1 = bz1 - fz
cy = math.floor(y1) bx2 = bx2 - fx
cz = math.floor(z1) by2 = by2 - fy
bz2 = bz2 - fz
-- target cell
local tcx,tcy,tcz -- cell
tcx = math.floor(x2+fx+gx*0.002) local cx,cy,cz
tcy = math.floor(y2+fy+gy*0.002) cx = math.floor(x1)
tcz = math.floor(z2+fz+gz*0.002) cy = math.floor(y1)
cz = math.floor(z1)
-- sub deltas
local sx, sy, sz -- target cell
sx = (x1 % 1.0) - 0.001 local tcx,tcy,tcz
sy = (y1 % 1.0) - 0.001 tcx = math.floor(x2+fx+gx*0.002)
sz = (z1 % 1.0) - 0.001 tcy = math.floor(y2+fy+gy*0.002)
if gx >= 0 then sx = 1-sx end tcz = math.floor(z2+fz+gz*0.002)
if gy >= 0 then sy = 1-sy end
if gz >= 0 then sz = 1-sz end -- sub deltas
local sx, sy, sz
-- restricted x/y/z sx = (x1 % 1.0) - 0.001
local rx,ry,rz sy = (y1 % 1.0) - 0.001
rx = nil sz = (z1 % 1.0) - 0.001
ry = nil if gx >= 0 then sx = 1-sx end
rz = nil if gy >= 0 then sy = 1-sy end
if gz >= 0 then sz = 1-sz end
-- TODO: unset these when another boundary is crossed
-- restricted x/y/z
local i local rx,ry,rz
local iend = ( rx = nil
math.abs(tcx-cx) ry = nil
+ math.abs(tcy-cy) rz = nil
+ math.abs(tcz-cz)
) -- TODO: unset these when another boundary is crossed
for i=1,iend do local i
-- get the time it takes to hit the boundary local iend = (
local tx = sx/depsilon(dx) math.abs(tcx-cx)
local ty = sy/depsilon(dy) + math.abs(tcy-cy)
local tz = sz/depsilon(dz) + math.abs(tcz-cz)
)
local t, d, ck
for i=1,iend do
if tx < ty and tx < tz then -- get the time it takes to hit the boundary
-- X first local tx = sx/depsilon(dx)
d = 0 local ty = sy/depsilon(dy)
t = tx local tz = sz/depsilon(dz)
elseif ty < tx and ty < tz then
-- Y first local t, d, ck
d = 1
t = ty if tx < ty and tx < tz then
else -- X first
-- Z first d = 0
d = 2 t = tx
t = tz elseif ty < tx and ty < tz then
end -- Y first
d = 1
sx = sx - t*dx t = ty
sy = sy - t*dy else
sz = sz - t*dz -- Z first
x1 = rx or x1 + t*dx*gx d = 2
y1 = ry or y1 + t*dy*gy t = tz
z1 = rz or z1 + t*dz*gz end
if d == 0 then sx = sx - t*dx
-- X first sy = sy - t*dy
sx = 1.0 sz = sz - t*dz
ck = rx or box_is_clear(cx+gx,y1+by1,z1+bz1,cx+gx,y1+by2,z1+bz2,canwrap) x1 = rx or x1 + t*dx*gx
if not ck then rx = cx + tlx end y1 = ry or y1 + t*dy*gy
if not rx then cx = cx + gx end z1 = rz or z1 + t*dz*gz
elseif d == 1 then
-- Y first if d == 0 then
sy = 1.0 -- X first
ck = ry or box_is_clear(x1+bx1,cy+gy,z1+bz1,x1+bx2,cy+gy,z1+bz2,canwrap) sx = 1.0
if not ck then ry = cy + tly end ck = rx or box_is_clear(cx+gx,y1+by1,z1+bz1,cx+gx,y1+by2,z1+bz2,canwrap)
if not ry then cy = cy + gy end if not ck then rx = cx + tlx end
else if not rx then cx = cx + gx end
-- Z first elseif d == 1 then
sz = 1.0 -- Y first
ck = rz or box_is_clear(x1+bx1,y1+by1,cz+gz,x1+bx2,y1+by2,cz+gz,canwrap) sy = 1.0
if not ck then rz = cz + tlz end ck = ry or box_is_clear(x1+bx1,cy+gy,z1+bz1,x1+bx2,cy+gy,z1+bz2,canwrap)
if not rz then cz = cz + gz end if not ck then ry = cy + tly end
end if not ry then cy = cy + gy end
else
--if not ck then return x1-bx1, y1-by1, z1-bz1 end -- Z first
end sz = 1.0
-- ck = rz or box_is_clear(x1+bx1,y1+by1,cz+gz,x1+bx2,y1+by2,cz+gz,canwrap)
if rx then rx = rx - fx end if not ck then rz = cz + tlz end
if ry then ry = ry - fy end if not rz then cz = cz + gz end
if rz then rz = rz - fz end end
return rx or x2, ry or y2, rz or z2 --if not ck then return x1-bx1, y1-by1, z1-bz1 end
end end
--
function isect_line_sphere(x1,y1,z1,fx,fy,fz,x2,y2,z2) if rx then rx = rx - fx end
if ry then ry = ry - fy end
end if rz then rz = rz - fz end
return rx or x2, ry or y2, rz or z2
end
function isect_line_sphere(x1,y1,z1,fx,fy,fz,x2,y2,z2)
end

View File

@ -733,7 +733,7 @@ function new_player(settings)
if this.tool == TOOL_BLOCK and this.blx1 then if this.tool == TOOL_BLOCK and this.blx1 then
if (not this.t_newblock) and this.blocks > 0 then if (not this.t_newblock) and this.blocks > 0 then
if this.blx1 >= 0 and this.blx1 < xlen and this.blz1 >= 0 and this.blz1 < zlen then if this.blx1 >= 0 and this.blx1 < xlen and this.blz1 >= 0 and this.blz1 < zlen then
if this.bly1 <= ylen-3 then if this.bly1 <= ylen-3 and map_is_buildable(this.blx1, this.bly1, this.blz1) then
common.net_send(nil, common.net_pack("BHHHBBBB", common.net_send(nil, common.net_pack("BHHHBBBB",
0x08, 0x08,
this.blx1, this.bly1, this.blz1, this.blx1, this.bly1, this.blz1,
@ -1037,8 +1037,9 @@ function new_player(settings)
td, td,
this.blx1, this.bly1, this.blz1, this.blx1, this.bly1, this.blz1,
this.blx2, this.bly2, this.blz2 this.blx2, this.bly2, this.blz2
= trace_map_ray_dist(camx,camy,camz, fwx,fwy,fwz, 5) = trace_map_ray_dist(camx,camy,camz, fwx,fwy,fwz, 5, false)
this.bld1 = td this.bld1 = td
this.bld2 = td this.bld2 = td
@ -1814,24 +1815,32 @@ function new_player(settings)
-- TODO: wireframe cube -- TODO: wireframe cube
if this.tool == TOOL_BLOCK and this.blx1 and (this.alive or this.respawning) then if this.tool == TOOL_BLOCK and this.blx1 and (this.alive or this.respawning) then
bname, mdl_data = client.model_bone_get(mdl_cube, mdl_cube_bone) if map_is_buildable(this.blx1, this.bly1, this.blz1) or MODE_BLOCK_PLACE_IN_AIR then
bname, mdl_data = client.model_bone_get(mdl_cube, mdl_cube_bone)
mdl_data_backup = mdl_data
mdl_data_backup = mdl_data
for i=1,#mdl_data do
if mdl_data[i].r > 4 then for i=1,#mdl_data do
mdl_data[i].r = math.max(this.blk_color[1], 5) --going all the way down to if mdl_data[i].r > 4 then
mdl_data[i].g = math.max(this.blk_color[2], 5) --to 4 breaks it and you'd mdl_data[i].r = math.max(this.blk_color[1], 5) --going all the way down to
mdl_data[i].b = math.max(this.blk_color[3], 5) --have to reload the model mdl_data[i].g = math.max(this.blk_color[2], 5) --to 4 breaks it and you'd
mdl_data[i].b = math.max(this.blk_color[3], 5) --have to reload the model
end
end end
client.model_bone_set(mdl_cube, mdl_cube_bone, bname, mdl_data)
client.model_render_bone_global(mdl_cube, mdl_cube_bone,
this.blx1+0.5, this.bly1+0.5, this.blz1+0.5,
0.0, 0.0, 0.0, 24.0) --no rotation, 24 roughly equals the cube size
else
client.model_render_bone_global(mdl_Xcube, mdl_Xcube_bone,
this.blx1+0.5, this.bly1+0.5, this.blz1+0.5,
0.0, 0.0, 0.0, 24.0)
print(this.blx1.." "..this.bly1.." "..this.blz1)
end end
elseif this.tool == TOOL_SPADE and this.blx1 and (this.alive or this.respawning) and map_block_get(this.blx2, this.bly2, this.blz2) then
client.model_bone_set(mdl_cube, mdl_cube_bone, bname, mdl_data)
client.model_render_bone_global(mdl_cube, mdl_cube_bone,
this.blx1+0.5, this.bly1+0.5, this.blz1+0.5,
0.0, 0.0, 0.0, 24.0) --no rotation, 24 roughly equals the cube size
elseif this.tool == TOOL_SPADE and this.blx1 and (this.alive or this.respawning) then
client.model_render_bone_global(mdl_test, mdl_test_bone, client.model_render_bone_global(mdl_test, mdl_test_bone,
this.blx1+0.5, this.bly1+0.5, this.blz1+0.5, this.blx1+0.5, this.bly1+0.5, this.blz1+0.5,
rotpos*0.01, rotpos*0.004, 0.0, 0.1+0.01*math.sin(rotpos*0.071)) rotpos*0.01, rotpos*0.004, 0.0, 0.1+0.01*math.sin(rotpos*0.071))

BIN
pkg/base/pmf/Xcube.pmf Normal file

Binary file not shown.

BIN
tools/Xcube.kv6 Normal file

Binary file not shown.

View File

@ -0,0 +1 @@
kv62pmf.py Xcube.kv6 Xcube.pmf 1 1 bnXcube