Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- CounterStrike gametype like --
- -- Inspired from Nuggets's Conquest and geo scripts --
- -- The goal for the blue team is to explode the red base --
- -- Red team have to kill the player holding the bomb to avoid it --
- -- Contains Nuggets, AelitePrime and Wizard codes --
- -- The script works only on BloodGulch --
- -- It requieres a ctf gametype with the nav points disabled --
- -- Also made in a Rockets only purpose --
- RocketId = nil
- BombId = nil
- bombarea = nil
- bomb = {}
- bomb.respawn = 45.0
- bomb.spawns = {40.24, -79.12, 0.01} --blue base
- flagcoords = {95.69, -159.44, 0.01} --red flag coords
- players = {}
- players.bomb = false
- players.monitored = false
- players.terroristneedweap = false
- terroristscounter = 0
- redscounter = 0
- respawn_time = 7
- weapons = {}
- finalscore = 0
- function GetRequiredVersion()
- return 200
- end
- function OnScriptLoad(processid, game, persistent)
- --writedword(0x671340, 0x3C, 2)
- writedword(0x488A7E, 0, 0xFFFFFFFF)
- writedword(0x488A7E, 1, 0xFFFFFFFF)
- writedword(0x671340, 0x48, respawn_time * 30)
- writebyte(0x671340, 0x58, 2)
- end
- function OnScriptUnload()
- end
- function OnGameEnd(stage)
- if stage == 1 then
- if finalscore ~= 2 then
- say("red team won")
- writedword(0x639B98, 0x10, 2)
- players.terroristneedweap = nil
- terroristscounter = 0
- redscounter = 0
- else
- say("blue team won")
- writedword(0x639B98 + 0x4, 0x10, 2)
- players.terroristneedweap = nil
- terroristscounter = 0
- redscounter = 0
- end
- elseif stage == 3 then
- writedword(0x488A7E, 0, 17 * 30)
- end
- end
- function OnNewGame(map)
- RocketId = gettagid("weap", "weapons\\rocket launcher\\rocket launcher")
- BombId = gettagid("weap", "weapons\\ball\\ball")
- bomb.x = bomb.spawns[1]
- bomb.y = bomb.spawns[2]
- bomb.z = bomb.spawns[3]
- bomb.objId = createobject(BombId, 0, 0, false, bomb.x, bomb.y, bomb.z)
- local m_object = getobject(bomb.objId)
- writefloat(m_object + 0x74, 0)
- writefloat(m_object + 0x78, -0.3)
- bomb.respawn_remain = bomb.respawn
- registertimer(1000, "Respawn", "bomb")
- registertimer(5000, "CreateBomb")
- writedword(0x488A7E + 0x0, 0xFFFFFFFF)
- registertimer(0, "CreationDelay")
- end
- function CreateBomb(id, count)
- if count == 1 then
- bombarea = GEO.newRectPrism("bombarea", 5, 5, 5, flagcoords[1], flagcoords[2], flagcoords[3])
- return false
- end
- end
- function newplayer(player)
- local hash = gethash(player)
- local team = getteam(player)
- players[hash] = players[hash] or {}
- players[hash].bomb = false
- players[hash].monitored = false
- players[hash].terroristneedweap = false
- if team == 1 then
- terroristscounter = terroristscounter + 1
- privatesay(player, "You are a terrorist, explode the red base")
- elseif team == 0 and terroristscounter == 1 and redscounter == 1 then
- changeteam(player, true)
- privatesay(player, "The game needs more terrorists, go explode the red base")
- terroristscounter = terroristscounter + 1
- elseif team == 1 and terroristscounter == 2 and redscounter == 1 then
- changeteam(player, true)
- privatesay(player, "The game needs more reds, protect your base")
- redscounter = redscounter + 1
- elseif team == 0 and terroristscounter == 2 and redscounter == 1 then
- changeteam(player, true)
- privatesay(player, "The game needs more terrorists, go explode the red base")
- terroristscounter = terroristscounter + 1
- elseif team == 0 and terroristscounter == 5 and redscounter == 3 then
- changeteam(player, true)
- privatesay(player, "The game needs more terrorists, go explode the red base")
- terroristscounter = terroristscounter + 1
- elseif team == 1 and terroristscounter == 6 and redscounter == 3 then
- changeteam(player, true)
- privatesay(player, "The game needs more reds, protect your base")
- redscounter = redscounter + 1
- elseif team == 0 and terroristscounter == 6 and redscounter == 4 then
- changeteam(player, true)
- privatesay(player, "The game needs more terrorists, go explode the red base")
- terroristscounter = terroristscounter + 1
- elseif team == 0 and terroristscounter == 9 and redscounter == 5 then
- changeteam(player, true)
- privatesay(player, "The game needs more terrorists, go explode the red base")
- terroristscounter = terroristscounter + 1
- else
- privatesay(player, "Protect your base from the blue terrorists")
- redscounter = redscounter +1
- end
- end
- function CreationDelay(id, count)
- for i = 0,1 do
- ctf_flag_coords_pointer = readdword(0x639B98 + i * 4, 0x0)
- writefloat(ctf_flag_coords_pointer, 0)
- writefloat(ctf_flag_coords_pointer + 4, 0)
- writefloat(ctf_flag_coords_pointer + 8, -1000)
- end
- return false
- end
- function OnPlayerJoin(player)
- newplayer(player)
- end
- function OnObjectCreationAttempt(mapId, parentId, player)
- local tagname, tagtype = gettaginfo(mapId)
- if tagname == "weapons\\flag\\flag" then
- local m_objectId = readdword(0x639B98 + 0x8)
- registertimer(0, "PutUnderMap", m_objectId)
- return
- end
- return nil
- end
- function OnPlayerSpawnEnd(player, m_objectId)
- for i = 0,3 do
- local m_object = getobject(m_objectId)
- if m_object then
- local weapID = readdword(m_object + 0x2F8 + i*4)
- local weap = getobject(weapID)
- if weap then
- destroyobject(weapID)
- end
- end
- end
- local rocketla = createobject(RocketId, 0, 1, false, 0, 0, 0)
- assignweapon(player, rocketla)
- registertimer(1000, "InfiniteAmmo", player)
- end
- function OnObjectInteraction(player, objId, mapId)
- local team = getteam(player)
- local tagname, tagtype = gettaginfo(mapId)
- if tagtype == "weap" then
- if tagname == "weapons\\ball\\ball" then
- if team == 0 then
- return false
- end
- elseif tagname == "weapons\\flag\\flag" then
- return false
- end
- end
- end
- function OnWeaponPickup(player, weapId, slot, mapId)
- local hash = gethash(player)
- local tagname = gettaginfo(mapId)
- if tagname == "weapons\\ball\\ball" then
- players[hash].bomb = true
- bomb.player = player
- sendconsoletext(player, "You have the bomb")
- sendconsoletext(player, "Go blow the red base")
- end
- end
- function OnWeaponDrop(player, weapId, slot, mapId)
- local hash = gethash(player)
- local tagname = gettaginfo(mapId)
- if tagname == "weapons\\ball\\ball" then
- players[hash].bomb = false
- bomb.player = nil
- end
- end
- function Respawn(id, count, item)
- if _G[item].player then
- _G[item].respawn_remain = _G[item].respawn
- else
- local objId = _G[item].objId
- local m_object = getobject(objId)
- if m_object then
- local x, y, z = getobjectcoords(objId)
- if math.round(x, 1) == math.round(_G[item].x, 1) and math.round(y, 1) == math.round(_G[item].y, 1) and math.round(z, 1) == math.round(_G[item].z, 1) then
- _G[item].respawn_remain = _G[item].respawn
- else
- _G[item].respawn_remain = _G[item].respawn_remain - 1
- if _G[item].respawn_remain <= 0 then
- movobjectcoords(objId, _G[item].x, _G[item].y, _G[item].z)
- local m_object = getobject(_G[item].objId)
- writebit(m_object, 0x10, 5, 0)
- _G[item].respawn_remain = _G[item].respawn
- end
- end
- else
- _G[item].respawn_remain = _G[item].respawn_remain - 1
- if _G[item].respawn_remain <= 0 then
- --[[local mapId --pb?
- if item == "bomb" then
- mapId = gettaginfo("weap", "weapons\\ball\\ball")
- end ]]--
- _G[item].objId = createobject(BombId, 0, 0, false, _G[item].x, _G[item].y, _G[item].z)
- --writefloat(_G[item].objId + 0x74, 0)
- --writefloat(_G[item].objId + 0x78, -0.3)
- _G[item].respawn_remain = _G[item].respawn
- end
- end
- end
- return true
- end
- registertimer(10, "WeaponMonitor")
- function WeaponMonitor(id, count)
- for player = 0,15 do
- weapons[player] = weapons[player] or {}
- local m_player = getplayer(player)
- if m_player then
- local temp = {}
- local objId = readdword(m_player, 0x34)
- local m_object = getobject(objId)
- if m_object then
- for i = 0,3 do
- local weapId = readdword(m_object, 0x2F8 + (i * 4))
- local m_weapon = getobject(weapId)
- if m_weapon then
- local mapId = readdword(m_weapon)
- if weapons[player][i] then
- if weapons[player][i].weapId ~= weapId then
- OnWeaponDrop(player, weapons[player][i].weapId, i, weapons[player][i].mapId)
- weapons[player][i] = {}
- weapons[player][i].weapId = weapId
- weapons[player][i].mapId = mapId
- OnWeaponPickup(player, weapId, i, mapId)
- end
- else
- weapons[player][i] = {}
- weapons[player][i].weapId = weapId
- weapons[player][i].mapId = mapId
- OnWeaponPickup(player, weapId, i, mapId)
- end
- else
- if weapons[player][i] then
- OnWeaponDrop(player, weapons[player][i].weapId, i, weapons[player][i].mapId)
- weapons[player][i] = nil
- end
- end
- end
- else
- for i = 0,3 do
- if weapons[player][i] then
- OnWeaponDrop(player, weapons[player][i].weapId, i, weapons[player][i].mapId)
- weapons[player][i] = nil
- end
- end
- end
- end
- end
- return true
- end
- function setscore(player, score)
- finalscore = finalscore + 1
- local m_player = getplayer(player)
- if m_player then
- local actualscore = readdword(m_player + 0xC8)
- local playerscore = actualscore + score
- writeword(m_player, 0xC8, playerscore)
- end
- end
- function PutUnderMap(id, count, m_objectId)
- local m_object = getobject(m_objectId)
- if m_object then
- local x,y,z = getobjectcoords(m_objectId)
- movobjectcoords(m_objectId, x, y, z - 20)
- end
- return false
- end
- function OnTeamChange(player, old_team, dest_team, relevant)
- if relevant == 1 or relevant == true then
- return false
- --[[local hash = gethash(player)
- if dest_team == 0 then
- privatesay(player, "You are a terrorist, explode the red base")
- else
- privatesay(player, "Protect your base from the blue terrorists")
- end
- players[hash].bomb = false
- players[hash].monitored = false--]]
- end
- end
- function OnPlayerLeave(player)
- local hash = gethash(player)
- local m_objectId = getplayerobjectid(player)
- if m_objectId then
- local m_object = getobject(m_objectId)
- if m_object then
- for i = 0,3 do
- local weapID = readdword(m_object + 0x2F8 + i*4)
- if weapID then
- local weap = getobject(weapID)
- if weap then
- --registertimer(0, "destroyweaps", weapID)
- destroyobject(weapID)
- end
- end
- end
- end
- end
- players[hash].bomb = false
- players[hash].monitored = false
- players[hash].terroristneedweap = false
- local team = getteam(player)
- if team == 1 then
- terroristscounter = terroristscounter - 1
- else
- redscounter = redscounter - 1
- end
- end
- function OnPlayerKill(killer, victim, mode)
- local hash = gethash(victim)
- local m_player = getplayer(victim)
- if m_player == nil then
- return
- end
- local m_object = getobject(readdword(m_player + 0x34))
- if m_object then
- for i = 0,3 do
- local weapID = readdword(m_object + 0x2F8 + i*4)
- if weapID then
- local weap = getobject(weapID)
- if weap then
- --registertimer(0, "destroyweaps", weapID)
- destroyobject(weapID)
- end
- end
- end
- end
- players[hash].bomb = false
- players[hash].monitored = false
- end
- function OnClientUpdate(player)
- writedword(0x639B98 + 0x10, 0)
- writedword(0x639B98 + 0x14, 0)
- local objectid = getplayerobjectid(player)
- local hash = gethash(player)
- local team = getteam(player)
- if team == 1 and bombarea ~= nil then
- if not players[hash].monitored then
- bombarea:monitor(objectid)
- players[hash].monitored = true
- end
- if players[hash].bomb then
- local m_player = getplayer(player)
- if m_player == nil then
- return
- end
- local m_objectId = getplayerobjectid(player)
- if m_objectId == nil then
- return
- end
- local m_object = getobject(m_objectId)
- if m_object then
- local shooting = readbit(m_object + 0x209, 4)
- local nading2 = readbit(m_object + 0x209, 2)
- local nading = readbit(m_object + 0x209, 3)
- if shooting == true or nading == true then
- weapID = bomb.objId
- if m_player then
- if weapID then
- if getobject(weapID) then
- assignweapon(player, weapID)
- end
- end
- end
- end
- end
- end
- end
- if players[hash].terroristneedweap then
- local rocketl = createobject(RocketId, 0, 1, false, 0, 0, 0)
- assignweapon(player, rocketl)
- registertimer(1000, "InfiniteAmmo", player)
- terroristneedweap = nil
- end
- if finalscore == 2 then
- svcmd("sv_map_next")
- end
- end
- function ExplosionTimer(id, count)
- if count == 4 then
- for i=0,15 do
- if getplayer(i) then
- local hash = gethash(i)
- if players[hash].bomb then
- setscore(i, 1)
- local m_player = getplayer(i)
- local m_object = getobject(readdword(m_player + 0x34))
- if m_object then
- for x = 0,3 do
- local weapId = readdword(m_object + 0x2F8 + x*4)
- local weap = getobject(weapId)
- if weap then
- registertimer(0, "replacebomb", weapId)
- destroyobject(weapId)
- players[hash].terroristneedweap = true
- end
- end
- end
- end
- end
- end
- return true
- elseif count == 5 then
- say("The bomb exploded!")
- bombarea:killzone(true)
- return true
- elseif count == 6 then
- say("Area cleared")
- bombarea:killzone(false)
- return false
- else
- say("The bomb will explode in " .. 5 - 1*count .. " seconds.")
- return true
- end
- end
- function replacebomb(id, count, m_weaponId)
- if m_weaponId then
- local m_weapon = getobject(m_weaponId)
- if m_weapon then
- --[[bomb.x = bomb.spawns[1]
- bomb.y = bomb.spawns[2]
- bomb.z = bomb.spawns[3]
- movobjectcoords(m_weaponId, bomb.x, bomb.y, bomb.z)--]]
- writefloat(m_weapon + 0x5C, readfloat(m_weapon + 0x5C) + 40.24)
- writefloat(m_weapon + 0x60, readfloat(m_weapon + 0x60) + -79.12)
- writefloat(m_weapon + 0x64, readfloat(m_weapon + 0x64) + 0.01)
- end
- end
- return false
- end
- function InfiniteAmmo(id, count, player)
- local m_player = getplayer(player)
- if m_player then
- local objId = readdword(m_player, 0x34)
- local m_object = getobject(objId)
- if m_object then
- for i = 0,3 do
- local weapId = readdword(m_object, 0x2F8 + (i * 4))
- local m_weapon = getobject(weapId)
- if m_weapon then
- writeword(m_weapon, 0x2B6, 9999)
- writeword(m_weapon, 0x2B8, 9999)
- updateammo(weapId)
- end
- end
- return true
- end
- end
- return false
- end
- function math.round(input, precision)
- return math.floor(input * (10 ^ precision) + 0.5) / (10 ^ precision)
- end
- -------------------------Nuggets GEO Script----------------------------------------------------------------
- -- Create Metatable
- GEO = {}
- GEO.__index = GEO
- -- Set random seed and define infinity
- math.randomseed(os.time())
- math.inf = 1 / 0
- function inSphere(objId, x, y, z, r)
- local ox, oy, oz = getobjectcoords(objId)
- if ox then
- -- Pythagorean
- local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2 + (z - oz) ^ 2)
- if dist <= r then
- return true
- end
- end
- return false
- end
- function inCircle(objId, x, y, z, r, orientation)
- local ox, oy, oz = getobjectcoords(objId)
- if ox then
- -- Default orientation to "z"
- orientation = orientation or "z"
- -- Pythagorean based on circle's orientation
- if orientation == "z" then
- local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2)
- if dist <= r and oz == z then
- return true
- end
- elseif orientation == "y" then
- local dist = math.sqrt((x - ox) ^ 2 + (z - oz) ^ 2)
- if dist <= r and oy == y then
- return true
- end
- elseif orientation == "x" then
- local dist = math.sqrt((y - oy) ^ 2 + (z - oz) ^ 2)
- if dist <= r and ox == x then
- return true
- end
- end
- end
- return false
- end
- function inCylinder(objId, x, y, zlow, zhigh, r)
- local ox, oy, oz = getobjectcoords(objId)
- if ox then
- -- Pythagorean to see if object is within radius of circle
- local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2)
- -- Make sure the object is also within the height of the cylinder
- if dist <= r and z >= zlow and z <= zhigh then
- return true
- end
- end
- return false
- end
- function inRectangle(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- -- These functions are essentially the same
- return inRectPrism(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- end
- function inRectPrism(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- if getobject(objId) then
- local x, y, z = getobjectcoords(objId)
- if x then
- -- Make sure the coordinates are inside of each extreme of the rectangular prism
- if x <= xhigh and x >= xlow and y <= yhigh and y >= ylow and z <= zhigh and z >= zlow then
- return true
- end
- end
- end
- return false
- end
- function randomInSphere(x, y, z, r)
- -- Increase precision
- x = math.floor(x * 100)
- y = math.floor(y * 100)
- z = math.floor(z * 100)
- r = math.floor(r * 100)
- -- Find random values inside of the sphere.
- return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, math.random(z - r, z + r + 1) / 100
- end
- function randomInCircle(x, y, z, r, orientation)
- -- Increase precision
- r = math.floor(r * 100)
- -- Possible values depend on circle's orientation.
- if orientation == "z" then
- x = math.floor(x * 100)
- y = math.floor(y * 100)
- return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, z
- elseif orientation == "x" then
- y = math.floor(y * 100)
- z = math.floor(z * 100)
- return x, math.random(y - r, y + r + 1) / 100, math.random(z - r, z + r + 1) / 100
- elseif orientation == "y" then
- x = math.floor(x * 100)
- z = math.floor(z * 100)
- return math.random(x - r, x + r + 1) / 100, y, math.random(z - r, z + r + 1) / 100
- end
- end
- function randomInCylinder(x, y, zlow, zhigh, r)
- -- Increase precision
- x = math.floor(x * 100)
- y = math.floor(y * 100)
- zlow = math.floor(zlow * 100)
- zhigh = math.floor(zhigh * 100)
- r = math.floor(r * 100)
- -- Find random values inside of the cylinder.
- return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, math.random(zlow, zhigh + 1) / 100
- end
- function randomInRectPrism(xlow, xhigh, ylow, yhigh, zlow, zhigh)
- -- Increase precision
- xlow = math.floor(xlow * 100)
- xhigh = math.floor(xhigh * 100)
- ylow = math.floor(ylow * 100)
- yhigh = math.floor(yhigh * 100)
- zlow = math.floor(zlow * 100)
- zhigh = math.floor(zhigh * 100)
- -- Find random values inside of the rectangular prism.
- return math.random(xlow, xhigh + 1) / 100, math.random(ylow, yhigh + 1) / 100, math.random(zlow, zhigh)
- end
- -- Object Creation Comments (refer to this function for questions on how the other ones work)
- function GEO.newSphere(name, r, x, y, z)
- -- Check to see if there is already a GEO with this name.
- if not GEO[name] then
- -- Create new table
- GEO[name] = {}
- GEO[name].t = "sphere" -- type
- GEO[name].n = name -- name
- GEO[name].r = r or 1 -- radius (default value of 1)
- GEO[name].x = x or 0 -- x coordinate of center (default value of 0)
- GEO[name].y = y or 0 -- y coordinate of center (default value of 0)
- GEO[name].z = z or 0 -- z coordinate of center (default value of 0)
- -- Notify the console that a sphere has been created.
- hprintf("Sphere \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO) -- Add this object to the GEO metatable to allow GEO-editing functions to work on it.
- return GEO[name] -- Return the object
- end
- -- If no object was returned, the name was invalid; notify the console.
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.newCircle(name, r, x, y, z, orientation)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "circle"
- GEO[name].n = name
- GEO[name].o = orientation or "z" -- orientation
- GEO[name].r = r or 0
- GEO[name].x = x or 0
- GEO[name].y = y or 0
- GEO[name].z = z or 0
- hprintf("Circle \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.newCylinder(name, r, h, x, y, z)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "cylinder"
- GEO[name].n = name
- x = x or 0
- y = y or 0
- z = z or 0
- r = r or 1
- h = h or 1
- GEO[name].x = x
- GEO[name].y = y
- GEO[name].z = z
- GEO[name].r = r
- GEO[name].h = h -- height
- GEO[name].zlow = z - h / 2 -- lowest z-coordinate still within the cylinder
- GEO[name].zhigh = z + h / 2 -- highest z-coordinate still within the cylinder
- hprintf("Cylinder \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- end
- function GEO.newRectPrism(name, lx, ly, lz, x, y, z)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "rectprism"
- GEO[name].n = name
- lx = lx or 1
- ly = ly or 1
- lz = lz or 1
- x = x or 0
- y = y or 0
- z = z or 0
- GEO[name].lx = lx -- x length
- GEO[name].ly = ly -- y length
- GEO[name].lz = lz -- z length
- GEO[name].x = x
- GEO[name].y = y
- GEO[name].z = z
- GEO[name].xlow = x - lx / 2 -- lowest x-coordinate still within the rectangular prism
- GEO[name].xhigh = lx / 2 + x -- highest x-coordinate still within in the rectangular prism
- GEO[name].ylow = y - ly / 2 -- lowest y-coordinate still within the rectangular prism
- GEO[name].yhigh = ly / 2 + y -- highest y-coordinate still within the rectangular prism
- GEO[name].zlow = z - lz / 2 -- lowest z-coordinate still within the rectangular prism
- GEO[name].zhigh = lz / 2 + z -- highest z-coordinate still within the rectangular prism
- hprintf("Rectangular Prism \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.newRect(name, width, height, x, y, z, orientation)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "rectangle"
- GEO[name].n = name
- width = width or 1
- height = height or 1
- x = x or 0
- y = y or 0
- z = z or 0
- orientation = orientation or "z"
- GEO[name].width = width
- GEO[name].height = height
- GEO[name].x = x
- GEO[name].y = y
- GEO[name].z = z
- GEO[name].o = orientation
- -- Coordinates' highs and lows depend on orientation
- if orientation == "z" then
- GEO[name].xlow = x - width / 2
- GEO[name].xhigh = x + width / 2
- GEO[name].ylow = y - height / 2
- GEO[name].yhigh = y + height / 2
- GEO[name].zlow = z
- GEO[name].zhigh = z
- elseif orientation == "x" then
- GEO[name].xlow = x
- GEO[name].xhigh = x
- GEO[name].ylow = y - width / 2
- GEO[name].yhigh = y + width / 2
- GEO[name].zlow = z - height / 2
- GEO[name].zhigh = z + height / 2
- elseif orientation == "y" then
- GEO[name].xlow = x - width / 2
- GEO[name].xhigh = x + width / 2
- GEO[name].ylow = y
- GEO[name].yhigh = y
- GEO[name].zlow = z - height / 2
- GEO[name].zhigh = z + height / 2
- end
- hprintf("Rectangle \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.get(name)
- return GEO[name]
- end
- function GEO:delete()
- self:hide()
- GEO[self.n] = nil
- hprintf("Geo \"" .. self.n .. "\" deleted.")
- end
- function GEO:move(x, y, z)
- -- Move the center of the object
- -- Default to GEO's current coordinates
- GEO[self.n].x = x or GEO[self.n].x
- GEO[self.n].y = y or GEO[self.n].y
- GEO[self.n].z = z or GEO[self.n].z
- -- If this is a rectangular prism...
- if self.t == "rectprism" then
- -- Change the x, y, and z lows and highs accordingly to adjust to the new center
- GEO[self.n].xlow = x - GEO[self.n].lx / 2
- GEO[self.n].xhigh = GEO[self.n].lx / 2 + x
- GEO[self.n].ylow = y - GEO[self.n].ly / 2
- GEO[self.n].yhigh = GEO[self.n].ly / 2 + y
- GEO[self.n].zlow = z - GEO[self.n].lz / 2
- GEO[self.n].zhigh = GEO[self.n].lz / 2 + z
- -- If this is a rectangle...
- elseif self.t == "rectangle" then
- -- Change the x, y, and z lows and highs accordingly to adjust to the new center (depends on orientation)
- if self.o == "z" then
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y - self.height / 2
- GEO[self.n].yhigh = self.y + self.height / 2
- GEO[self.n].zlow = self.z
- GEO[self.n].zhigh = self.z
- elseif self.o == "x" then
- GEO[self.n].xlow = self.x
- GEO[self.n].xhigh = self.x
- GEO[self.n].ylow = self.y - self.width / 2
- GEO[self.n].yhigh = self.y + self.width / 2
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- elseif self.o == "y" then
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y
- GEO[self.n].yhigh = self.y
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- GEO[self.n].zlow = self.z - self.h / 2
- GEO[self.n].zhigh = self.z + self.h / 2
- end
- end
- function GEO:radius(new)
- if self.t == "sphere" or self.t == "circle" or self.t == "cylinder" then
- if new then -- If "new" is defined...
- GEO[self.n].r = new -- Change the radius to its value.
- else -- If not...
- return GEO[self.n].r -- Return its current radius.
- end
- end
- end
- function GEO:size(x, y, z)
- -- If this is a rectangular prism...
- if self.t == "rectprism" then
- if x or y or z then -- If any of these variables have been defined...
- -- Adjust lengths and x, y, and z highs and lows accordingly.
- GEO[self.n].lx = x or GEO[self.n].lx
- GEO[self.n].ly = y or GEO[self.n].ly
- GEO[self.n].lz = z or GEO[self.n].lz
- GEO[self.n].xlow = GEO[self.n].x - x / 2
- GEO[self.n].xhigh = x / 2 + GEO[self.n].x
- GEO[self.n].ylow = GEO[self.n].y - y / 2
- GEO[self.n].yhigh = y / 2 + GEO[self.n].y
- GEO[self.n].zlow = GEO[self.n].z - z / 2
- GEO[self.n].zhigh = z / 2 + GEO[self.n].z
- else -- Otherwise...
- return GEO[self.n].lx, GEO[self.n].ly, GEO[self.n].lz -- Return the x, y, and z lengths.
- end
- -- If this is a rectangle...
- elseif self.t == "rectangle" then
- if x or y or z then -- If any of these variables are defined...
- -- Adjust width, height, and x, y, and z highs and lows accordingly (depends on orientation).
- if self.o == "z" then
- GEO[self.n].width = x
- GEO[self.n].height = y
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y - self.height / 2
- GEO[self.n].yhigh = self.y + self.height / 2
- GEO[self.n].zlow = self.z
- GEO[self.n].zhigh = self.z
- elseif self.o == "x" then
- GEO[self.n].width = y
- GEO[self.n].height = z
- GEO[self.n].xlow = self.x
- GEO[self.n].xhigh = self.x
- GEO[self.n].ylow = self.y - self.width / 2
- GEO[self.n].yhigh = self.y + self.width / 2
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- elseif self.o == "y" then
- GEO[self.n].width = x
- GEO[self.n].height = z
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y
- GEO[self.n].yhigh = self.y
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- end
- else -- Otherwise...
- return GEO[self.n].width, GEO[self.n].height -- Return the width and height of the rectangle.
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- local h = x or y or z -- Whichever variable is defined, it is taken as the height.
- if h then -- If a height is specified...
- -- Adjust height and z high and low accordingly.
- GEO[self.n].h = h
- GEO[self.n].zlow = self.z - h / 2
- GEO[self.n].zhigh = self.z + h / 2
- else -- Otherwise...
- return GEO[self.n].h -- Return the height.
- end
- end
- end
- function GEO:extend(orienation, direction, amount)
- -- Change the direction from "+" or "-" to "high" or "low".
- local dir
- dir = string.gsub(direction, "-", "low")
- dir = string.gsub(direction, "+", "high")
- -- Get the face we're trying to extend (i.e. "xhigh")
- local face = string.lower(orientation) .. direction
- -- If this is a rectangular prism or a rectangle...
- if self.t == "rectprism" or self.t == "rectangle" then
- -- Make sure "face" is actually a valid face (and not something like "cheesederp")
- if self[face] then
- -- Use "GEO[self.n]" when you want to actually permanently change the value of something within the object; use "self" for reading information from the object.
- -- Change the length of the GEO in the orientation specified.
- GEO[self.n]["l" .. string.lower(orientation)] = self["l" .. string.lower(orientation)] + amount
- -- Figure out if the positive or negative face is being extended.
- if direction == "+" then
- GEO[self.n][face] = self[face] + amount
- GEO[self.n][string.lower(orientation)] = self[string.lower(orientation)] + amount / 2
- else
- GEO[self.n][face] = self[face] - amount
- GEO[self.n][string.lower(orientation)] = self[string.lower(orientation)] - amount / 2
- end
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- -- The orientation must be "z"
- if orientation == "z" then
- if self[face] then
- GEO[self.n].h = self.h + amount
- -- Figure out if the top or bottom face is being extended.
- if direction == "+" then
- GEO[self.n][face] = self[face] + amount
- GEO[self.n].z = self.z + amount / 2
- else
- GEO[self.n][face] = self[face] - amount
- GEO[self.n].z = self.z - amount / 2
- end
- end
- end
- end
- end
- function GEO:coords()
- return self.x, self.y, self.z
- end
- function GEO:high(orientation)
- if self.t == "sphere" or self.t == "circle" then
- return self[orientation] + self.r
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return self[orientation .. "high"]
- elseif self.t == "cylinder" then
- if orientation == "z" then
- return self.zhigh
- else
- return self[orientation] + self.r
- end
- end
- end
- function GEO:low(orientation)
- if self.t == "sphere" or self.t == "circle" then
- return self[orientation] - self.r
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return self[orientation .. "low"]
- elseif self.t == "cylinder" then
- if orientation == "z" then
- return self.zlow
- else
- return self[orientation] - self.r
- end
- end
- end
- function GEO:randcoords()
- if self.t == "sphere" then
- return randomInSphere(self.x, self.y, self.z, self.r)
- elseif self.t == "circle" then
- return randomInCircle(self.x, self.y, self.z, self.r, self.o)
- elseif self.t == "cylinder" then
- return randomInCylinder(self.x, self.y, self.zlow, self.zhigh, self.r)
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return randomInRectPrism(self.xlow, self.xhigh, self.ylow, self.yhigh, self.zlow, self.zhigh)
- end
- end
- function GEO:type()
- return self.t
- end
- function GEO:orientation()
- return self.o
- end
- function GEO:name()
- return self.n
- end
- function GEO:perimeter(density, mapId)
- -- Default density to 10
- density = density or 10
- -- Default tagtype and tagname to Full-Spectrum Visions
- mapId = mapId or gettagid("eqip", "powerups\\full-spectrum vision")
- tagname, tagtype = gettaginfo(mapId)
- -- Store all of the perimeter objects in a table
- GEO[self.n].p = GEO[self.n].p or {}
- -- Find the change in angle per point from 0 - 2pi (0° - 360°)
- local angle_increment = 2 * math.pi / density
- if self.t == "sphere" or self.t == "cylinder" then
- for i = 1,density do
- -- Use trigonometry to find the outer edge of the circle (for a sphere, this will be at the z-center -- the widest part of the sphere).
- local x = self.r * math.cos(angle_increment * i)
- local y = self.r * math.sin(angle_increment * i)
- local z = self.z
- local objId = createobject(mapId, 0, 0, false, self.x + x, self.y + y, self.z + z)
- GEO[self.n].p[objId] = {self.x + x, self.y + y, self.z + z}
- end
- elseif self.t == "circle" then
- if self.o == "z" then
- for i = 1,density do
- -- Use trigonometry to find the outer edge of the circle (for a sphere, this will be at the z-center -- the widest part of the sphere).
- local x = self.r * math.cos(angle_increment * i)
- local y = self.r * math.sin(angle_increment * i)
- local z = self.z
- local objId = createobject(mapId, 0, 0, false, self.x + x, self.y + y, self.z + z)
- GEO[self.n].p[objId] = {self.x + x, self.y + y, self.z + z}
- end
- end
- elseif self.t == "rectprism" or self.t == "rectangle" then
- if self.t == "rectangle" then
- if self.o ~= "z" then return end
- end
- -- Create points at four corners of the rectangle
- local o1 = createobject(mapId, 0, 0, false, self.xhigh, self.yhigh, self.z)
- local o2 = createobject(mapId, 0, 0, false, self.xhigh, self.ylow, self.z)
- local o3 = createobject(mapId, 0, 0, false, self.xlow, self.yhigh, self.z)
- local o4 = createobject(mapId, 0, 0, false, self.xlow, self.ylow, self.z)
- GEO[self.n].p[o1] = {self.xhigh, self.yhigh, self.z}
- GEO[self.n].p[o2] = {self.xhigh, self.yhigh, self.z}
- GEO[self.n].p[o3] = {self.xhigh, self.yhigh, self.z}
- GEO[self.n].p[o4] = {self.xhigh, self.yhigh, self.z}
- for i = 1,density do
- local herp = createobject(mapId, 0, 0, false, self.xhigh - (i * self.lx / density), self.yhigh, self.z)
- local derp = createobject(mapId, 0, 0, false, self.xhigh, self.yhigh - (i * self.ly / density), self.z)
- local weee = createobject(mapId, 0, 0, false, self.xhigh - (i * self.lx / density), self.ylow, self.z)
- local cheese = createobject(mapId, 0, 0, false, self.xlow, self.ylow + (i * self.ly / density), self.z)
- GEO[self.n].p[herp] = {self.xhigh - (i * self.lx / density), self.yhigh, self.z}
- GEO[self.n].p[derp] = {self.xhigh, self.yhigh - (i * self.ly / density), self.z}
- GEO[self.n].p[weee] = {self.xhigh - (i * self.lx / density), self.ylow, self.z}
- GEO[self.n].p[cheese] = {self.xlow, self.ylow + (i * self.ly / density), self.z}
- end
- end
- end
- function GEO:hide()
- if self.p then
- for k,v in pairs(GEO[self.n].p) do
- if getobject(k) then
- destroyobject(k)
- GEO[self.n].p[k] = nil
- end
- end
- end
- end
- -- Never quite got this to work right, but I'm saving it for the sake of the formula.
- --[[function GEO:surface(density)
- GEO[self.n].p = GEO[self.n].p or {}
- if self.t == "sphere" then
- local inc = math.pi * (3 - math.sqrt(5))
- local off = 2 / density
- for i = 1,density do
- local y = self.r * i * off - 1 + (off / 2)
- local r = self.r * math.sqrt(1 - y ^ 2)
- local phi = i * inc
- local x = r * math.cos(phi)
- local z = r * math.sin(phi)
- local objId = createobject(mapId, 0, 0, false, x, y, z)
- GEO[self.n].p[objId] = {x, y, z}
- end
- end
- end--]]
- function GEO:contains(objId)
- if self.t == "sphere" then
- return inSphere(objId, self.x, self.y, self.z, self.r)
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return inRectPrism(objId, self.xlow, self.xhigh, self.ylow, self.yhigh, self.zlow, self.zhigh)
- elseif self.t == "circle" then
- return inCircle(objId, self.x, self.y, self.z, self.r, self.o)
- elseif self.t == "cylinder" then
- return inCylinder(objId, self.x, self.y, self.zlow, self.zhigh, self.r)
- end
- end
- function GEO:follow(objId)
- -- If the objId exists...
- if getobject(objId) then
- GEO[self.n].f = objId -- Save it (the GEOTimer will access it)
- -- Check to see if the object is a player
- if objectidtoplayer(objId) then
- GEO[self.n].player = true
- end
- end
- end
- function GEO:unfollow()
- -- Nullify the saved objId from GEO:follow()
- GEO[self.n].f = nil
- end
- function GEO.followedBy(objId)
- -- Initialize table
- local geos = {}
- -- Loop through the GEO table
- for k,v in pairs(GEO) do
- if type(v) == "table" and k ~= "__index" then -- make sure we're actually getting a GEO object
- if v.f == objId then
- -- If this GEO has this objId saved, insert it into the geos table.
- table.insert(geos, v)
- end
- end
- end
- -- Return the GEOs following objId in a table.
- return geos
- end
- function GEO.cleanup(player)
- local m_player = getplayer(player)
- local objId = readdword(m_player, 0x34)
- local geos = GEO.followedBy(objId)
- for k,v in ipairs(geos) do
- v:delete()
- end
- end
- function GEO:velocity(x, y, z)
- GEO[self.n].vx = x or GEO[self.n].vx
- GEO[self.n].vy = y or GEO[self.n].vy
- GEO[self.n].vz = z or GEO[self.n].vz
- end
- function GEO:killzone(bool)
- if bool == true then
- GEO[self.n].kz = true
- elseif bool == false then
- GEO[self.n].kz = false
- elseif bool == nil then
- return GEO[self.n].kz or false
- end
- end
- function GEO:damagezone(bool, damage)
- if bool == true then
- GEO[self.n].damage = damage or 1 -- Amount of damage applied per second.
- elseif bool == false then
- GEO[self.n].damage = nil
- elseif bool == nil then -- If nothing is passed, return true if this GEO is a damagezone, false if not.
- if GEO[self.n].damage then
- return true
- else
- return false
- end
- end
- end
- function GEO:face(orientation, direction)
- -- If this is a rectangular prism...
- if self.t == "rectprism" then
- orientation = orientation or "z"
- direction = direction or "+"
- if orientation == "z" then
- local width = self.lx
- local height = self.ly
- local highlow
- if direction == "+" then
- highlow = self.zhigh
- else
- highlow = self.zlow
- end
- -- Create a new rectangle which overlays the specified face and return that rectangle.
- return GEO.newRect(self.n .. "ZFace" .. os.time(), width, height, self.x, self.y, highlow, orientation)
- elseif orientation == "x" then
- local width = self.ly
- local height = self.lz
- local highlow
- if direction == "+" then
- highlow = self.xhigh
- else
- highlow = self.xlow
- end
- return GEO.newRect(self.n .. "XFace" .. os.time(), width, height, highlow, self.y, self.z, orientation)
- elseif orientation == "y" then
- local width = self.lx
- local height = self.lz
- local highlow
- if direction == "+" then
- highlow = self.yhigh
- else
- highlow = self.ylow
- end
- return GEO.newRect(self.n .. "YFace" .. os.time(), width, height, self.x, highlow, self.z, orientation)
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- if orientation == "z" then
- local highlow
- if direction == "+" then
- highlow = self.zhigh
- else
- highlow = self.zlow
- end
- -- Return a new circle which overlays the specified face and return that circle.
- return GEO.newCircle(self.n .. "ZFace" .. os.time(), self.r, self.x, self.y, highlow, "z")
- else
- hprintf("You may only retrieve the Z face of a cylinder.")
- end
- end
- end
- function GEO:copy(name)
- name = name or self.n .. "Copy" .. os.time()
- if not GEO[name] then
- GEO[name] = self
- return GEO[name]
- end
- end
- function GEO:monitor(objId)
- if getobject(objId) then
- GEO[self.n].m = GEO[self.n].m or {}
- GEO[self.n].c = GEO[self.n].c or {}
- GEO[self.n].m[objId] = true
- end
- end
- registertimer(10, "GEOTimer")
- function GEOTimer(id, count)
- -- Create a coordinates table for players if it hasn't already been created
- pcoords = pcoords or {}
- -- Loop through the GEO table
- for k,v in pairs(GEO) do
- if type(v) == "table" and k ~= "__index" then
- -- If this GEO is following an object...
- if v.f then
- -- Get the coordinates of the object
- local x, y, z = getobjectcoords(v.f)
- if x then -- If this object exists...
- if v.player then
- local player = objectidtoplayer(v.f)
- if player then
- local m_player = getplayer(player) -- See if the player is still here
- if m_player then -- If they are...
- local time_until_respawn = readdword(m_player, 0x2C) -- Check to see if they're dead
- if time_until_respawn == 0 then -- If they're not...
- if v.p then -- If this GEO has perimeter objects...
- for objId, coords in pairs(v.p) do
- if getobject(objId) then
- local ox, oy, oz = table.unpack(coords)
- local x_diff = x - v.x
- local y_diff = y - v.y
- local z_diff = z - v.z
- local m_object = getobject(objId)
- movobjcoords(objId, ox + x_diff, oy + y_diff, oz + z_diff) -- Move them with the GEO.
- GEO[v.n].p[objId] = {ox + x_diff, oy + y_diff, oz + z_diff}
- end
- end
- end
- v:move(x, y, z) -- Move the GEO to the player's coordinates
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- else -- Otherwise...
- if v.p then -- If this GEO has perimeter objects...
- for objId, coords in pairs(v.p) do
- if getobject(objId) then
- local ox, oy, oz = table.unpack(coords)
- local x_diff = x - v.x
- local y_diff = y - v.y
- local z_diff = z - v.z
- local m_object = getobject(objId)
- movobjcoords(objId, ox + x_diff, oy + y_diff, oz + z_diff) -- Move them with the GEO.
- GEO[v.n].p[objId] = {ox + x_diff, oy + y_diff, oz + z_diff}
- end
- end
- end
- v:move(x, y, z) -- Don't worry about all of that player nonsense and just move the damn GEO.
- end
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- end
- -- If after all of that following nonsense, we still have a GEO...
- if v then
- -- If this GEO is a killzone...
- if v.kz then
- -- Check if anyone is inside of it.
- for i = 0,15 do
- if getplayer(i) then
- local m_player = getplayer(i)
- local objId = readdword(m_player, 0x34)
- if v:contains(objId) then
- kill(i) -- Kill that ho.
- end
- end
- end
- end
- -- If this GEO is a damagezone...
- if v.damage then
- -- Check if anyone is inside of it.
- for i = 0,15 do
- local m_player = getplayer(i)
- if m_player then
- local objId = readdword(m_player, 0x34)
- if v:contains(objId) then
- applydmg(objId, v.damage / 100) -- Apply damage
- end
- end
- end
- end
- -- If this GEO is monitoring for objects entering and exiting it...
- if v.m then
- -- Loop through the table of objects this GEO is monitoring for.
- for objId,_ in pairs(v.m) do
- -- If this object still exists...
- if getobject(objId) then
- -- If this object is inside of the GEO...
- if v:contains(objId) then
- -- If the GEO didn't know this object was inside of it 1/100 of a second ago...
- if not v.c[objId] then
- local player = objectidtoplayer(objId)
- -- Call OnGeoEnter.
- local allow = OnGeoEnter(v, player, objId)
- if allow == 0 or allow == false then
- local hash = gethash(player)
- if pcoords[hash] then
- movobjcoords(objId, table.unpack(pcoords[hash]))
- end
- else
- GEO[k].c[objId] = true
- end
- end
- else -- Otherwise...
- -- If the GEO thought this object was inside of it 1/100 of a second ago...
- if v.c[objId] then
- local player = objectidtoplayer(objId)
- -- Call OnGeoExit.
- local allow = OnGeoExit(v, player, objId)
- if allow == 0 or allow == false then
- local hash = gethash(player)
- if pcoords[hash] then
- movobjcoords(objId, table.unpack(pcoords[hash]))
- end
- else
- GEO[k].c[objId] = nil
- end
- end
- end
- else -- Otherwise...
- GEO[k].m[objId] = nil -- Stop monitoring for this object.
- end
- end
- end
- -- If this GEO has a velocity...
- if v.vx or v.vy or v.vz then
- if v.p then -- If this GEO has perimeter objects...
- for objId, coords in pairs(v.p) do
- if getobject(objId) then
- local ox, oy, oz = table.unpack(coords)
- local m_object = getobject(objId)
- movobjcoords(objId, ox + (v.vx or 0), oy + (v.vy or 0), oz + (v.vz or 0)) -- Move them with the GEO.
- GEO[v.n].p[objId] = {ox + (v.vx or 0), oy + (v.vy or 0), oz + (v.vz or 0)}
- end
- end
- end
- -- Move that ho.
- v:move(v.x + (v.vx or 0) / 100, v.y + (v.vy or 0) / 100, v.z + (v.vz or 0) / 100)
- end
- end
- end
- end
- -- Update coordinates at a slight delay for blocking GEO entry/exit (if there is no delay, players in mid-air could end up dying since they'll just be teleported in mid-air perpetually)
- if count % 25 == 0 then
- for i = 0,15 do
- local m_player = getplayer(i)
- if m_player then
- local hash = gethash(i)
- local objId = readdword(m_player, 0x34)
- if getobject(objId) then
- pcoords[hash] = {getobjectcoords(objId)}
- else
- pcoords[hash] = nil
- end
- end
- end
- end
- return true
- end
- function OnGeoEnter(geo, player, objId)
- local hash = gethash(player)
- if geo == bombarea then
- if players[hash].bomb then
- privatesay(player, "Bomb droped")
- registertimer(1000, "ExplosionTimer")
- return true
- else
- privatesay(player, "You don't have the bomb")
- return true
- end
- end
- return true
- end
- function OnGeoExit(geo, player, objId)
- return true
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement