Advertisement
Combreal

CsGt_Old2.lua

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