Advertisement
Combreal

Csgt02.lua

Dec 18th, 2014
771
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 70.53 KB | None | 0 0
  1. --      CounterStrike gametype like                                             --
  2. --      Inspired from Nuggets's Conquest and geo scripts                        --
  3. --      The goal for the blue team is to explode the red base                   --
  4. --      Red team have to kill the player holding the bomb to avoid it           --
  5. --      Contains Nuggets, AelitePrime and Wizard codes                          --
  6. --      The script works only on BloodGulch                                     --
  7. --      It requieres a ctf gametype with the nav points disabled                --
  8. --      Also made in a Rockets only purpose                                     --
  9.  
  10.         RocketId = nil
  11.  
  12.         BombId = nil
  13.  
  14.         bombarea = nil
  15.  
  16.         bomb = {}
  17.  
  18.         bomb.respawn = 45.0
  19.  
  20.         bomb.spawns = {40.15, -76.7, 0.01} --blue base
  21.  
  22.         flagcoords = {95.69, -159.44, 0.01} --red flag coords
  23.  
  24.         players = {}
  25.         players.bomb = nil
  26.         players.monitored = false
  27.  
  28.         terroristneedweap = nil
  29.  
  30.         respawn_time = 7
  31.  
  32.         weapons = {}
  33.  
  34.         finalscore = 0
  35.  
  36.         terroristscounter = 0
  37.         redscounter = 0
  38.  
  39. function GetRequiredVersion()
  40.         return 200
  41. end
  42.  
  43. function OnScriptLoad(processid, game, persistent)
  44.     LoadTags()
  45.     GetGameAddresses(game)
  46.     writedword(flag_respawn_addr, 0, 0xFFFFFFFF) -- try to disable the flag
  47.     writedword(flag_respawn_addr, 1, 0xFFFFFFFF) -- try to disable the flag
  48.     writedword(gametype_base, 0x48, respawn_time * 30) -- and avoid it respawns
  49.     writebyte(gametype_base, 0x58, 2)
  50. end
  51.  
  52. function OnScriptUnload()
  53.  
  54. end
  55.  
  56. function GetGameAddresses(game)
  57.     if game == "PC" then
  58.         flag_respawn_addr = 0x488A7E -- Confirmed by Nugets
  59.         stats_header = 0x639720 -- Confirmed.
  60.         stats_globals = 0x639898 -- Confirmed.
  61.         ctf_globals = 0x639B98 -- Confirmed.
  62.         slayer_globals = 0x63A0E8 -- Confirmed.
  63.         oddball_globals = 0x639E58 -- Confirmed.
  64.         koth_globals = 0x639BD0 -- Confirmed.
  65.         race_globals = 0x639FA0 -- Confirmed.
  66.         race_locs = 0x670F40 -- Confirmed.
  67.         map_pointer = 0x63525c -- Confirmed.
  68.         gametype_base = 0x671340 -- Confirmed.
  69.         network_struct = 0x745BA0 -- Confirmed.
  70.         camera_base = 0x69C2F8 -- Confirmed.
  71.         player_header_pointer = 0x75ECE4 -- Confirmed.
  72.         obj_header_pointer = 0x744C18 -- Confirmed.
  73.         map_header_base = 0x630E74 -- Confirmed.
  74.         banlist_header = 0x641280 -- Confirmed.
  75.         game_globals = "???" -- (???) Why do I not have this for PC?
  76.         gameinfo_header = 0x671420 -- Confirmed.
  77.         mapcycle_header = 0x614B4C -- Confirmed.
  78.         network_server_globals = 0x69B934 -- Confirmed.
  79.         flags_pointer = 0x6A590C -- Confirmed.
  80.         hash_table_base = 0x6A2AE4 -- Confirmed.
  81.         --Patches
  82.         gametype_patch = 0x481F3C
  83.         hashcheck_patch = 0x59c280 -- Confirmed.
  84.         servername_patch = 0x517D6B -- Confirmed.
  85.         versioncheck_patch = 0x5152E7 -- Confirmed.
  86.     else
  87.         stats_header = 0x5BD740 -- Confirmed.
  88.         stats_globals = 0x5BD8B8 -- Confirmed.
  89.         ctf_globals = 0x5BDBB8 -- Confirmed.
  90.         slayer_globals = 0x5BE108 -- Confirmed.
  91.         oddball_globals = 0x5BDE78 -- Confirmed.
  92.         koth_globals = 0x5BDBF0 -- Confirmed.
  93.         race_globals = 0x5BDFC0 -- Confirmed.
  94.         race_locs = 0x5F5098 -- Confirmed.
  95.         map_pointer = 0x5B927C -- Confirmed.
  96.         gametype_base = 0x5F5498 -- Confirmed.
  97.         network_struct = 0x6C7980 -- Confirmed.
  98.         camera_base = 0x62075C -- Confirmed.
  99.         player_globals = 0x6E1478 -- From OS.
  100.         player_header_pointer = 0x6E1480 -- Confirmed.
  101.         obj_header_pointer = 0x6C69F0 -- Confirmed.
  102.         map_header_base = 0x6E2CA4 -- Confirmed.
  103.         banlist_header = 0x5C52A0 -- Confirmed.
  104.         game_globals = 0x61CFE0 -- Confirmed.
  105.         gameinfo_header = 0x5F55BC -- Confirmed.
  106.         mapcycle_header = 0x598A8C -- Confirmed.
  107.         network_server_globals = 0x61FB64 -- Confirmed.
  108.         hash_table_base = 0x5AFB34 -- Confirmed.
  109.         --Patches
  110.         hashcheck_patch = 0x530130 -- Confirmed.
  111.         servername_patch = 0x4CE0CD -- Confirmed.
  112.         versioncheck_patch = 0x4CB587 -- Confirmed.
  113.     end
  114. end
  115.  
  116. function OnGameEnd(stage)
  117.     if stage == 1 then
  118.         if finalscore ~= 3 then
  119.             say("red team won")
  120.             writedword(ctf_globals, 0x10, 3)
  121.             terroristneedweap = nil
  122.         else
  123.             say("blue team won")
  124.             writedword(ctf_globals + 0x4, 0x10, 3)
  125.             terroristneedweap = nil
  126.         end
  127.     elseif stage == 3 then
  128.         writedword(flag_respawn_addr, 0, 17 * 30) -- flag respawn addr
  129.     end
  130. end
  131.  
  132. function OnNewGame(map)
  133.     LoadTags()
  134.     RocketId = rocketlauncher_tag_id
  135.     BombId = oddball_tag_id
  136.     bomb.x = bomb.spawns[1]
  137.     bomb.y = bomb.spawns[2]
  138.     bomb.z = bomb.spawns[3]
  139.     bomb.objId = createobject(BombId, 0, 0, false, bomb.x, bomb.y, bomb.z)
  140.     local m_object = getobject(bomb.objId)
  141.     writefloat(m_object + 0x74, 0) -- -0.3 pitch the objective
  142.     writefloat(m_object + 0x78, 1) --pitch the objective
  143.     bomb.respawn_remain = bomb.respawn
  144.     registertimer(1000, "Respawn", "bomb")
  145.     registertimer(5000, "CreateBomb")
  146.     writedword(flag_respawn_addr + 0x0, 0xFFFFFFFF)  -- coord flag pointer
  147.     registertimer(0, "CreationDelay") -- flag undermap
  148. end
  149.  
  150. function CreateBomb(id, count)
  151.     if count == 1 then
  152.         bombarea = GEO.newRectPrism("bombarea", 5, 5, 5, flagcoords[1], flagcoords[2], flagcoords[3])
  153.         return false
  154.     end
  155. end
  156.  
  157. function newplayer(player)
  158.     local hash = gethash(player)
  159.     local team = getteam(player)
  160.     players[hash] = players[hash] or {}
  161.     players[hash].bomb = false
  162.     players[hash].monitored = false
  163.     if team == 1 then -- kindof messy but working, ok terrible
  164.         privatesay(player, "You are a terrorist, explode the red base")
  165.         privatesay(player, "Type help in chat for further instructions")
  166.         terroristscounter = terroristscounter + 1
  167.     elseif team == 0 and terroristscounter == 1 and redscounter == 1 then
  168.         changeteam(player, true)
  169.         privatesay(player, "The game needs more terrorists, go explode the red base")
  170.         privatesay(player, "Type help in chat for further instructions")
  171.         terroristscounter = terroristscounter + 1
  172.     elseif team == 1 and terroristscounter == 2 and redscounter == 1 then
  173.         changeteam(player, true)
  174.         privatesay(player, "The game needs more reds, protect your base")
  175.         privatesay(player, "Type help in chat for further instructions")
  176.         redscounter = redscounter + 1
  177.     elseif team == 0 and terroristscounter == 2 and redscounter == 1 then
  178.         changeteam(player, true)
  179.         privatesay(player, "The game needs more terrorists, go explode the red base")
  180.         privatesay(player, "Type help in chat for further instructions")
  181.         terroristscounter = terroristscounter + 1
  182.     elseif team == 0 and terroristscounter == 5 and redscounter == 3 then
  183.         changeteam(player, true)
  184.         privatesay(player, "The game needs more terrorists, go explode the red base")
  185.         privatesay(player, "Type help in chat for further instructions")
  186.         terroristscounter = terroristscounter + 1
  187.     elseif team == 1 and terroristscounter == 6 and redscounter == 3 then
  188.         changeteam(player, true)
  189.         privatesay(player, "The game needs more reds, protect your base")
  190.         privatesay(player, "Type help in chat for further instructions")
  191.         redscounter = redscounter + 1
  192.     elseif team == 0 and terroristscounter == 6 and redscounter == 4 then
  193.         changeteam(player, true)
  194.         privatesay(player, "The game needs more terrorists, go explode the red base")
  195.         privatesay(player, "Type help in chat for further instructions")
  196.         terroristscounter = terroristscounter + 1
  197.     elseif team == 0 and terroristscounter == 9 and redscounter == 5 then
  198.         changeteam(player, true)
  199.         privatesay(player, "The game needs more terrorists, go explode the red base")
  200.         privatesay(player, "Type help in chat for further instructions")
  201.         terroristscounter = terroristscounter + 1
  202.     else
  203.         privatesay(player, "Protect your base from the blue terrorists")
  204.         privatesay(player, "Type help in chat for further instructions")
  205.         redscounter = redscounter + 1
  206.     end
  207. end
  208.  
  209.  
  210. function CreationDelay(id, count)
  211.     for i = 0,1 do
  212.         ctf_flag_coords_pointer = readdword(ctf_globals + i * 4, 0x0)
  213.         writefloat(ctf_flag_coords_pointer, 0)
  214.         writefloat(ctf_flag_coords_pointer + 4, 0)
  215.         writefloat(ctf_flag_coords_pointer + 8, -1000)
  216.     end
  217.     return false
  218. end
  219.  
  220. function OnPlayerJoin(player)
  221.     newplayer(player)
  222. end
  223.  
  224. function OnObjectCreationAttempt(mapId, parentId, player)
  225.         if mapId == flag_tag_id then
  226.             local m_objectId = readdword(ctf_globals + 0x8)
  227.             registertimer(0, "PutUnderMap", m_objectId)
  228.             return
  229.         end
  230.     return nil
  231. end
  232.  
  233. function OnPlayerSpawnEnd(player, m_objectId)
  234.     for i = 0,3 do
  235.         local m_object = getobject(m_objectId)
  236.         if m_object then
  237.             local weapID = readdword(m_object + 0x2F8 + i*4)
  238.             local weap = getobject(weapID)
  239.             if weap then
  240.                 destroyobject(weapID)
  241.             end
  242.         end
  243.     end
  244.     local rocketla = createobject(RocketId, 0, 1, false, 0, 0, 0)
  245.     assignweapon(player, rocketla)
  246.     registertimer(1000, "InfiniteAmmo", player)
  247. end
  248.  
  249. function OnObjectInteraction(player, objId, mapId)
  250.     local team = getteam(player)
  251.     if mapId == oddball_tag_id then
  252.         if team == 0 then
  253.             return false
  254.         end
  255.     elseif mapId == flag_tag_id then -- useless as flag is undermap
  256.         return false
  257.     end
  258. end
  259.  
  260. function OnWeaponPickup(player, weapId, slot, mapId)
  261.     local hash = gethash(player)
  262.     if mapId == oddball_tag_id then
  263.         players[hash].bomb = true
  264.         bomb.player = player
  265.         sendconsoletext(player, "You have the bomb")
  266.         sendconsoletext(player, "Go blow the red base")
  267.     end
  268. end
  269.  
  270. function OnWeaponDrop(player, weapId, slot, mapId)
  271.     local hash = gethash(player)
  272.     if mapId == oddball_tag_id then
  273.         players[hash].bomb = false
  274.         bomb.player = nil
  275.     end
  276. end
  277.  
  278. function Respawn(id, count, item)
  279.         if _G[item].player then
  280.                 _G[item].respawn_remain = _G[item].respawn
  281.         else
  282.                 local objId = _G[item].objId
  283.                 local m_object = getobject(objId)
  284.                 if m_object then
  285.                         local x, y, z = getobjectcoords(objId)
  286.                         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
  287.                                 _G[item].respawn_remain = _G[item].respawn
  288.                         else
  289.                                 _G[item].respawn_remain = _G[item].respawn_remain - 1
  290.                                 if _G[item].respawn_remain <= 0 then
  291.                                         movobjectcoords(objId, _G[item].x, _G[item].y, _G[item].z)
  292.                                         local m_object = getobject(_G[item].objId)
  293.                                         writebit(m_object, 0x10, 5, 0)
  294.                                         _G[item].respawn_remain = _G[item].respawn
  295.                                 end
  296.                         end
  297.                 else
  298.                         _G[item].respawn_remain = _G[item].respawn_remain - 1
  299.                         if _G[item].respawn_remain <= 0 then
  300.                                 _G[item].objId = createobject(BombId, 0, 0, false, _G[item].x, _G[item].y, _G[item].z)
  301.                                 _G[item].respawn_remain = _G[item].respawn
  302.                         end
  303.                 end
  304.         end
  305.         return true
  306. end
  307.  
  308. registertimer(10, "WeaponMonitor")
  309.  
  310. function WeaponMonitor(id, count)
  311.  
  312.     for player = 0,15 do
  313.         weapons[player] = weapons[player] or {}
  314.         local m_player = getplayer(player)
  315.         if m_player then
  316.             local temp = {}
  317.             local objId = readdword(m_player, 0x34) -- for ctf global
  318.             local m_object = getobject(objId)
  319.             if m_object then
  320.                 for i = 0,3 do
  321.                     local weapId = readdword(m_object, 0x2F8 + (i * 4))
  322.                     local m_weapon = getobject(weapId)
  323.                     if m_weapon then
  324.                         local mapId = readdword(m_weapon)
  325.                         if weapons[player][i] then
  326.                             if weapons[player][i].weapId ~= weapId then
  327.                                 OnWeaponDrop(player, weapons[player][i].weapId, i, weapons[player][i].mapId)
  328.                                 weapons[player][i] = {}
  329.                                 weapons[player][i].weapId = weapId
  330.                                 weapons[player][i].mapId = mapId
  331.                                 OnWeaponPickup(player, weapId, i, mapId)
  332.                             end
  333.                         else
  334.                             weapons[player][i] = {}
  335.                             weapons[player][i].weapId = weapId
  336.                             weapons[player][i].mapId = mapId
  337.                             OnWeaponPickup(player, weapId, i, mapId)
  338.                         end
  339.                     else
  340.                         if weapons[player][i] then
  341.                             OnWeaponDrop(player, weapons[player][i].weapId, i, weapons[player][i].mapId)
  342.                             weapons[player][i] = nil
  343.                         end
  344.                     end
  345.                 end
  346.             else
  347.                 for i = 0,3 do
  348.                     if weapons[player][i] then
  349.                         OnWeaponDrop(player, weapons[player][i].weapId, i, weapons[player][i].mapId)
  350.                         weapons[player][i] = nil
  351.                     end
  352.                 end
  353.             end
  354.         end
  355.     end
  356.  
  357.     return true
  358. end
  359.  
  360. function setscore(player, score)
  361. finalscore = finalscore + 1
  362.     local m_player = getplayer(player)
  363.     if m_player then
  364.         local actualscore = readdword(m_player + 0xC8)
  365.         local playerscore = actualscore + score
  366.         writeword(m_player, 0xC8, playerscore)
  367.     end
  368. end
  369.  
  370. function PutUnderMap(id, count, m_objectId)
  371.     local m_object = getobject(m_objectId)
  372.     if m_object then
  373.         local x,y,z = getobjectcoords(m_objectId)
  374.         movobjectcoords(m_objectId, x, y, z - 20)
  375.     end
  376.     return false
  377. end
  378.  
  379. function OnTeamChange(player, old_team, dest_team, relevant)
  380.     if relevant == 1 or relevant == true then
  381.         local hash = gethash(player)
  382.         if dest_team == 0 then
  383.             privatesay(player, "You are a terrorist, explode the red base")
  384.             privatesay(player, "Type help in chat for further instructions")
  385.             redscounter = redscounter - 1
  386.             terroristscounter = terroristscounter + 1
  387.         else
  388.             privatesay(player, "Protect your base from the blue terrorists")
  389.             privatesay(player, "Type help in chat for further instructions")
  390.             terroristscounter = terroristscounter - 1
  391.             redscounter = redscounter + 1
  392.         end
  393.         players[hash].bomb = false
  394.         players[hash].monitored = false
  395.     end
  396. end
  397.  
  398. function OnServerChat(player, type, message)
  399.     if player then
  400.         local team = getteam(player)
  401.         if string.lower(message) == "help" then
  402.             if team == 0 then
  403.                 registertimer(1000, "RedHelper", player)
  404.             else
  405.                 registertimer(1000, "BlueHelper", player)
  406.             end
  407.         end
  408.     end
  409. end
  410.  
  411. function RedHelper(id, count, player)
  412.     if getplayer(player) then
  413.         if count == 1 then
  414.             sendconsoletext(player, "CounterStrike GameType:")
  415.             return true
  416.         elseif count == 4 then
  417.             sendconsoletext(player, "You must avoid a blue player holding the bomb enters your base")
  418.             return true
  419.         elseif count == 7 then
  420.             sendconsoletext(player, "If your team managed to prevent the bomb from exploding in your base 3 times")
  421.             return true
  422.         elseif count == 10 then
  423.             sendconsoletext(player, "and if the game reached its time limit, you won.")
  424.             return true
  425.         elseif count == 13 then
  426.             return false
  427.         else
  428.             return true
  429.         end
  430.     end
  431. end
  432.  
  433. function BlueHelper(id, count, player)
  434.     if getplayer(player) then
  435.         if count == 1 then
  436.             sendconsoletext(player, "CounterStrike GameType:")
  437.             return true
  438.         elseif count == 4 then
  439.             sendconsoletext(player, "You have to pick up the bomb in the back entrance of your base")
  440.             return true
  441.         elseif count == 7 then
  442.             sendconsoletext(player, "and go to explode it in the red base to score")
  443.             return true
  444.         elseif count == 10 then
  445.             sendconsoletext(player, "When your team score 3 times, you won.")
  446.             return true
  447.         elseif count == 13 then
  448.             return false
  449.         else
  450.             return true
  451.         end
  452.     end
  453. end
  454.  
  455. function OnPlayerLeave(player)
  456.     local hash = gethash(player)
  457.     local m_objectId = getplayerobjectid(player)
  458.     if m_objectId then
  459.         local m_object = getobject(m_objectId)
  460.         if m_object then
  461.             for i = 0,3 do
  462.                 local weapID = readdword(m_object + 0x2F8 + i*4)
  463.                 if weapID then
  464.                     local weap = getobject(weapID)
  465.                     if weap then
  466.                         destroyobject(weapID)
  467.                     end
  468.                 end
  469.             end
  470.         end
  471.     end
  472.     players[hash].bomb = false
  473.     players[hash].monitored = false
  474. end
  475.  
  476. function OnPlayerKill(killer, victim, mode)
  477.     local hash = gethash(victim)
  478.     local m_player = getplayer(victim)
  479.     if m_player == nil then
  480.         return
  481.     end
  482.     local m_object = getobject(readdword(m_player +  0x34))
  483.     if m_object then
  484.         for i = 0,3 do
  485.             local weapID = readdword(m_object + 0x2F8 + i*4)
  486.             if weapID then
  487.                 local weap = getobject(weapID)
  488.                 if weap then
  489.                     destroyobject(weapID)
  490.                 end
  491.             end
  492.         end
  493.     end
  494.     players[hash].bomb = false
  495.     players[hash].monitored = false
  496. end
  497.  
  498. function OnClientUpdate(player)
  499.     writedword(ctf_globals + 0x10, 0) -- dunno
  500.     writedword(ctf_globals + 0x14, 0) --
  501.     local objectid = getplayerobjectid(player)
  502.     local hash = gethash(player)
  503.     local team = getteam(player)
  504.     if team == 1 and bombarea ~= nil then
  505.         if not players[hash].monitored then
  506.             bombarea:monitor(objectid)
  507.             players[hash].monitored = true
  508.         end
  509.         if players[hash].bomb then
  510.             local m_player = getplayer(player)
  511.             if m_player == nil then
  512.                 return
  513.             end
  514.             local m_objectId = getplayerobjectid(player)
  515.             if m_objectId == nil then
  516.                 return
  517.             end
  518.             local m_object = getobject(m_objectId)
  519.             if m_object then
  520.                 local shooting = readbit(m_object + 0x209, 4)
  521.                 local nading2 = readbit(m_object + 0x209, 2)
  522.                 local nading = readbit(m_object + 0x209, 3)
  523.                 if shooting == true or nading == true then
  524.                     weapID = bomb.objId
  525.                     if m_player then
  526.                         if weapID then
  527.                             if getobject(weapID) then
  528.                                 assignweapon(player, weapID)
  529.                             end
  530.                         end
  531.                     end
  532.                 end
  533.             end
  534.         end
  535.     end
  536.     if terroristneedweap then
  537.         local rocketl = createobject(RocketId, 0, 1, false, 0, 0, 0)
  538.         assignweapon(player, rocketl)
  539.         registertimer(1000, "InfiniteAmmo", player)
  540.         terroristneedweap = nil
  541.     end
  542.     if finalscore == 3 then
  543.         svcmd("sv_map_next")
  544.     end
  545. end
  546.  
  547. function ExplosionTimer(id, count)
  548.     if count == 4 then
  549.         for i=0,15 do
  550.             if getplayer(i) then
  551.                 local hash = gethash(i)
  552.                 if players[hash].bomb then
  553.                     setscore(i, 1)
  554.                     local m_player = getplayer(i)
  555.                     local m_object = getobject(readdword(m_player +  0x34))
  556.                     if m_object then
  557.                         for x = 0,3 do
  558.                             local weapId = readdword(m_object + 0x2F8 + x*4)
  559.                             local weap = getobject(weapId)
  560.                             if weap then
  561.                                 registertimer(0, "replacebomb", weapId)
  562.                                 destroyobject(weapId)
  563.                                 terroristneedweap = true
  564.                             end
  565.                         end
  566.                     end
  567.                 end
  568.             end
  569.         end
  570.         return true
  571.     elseif count == 5 then
  572.         say("The bomb exploded!")
  573.         bombarea:killzone(true)
  574.         return true
  575.  
  576.     elseif count == 6 then
  577.         say("Area cleared")
  578.         bombarea:killzone(false)
  579.         return false
  580.     else
  581.         say("The bomb will explode in " .. 5 - 1*count .. " seconds.")
  582.         return true
  583.     end
  584. end
  585.  
  586. function replacebomb(id, count, m_weaponId)
  587.     if m_weaponId then
  588.         local m_weapon = getobject(m_weaponId)
  589.         if m_weapon then
  590.             writefloat(m_weapon + 0x5C, readfloat(m_weapon + 0x5C) + 40.15) -- x
  591.             writefloat(m_weapon + 0x60, readfloat(m_weapon + 0x60) + -76.7) -- y
  592.             writefloat(m_weapon + 0x64, readfloat(m_weapon + 0x64) + 0.01)  -- and z
  593.         end
  594.     end
  595.     return false
  596. end
  597.  
  598. function InfiniteAmmo(id, count, player)
  599.     local m_player = getplayer(player)
  600.     if m_player then
  601.         local objId = readdword(m_player, 0x34)
  602.         local m_object = getobject(objId)
  603.         if m_object then
  604.             for i = 0,3 do
  605.                 local weapId = readdword(m_object, 0x2F8 + (i * 4))
  606.                 local m_weapon = getobject(weapId)
  607.                 if m_weapon then
  608.                     writeword(m_weapon, 0x2B6, 9999)
  609.                     writeword(m_weapon, 0x2B8, 9999)
  610.                     updateammo(weapId)
  611.                 end
  612.             end
  613.  
  614.             return true
  615.         end
  616.     end
  617.     return false
  618. end
  619.  
  620. function math.round(input, precision)
  621.     return math.floor(input * (10 ^ precision) + 0.5) / (10 ^ precision)
  622. end
  623.  
  624. function LoadTags()
  625.     -- Bipeds
  626.     cyborg_tag_id = gettagid("bipd", "characters\\cyborg_mp\\cyborg_mp")
  627.     captain_tag_id = gettagid("bipd", "characters\\captain\\captain")
  628.     cortana_tag_id = gettagid("bipd", "characters\\cortana\\cortana")
  629.     cortana2_tag_id = gettagid("bipd", "characters\\cortana\\halo_enhanced\\halo_enhanced")
  630.     crewman_tag_id = gettagid("bipd", "characters\\crewman\\crewman")
  631.     elite_tag_id = gettagid("bipd", "characters\\elite\\elite")
  632.     elite2_tag_id = gettagid("bipd", "characters\\elite\\elite special")
  633.     relite_tag_id = gettagid("bipd", "revolution\\biped\\cmt_elite")
  634.     engineer_tag_id = gettagid("bipd", "characters\\engineer\\engineer")
  635.     flood_tag_id = gettagid("bipd", "characters\\flood_captain\\flood_captain")
  636.     flood2_tag_id = gettagid("bipd", "characters\\flood_infection\\flood_infection")
  637.     -- Equipment
  638.     camouflage_tag_id = gettagid("eqip", "powerups\\active camouflage")
  639.     healthpack_tag_id = gettagid("eqip", "powerups\\health pack")
  640.     overshield_tag_id = gettagid("eqip", "powerups\\over shield")
  641.     doublespeed_tag_id = gettagid("eqip", "powerups\\double speed")
  642.     fullspec_tag_id = gettagid("eqip", "powerups\\full-spectrum vision")
  643.     fragnade_tag_id = gettagid("eqip", "weapons\\frag grenade\\frag grenade")
  644.     plasmanade_tag_id = gettagid("eqip", "weapons\\plasma grenade\\plasma grenade")
  645.     rifleammo_tag_id = gettagid("eqip", "powerups\\assault rifle ammo\\assault rifle ammo")
  646.     needlerammo_tag_id = gettagid("eqip", "powerups\\needler ammo\\needler ammo")
  647.     pistolammo_tag_id = gettagid("eqip", "powerups\\pistol ammo\\pistol ammo")
  648.     rocketammo_tag_id = gettagid("eqip", "powerups\\rocket launcher ammo\\rocket launcher ammo")
  649.     shotgunammo_tag_id = gettagid("eqip", "powerups\\shotgun ammo\\shotgun ammo")
  650.     sniperammo_tag_id = gettagid("eqip", "powerups\\sniper rifle ammo\\sniper rifle ammo")
  651.     flameammo_tag_id = gettagid("eqip", "powerups\\flamethrower ammo\\flamethrower ammo")
  652.     -- Vehicles
  653.     banshee_tag_id = gettagid("vehi", "vehicles\\banshee\\banshee_mp")
  654.     turret_tag_id = gettagid("vehi", "vehicles\\c gun turret\\c gun turret_mp")
  655.     ghost_tag_id = gettagid("vehi", "vehicles\\ghost\\ghost_mp")
  656.     rwarthog_tag_id = gettagid("vehi", "vehicles\\rwarthog\\rwarthog")
  657.     scorpion_tag_id = gettagid("vehi", "vehicles\\scorpion\\scorpion_mp")
  658.     warthog_tag_id = gettagid("vehi", "vehicles\\warthog\\mp_warthog")
  659.     wraith_tag_id = gettagid("vehi", "vehicles\\wraith\\wraith")
  660.     pelican_tag_id = gettagid("vehi", "vehicles\\pelican\\pelican")
  661.     -- Weapons
  662.     assaultrifle_tag_id = gettagid("weap", "weapons\\assault rifle\\assault rifle")
  663.     oddball_tag_id = gettagid("weap", "weapons\\ball\\ball")
  664.     flag_tag_id = gettagid("weap", "weapons\\flag\\flag")
  665.     flamethrower_tag_id = gettagid("weap", "weapons\\flamethrower\\flamethrower")
  666.     gravityrifle_tag_id = gettagid("weap", "weapons\\gravity rifle\\gravity rifle")
  667.     needler_tag_id = gettagid("weap", "weapons\\needler\\mp_needler")
  668.     pistol_tag_id = gettagid("weap", "weapons\\pistol\\pistol")
  669.     plasmapistol_tag_id = gettagid("weap", "weapons\\plasma pistol\\plasma pistol")
  670.     plasmarifle_tag_id = gettagid("weap", "weapons\\plasma rifle\\plasma rifle")
  671.     plasmacannon_tag_id = gettagid("weap", "weapons\\plasma_cannon\\plasma_cannon")
  672.     rocketlauncher_tag_id = gettagid("weap", "weapons\\rocket launcher\\rocket launcher")
  673.     shotgun_tag_id = gettagid("weap", "weapons\\shotgun\\shotgun")
  674.     sniper_tag_id = gettagid("weap", "weapons\\sniper rifle\\sniper rifle")
  675.     energysword_tag_id = gettagid("weap", "weapons\\energy sword\\energy sword")
  676.     -- Projectiles
  677.     bansheebolt_tag_id = gettagid("proj", "vehicles\\banshee\\banshee bolt")
  678.     bansheeblast_tag_id = gettagid("proj", "vehicles\\banshee\\mp_banshee fuel rod")
  679.     turretfire_tag_id = gettagid("proj", "vehicles\\c gun turret\\mp gun turret")
  680.     ghostbolt_tag_id = gettagid("proj", "vehicles\\ghost\\ghost bolt")
  681.     tankshot_tag_id = gettagid("proj", "vehicles\\scorpion\\bullet")
  682.     tankblast_tag_id = gettagid("proj", "vehicles\\scorpion\\tank shell")
  683.     warthogshot_tag_id = gettagid("proj", "vehicles\\warthog\\bullet")
  684.     rifleshot_tag_id = gettagid("proj", "weapons\\assault rifle\\bullet")
  685.     flame_tag_id = gettagid("proj", "weapons\\flamethrower\\flame")
  686.     needlerfire_tag_id = gettagid("proj", "weapons\\needler\\mp_needle")
  687.     pistolshot_tag_id = gettagid("proj", "weapons\\pistol\\bullet")
  688.     plasmapistolbolt_tag_id = gettagid("proj", "weapons\\plasma pistol\\bolt")
  689.     plasmariflebolt_tag_id = gettagid("proj", "weapons\\plasma rifle\\bolt")
  690.     plasmarifleblast_tag_id = gettagid("proj", "weapons\\plasma rifle\\charged bolt")
  691.     plasmacannonshot_tag_id = gettagid("proj", "weapons\\plasma_cannon\\plasma_cannon")
  692.     rocket_tag_id = gettagid("proj", "weapons\\rocket launcher\\rocket")
  693.     shotgunshot_tag_id = gettagid("proj", "weapons\\shotgun\\pellet")
  694.     snipershot_tag_id = gettagid("proj", "weapons\\sniper rifle\\sniper bullet")
  695.     -- Globals
  696.     global_distanceId = gettagid("jpt!", "globals\\distance")
  697.     global_fallingId = gettagid("jpt!", "globals\\falling")
  698. end
  699.  
  700. -------------------------Nuggets GEO Script----------------------------------------------------------------
  701. -- Create Metatable
  702. GEO = {}
  703. GEO.__index = GEO
  704.  
  705. -- Set random seed and define infinity
  706. math.randomseed(os.time())
  707. math.inf = 1 / 0
  708.  
  709. function inSphere(objId, x, y, z, r)
  710.  
  711.         local ox, oy, oz = getobjectcoords(objId)
  712.         if ox then
  713.                 -- Pythagorean
  714.                 local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2 + (z - oz) ^ 2)
  715.                 if dist <= r then
  716.                         return true
  717.                 end
  718.         end
  719.  
  720.         return false
  721. end
  722.  
  723. function inCircle(objId, x, y, z, r, orientation)
  724.  
  725.         local ox, oy, oz = getobjectcoords(objId)
  726.         if ox then
  727.                 -- Default orientation to "z"
  728.                 orientation = orientation or "z"
  729.                 -- Pythagorean based on circle's orientation
  730.                 if orientation == "z" then
  731.                         local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2)
  732.                         if dist <= r and oz == z then
  733.                                 return true
  734.                         end
  735.                 elseif orientation == "y" then
  736.                         local dist = math.sqrt((x - ox) ^ 2 + (z - oz) ^ 2)
  737.                         if dist <= r and oy == y then
  738.                                 return true
  739.                         end
  740.                 elseif orientation == "x" then
  741.                         local dist = math.sqrt((y - oy) ^ 2 + (z - oz) ^ 2)
  742.                         if dist <= r and ox == x then
  743.                                 return true
  744.                         end
  745.                 end
  746.         end
  747.  
  748.         return false
  749. end
  750.  
  751. function inCylinder(objId, x, y, zlow, zhigh, r)
  752.  
  753.         local ox, oy, oz = getobjectcoords(objId)
  754.         if ox then
  755.                 -- Pythagorean to see if object is within radius of circle
  756.                 local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2)
  757.                 -- Make sure the object is also within the height of the cylinder
  758.                 if dist <= r and z >= zlow and z <= zhigh then
  759.                         return true
  760.                 end
  761.         end
  762.  
  763.         return false
  764. end
  765.  
  766. function inRectangle(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
  767.  
  768.         -- These functions are essentially the same
  769.         return inRectPrism(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
  770. end
  771.  
  772. function inRectPrism(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
  773.     if getobject(objId) then
  774.         local x, y, z = getobjectcoords(objId)
  775.         if x then
  776.         -- Make sure the coordinates are inside of each extreme of the rectangular prism
  777.             if x <= xhigh and x >= xlow and y <= yhigh and y >= ylow and z <= zhigh and z >= zlow then
  778.                 return true
  779.             end
  780.         end
  781.     end
  782. return false
  783. end
  784.  
  785. function randomInSphere(x, y, z, r)
  786.  
  787.         -- Increase precision
  788.         x = math.floor(x * 100)
  789.         y = math.floor(y * 100)
  790.         z = math.floor(z * 100)
  791.         r = math.floor(r * 100)
  792.  
  793.         -- Find random values inside of the sphere.
  794.         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
  795. end
  796.  
  797. function randomInCircle(x, y, z, r, orientation)
  798.  
  799.         -- Increase precision
  800.         r = math.floor(r * 100)
  801.  
  802.         -- Possible values depend on circle's orientation.
  803.         if orientation == "z" then
  804.                 x = math.floor(x * 100)
  805.                 y = math.floor(y * 100)
  806.                 return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, z
  807.         elseif orientation == "x" then
  808.                 y = math.floor(y * 100)
  809.                 z = math.floor(z * 100)
  810.                 return x, math.random(y - r, y + r + 1) / 100, math.random(z - r, z + r + 1) / 100
  811.         elseif orientation == "y" then
  812.                 x = math.floor(x * 100)
  813.                 z = math.floor(z * 100)
  814.                 return math.random(x - r, x + r + 1) / 100, y, math.random(z - r, z + r + 1) / 100
  815.         end
  816. end
  817.  
  818. function randomInCylinder(x, y, zlow, zhigh, r)
  819.  
  820.         -- Increase precision
  821.         x = math.floor(x * 100)
  822.         y = math.floor(y * 100)
  823.         zlow = math.floor(zlow * 100)
  824.         zhigh = math.floor(zhigh * 100)
  825.         r = math.floor(r * 100)
  826.  
  827.         -- Find random values inside of the cylinder.
  828.         return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, math.random(zlow, zhigh + 1) / 100
  829. end
  830.  
  831. function randomInRectPrism(xlow, xhigh, ylow, yhigh, zlow, zhigh)
  832.  
  833.         -- Increase precision
  834.         xlow = math.floor(xlow * 100)
  835.         xhigh = math.floor(xhigh * 100)
  836.         ylow = math.floor(ylow * 100)
  837.         yhigh = math.floor(yhigh * 100)
  838.         zlow = math.floor(zlow * 100)
  839.         zhigh = math.floor(zhigh * 100)
  840.  
  841.         -- Find random values inside of the rectangular prism.
  842.         return math.random(xlow, xhigh + 1) / 100, math.random(ylow, yhigh + 1) / 100, math.random(zlow, zhigh)
  843. end
  844.  
  845. -- Object Creation Comments (refer to this function for questions on how the other ones work)
  846. function GEO.newSphere(name, r, x, y, z)
  847.  
  848.         -- Check to see if there is already a GEO with this name.
  849.         if not GEO[name] then
  850.                 -- Create new table
  851.                 GEO[name] = {}
  852.                 GEO[name].t = "sphere"  -- type
  853.                 GEO[name].n = name  -- name
  854.                 GEO[name].r = r or 1  -- radius (default value of 1)
  855.                 GEO[name].x = x or 0  -- x coordinate of center (default value of 0)
  856.                 GEO[name].y = y or 0  -- y coordinate of center (default value of 0)
  857.                 GEO[name].z = z or 0  -- z coordinate of center (default value of 0)
  858.  
  859.                 -- Notify the console that a sphere has been created.
  860.                 hprintf("Sphere \"" .. name .. "\" created.")
  861.                 setmetatable(GEO[name], GEO)  -- Add this object to the GEO metatable to allow GEO-editing functions to work on it.
  862.                 return GEO[name]  -- Return the object
  863.         end
  864.  
  865.         -- If no object was returned, the name was invalid; notify the console.
  866.         hprintf("Invalid name: \"" .. name .. "\"")
  867. end
  868.  
  869. function GEO.newCircle(name, r, x, y, z, orientation)
  870.  
  871.         if not GEO[name] then
  872.                 GEO[name] = {}
  873.                 GEO[name].t = "circle"
  874.                 GEO[name].n = name
  875.                 GEO[name].o = orientation or "z"  -- orientation
  876.                 GEO[name].r = r or 0
  877.                 GEO[name].x = x or 0
  878.                 GEO[name].y = y or 0
  879.                 GEO[name].z = z or 0
  880.  
  881.                 hprintf("Circle \"" .. name .. "\" created.")
  882.                 setmetatable(GEO[name], GEO)
  883.                 return GEO[name]
  884.         end
  885.  
  886.         hprintf("Invalid name: \"" .. name .. "\"")
  887. end
  888.  
  889. function GEO.newCylinder(name, r, h, x, y, z)
  890.  
  891.         if not GEO[name] then
  892.                 GEO[name] = {}
  893.                 GEO[name].t = "cylinder"
  894.                 GEO[name].n = name
  895.                 x = x or 0
  896.                 y = y or 0
  897.                 z = z or 0
  898.                 r = r or 1
  899.                 h = h or 1
  900.                 GEO[name].x = x
  901.                 GEO[name].y = y
  902.                 GEO[name].z = z
  903.                 GEO[name].r = r
  904.                 GEO[name].h = h  -- height
  905.                 GEO[name].zlow = z - h / 2  -- lowest z-coordinate still within the cylinder
  906.                 GEO[name].zhigh = z + h / 2  -- highest z-coordinate still within the cylinder
  907.  
  908.                 hprintf("Cylinder \"" .. name .. "\" created.")
  909.                 setmetatable(GEO[name], GEO)
  910.                 return GEO[name]
  911.         end
  912. end
  913.  
  914. function GEO.newRectPrism(name, lx, ly, lz, x, y, z)
  915.  
  916.         if not GEO[name] then
  917.                 GEO[name] = {}
  918.                 GEO[name].t = "rectprism"
  919.                 GEO[name].n = name
  920.                 lx = lx or 1
  921.                 ly = ly or 1
  922.                 lz = lz or 1
  923.                 x = x or 0
  924.                 y = y or 0
  925.                 z = z or 0
  926.                 GEO[name].lx = lx  -- x length
  927.                 GEO[name].ly = ly  -- y length
  928.                 GEO[name].lz = lz  -- z length
  929.                 GEO[name].x = x
  930.                 GEO[name].y = y
  931.                 GEO[name].z = z
  932.                 GEO[name].xlow = x - lx / 2  -- lowest x-coordinate still within the rectangular prism
  933.                 GEO[name].xhigh = lx / 2 + x  -- highest x-coordinate still within in the rectangular prism
  934.                 GEO[name].ylow = y - ly / 2  -- lowest y-coordinate still within the rectangular prism
  935.                 GEO[name].yhigh = ly / 2 + y  -- highest y-coordinate still within the rectangular prism
  936.                 GEO[name].zlow = z - lz / 2  -- lowest z-coordinate still within the rectangular prism
  937.                 GEO[name].zhigh = lz / 2 + z  -- highest z-coordinate still within the rectangular prism
  938.  
  939.                 hprintf("Rectangular Prism \"" .. name .. "\" created.")
  940.                 setmetatable(GEO[name], GEO)
  941.                 return GEO[name]
  942.         end
  943.  
  944.         hprintf("Invalid name: \"" .. name .. "\"")
  945. end
  946.  
  947. function GEO.newRect(name, width, height, x, y, z, orientation)
  948.  
  949.         if not GEO[name] then
  950.                 GEO[name] = {}
  951.                 GEO[name].t = "rectangle"
  952.                 GEO[name].n = name
  953.                 width = width or 1
  954.                 height = height or 1
  955.                 x = x or 0
  956.                 y = y or 0
  957.                 z = z or 0
  958.                 orientation = orientation or "z"
  959.                 GEO[name].width = width
  960.                 GEO[name].height = height
  961.                 GEO[name].x = x
  962.                 GEO[name].y = y
  963.                 GEO[name].z = z
  964.                 GEO[name].o = orientation
  965.  
  966.                 -- Coordinates' highs and lows depend on orientation
  967.                 if orientation == "z" then
  968.                         GEO[name].xlow = x - width / 2
  969.                         GEO[name].xhigh = x + width / 2
  970.                         GEO[name].ylow = y - height / 2
  971.                         GEO[name].yhigh = y + height / 2
  972.                         GEO[name].zlow = z
  973.                         GEO[name].zhigh = z
  974.                 elseif orientation == "x" then
  975.                         GEO[name].xlow = x
  976.                         GEO[name].xhigh = x
  977.                         GEO[name].ylow = y - width / 2
  978.                         GEO[name].yhigh = y + width / 2
  979.                         GEO[name].zlow = z - height / 2
  980.                         GEO[name].zhigh = z + height / 2
  981.                 elseif orientation == "y" then
  982.                         GEO[name].xlow = x - width / 2
  983.                         GEO[name].xhigh = x + width / 2
  984.                         GEO[name].ylow = y
  985.                         GEO[name].yhigh = y
  986.                         GEO[name].zlow = z - height / 2
  987.                         GEO[name].zhigh = z + height / 2
  988.                 end
  989.  
  990.                 hprintf("Rectangle \"" .. name .. "\" created.")
  991.                 setmetatable(GEO[name], GEO)
  992.                 return GEO[name]
  993.         end
  994.  
  995.         hprintf("Invalid name: \""  .. name .. "\"")
  996. end
  997.  
  998. function GEO.get(name)
  999.  
  1000.         return GEO[name]
  1001. end
  1002.  
  1003. function GEO:delete()
  1004.  
  1005.         self:hide()
  1006.         GEO[self.n] = nil
  1007.         hprintf("Geo \"" .. self.n .. "\" deleted.")
  1008. end
  1009.  
  1010. function GEO:move(x, y, z)
  1011.  
  1012.         -- Move the center of the object
  1013.         -- Default to GEO's current coordinates
  1014.         GEO[self.n].x = x or GEO[self.n].x
  1015.         GEO[self.n].y = y or GEO[self.n].y
  1016.         GEO[self.n].z = z or GEO[self.n].z
  1017.  
  1018.         -- If this is a rectangular prism...
  1019.         if self.t == "rectprism" then
  1020.                 -- Change the x, y, and z lows and highs accordingly to adjust to the new center
  1021.                 GEO[self.n].xlow = x - GEO[self.n].lx / 2
  1022.                 GEO[self.n].xhigh = GEO[self.n].lx / 2 + x
  1023.                 GEO[self.n].ylow = y - GEO[self.n].ly / 2
  1024.                 GEO[self.n].yhigh = GEO[self.n].ly / 2 + y
  1025.                 GEO[self.n].zlow = z - GEO[self.n].lz / 2
  1026.                 GEO[self.n].zhigh = GEO[self.n].lz / 2 + z
  1027.  
  1028.         -- If this is a rectangle...
  1029.         elseif self.t == "rectangle" then
  1030.                 -- Change the x, y, and z lows and highs accordingly to adjust to the new center (depends on orientation)
  1031.                 if self.o == "z" then
  1032.                         GEO[self.n].xlow = self.x - self.width / 2
  1033.                         GEO[self.n].xhigh = self.x + self.width / 2
  1034.                         GEO[self.n].ylow = self.y - self.height / 2
  1035.                         GEO[self.n].yhigh = self.y + self.height / 2
  1036.                         GEO[self.n].zlow = self.z
  1037.                         GEO[self.n].zhigh = self.z
  1038.                 elseif self.o == "x" then
  1039.                         GEO[self.n].xlow = self.x
  1040.                         GEO[self.n].xhigh = self.x
  1041.                         GEO[self.n].ylow = self.y - self.width / 2
  1042.                         GEO[self.n].yhigh = self.y + self.width / 2
  1043.                         GEO[self.n].zlow = self.z - self.height / 2
  1044.                         GEO[self.n].zhigh = self.z + self.height / 2
  1045.                 elseif self.o == "y" then
  1046.                         GEO[self.n].xlow = self.x - self.width / 2
  1047.                         GEO[self.n].xhigh = self.x + self.width / 2
  1048.                         GEO[self.n].ylow = self.y
  1049.                         GEO[self.n].yhigh = self.y
  1050.                         GEO[self.n].zlow = self.z - self.height / 2
  1051.                         GEO[self.n].zhigh = self.z + self.height / 2
  1052.                 end
  1053.  
  1054.         -- If this is a cylinder...
  1055.         elseif self.t == "cylinder" then
  1056.                 GEO[self.n].zlow = self.z - self.h / 2
  1057.                 GEO[self.n].zhigh = self.z + self.h / 2
  1058.         end
  1059. end
  1060.  
  1061. function GEO:radius(new)
  1062.  
  1063.         if self.t == "sphere" or self.t == "circle" or self.t == "cylinder" then
  1064.                 if new then  -- If "new" is defined...
  1065.                         GEO[self.n].r = new  -- Change the radius to its value.
  1066.                 else  -- If not...
  1067.                         return GEO[self.n].r  -- Return its current radius.
  1068.                 end
  1069.         end
  1070. end
  1071.  
  1072. function GEO:size(x, y, z)
  1073.  
  1074.         -- If this is a rectangular prism...
  1075.         if self.t == "rectprism" then
  1076.                 if x or y or z then  -- If any of these variables have been defined...
  1077.                         -- Adjust lengths and x, y, and z highs and lows accordingly.
  1078.                         GEO[self.n].lx = x or GEO[self.n].lx
  1079.                         GEO[self.n].ly = y or GEO[self.n].ly
  1080.                         GEO[self.n].lz = z or GEO[self.n].lz
  1081.                         GEO[self.n].xlow = GEO[self.n].x - x / 2
  1082.                         GEO[self.n].xhigh = x / 2 + GEO[self.n].x
  1083.                         GEO[self.n].ylow = GEO[self.n].y - y / 2
  1084.                         GEO[self.n].yhigh = y / 2 + GEO[self.n].y
  1085.                         GEO[self.n].zlow = GEO[self.n].z - z / 2
  1086.                         GEO[self.n].zhigh = z / 2 + GEO[self.n].z
  1087.                 else  -- Otherwise...
  1088.                         return GEO[self.n].lx, GEO[self.n].ly, GEO[self.n].lz  -- Return the x, y, and z lengths.
  1089.                 end
  1090.  
  1091.         -- If this is a rectangle...
  1092.         elseif self.t == "rectangle" then
  1093.                 if x or y or z then  -- If any of these variables are defined...
  1094.                         -- Adjust width, height, and x, y, and z highs and lows accordingly (depends on orientation).
  1095.                         if self.o == "z" then
  1096.                                 GEO[self.n].width = x
  1097.                                 GEO[self.n].height = y
  1098.                                 GEO[self.n].xlow = self.x - self.width / 2
  1099.                                 GEO[self.n].xhigh = self.x + self.width / 2
  1100.                                 GEO[self.n].ylow = self.y - self.height / 2
  1101.                                 GEO[self.n].yhigh = self.y + self.height / 2
  1102.                                 GEO[self.n].zlow = self.z
  1103.                                 GEO[self.n].zhigh = self.z
  1104.                         elseif self.o == "x" then
  1105.                                 GEO[self.n].width = y
  1106.                                 GEO[self.n].height = z
  1107.                                 GEO[self.n].xlow = self.x
  1108.                                 GEO[self.n].xhigh = self.x
  1109.                                 GEO[self.n].ylow = self.y - self.width / 2
  1110.                                 GEO[self.n].yhigh = self.y + self.width / 2
  1111.                                 GEO[self.n].zlow = self.z - self.height / 2
  1112.                                 GEO[self.n].zhigh = self.z + self.height / 2
  1113.                         elseif self.o == "y" then
  1114.                                 GEO[self.n].width = x
  1115.                                 GEO[self.n].height = z
  1116.                                 GEO[self.n].xlow = self.x - self.width / 2
  1117.                                 GEO[self.n].xhigh = self.x + self.width / 2
  1118.                                 GEO[self.n].ylow = self.y
  1119.                                 GEO[self.n].yhigh = self.y
  1120.                                 GEO[self.n].zlow = self.z - self.height / 2
  1121.                                 GEO[self.n].zhigh = self.z + self.height / 2
  1122.                         end
  1123.                 else  -- Otherwise...
  1124.                         return GEO[self.n].width, GEO[self.n].height  -- Return the width and height of the rectangle.
  1125.                 end
  1126.  
  1127.         -- If this is a cylinder...
  1128.         elseif self.t == "cylinder" then
  1129.                 local h = x or y or z  -- Whichever variable is defined, it is taken as the height.
  1130.                 if h then  -- If a height is specified...
  1131.                         -- Adjust height and z high and low accordingly.
  1132.                         GEO[self.n].h = h
  1133.                         GEO[self.n].zlow = self.z - h / 2
  1134.                         GEO[self.n].zhigh = self.z + h / 2
  1135.                 else  -- Otherwise...
  1136.                         return GEO[self.n].h  -- Return the height.
  1137.                 end
  1138.         end
  1139. end
  1140.  
  1141. function GEO:extend(orienation, direction, amount)
  1142.  
  1143.         -- Change the direction from "+" or "-" to "high" or "low".
  1144.         local dir
  1145.         dir = string.gsub(direction, "-", "low")
  1146.         dir = string.gsub(direction, "+", "high")
  1147.  
  1148.         -- Get the face we're trying to extend (i.e. "xhigh")
  1149.         local face = string.lower(orientation) .. direction
  1150.  
  1151.         -- If this is a rectangular prism or a rectangle...
  1152.         if self.t == "rectprism" or self.t == "rectangle" then
  1153.                 -- Make sure "face" is actually a valid face (and not something like "cheesederp")
  1154.                 if self[face] then
  1155.                         -- 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.
  1156.                         -- Change the length of the GEO in the orientation specified.
  1157.                         GEO[self.n]["l" .. string.lower(orientation)] = self["l" .. string.lower(orientation)] + amount
  1158.  
  1159.                         -- Figure out if the positive or negative face is being extended.
  1160.                         if direction == "+" then
  1161.                                 GEO[self.n][face] = self[face] + amount
  1162.                                 GEO[self.n][string.lower(orientation)] = self[string.lower(orientation)] + amount / 2
  1163.                         else
  1164.                                 GEO[self.n][face] = self[face] - amount
  1165.                                 GEO[self.n][string.lower(orientation)] = self[string.lower(orientation)] - amount / 2
  1166.                         end
  1167.                 end
  1168.  
  1169.         -- If this is a cylinder...
  1170.         elseif self.t == "cylinder" then
  1171.                 -- The orientation must be "z"
  1172.                 if orientation == "z" then
  1173.                         if self[face] then
  1174.                                 GEO[self.n].h = self.h + amount
  1175.  
  1176.                                 -- Figure out if the top or bottom face is being extended.
  1177.                                 if direction == "+" then
  1178.                                         GEO[self.n][face] = self[face] + amount
  1179.                                         GEO[self.n].z = self.z + amount / 2
  1180.                                 else
  1181.                                         GEO[self.n][face] = self[face] - amount
  1182.                                         GEO[self.n].z = self.z - amount / 2
  1183.                                 end
  1184.                         end
  1185.                 end
  1186.         end
  1187. end
  1188.  
  1189. function GEO:coords()
  1190.  
  1191.         return self.x, self.y, self.z
  1192. end
  1193.  
  1194. function GEO:high(orientation)
  1195.  
  1196.         if self.t == "sphere" or self.t == "circle" then
  1197.                 return self[orientation] + self.r
  1198.         elseif self.t == "rectprism" or self.t == "rectangle" then
  1199.                 return self[orientation .. "high"]
  1200.         elseif self.t == "cylinder" then
  1201.                 if orientation == "z" then
  1202.                         return self.zhigh
  1203.                 else
  1204.                         return self[orientation] + self.r
  1205.                 end
  1206.         end
  1207. end
  1208.  
  1209. function GEO:low(orientation)
  1210.  
  1211.         if self.t == "sphere" or self.t == "circle" then
  1212.                 return self[orientation] - self.r
  1213.         elseif self.t == "rectprism" or self.t == "rectangle" then
  1214.                 return self[orientation .. "low"]
  1215.         elseif self.t == "cylinder" then
  1216.                 if orientation == "z" then
  1217.                         return self.zlow
  1218.                 else
  1219.                         return self[orientation] - self.r
  1220.                 end
  1221.         end
  1222. end
  1223.  
  1224. function GEO:randcoords()
  1225.  
  1226.         if self.t == "sphere" then
  1227.                 return randomInSphere(self.x, self.y, self.z, self.r)
  1228.         elseif self.t == "circle" then
  1229.                 return randomInCircle(self.x, self.y, self.z, self.r, self.o)
  1230.         elseif self.t == "cylinder" then
  1231.                 return randomInCylinder(self.x, self.y, self.zlow, self.zhigh, self.r)
  1232.         elseif self.t == "rectprism" or self.t == "rectangle" then
  1233.                 return randomInRectPrism(self.xlow, self.xhigh, self.ylow, self.yhigh, self.zlow, self.zhigh)
  1234.         end
  1235. end
  1236.  
  1237. function GEO:type()
  1238.  
  1239.         return self.t
  1240. end
  1241.  
  1242. function GEO:orientation()
  1243.  
  1244.         return self.o
  1245. end
  1246.  
  1247. function GEO:name()
  1248.  
  1249.         return self.n
  1250. end
  1251.  
  1252. function GEO:perimeter(density, mapId)
  1253.  
  1254.         -- Default density to 10
  1255.         density = density or 10
  1256.  
  1257.         -- Default tagtype and tagname to Full-Spectrum Visions
  1258.         mapId = mapId or gettagid("eqip", "powerups\\full-spectrum vision")
  1259.  
  1260.         tagname, tagtype = gettaginfo(mapId)
  1261.  
  1262.         -- Store all of the perimeter objects in a table
  1263.         GEO[self.n].p = GEO[self.n].p or {}
  1264.  
  1265.         -- Find the change in angle per point from 0 - 2pi (0° - 360°)
  1266.         local angle_increment = 2 * math.pi / density
  1267.         if self.t == "sphere" or self.t == "cylinder" then
  1268.                 for i = 1,density do
  1269.                         -- 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).
  1270.                         local x = self.r * math.cos(angle_increment * i)
  1271.                         local y = self.r * math.sin(angle_increment * i)
  1272.                         local z = self.z
  1273.                         local objId = createobject(mapId, 0, 0, false, self.x + x, self.y + y, self.z + z)
  1274.                         GEO[self.n].p[objId] = {self.x + x, self.y + y, self.z + z}
  1275.                 end
  1276.         elseif self.t == "circle" then
  1277.                 if self.o == "z" then
  1278.                         for i = 1,density do
  1279.                                 -- 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).
  1280.                                 local x = self.r * math.cos(angle_increment * i)
  1281.                                 local y = self.r * math.sin(angle_increment * i)
  1282.                                 local z = self.z
  1283.                                 local objId = createobject(mapId, 0, 0, false, self.x + x, self.y + y, self.z + z)
  1284.                                 GEO[self.n].p[objId] = {self.x + x, self.y + y, self.z + z}
  1285.                         end
  1286.                 end
  1287.         elseif self.t == "rectprism" or self.t == "rectangle" then
  1288.                 if self.t == "rectangle" then
  1289.                         if self.o ~= "z" then return end
  1290.                 end
  1291.                 -- Create points at four corners of the rectangle
  1292.                 local o1 = createobject(mapId, 0, 0, false, self.xhigh, self.yhigh, self.z)
  1293.                 local o2 = createobject(mapId, 0, 0, false, self.xhigh, self.ylow, self.z)
  1294.                 local o3 = createobject(mapId, 0, 0, false, self.xlow, self.yhigh, self.z)
  1295.                 local o4 = createobject(mapId, 0, 0, false, self.xlow, self.ylow, self.z)
  1296.                 GEO[self.n].p[o1] = {self.xhigh, self.yhigh, self.z}
  1297.                 GEO[self.n].p[o2] = {self.xhigh, self.yhigh, self.z}
  1298.                 GEO[self.n].p[o3] = {self.xhigh, self.yhigh, self.z}
  1299.                 GEO[self.n].p[o4] = {self.xhigh, self.yhigh, self.z}
  1300.  
  1301.                 for i = 1,density do
  1302.                         local herp = createobject(mapId, 0, 0, false, self.xhigh - (i * self.lx / density), self.yhigh, self.z)
  1303.                         local derp = createobject(mapId, 0, 0, false, self.xhigh, self.yhigh - (i * self.ly / density), self.z)
  1304.                         local weee = createobject(mapId, 0, 0, false, self.xhigh - (i * self.lx / density), self.ylow, self.z)
  1305.                         local cheese = createobject(mapId, 0, 0, false, self.xlow, self.ylow + (i * self.ly / density), self.z)
  1306.                         GEO[self.n].p[herp] = {self.xhigh - (i * self.lx / density), self.yhigh, self.z}
  1307.                         GEO[self.n].p[derp] = {self.xhigh, self.yhigh - (i * self.ly / density), self.z}
  1308.                         GEO[self.n].p[weee] = {self.xhigh - (i * self.lx / density), self.ylow, self.z}
  1309.                         GEO[self.n].p[cheese] = {self.xlow, self.ylow + (i * self.ly / density), self.z}
  1310.                 end
  1311.         end
  1312. end
  1313.  
  1314. function GEO:hide()
  1315.  
  1316.         if self.p then
  1317.                 for k,v in pairs(GEO[self.n].p) do
  1318.                         if getobject(k) then
  1319.                                 destroyobject(k)
  1320.                                 GEO[self.n].p[k] = nil
  1321.                         end
  1322.                 end
  1323.         end
  1324. end
  1325.  
  1326. -- Never quite got this to work right, but I'm saving it for the sake of the formula.
  1327. --[[function GEO:surface(density)
  1328.  
  1329.         GEO[self.n].p = GEO[self.n].p or {}
  1330.         if self.t == "sphere" then
  1331.                 local inc = math.pi * (3 - math.sqrt(5))
  1332.                 local off = 2 / density
  1333.                 for i = 1,density do
  1334.                         local y = self.r * i * off - 1 + (off / 2)
  1335.                         local r = self.r * math.sqrt(1 - y ^ 2)
  1336.                         local phi = i * inc
  1337.                         local x = r * math.cos(phi)
  1338.                         local z = r * math.sin(phi)
  1339.                         local objId = createobject(mapId, 0, 0, false, x, y, z)
  1340.                         GEO[self.n].p[objId] = {x, y, z}
  1341.                 end
  1342.         end
  1343. end--]]
  1344.  
  1345. function GEO:contains(objId)
  1346.  
  1347.         if self.t == "sphere" then
  1348.                 return inSphere(objId, self.x, self.y, self.z, self.r)
  1349.         elseif self.t == "rectprism" or self.t == "rectangle" then
  1350.                 return inRectPrism(objId, self.xlow, self.xhigh, self.ylow, self.yhigh, self.zlow, self.zhigh)
  1351.         elseif self.t == "circle" then
  1352.                 return inCircle(objId, self.x, self.y, self.z, self.r, self.o)
  1353.         elseif self.t == "cylinder" then
  1354.                 return inCylinder(objId, self.x, self.y, self.zlow, self.zhigh, self.r)
  1355.         end
  1356. end
  1357.  
  1358. function GEO:follow(objId)
  1359.  
  1360.         -- If the objId exists...
  1361.         if getobject(objId) then
  1362.                 GEO[self.n].f = objId  -- Save it (the GEOTimer will access it)
  1363.                 -- Check to see if the object is a player
  1364.                 if objectidtoplayer(objId) then
  1365.                         GEO[self.n].player = true
  1366.                 end
  1367.         end
  1368. end
  1369.  
  1370. function GEO:unfollow()
  1371.  
  1372.         -- Nullify the saved objId from GEO:follow()
  1373.         GEO[self.n].f = nil
  1374. end
  1375.  
  1376. function GEO.followedBy(objId)
  1377.  
  1378.         -- Initialize table
  1379.         local geos = {}
  1380.  
  1381.         -- Loop through the GEO table
  1382.         for k,v in pairs(GEO) do
  1383.                 if type(v) == "table" and k ~= "__index" then  -- make sure we're actually getting a GEO object
  1384.                         if v.f == objId then
  1385.                                 -- If this GEO has this objId saved, insert it into the geos table.
  1386.                                 table.insert(geos, v)
  1387.                         end
  1388.                 end
  1389.         end
  1390.  
  1391.         -- Return the GEOs following objId in a table.
  1392.         return geos
  1393. end
  1394.  
  1395. function GEO.cleanup(player)
  1396.  
  1397.         local m_player = getplayer(player)
  1398.         local objId = readdword(m_player, 0x34)
  1399.         local geos = GEO.followedBy(objId)
  1400.         for k,v in ipairs(geos) do
  1401.                 v:delete()
  1402.         end
  1403. end
  1404.  
  1405. function GEO:velocity(x, y, z)
  1406.  
  1407.         GEO[self.n].vx = x or GEO[self.n].vx
  1408.         GEO[self.n].vy = y or GEO[self.n].vy
  1409.         GEO[self.n].vz = z or GEO[self.n].vz
  1410. end
  1411.  
  1412. function GEO:killzone(bool)
  1413.  
  1414.         if bool == true then
  1415.                 GEO[self.n].kz = true
  1416.         elseif bool == false then
  1417.                 GEO[self.n].kz = false
  1418.         elseif bool == nil then
  1419.                 return GEO[self.n].kz or false
  1420.         end
  1421. end
  1422.  
  1423. function GEO:damagezone(bool, damage)
  1424.  
  1425.         if bool == true then
  1426.                 GEO[self.n].damage = damage or 1  -- Amount of damage applied per second.
  1427.         elseif bool == false then
  1428.                 GEO[self.n].damage = nil
  1429.         elseif bool == nil then  -- If nothing is passed, return true if this GEO is a damagezone, false if not.
  1430.                 if GEO[self.n].damage then
  1431.                         return true
  1432.                 else
  1433.                         return false
  1434.                 end
  1435.         end
  1436. end
  1437.  
  1438. function GEO:face(orientation, direction)
  1439.  
  1440.         -- If this is a rectangular prism...
  1441.         if self.t == "rectprism" then
  1442.                 orientation = orientation or "z"
  1443.                 direction = direction or "+"
  1444.                 if orientation == "z" then
  1445.                         local width = self.lx
  1446.                         local height = self.ly
  1447.                         local highlow
  1448.                         if direction == "+" then
  1449.                                 highlow = self.zhigh
  1450.                         else
  1451.                                 highlow = self.zlow
  1452.                         end
  1453.  
  1454.                         -- Create a new rectangle which overlays the specified face and return that rectangle.
  1455.                         return GEO.newRect(self.n .. "ZFace" .. os.time(), width, height, self.x, self.y, highlow, orientation)
  1456.  
  1457.                 elseif orientation == "x" then
  1458.                         local width = self.ly
  1459.                         local height = self.lz
  1460.                         local highlow
  1461.                         if direction == "+" then
  1462.                                 highlow = self.xhigh
  1463.                         else
  1464.                                 highlow = self.xlow
  1465.                         end
  1466.  
  1467.                         return GEO.newRect(self.n .. "XFace" .. os.time(), width, height, highlow, self.y, self.z, orientation)
  1468.  
  1469.                 elseif orientation == "y" then
  1470.                         local width = self.lx
  1471.                         local height = self.lz
  1472.                         local highlow
  1473.                         if direction == "+" then
  1474.                                 highlow = self.yhigh
  1475.                         else
  1476.                                 highlow = self.ylow
  1477.                         end
  1478.  
  1479.                         return GEO.newRect(self.n .. "YFace" .. os.time(), width, height, self.x, highlow, self.z, orientation)
  1480.                 end
  1481.  
  1482.         -- If this is a cylinder...
  1483.         elseif self.t == "cylinder" then
  1484.                 if orientation == "z" then
  1485.                         local highlow
  1486.                         if direction == "+" then
  1487.                                 highlow = self.zhigh
  1488.                         else
  1489.                                 highlow = self.zlow
  1490.                         end
  1491.  
  1492.                         -- Return a new circle which overlays the specified face and return that circle.
  1493.                         return GEO.newCircle(self.n .. "ZFace" .. os.time(), self.r, self.x, self.y, highlow, "z")
  1494.                 else
  1495.                         hprintf("You may only retrieve the Z face of a cylinder.")
  1496.                 end
  1497.         end
  1498. end
  1499.  
  1500. function GEO:copy(name)
  1501.  
  1502.         name = name or self.n .. "Copy" .. os.time()
  1503.         if not GEO[name] then
  1504.                 GEO[name] = self
  1505.                 return GEO[name]
  1506.         end
  1507. end
  1508.  
  1509. function GEO:monitor(objId)
  1510.  
  1511.         if getobject(objId) then
  1512.                 GEO[self.n].m = GEO[self.n].m or {}
  1513.                 GEO[self.n].c = GEO[self.n].c or {}
  1514.                 GEO[self.n].m[objId] = true
  1515.         end
  1516. end
  1517.  
  1518. registertimer(10, "GEOTimer")
  1519.  
  1520. function GEOTimer(id, count)
  1521.  
  1522.         -- Create a coordinates table for players if it hasn't already been created
  1523.         pcoords = pcoords or {}
  1524.  
  1525.         -- Loop through the GEO table
  1526.         for k,v in pairs(GEO) do
  1527.                 if type(v) == "table" and k ~= "__index" then
  1528.                         -- If this GEO is following an object...
  1529.                         if v.f then
  1530.                                 -- Get the coordinates of the object
  1531.                                 local x, y, z = getobjectcoords(v.f)
  1532.                                 if x then  -- If this object exists...
  1533.                                         if v.player then
  1534.                                                 local player = objectidtoplayer(v.f)
  1535.                                                 if player then
  1536.                                                         local m_player = getplayer(player)  -- See if the player is still here
  1537.                                                         if m_player then  -- If they are...
  1538.                                                                 local time_until_respawn = readdword(m_player, 0x2C)  -- Check to see if they're dead
  1539.                                                                 if time_until_respawn == 0 then  -- If they're not...
  1540.                                                                         if v.p then  -- If this GEO has perimeter objects...
  1541.                                                                                 for objId, coords in pairs(v.p) do
  1542.                                                                                         if getobject(objId) then
  1543.                                                                                                 local ox, oy, oz = table.unpack(coords)
  1544.                                                                                                 local x_diff = x - v.x
  1545.                                                                                                 local y_diff = y - v.y
  1546.                                                                                                 local z_diff = z - v.z
  1547.                                                                                                 local m_object = getobject(objId)
  1548.                                                                                                 movobjcoords(objId, ox + x_diff, oy + y_diff, oz + z_diff)  -- Move them with the GEO.
  1549.                                                                                                 GEO[v.n].p[objId] = {ox + x_diff, oy + y_diff, oz + z_diff}
  1550.                                                                                         end
  1551.                                                                                 end
  1552.                                                                         end
  1553.                                                                         v:move(x, y, z)  -- Move the GEO to the player's coordinates
  1554.                                                                 else  -- Otherwise...
  1555.                                                                         v:delete()  -- Delete the GEO.
  1556.                                                                 end
  1557.                                                         else  -- Otherwise...
  1558.                                                                 v:delete()  -- Delete the GEO.
  1559.                                                         end
  1560.                                                 else  -- Otherwise...
  1561.                                                         v:delete()  -- Delete the GEO.
  1562.                                                 end
  1563.                                         else  -- Otherwise...
  1564.                                                 if v.p then  -- If this GEO has perimeter objects...
  1565.                                                         for objId, coords in pairs(v.p) do
  1566.                                                                 if getobject(objId) then
  1567.                                                                         local ox, oy, oz = table.unpack(coords)
  1568.                                                                         local x_diff = x - v.x
  1569.                                                                         local y_diff = y - v.y
  1570.                                                                         local z_diff = z - v.z
  1571.                                                                         local m_object = getobject(objId)
  1572.                                                                         movobjcoords(objId, ox + x_diff, oy + y_diff, oz + z_diff)  -- Move them with the GEO.
  1573.                                                                         GEO[v.n].p[objId] = {ox + x_diff, oy + y_diff, oz + z_diff}
  1574.                                                                 end
  1575.                                                         end
  1576.                                                 end
  1577.                                                 v:move(x, y, z)  -- Don't worry about all of that player nonsense and just move the damn GEO.
  1578.                                         end
  1579.                                 else  -- Otherwise...
  1580.                                         v:delete()  -- Delete the GEO.
  1581.                                 end
  1582.                         end
  1583.  
  1584.                         -- If after all of that following nonsense, we still have a GEO...
  1585.                         if v then
  1586.                                 -- If this GEO is a killzone...
  1587.                                 if v.kz then
  1588.                                         -- Check if anyone is inside of it.
  1589.                                         for i = 0,15 do
  1590.                                                 if getplayer(i) then
  1591.                                                         local m_player = getplayer(i)
  1592.                                                         local objId = readdword(m_player, 0x34)
  1593.                                                         if v:contains(objId) then
  1594.                                                                 kill(i)  -- Kill that ho.
  1595.                                                         end
  1596.                                                 end
  1597.                                         end
  1598.                                 end
  1599.  
  1600.                                 -- If this GEO is a damagezone...
  1601.                                 if v.damage then
  1602.                                         -- Check if anyone is inside of it.
  1603.                                         for i = 0,15 do
  1604.                                                 local m_player = getplayer(i)
  1605.                                                 if m_player then
  1606.                                                         local objId = readdword(m_player, 0x34)
  1607.                                                         if v:contains(objId) then
  1608.                                                                 applydmg(objId, v.damage / 100)  -- Apply damage
  1609.                                                         end
  1610.                                                 end
  1611.                                         end
  1612.                                 end
  1613.  
  1614.                                 -- If this GEO is monitoring for objects entering and exiting it...
  1615.                                 if v.m then
  1616.                                         -- Loop through the table of objects this GEO is monitoring for.
  1617.                                         for objId,_ in pairs(v.m) do
  1618.                                                 -- If this object still exists...
  1619.                                                 if getobject(objId) then
  1620.                                                         -- If this object is inside of the GEO...
  1621.                                                         if v:contains(objId) then
  1622.                                                                 -- If the GEO didn't know this object was inside of it 1/100 of a second ago...
  1623.                                                                 if not v.c[objId] then
  1624.                                                                         local player = objectidtoplayer(objId)
  1625.                                                                         -- Call OnGeoEnter.
  1626.                                                                         local allow = OnGeoEnter(v, player, objId)
  1627.                                                                         if allow == 0 or allow == false then
  1628.                                                                                 local hash = gethash(player)
  1629.                                                                                 if pcoords[hash] then
  1630.                                                                                         movobjcoords(objId, table.unpack(pcoords[hash]))
  1631.                                                                                 end
  1632.                                                                         else
  1633.                                                                                 GEO[k].c[objId] = true
  1634.                                                                         end
  1635.                                                                 end
  1636.                                                         else  -- Otherwise...
  1637.                                                                 -- If the GEO thought this object was inside of it 1/100 of a second ago...
  1638.                                                                 if v.c[objId] then
  1639.                                                                         local player = objectidtoplayer(objId)
  1640.                                                                         -- Call OnGeoExit.
  1641.                                                                         local allow = OnGeoExit(v, player, objId)
  1642.                                                                         if allow == 0 or allow == false then
  1643.                                                                                 local hash = gethash(player)
  1644.                                                                                 if pcoords[hash] then
  1645.                                                                                         movobjcoords(objId, table.unpack(pcoords[hash]))
  1646.                                                                                 end
  1647.                                                                         else
  1648.                                                                                 GEO[k].c[objId] = nil
  1649.                                                                         end
  1650.                                                                 end
  1651.                                                         end
  1652.                                                 else  -- Otherwise...
  1653.                                                         GEO[k].m[objId] = nil  -- Stop monitoring for this object.
  1654.                                                 end
  1655.                                         end
  1656.                                 end
  1657.  
  1658.                                 -- If this GEO has a velocity...
  1659.                                 if v.vx or v.vy or v.vz then
  1660.                                         if v.p then  -- If this GEO has perimeter objects...
  1661.                                                 for objId, coords in pairs(v.p) do
  1662.                                                         if getobject(objId) then
  1663.                                                                 local ox, oy, oz = table.unpack(coords)
  1664.                                                                 local m_object = getobject(objId)
  1665.                                                                 movobjcoords(objId, ox + (v.vx or 0), oy + (v.vy or 0), oz + (v.vz or 0))  -- Move them with the GEO.
  1666.                                                                 GEO[v.n].p[objId] = {ox + (v.vx or 0), oy + (v.vy or 0), oz + (v.vz or 0)}
  1667.                                                         end
  1668.                                                 end
  1669.                                         end
  1670.                                         -- Move that ho.
  1671.                                         v:move(v.x + (v.vx or 0) / 100, v.y + (v.vy or 0) / 100, v.z + (v.vz or 0) / 100)
  1672.                                 end
  1673.                         end
  1674.                 end
  1675.         end
  1676.  
  1677.         -- 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)
  1678.         if count % 25 == 0 then
  1679.                 for i = 0,15 do
  1680.                         local m_player = getplayer(i)
  1681.                         if m_player then
  1682.                                 local hash = gethash(i)
  1683.                                 local objId = readdword(m_player, 0x34)
  1684.                                 if getobject(objId) then
  1685.                                         pcoords[hash] = {getobjectcoords(objId)}
  1686.                                 else
  1687.                                         pcoords[hash] = nil
  1688.                                 end
  1689.                         end
  1690.                 end
  1691.         end
  1692.  
  1693.         return true
  1694. end
  1695.  
  1696. function OnGeoEnter(geo, player, objId)
  1697.     local hash = gethash(player)
  1698.     if geo == bombarea then
  1699.         if players[hash].bomb then
  1700.             privatesay(player, "Bomb droped")
  1701.             registertimer(1000, "ExplosionTimer")
  1702.             return true
  1703.         else
  1704.             privatesay(player, "You don't have the bomb")
  1705.             return true
  1706.         end
  1707.     end
  1708.     return true
  1709. end
  1710.  
  1711. function OnGeoExit(geo, player, objId)
  1712.  
  1713.         return true
  1714. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement