Advertisement
Combreal

Csgt_crashing.lua

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