Advertisement
Combreal

Csgt.lua

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