-- LUA Script - precede every function and global member with lowercase name of script g_lift_base_list = {} g_player_Yoff = 0 -- init when level first runs function lift_base_init_name(e, name) g_lift_base_list[e] = {name = name, firstpass = true, hgt_min = nil, lifthight = nil, hgt_max = nil, rotation = nil, plrinlift = false, statechng = false, lift_state = 0, -- 0=Down, 1=Ascending, 2=Up, 3=Descending door_state = 0, -- 0=Closed, 1=Opening, 2=Open, 3=Closing dooroffset = 0, allentsin = false, ents_list = {} -- 8 element array, 1-3=walls, 4=roof, 5-6=static door, 7-8=doors } for i = 1, 8 do g_lift_base_list[e].ents_list[i] = {ent = nil, XO=0, YO=98, ZO=0, YR=0, SC=97} end end function position_doors (LB, x, y, z, offset) local md1, md2 = LB.ents_list[7], LB.ents_list[8] CollisionOff(md1.ent) CollisionOff(md2.ent) if LB.rotation == 90 then ResetPosition(md1.ent, x + md1.XO, y + md1.YO, z + (md1.ZO - offset)) ResetRotation(md1.ent, 0, md1.YR, 0) ResetPosition(md2.ent, x + md2.XO, y + md2.YO, z + (md2.ZO + offset)) ResetRotation(md2.ent, 0, md2.YR, 0) elseif LB.rotation == 180 then ResetPosition(md1.ent, x + (md1.XO - offset), y + md1.YO, z + md1.ZO) ResetRotation(md1.ent, 0, md1.YR, 0) ResetPosition(md2.ent, x + (md2.XO + offset), y + md2.YO, z + md2.ZO) ResetRotation(md2.ent, 0, md2.YR, 0) elseif LB.rotation == 270 then ResetPosition(md1.ent, x + md1.XO, y + md1.YO, z + (md1.ZO + offset)) ResetRotation(md1.ent, 0, md1.YR, 0) ResetPosition(md2.ent, x + md2.XO, y + md2.YO, z + (md2.ZO - offset)) ResetRotation(md2.ent, 0, md2.YR, 0) else ResetPosition(md1.ent, x + (md1.XO + offset), y + md1.YO, z + md1.ZO) ResetRotation(md1.ent, 0, md1.YR, 0) ResetPosition(md2.ent, x + (md2.XO - offset), y + md2.YO, z + md2.ZO) ResetRotation(md2.ent, 0, md2.YR, 0) end CollisionOn(md1.ent) CollisionOn(md2.ent) end function position_ents (LB, x, y, z) for k, e in ipairs (LB.ents_list) do CollisionOff(e.ent) ResetPosition(e.ent, x + e.XO, y + e.YO, z + e.ZO) ResetRotation(e.ent, 0, e.YR, 0) if k < 5 then Scale(e.ent, e.SC) end CollisionOn(e.ent) end end function calc_positions(LB) local wall1, wall2, wall3 = LB.ents_list[1], LB.ents_list[2], LB.ents_list[3] local sd1, sd2 = LB.ents_list[5], LB.ents_list[6] local md1, md2 = LB.ents_list[7], LB.ents_list[8] -- Position walls depending on angle if LB.rotation == 90 then -- x,y,z offsets wall1.XO, wall1.YO, wall1.ZO = 0, 2, -47 wall2.XO, wall2.YO, wall2.ZO = -47, 2, 0 wall3.XO, wall3.YO, wall3.ZO = 0, 2, 47 -- rotation wall1.YR, wall2.YR, wall3.YR = 180, 90, 180 -- doors sd1.XO, sd1.YO, sd1.ZO = 47, 2, -35 sd2.XO, sd2.YO, sd2.ZO = 47, 2, 35 sd1.YR, sd2.YR = 0, 180 md1.XO, md1.YO, md1.ZO = 47.5, 2, -12.25 md2.XO, md2.YO, md2.ZO = 47.5, 2, 12.25 md1.YR, md2.YR = 0, 180 elseif LB.rotation == 180 then -- x,y,z offsets wall1.XO, wall1.YO, wall1.ZO = -47, 2, 0 wall2.XO, wall2.YO, wall2.ZO = 0, 2, 47 wall3.XO, wall3.YO, wall3.ZO = 47, 2, 0 -- rotation wall1.YR, wall2.YR, wall3.YR = 90, 180, 90 -- doors sd1.XO, sd1.YO, sd1.ZO = -35, 2, -47 sd2.XO, sd2.YO, sd2.ZO = 35, 2, -47 sd1.YR, sd2.YR = 90, 270 md1.XO, md1.YO, md1.ZO = -12.25, 2, -47.5 md2.XO, md2.YO, md2.ZO = 12.25, 2, -47.5 md1.YR, md2.YR = 90, 270 elseif LB.rotation == 270 then -- x,y,z offsets wall1.XO, wall1.YO, wall1.ZO = 0, 2, 47 wall2.XO, wall2.YO, wall2.ZO = 47, 2, 0 wall3.XO, wall3.YO, wall3.ZO = 0, 2, -47 -- rotation wall1.YR, wall2.YR, wall3.YR = 180, 90, 180 -- doors sd1.XO, sd1.YO, sd1.ZO = -47, 2, 35 sd2.XO, sd2.YO, sd2.ZO = -47, 2, -35 sd1.YR, sd2.YR = 180, 0 md1.XO, md1.YO, md1.ZO = -47.5, 2, 12.25 md2.XO, md2.YO, md2.ZO = -47.5, 2, -12.25 md1.YR, md2.YR = 180, 0 else -- x,y,z offsets wall1.XO, wall1.YO, wall1.ZO = 47, 2, 0 wall2.XO, wall2.YO, wall2.ZO = 0, 2, -47 wall3.XO, wall3.YO, wall3.ZO = -47, 2, 0 -- rotation wall1.YR, wall2.YR, wall3.YR = 90, 180, 90 -- doors sd1.XO, sd1.YO, sd1.ZO = 35, 2, 47 sd2.XO, sd2.YO, sd2.ZO = -35, 2, 47 sd1.YR, sd2.YR = 270, 270 md1.XO, md1.YO, md1.ZO = 12.25, 2, 47.5 md2.XO, md2.YO, md2.ZO = -12.25, 2, 47.5 md1.YR, md2.YR = 270, 90 end end function position_base (e, Ent, LB) CollisionOff(e) ResetPosition(e, Ent.x, LB.lifthight, Ent.z) ResetRotation(e, 0, LB.rotation, 0) CollisionOn(e) end function lift_base_main(e) local Ent = g_Entity[e] if Ent.health == nil then return end local Px, Py, Pz = g_PlayerPosX, g_PlayerPosY, g_PlayerPosZ local LB = g_lift_base_list[e] -- Work out lift angle if LB.rotation == nil then local lift_angle = g_Entity[e].angley while lift_angle > 360 do lift_angle = lift_angle - 360 end while lift_angle < 0 do lift_angle = lift_angle + 360 end LB.rotation = lift_angle end -- Work out lift heights if LB.lifthight == nil then LB.lifthight = Ent.y if Ent.health > LB.lifthight then LB.hgt_max = Ent.health - LB.lifthight LB.hgt_min = LB.lifthight else LB.hgt_max = LB.lifthight - Ent.health LB.hgt_min = LB.lifthight - LB.hgt_max LB.lift_state = 2 -- Lift Up end end -- find entities associated with this lift if not LB.allentsin then local entsincount = 0 for i = 1, 8 do if LB.ents_list[i].ent ~= nil then entsincount = entsincount + 1 else for j, v in pairs (g_lift_entity_pos_list) do if v.name == LB.name and v.number == i then LB.ents_list[i].ent = j entsincount = entsincount + 1 end end end end if entsincount == 8 then LB.allentsin = true -- now we have all the ents initialise the array positions calc_positions(LB) else return end end if LB.firstpass then position_ents (LB, Ent.x, Ent.y, Ent.z) LB.firstpass = false end -- check if we are close to this lift local DX,DY,DZ = Px - Ent.x, math.abs(Py - Ent.y), Pz - Ent.z if LB.door_state == 0 and (DY > 70 or (DX*DX + DZ*DZ) > 40000) then return end -- Check if player is on the lift if Px > Ent.x - 47 and Px < Ent.x + 47 and Pz > Ent.z - 47 and Pz < Ent.z + 47 and Py > Ent.y - 2 and Py < Ent.y + 40 then if not LB.plrinlift then LB.plrinlift = true g_player_Yoff = Py - Ent.y LB.statechng = true end else LB.plrinlift = false LB.statechng = false -- Check if player in front of lift local sd1Ent = g_Entity[LB.ents_list[5].ent] local sd2Ent = g_Entity[LB.ents_list[6].ent] local DX1, DZ1 = Px - sd1Ent.x, Pz - sd1Ent.z local DX2, DZ2 = Px - sd2Ent.x, Pz - sd2Ent.z if DY < 50 and (DX1*DX1 + DZ1*DZ1) < 8000 and (DX2*DX2 + DZ2*DZ2) < 8000 then if LB.door_state == 0 then -- Door closed LB.dooroffset = 0 LB.door_state = 1 -- So open it -- TBD : play sound - door opening end else if LB.door_state == 2 then -- Door open LB.door_state = 3 -- So close it -- TBD : play sound -- door closing end end end if LB.door_state == 1 then -- Door opening if LB.dooroffset < 22 then LB.dooroffset = LB.dooroffset + 0.25 position_doors (LB, Ent.x, LB.lifthight, Ent.z, LB.dooroffset) else LB.door_state = 2 LB.dooroffset = 22 end elseif LB.door_state == 3 then -- Door closing if LB.dooroffset > 0 then LB.dooroffset = LB.dooroffset - 0.25 position_doors (LB, Ent.x, LB.lifthight, Ent.z, LB.dooroffset) else LB.door_state = 0 LB.dooroffset = 0 end end -- Now lets move lift if LB.plrinlift and LB.statechng then if LB.door_state == 2 then LB.door_state = 3 -- TBD : play sound - Door closing end if LB.lift_state == 0 then -- Lift Down if LB.door_state == 0 then -- Door closed LB.lift_state = 1 -- Going Up -- TBD : play sound - lift moving end elseif LB.lift_state == 2 then -- Lift Up if LB.door_state == 0 then -- Door closed LB.lift_state = 3 -- Going Down -- TBD : play sound - lift moving end end end if LB.lift_state == 1 then -- Going Up if LB.lifthight < LB.hgt_min + LB.hgt_max then LB.lifthight = LB.lifthight + 1 position_base (e, Ent, LB) position_ents (LB, Ent.x, LB.lifthight, Ent.z) if LB.plrinlift and (g_KeyPressW + g_KeyPressS + g_KeyPressA + g_KeyPressD) == 0 then SetFreezePosition (Px, LB.lifthight + g_player_Yoff, Pz) TransportToFreezePositionOnly() end else LB.lift_state = 2 -- Lift Up LB.door_state = 1 -- TBD : play sound - door opening LB.statechng = false end elseif LB.lift_state == 3 then -- Going Down if LB.lifthight > LB.hgt_min then LB.lifthight = LB.lifthight - 1 position_base (e, Ent, LB) position_ents (LB, Ent.x, LB.lifthight, Ent.z) if LB.plrinlift and (g_KeyPressW + g_KeyPressS + g_KeyPressA + g_KeyPressD) == 0 then SetFreezePosition (Px, LB.lifthight + g_player_Yoff, Pz) TransportToFreezePositionOnly() end else LB.lift_state = 0 LB.door_state = 1 -- TBD : play sound - door opening LB.statechng = false end end -- Prompt("Lift:" .. LB.name .. -- " LS=" .. LB.lift_state .. -- " DS=" .. LB.door_state .. -- " Hmin=" .. LB.hgt_min .. -- " Hmax=" .. LB.hgt_max) end