Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- GEOs (Geometric Environment Objects) for Phasor 2.0
- --[[
- Documentation:
- This script allows the creation of environmental volumes in the shapes of spheres, rectangular prisms, cylinders, rectangles, or circles.
- These environmental volumes allow you to create complex environments with just a few lines of code, including the ability to make a volume a killzone, in which players will immediately die upon entering the volume or any user-defined actions as defined by the functions OnGeoEnter and OnGeoExit.
- GEOs can be returned and manipulated as objects in Lua; this means you can set a variable to be equal to a GEO, making it easy to manipulate in various areas of code.
- Changes from GEOs for Phasor 058 and GEOs for 2.0:
- -- GEO:damagezone now has the following function header: GEO:damagezone(boolean, damage).
- -- GEO:freeze has been changed to GEO:unfollow.
- GEO Creation Functions:
- GEO.newSphere(name, radius, x_coord, y_coord, z_coord)
- -- name: <string> Name of this new GEO (must be unique).
- -- radius: <float> Radius of this sphere.
- -- x_coord: <float> X-coordinate of the center of this sphere.
- -- y_coord: <float> Y-coordinate of the center of this sphere.
- -- z_coord: <float> Z-coordinate of the center of this sphere.
- Example:
- local sphere = GEO.newSphere("Sphere1", 5, 0, 0, 0)
- Notes:
- GEO.newSphere creates a spherical GEO with the specified name (keep in mind GEO names must be unique from each other), radius, and x, y, and z-coordinates of the center of the sphere. Returns the sphere as an object.
- GEO.newRectPrism(name, x_length, y_length, z_length, x_coord, y_coord, z_coord)
- -- name: <string> Name of this new GEO (must be unique).
- -- x_length: <float> Length of this rectangular prism in the X direction.
- -- y_length: <float> Length of this rectangular prism in the Y direction.
- -- z_length: <float> Length of this rectangular prism in the Z direction.
- -- x_coord: <float> X-coordinate of the center of this rectangular prism.
- -- y_coord: <float> Y-coordinate of the center of this rectangular prism.
- -- z_coord: <float> Z-coordinate of the center of this rectangular prism.
- Example:
- local rectprism = GEO.newRectPrism("RectPrism1", 3, 3, 10, 0, 0, 5)
- Notes:
- GEO.newRectPrism creates a rectangular prism GEO with the specified name (keep in mind GEO names must be unique from each other), x, y, and z lengths, and x, y, and z-coordinates of the center of the rectangular prism. Returns the rectangular prism as an object.
- GEO.newCylinder(name, radius, height, x_coord, y_coord, z_coord)
- -- name: <string> Name of this new GEO (must be unique).
- -- radius: <float> Radius of this cylinder.
- -- height: <float> Height of this cylinder.
- -- x_coord: <float> X-coordinate of the center of this cylinder.
- -- y_coord: <float> Y-coordinate of the center of this cylinder.
- -- z_coord: <float> Z-coordinate of the center of this cylinder.
- Example:
- local cylinder = GEO.newCylinder("Cylinder1", 3, 10, 0, 0, 0)
- Notes:
- GEO.newCylinder creates a cylindrical GEO with the specified name (keep in mind GEO names must be unique from each other), radius, height, and x, y, and z-coordinates of the center of the cylinder. Returns the cylinder as an object.
- GEO.newRect(name, width, height, x_coord, y_coord, z_coord, [orientation])
- -- name: <string> Name of this new GEO (must be unique).
- -- width: <float> Width of this rectangle.
- -- height: <float> Height of this rectangle.
- -- x_coord: <float> X-coordinate of the center of this rectangle.
- -- y_coord: <float> Y-coordinate of the center of this rectangle.
- -- z_coord: <float> Z-coordinate of the center of this rectangle.
- -- orientation: <string> Axis of orientation ("x", "y", or "z") (default = "z").
- Example:
- local rectangle = GEO.newRect("Rect1", 5, 10, 0, 0, 5, "x")
- Notes:
- GEO.newRect creates a rectangular GEO with the specified name (keep in mind GEO names must be unique from each other), width, height, x, y, and z-coordinates of the center of the rectangle, and orientation. The orientation specifies which axis ("x", "y", or "z") has a length of 0 in the rectangle. For example, by default, orientation is "z". This means you would see the rectangle if you were looking down on top of it (or up from underneath). You can also think of the orientation axis as being the axis that punches through the center of the object.
- GEO.newCircle(name, radius, x_coord, y_coord, z_coord, [orientation])
- -- name: <string> Name of this new GEO (must be unique).
- -- radius: <float> Radius of this circle.
- -- x_coord: <float> X-coordinate of the center of this circle.
- -- y_coord: <float> Y-coordinate of the center of this circle.
- -- z_coord: <float> Z-coordinate of the center of this circle.
- -- orientation: <string> Axis of orientation ("x", "y", or "z") (default = "z")
- Example:
- local circle = GEO.newCircle("Circle1", 10, 0, 0, 5, "x")
- Notes:
- GEO.newCircle creates a circular GEO with the specified name (keep in mind GEO names must be unique from each other), radius, x, y, and z-coordinates of the center of the circle, and orientation. The orienation specifies which axis ("x", "y", or "z") has a length of 0 in the circle. For example, by default, orientation is "z". This means you would see the circle if you were looking down on top of it (or up from underneath). You can also think of the orientation axis as being the axis that punches through the center of the object.
- Once you've created your GEO, you want to make it do something. The following are GEO-editing functions.
- Note that the following functions are members of the GEO metatable. This means to call the function, you specify the GEO variable before the function (separated by a colon). See the functions below for more specific examples.
- GEO Editing Functions:
- GEO:delete()
- Example:
- local sphere = GEO.newSphere("Sphere", 5, 0, 0, 0)
- sphere:delete()
- Notes:
- Deletes the specified GEO.
- GEO:move(x_coord, y_coord, z_coord)
- -- x_coord: <float> New x-coordinate of the center of this GEO.
- -- y_coord: <float> New y-coordinate of the center of this GEO.
- -- z_coord: <float> New z-coordinate of the center of this GEO.
- Example:
- local sphere = GEO.newSphere("Sphere", 5, 0, 0, 0)
- sphere:move(0, 0, 10)
- Notes:
- Moves the center of the specified GEO to the specified x, y, and z-coordinates.
- GEO:radius([new_radius])
- -- new_radius: <float> New radius of specified GEO (if no radius is specified, the radius of the GEO is returned).
- Example:
- local cylinder = GEO.newCylinder("Cylinder", 10, 20, 0, 0, 0)
- local cyl_radius = cylinder:radius()
- if cyl_radius < 20 then
- cylinder:radius(20)
- end
- Notes:
- If a new_radius is specified, changes the radius of the specified GEO to the value of new_radius. Otherwise, returns the radius of the specified GEO. Note that this can only be used for spheres, circles, and cylinders.
- GEO:size([x_length], [y_length], [z_length])
- -- x_length: <float> New length of GEO in the x direction.
- -- y_length: <float> New length of GEO in the y direction.
- -- z_length: <float> New length of GEO in the z direction.
- -- Read the notes for descriptions about how the optional parameters work in this function.
- Example:
- -- Create three GEOs
- local rectprism = GEO.newRectPrism("RectPrism", 5, 5, 10, 0, 0, 5)
- local rectangle = GEO.newRect("Rect", 5, 10, 0, 0, 5, "y")
- local cylinder = GEO.newCylinder("Cylinder", 5, 20, 0, 0, 10)
- -- Get sizes of all three shapes
- local rpx, rpy, rpz = rectprism:size()
- local rw, rh = rectangle:size()
- local cyl_height = cylinder:size()
- -- Double their sizes
- rectprism:size(rpx * 2, rpy * 2, rpz * 2)
- rectangle:size(rw * 2, 0, rh * 2)
- cylinder:size(cyl_height * 2)
- Notes:
- If any coordinate is specified, changes the GEO's size in the x, y, and z directions respectively. If no coordinate is specified in any direction, this returns the size of the object. Note this can only be used for rectangular prisms, rectangles, and cylinders. Also note if you're attempting to retrieve the size of an object, rectangular prisms will return three values (x, y, and z), rectangles will return two values (width and height), and cylinders will return one value (height). Also note that when changing the height of a cylinder, you need only specify one number (since you're only changing the height). If you're trying to change the size of a rectangle, keep its orientation in mind when changing the x, y, and z lengths (changes in length of the axis of which the rectangle is oriented will be ignored).
- GEO:contains(objId)
- objId: <object id> Object being tested to see if it is inside of the specfied GEO.
- Example:
- local sphere = GEO.newSphere("Sphere", 5, 0, 0, 0)
- function OnPlayerSpawn(player)
- local m_player = getplayer(player)
- local objId = readdword(m_player, 0x34)
- if sphere:contains(objId) then
- say(getname(player) .. " has spawned inside of the sphere")
- end
- end
- Notes:
- Checks if the specified objId is within the specified GEO. Returns true or false.
- GEO:follow(objId)
- objId: <object id> Object this GEO should follow.
- Example:
- function OnPlayerSpawn(player)
- local m_player = getplayer(player)
- local objId = readdword(m_player, 0x34)
- -- Create a sphere with the objId in the name so you know it is unique
- local sphere = GEO.newSphere("Sphere" .. objId, 5, 0, 0, 0)
- sphere:follow(objId)
- end
- Notes:
- Sets a GEO to follow the specified objId. The GEO will be automatically deleted if the object it is following has also been deleted.
- GEO:unfollow()
- Example:
- function OnPlayerSpawn(player)
- local m_player = getplayer(player)
- local objId = readdword(m_player, 0x34)
- -- Create a sphere with the objId in the name so you know it is unique
- local sphere = GEO.newSphere("Sphere" .. objId, 5, 0, 0, 0)
- sphere:follow(objId)
- sphere:unfollow()
- end
- Notes:
- Tells the specified GEO to stop following the objId it is currently following.
- GEO:velocity(x_velocity, y_velocity, z_velocity)
- x_velocity: <float> GEO's velocity in the x direction.
- y_velocity: <float> GEO's velocity in the y direction.
- z_velocity: <float> GEO's velocity in the z direction.
- Example:
- local rectangle = GEO.newRectPrism("RectPrism", math.inf, math.inf, 100, 0, 0, -50)
- rectangle:velocity(0, 0, 0.1)
- Notes:
- Sets the velocity of the specified GEO in the x, y, and z directions.
- GEO:killzone([boolean])
- boolean: <boolean> The ability of this GEO to be a killzone (if no boolean is specified, the current killzone boolean is returned).
- Example:
- local killsphere = GEO.newSphere("Sphere", 10, 0, 0, 0)
- killsphere:killzone(true)
- Notes:
- Toggles the ability for a GEO to be a killzone. If a GEO is a killzone, any player to enter the GEO will automatically die.
- GEO:damagezone(boolean, damage)
- boolean: <boolean> Indicates whether or not this GEO is a damagezone (if no boolean is specified, the current damagezone boolean is returned).
- damage: <float> Amount of damage per second this GEO does to a player within it.
- Example:
- local damagesphere = GEO.newSphere("Sphere", 10, 0, 0, 0)
- damagesphere:damagezone(true, 10)
- Notes:
- Toggles the ability for a GEO to be a damagezone. If a GEO is a damagezone, the player will be damaaged at the rate you specify.
- GEO:face(orientation, direction)
- orientation: <string> The axis on which the face will be created ("x", "y", or "z").
- direction: <string> The specification of the "top" or "bottom" face in the specified orientation ("+" or "-").
- Example:
- local cylinder = GEO.newCylinder("Cylinder", 5, 10, 0, 0, 5)
- local topcircle = cylinder:face("z", "+")
- local bottomcircle = cylinder:face("z", "-")
- Notes:
- Cuts the face of the specified three-dimensional GEO off to create a two-dimensional GEO given the orientation ("x", "y", or "z") and direction ("+" or "-"). For example, if the orientation is "z" and the direction is "+", and you're passing a rectangular prism, you will end up with the a rectangle with the same position and size as the top face of your rectangular prism. Note you can only use this for rectangular prisms and cylinders. Also note that for cylinders, you may only use the "z" orientation. Returns the new two-dimensional GEO as an object.
- GEO:extend(orientation, direction, amount)
- orientation: <string> The axis on which the face will be extended ("x", "y", or "z").
- direction: <string> The specification of the "top" or "bottom" face in the specified orientation ("+" or "-").
- amount: <float> Distance the specified face will be extended.
- Example:
- local cylinder = GEO.newCylinder("Cylinder", 5, 10, 0, 0, 5)
- cylinder:extend("z", "+", 10)
- Notes:
- Extends the specified face by the specified amount (see the function face for how to specify orientation and direction). Note that this may only be used on rectangular prisms, rectangles, and cylinders.
- GEO:copy([name])
- name: <string> Name given to the copy of the specified GEO (if no name is specified, a default name is given).
- Example:
- local sphere = GEO.newSphere("Sphere", 5, 0, 0, 0)
- local sphere2 = sphere:copy()
- Notes:
- Returns a copy of the specified GEO with the specified name. If no name is specified, a default name will be given.
- GEO:monitor(objId)
- objId: <object id> The object this GEO should monitor for entering/exiting.
- Example:
- local rectprism = GEO.newRectPrism("RectPrism", math.inf, math.inf, 100, 0, 0, -50)
- function OnPlayerSpawn(player)
- local m_player = getplayer(player)
- local objId = readdword(m_player, 0x34)
- -- Tells rectprism to monitor this newly-created objId for entering and exiting.
- rectprism:monitor(objId)
- end
- Notes:
- Tells the specified GEO to monitor when objId enters and exits it. Note that this must be used in order for OnGeoEnter and OnGeoExit to work for the specified GEO and objId. This is for the sake of the script not having to check the coordinates of every single object and comparing them to the volumes of every single GEO every 1/100 of a second.
- GEO:coords()
- Example:
- local sphere = GEO.newSphere("Sphere", 10, 0, 0, 0)
- local x, y, z = sphere:coords()
- Notes:
- Returns the x, y, and z coordinates of the center of the specified GEO.
- GEO:high(orientation)
- orientation: <string> Axis of which you're attempting to find the highest point ("x", "y", or "z").
- Example:
- local sphere = GEO.newSphere("Sphere", 10, 0, 0, 0)
- local zhigh = sphere:high("z")
- Notes:
- Returns the highest coordinate in the specified orientation (i.e. geo:high("z") would return the highest z coordinate still considered to be inside of the GEO).
- GEO:low(orientation)
- orientation: <string> Axis of which you're attempting to find the lowest point ("x", "y", or "z")
- Example:
- local sphere = GEO.newSphere("Sphere", 10, 0, 0, 0)
- local zlow = sphere:low("z")
- Notes:
- Returns the lowest coordinate in the specified orientation (i.e. geo:low("z") would return the lowest z coordinate still considered to be inside of the GEO).
- GEO:randcoords()
- Example:
- local cylinder = GEO.newCylinder("Cylinder", 5, 10, 0, 0, 0)
- local x, y, z = cylinder:randcoords()
- Notes:
- Returns random x, y, and z coordinates within the specified GEO.
- GEO:type()
- Example:
- local cylinder = GEO.newCylinder("Cylinder", 5, 10, 0, 0, 0)
- local type = cylinder:type()
- Notes:
- Returns the type of the specified GEO as a string.
- GEO:orientation()
- Example:
- local cylinder = GEO.newCylinder("Cylinder", 5, 10, 0, 0, 0)
- local circle = cylinder:face("z", "+")
- local orientation = circle:orientation()
- Notes:
- Returns the orientation of a 2-dimensional GEO. Note that this can only be used on rectangles and circles.
- GEO:name()
- Example:
- local sphere = GEO.newSphere("Sphere", 5, 0, 0, 0)
- local name = sphere:name()
- Notes:
- Returns the name of the specified GEO.
- GEO:perimeter(density, [mapId])
- density: <int> Amount of objects that should spawn around the perimeter of the GEO.
- mapId: <tag id> The tag of the objects that should spawn around the GEO's perimeter (default = Full-Spectrum Vision)
- Example:
- local sphere = GEO.newSphere("sphere", 5, 0, 0, 0.5)
- sphere:perimeter(20)
- local rectprism = GEO.newRectPrism("rectprism", 3, 4, 5, 0, 0, 0.5)
- rectprism:perimeter(7, "weap", "weapons\\flag\\flag")
- Notes:
- Spawns the specified object (given via mapId) with the specified density about the perimeter of the Z-center of the specified GEO. For spheres and cylinders, the amount of objects spawned will be equal to the density. For rectangular prisms, the density specifies the amount of objects spawned per edge (so a density of 10 will spawn a total of 40 objects). You may want to make sure the GEO's center is slightly above the ground so the objects don't spawn under the map. Also be careful when this function is used, as it does create objects. I believe some Phasor functions (such as OnNewGame) screw up when you try to spawn objects in them.
- OnGeoEnter and OnGeoExit Event Functions:
- OnGeoEnter(geo, player, objId)
- geo: <GEO object> The GEO the player or object is entering.
- player: <player memory id> The player entering the GEO.
- objId: <object id> The objId entering the GEO.
- Example:
- sphere = GEO.newSphere("sphere", 5, 0, 0, 0)
- function OnPlayerSpawn(player, objId)
- sphere:monitor(objId)
- end
- function OnGeoEnter(geo, player, objId)
- if geo == sphere then
- privatesay(player, "You may not enter this GEO.")
- return false
- end
- return true
- end
- Notes:
- Called when an object that is being monitored by a GEO enters that GEO. Return 1 to allow players to enter, return 0 to disallow this.
- OnGeoExit(geo, player, objId)
- geo: <GEO object> The GEO the player or object is exiting.
- player: <player memory id> The player exiting the GEO.
- objId: <object id> The objId exiting the GEO.
- Example:
- sphere = GEO.newSphere("sphere", 5, 0, 0, 0)
- function OnPlayerSpawn(player, objId)
- sphere:monitor(objId)
- end
- function OnGeoExit(geo, player, objId)
- if geo == sphere then
- privatesay(player, "You may not exit this GEO.")
- return false
- end
- return true
- end
- Notes:
- Called when an object that is being monitored by a GEO exits that GEO. Return 1 to allow players to exit, return 0 to disallow this.
- Miscellaneous GEO functions:
- GEO.get(name)
- name: <string> Name of the GEO you're trying to access.
- Example:
- function OnPlayerSpawn(player)
- local m_player = getplayer(player)
- local objId = readdword(m_player, 0x34)
- local sphere = GEO.newSphere("Sphere" .. objId, 5, 0, 0, 0)
- sphere:follow(objId)
- end
- function OnPlayerKill(killer, victim, mode)
- local m_victim = getplayer(victim)
- local v_objectId = readdword(m_victim, 0x34)
- local victim_sphere = GEO.get("Sphere" .. v_objectId)
- victim_sphere:freeze()
- end
- Notes:
- Returns a GEO given the specified name.
- GEO.followedBy(objId)
- objId: <object id> Object being followed by GEOs.
- Example:
- function OnPlayerKill(killer, victim, mode)
- local geos = GEO.followedBy(victim)
- for k,v in ipairs(geos) do
- v:freeze()
- end
- end
- Notes:
- Returns a list of GEOs following the specified objId.
- GEO.cleanup(player)
- player: <player memory id> Player whose following of GEOs you want to delete.
- Example:
- -- Note that this is here only for the sake of example; this is not necessary, as the GEOTimer takes care of this automatically.
- function OnPlayerKill(killer, victim, mode)
- GEO.cleanup(victim)
- end
- Notes:
- Deletes all of the GEOs currently following the specified player.
- If you have any questions about how GEOs work, PM me (Nuggets) at phasor.proboards.com.
- --]]
- -- Create Metatable
- GEO = {}
- GEO.__index = GEO
- -- Set random seed and define infinity
- math.randomseed(os.time())
- math.inf = 1 / 0
- function inSphere(objId, x, y, z, r)
- local ox, oy, oz = getobjectcoords(objId)
- if ox then
- -- Pythagorean
- local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2 + (z - oz) ^ 2)
- if dist <= r then
- return true
- end
- end
- return false
- end
- function inCircle(objId, x, y, z, r, orientation)
- local ox, oy, oz = getobjectcoords(objId)
- if ox then
- -- Default orientation to "z"
- orientation = orientation or "z"
- -- Pythagorean based on circle's orientation
- if orientation == "z" then
- local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2)
- if dist <= r and oz == z then
- return true
- end
- elseif orientation == "y" then
- local dist = math.sqrt((x - ox) ^ 2 + (z - oz) ^ 2)
- if dist <= r and oy == y then
- return true
- end
- elseif orientation == "x" then
- local dist = math.sqrt((y - oy) ^ 2 + (z - oz) ^ 2)
- if dist <= r and ox == x then
- return true
- end
- end
- end
- return false
- end
- function inCylinder(objId, x, y, zlow, zhigh, r)
- local ox, oy, oz = getobjectcoords(objId)
- if ox then
- -- Pythagorean to see if object is within radius of circle
- local dist = math.sqrt((x - ox) ^ 2 + (y - oy) ^ 2)
- -- Make sure the object is also within the height of the cylinder
- if dist <= r and z >= zlow and z <= zhigh then
- return true
- end
- end
- return false
- end
- function inRectangle(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- -- These functions are essentially the same
- return inRectPrism(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- end
- function inRectPrism(objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- local x, y, z = getobjectcoords(objId)
- if x then
- -- Make sure the coordinates are inside of each extreme of the rectangular prism
- if x <= xhigh and x >= xlow and y <= yhigh and y >= ylow and z <= zhigh and z >= zlow then
- return true
- end
- end
- return false
- end
- function randomInSphere(x, y, z, r)
- -- Increase precision
- x = math.floor(x * 100)
- y = math.floor(y * 100)
- z = math.floor(z * 100)
- r = math.floor(r * 100)
- -- Find random values inside of the sphere.
- return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, math.random(z - r, z + r + 1) / 100
- end
- function randomInCircle(x, y, z, r, orientation)
- -- Increase precision
- r = math.floor(r * 100)
- -- Possible values depend on circle's orientation.
- if orientation == "z" then
- x = math.floor(x * 100)
- y = math.floor(y * 100)
- return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, z
- elseif orientation == "x" then
- y = math.floor(y * 100)
- z = math.floor(z * 100)
- return x, math.random(y - r, y + r + 1) / 100, math.random(z - r, z + r + 1) / 100
- elseif orientation == "y" then
- x = math.floor(x * 100)
- z = math.floor(z * 100)
- return math.random(x - r, x + r + 1) / 100, y, math.random(z - r, z + r + 1) / 100
- end
- end
- function randomInCylinder(x, y, zlow, zhigh, r)
- -- Increase precision
- x = math.floor(x * 100)
- y = math.floor(y * 100)
- zlow = math.floor(zlow * 100)
- zhigh = math.floor(zhigh * 100)
- r = math.floor(r * 100)
- -- Find random values inside of the cylinder.
- return math.random(x - r, x + r + 1) / 100, math.random(y - r, y + r + 1) / 100, math.random(zlow, zhigh + 1) / 100
- end
- function randomInRectPrism(xlow, xhigh, ylow, yhigh, zlow, zhigh)
- -- Increase precision
- xlow = math.floor(xlow * 100)
- xhigh = math.floor(xhigh * 100)
- ylow = math.floor(ylow * 100)
- yhigh = math.floor(yhigh * 100)
- zlow = math.floor(zlow * 100)
- zhigh = math.floor(zhigh * 100)
- -- Find random values inside of the rectangular prism.
- return math.random(xlow, xhigh + 1) / 100, math.random(ylow, yhigh + 1) / 100, math.random(zlow, zhigh)
- end
- -- Object Creation Comments (refer to this function for questions on how the other ones work)
- function GEO.newSphere(name, r, x, y, z)
- -- Check to see if there is already a GEO with this name.
- if not GEO[name] then
- -- Create new table
- GEO[name] = {}
- GEO[name].t = "sphere" -- type
- GEO[name].n = name -- name
- GEO[name].r = r or 1 -- radius (default value of 1)
- GEO[name].x = x or 0 -- x coordinate of center (default value of 0)
- GEO[name].y = y or 0 -- y coordinate of center (default value of 0)
- GEO[name].z = z or 0 -- z coordinate of center (default value of 0)
- -- Notify the console that a sphere has been created.
- hprintf("Sphere \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO) -- Add this object to the GEO metatable to allow GEO-editing functions to work on it.
- return GEO[name] -- Return the object
- end
- -- If no object was returned, the name was invalid; notify the console.
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.newCircle(name, r, x, y, z, orientation)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "circle"
- GEO[name].n = name
- GEO[name].o = orientation or "z" -- orientation
- GEO[name].r = r or 0
- GEO[name].x = x or 0
- GEO[name].y = y or 0
- GEO[name].z = z or 0
- hprintf("Circle \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.newCylinder(name, r, h, x, y, z)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "cylinder"
- GEO[name].n = name
- x = x or 0
- y = y or 0
- z = z or 0
- r = r or 1
- h = h or 1
- GEO[name].x = x
- GEO[name].y = y
- GEO[name].z = z
- GEO[name].r = r
- GEO[name].h = h -- height
- GEO[name].zlow = z - h / 2 -- lowest z-coordinate still within the cylinder
- GEO[name].zhigh = z + h / 2 -- highest z-coordinate still within the cylinder
- hprintf("Cylinder \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- end
- function GEO.newRectPrism(name, lx, ly, lz, x, y, z)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "rectprism"
- GEO[name].n = name
- lx = lx or 1
- ly = ly or 1
- lz = lz or 1
- x = x or 0
- y = y or 0
- z = z or 0
- GEO[name].lx = lx -- x length
- GEO[name].ly = ly -- y length
- GEO[name].lz = lz -- z length
- GEO[name].x = x
- GEO[name].y = y
- GEO[name].z = z
- GEO[name].xlow = x - lx / 2 -- lowest x-coordinate still within the rectangular prism
- GEO[name].xhigh = lx / 2 + x -- highest x-coordinate still within in the rectangular prism
- GEO[name].ylow = y - ly / 2 -- lowest y-coordinate still within the rectangular prism
- GEO[name].yhigh = ly / 2 + y -- highest y-coordinate still within the rectangular prism
- GEO[name].zlow = z - lz / 2 -- lowest z-coordinate still within the rectangular prism
- GEO[name].zhigh = lz / 2 + z -- highest z-coordinate still within the rectangular prism
- hprintf("Rectangular Prism \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.newRect(name, width, height, x, y, z, orientation)
- if not GEO[name] then
- GEO[name] = {}
- GEO[name].t = "rectangle"
- GEO[name].n = name
- width = width or 1
- height = height or 1
- x = x or 0
- y = y or 0
- z = z or 0
- orientation = orientation or "z"
- GEO[name].width = width
- GEO[name].height = height
- GEO[name].x = x
- GEO[name].y = y
- GEO[name].z = z
- GEO[name].o = orientation
- -- Coordinates' highs and lows depend on orientation
- if orientation == "z" then
- GEO[name].xlow = x - width / 2
- GEO[name].xhigh = x + width / 2
- GEO[name].ylow = y - height / 2
- GEO[name].yhigh = y + height / 2
- GEO[name].zlow = z
- GEO[name].zhigh = z
- elseif orientation == "x" then
- GEO[name].xlow = x
- GEO[name].xhigh = x
- GEO[name].ylow = y - width / 2
- GEO[name].yhigh = y + width / 2
- GEO[name].zlow = z - height / 2
- GEO[name].zhigh = z + height / 2
- elseif orientation == "y" then
- GEO[name].xlow = x - width / 2
- GEO[name].xhigh = x + width / 2
- GEO[name].ylow = y
- GEO[name].yhigh = y
- GEO[name].zlow = z - height / 2
- GEO[name].zhigh = z + height / 2
- end
- hprintf("Rectangle \"" .. name .. "\" created.")
- setmetatable(GEO[name], GEO)
- return GEO[name]
- end
- hprintf("Invalid name: \"" .. name .. "\"")
- end
- function GEO.get(name)
- return GEO[name]
- end
- function GEO:delete()
- self:hide()
- GEO[self.n] = nil
- hprintf("Geo \"" .. self.n .. "\" deleted.")
- end
- function GEO:move(x, y, z)
- -- Move the center of the object
- -- Default to GEO's current coordinates
- GEO[self.n].x = x or GEO[self.n].x
- GEO[self.n].y = y or GEO[self.n].y
- GEO[self.n].z = z or GEO[self.n].z
- -- If this is a rectangular prism...
- if self.t == "rectprism" then
- -- Change the x, y, and z lows and highs accordingly to adjust to the new center
- GEO[self.n].xlow = x - GEO[self.n].lx / 2
- GEO[self.n].xhigh = GEO[self.n].lx / 2 + x
- GEO[self.n].ylow = y - GEO[self.n].ly / 2
- GEO[self.n].yhigh = GEO[self.n].ly / 2 + y
- GEO[self.n].zlow = z - GEO[self.n].lz / 2
- GEO[self.n].zhigh = GEO[self.n].lz / 2 + z
- -- If this is a rectangle...
- elseif self.t == "rectangle" then
- -- Change the x, y, and z lows and highs accordingly to adjust to the new center (depends on orientation)
- if self.o == "z" then
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y - self.height / 2
- GEO[self.n].yhigh = self.y + self.height / 2
- GEO[self.n].zlow = self.z
- GEO[self.n].zhigh = self.z
- elseif self.o == "x" then
- GEO[self.n].xlow = self.x
- GEO[self.n].xhigh = self.x
- GEO[self.n].ylow = self.y - self.width / 2
- GEO[self.n].yhigh = self.y + self.width / 2
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- elseif self.o == "y" then
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y
- GEO[self.n].yhigh = self.y
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- GEO[self.n].zlow = self.z - self.h / 2
- GEO[self.n].zhigh = self.z + self.h / 2
- end
- end
- function GEO:radius(new)
- if self.t == "sphere" or self.t == "circle" or self.t == "cylinder" then
- if new then -- If "new" is defined...
- GEO[self.n].r = new -- Change the radius to its value.
- else -- If not...
- return GEO[self.n].r -- Return its current radius.
- end
- end
- end
- function GEO:size(x, y, z)
- -- If this is a rectangular prism...
- if self.t == "rectprism" then
- if x or y or z then -- If any of these variables have been defined...
- -- Adjust lengths and x, y, and z highs and lows accordingly.
- GEO[self.n].lx = x or GEO[self.n].lx
- GEO[self.n].ly = y or GEO[self.n].ly
- GEO[self.n].lz = z or GEO[self.n].lz
- GEO[self.n].xlow = GEO[self.n].x - x / 2
- GEO[self.n].xhigh = x / 2 + GEO[self.n].x
- GEO[self.n].ylow = GEO[self.n].y - y / 2
- GEO[self.n].yhigh = y / 2 + GEO[self.n].y
- GEO[self.n].zlow = GEO[self.n].z - z / 2
- GEO[self.n].zhigh = z / 2 + GEO[self.n].z
- else -- Otherwise...
- return GEO[self.n].lx, GEO[self.n].ly, GEO[self.n].lz -- Return the x, y, and z lengths.
- end
- -- If this is a rectangle...
- elseif self.t == "rectangle" then
- if x or y or z then -- If any of these variables are defined...
- -- Adjust width, height, and x, y, and z highs and lows accordingly (depends on orientation).
- if self.o == "z" then
- GEO[self.n].width = x
- GEO[self.n].height = y
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y - self.height / 2
- GEO[self.n].yhigh = self.y + self.height / 2
- GEO[self.n].zlow = self.z
- GEO[self.n].zhigh = self.z
- elseif self.o == "x" then
- GEO[self.n].width = y
- GEO[self.n].height = z
- GEO[self.n].xlow = self.x
- GEO[self.n].xhigh = self.x
- GEO[self.n].ylow = self.y - self.width / 2
- GEO[self.n].yhigh = self.y + self.width / 2
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- elseif self.o == "y" then
- GEO[self.n].width = x
- GEO[self.n].height = z
- GEO[self.n].xlow = self.x - self.width / 2
- GEO[self.n].xhigh = self.x + self.width / 2
- GEO[self.n].ylow = self.y
- GEO[self.n].yhigh = self.y
- GEO[self.n].zlow = self.z - self.height / 2
- GEO[self.n].zhigh = self.z + self.height / 2
- end
- else -- Otherwise...
- return GEO[self.n].width, GEO[self.n].height -- Return the width and height of the rectangle.
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- local h = x or y or z -- Whichever variable is defined, it is taken as the height.
- if h then -- If a height is specified...
- -- Adjust height and z high and low accordingly.
- GEO[self.n].h = h
- GEO[self.n].zlow = self.z - h / 2
- GEO[self.n].zhigh = self.z + h / 2
- else -- Otherwise...
- return GEO[self.n].h -- Return the height.
- end
- end
- end
- function GEO:extend(orienation, direction, amount)
- -- Change the direction from "+" or "-" to "high" or "low".
- local dir
- dir = string.gsub(direction, "-", "low")
- dir = string.gsub(direction, "+", "high")
- -- Get the face we're trying to extend (i.e. "xhigh")
- local face = string.lower(orientation) .. direction
- -- If this is a rectangular prism or a rectangle...
- if self.t == "rectprism" or self.t == "rectangle" then
- -- Make sure "face" is actually a valid face (and not something like "cheesederp")
- if self[face] then
- -- Use "GEO[self.n]" when you want to actually permanently change the value of something within the object; use "self" for reading information from the object.
- -- Change the length of the GEO in the orientation specified.
- GEO[self.n]["l" .. string.lower(orientation)] = self["l" .. string.lower(orientation)] + amount
- -- Figure out if the positive or negative face is being extended.
- if direction == "+" then
- GEO[self.n][face] = self[face] + amount
- GEO[self.n][string.lower(orientation)] = self[string.lower(orientation)] + amount / 2
- else
- GEO[self.n][face] = self[face] - amount
- GEO[self.n][string.lower(orientation)] = self[string.lower(orientation)] - amount / 2
- end
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- -- The orientation must be "z"
- if orientation == "z" then
- if self[face] then
- GEO[self.n].h = self.h + amount
- -- Figure out if the top or bottom face is being extended.
- if direction == "+" then
- GEO[self.n][face] = self[face] + amount
- GEO[self.n].z = self.z + amount / 2
- else
- GEO[self.n][face] = self[face] - amount
- GEO[self.n].z = self.z - amount / 2
- end
- end
- end
- end
- end
- function GEO:coords()
- return self.x, self.y, self.z
- end
- function GEO:high(orientation)
- if self.t == "sphere" or self.t == "circle" then
- return self[orientation] + self.r
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return self[orientation .. "high"]
- elseif self.t == "cylinder" then
- if orientation == "z" then
- return self.zhigh
- else
- return self[orientation] + self.r
- end
- end
- end
- function GEO:low(orientation)
- if self.t == "sphere" or self.t == "circle" then
- return self[orientation] - self.r
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return self[orientation .. "low"]
- elseif self.t == "cylinder" then
- if orientation == "z" then
- return self.zlow
- else
- return self[orientation] - self.r
- end
- end
- end
- function GEO:randcoords()
- if self.t == "sphere" then
- return randomInSphere(self.x, self.y, self.z, self.r)
- elseif self.t == "circle" then
- return randomInCircle(self.x, self.y, self.z, self.r, self.o)
- elseif self.t == "cylinder" then
- return randomInCylinder(self.x, self.y, self.zlow, self.zhigh, self.r)
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return randomInRectPrism(self.xlow, self.xhigh, self.ylow, self.yhigh, self.zlow, self.zhigh)
- end
- end
- function GEO:type()
- return self.t
- end
- function GEO:orientation()
- return self.o
- end
- function GEO:name()
- return self.n
- end
- function GEO:perimeter(density, mapId)
- -- Default density to 10
- density = density or 10
- -- Default tagtype and tagname to Full-Spectrum Visions
- mapId = mapId or gettagid("eqip", "powerups\\full-spectrum vision")
- tagname, tagtype = gettaginfo(mapId)
- -- Store all of the perimeter objects in a table
- GEO[self.n].p = GEO[self.n].p or {}
- -- Find the change in angle per point from 0 - 2pi (0° - 360°)
- local angle_increment = 2 * math.pi / density
- if self.t == "sphere" or self.t == "cylinder" then
- for i = 1,density do
- -- Use trigonometry to find the outer edge of the circle (for a sphere, this will be at the z-center -- the widest part of the sphere).
- local x = self.r * math.cos(angle_increment * i)
- local y = self.r * math.sin(angle_increment * i)
- local z = self.z
- local objId = createobject(mapId, 0, 0, false, self.x + x, self.y + y, self.z + z)
- GEO[self.n].p[objId] = {self.x + x, self.y + y, self.z + z}
- end
- elseif self.t == "circle" then
- if self.o == "z" then
- for i = 1,density do
- -- Use trigonometry to find the outer edge of the circle (for a sphere, this will be at the z-center -- the widest part of the sphere).
- local x = self.r * math.cos(angle_increment * i)
- local y = self.r * math.sin(angle_increment * i)
- local z = self.z
- local objId = createobject(mapId, 0, 0, false, self.x + x, self.y + y, self.z + z)
- GEO[self.n].p[objId] = {self.x + x, self.y + y, self.z + z}
- end
- end
- elseif self.t == "rectprism" or self.t == "rectangle" then
- if self.t == "rectangle" then
- if self.o ~= "z" then return end
- end
- -- Create points at four corners of the rectangle
- local o1 = createobject(mapId, 0, 0, false, self.xhigh, self.yhigh, self.z)
- local o2 = createobject(mapId, 0, 0, false, self.xhigh, self.ylow, self.z)
- local o3 = createobject(mapId, 0, 0, false, self.xlow, self.yhigh, self.z)
- local o4 = createobject(mapId, 0, 0, false, self.xlow, self.ylow, self.z)
- GEO[self.n].p[o1] = {self.xhigh, self.yhigh, self.z}
- GEO[self.n].p[o2] = {self.xhigh, self.yhigh, self.z}
- GEO[self.n].p[o3] = {self.xhigh, self.yhigh, self.z}
- GEO[self.n].p[o4] = {self.xhigh, self.yhigh, self.z}
- for i = 1,density do
- local herp = createobject(mapId, 0, 0, false, self.xhigh - (i * self.lx / density), self.yhigh, self.z)
- local derp = createobject(mapId, 0, 0, false, self.xhigh, self.yhigh - (i * self.ly / density), self.z)
- local weee = createobject(mapId, 0, 0, false, self.xhigh - (i * self.lx / density), self.ylow, self.z)
- local cheese = createobject(mapId, 0, 0, false, self.xlow, self.ylow + (i * self.ly / density), self.z)
- GEO[self.n].p[herp] = {self.xhigh - (i * self.lx / density), self.yhigh, self.z}
- GEO[self.n].p[derp] = {self.xhigh, self.yhigh - (i * self.ly / density), self.z}
- GEO[self.n].p[weee] = {self.xhigh - (i * self.lx / density), self.ylow, self.z}
- GEO[self.n].p[cheese] = {self.xlow, self.ylow + (i * self.ly / density), self.z}
- end
- end
- end
- function GEO:hide()
- if self.p then
- for k,v in pairs(GEO[self.n].p) do
- if getobject(k) then
- destroyobject(k)
- GEO[self.n].p[k] = nil
- end
- end
- end
- end
- -- Never quite got this to work right, but I'm saving it for the sake of the formula.
- --[[function GEO:surface(density)
- GEO[self.n].p = GEO[self.n].p or {}
- if self.t == "sphere" then
- local inc = math.pi * (3 - math.sqrt(5))
- local off = 2 / density
- for i = 1,density do
- local y = self.r * i * off - 1 + (off / 2)
- local r = self.r * math.sqrt(1 - y ^ 2)
- local phi = i * inc
- local x = r * math.cos(phi)
- local z = r * math.sin(phi)
- local objId = createobject(mapId, 0, 0, false, x, y, z)
- GEO[self.n].p[objId] = {x, y, z}
- end
- end
- end--]]
- function GEO:contains(objId)
- if self.t == "sphere" then
- return inSphere(objId, self.x, self.y, self.z, self.r)
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return inRectPrism(objId, self.xlow, self.xhigh, self.ylow, self.yhigh, self.zlow, self.zhigh)
- elseif self.t == "circle" then
- return inCircle(objId, self.x, self.y, self.z, self.r, self.o)
- elseif self.t == "cylinder" then
- return inCylinder(objId, self.x, self.y, self.zlow, self.zhigh, self.r)
- end
- end
- function GEO:follow(objId)
- -- If the objId exists...
- if getobject(objId) then
- GEO[self.n].f = objId -- Save it (the GEOTimer will access it)
- -- Check to see if the object is a player
- if objectidtoplayer(objId) then
- GEO[self.n].player = true
- end
- end
- end
- function GEO:unfollow()
- -- Nullify the saved objId from GEO:follow()
- GEO[self.n].f = nil
- end
- function GEO.followedBy(objId)
- -- Initialize table
- local geos = {}
- -- Loop through the GEO table
- for k,v in pairs(GEO) do
- if type(v) == "table" and k ~= "__index" then -- make sure we're actually getting a GEO object
- if v.f == objId then
- -- If this GEO has this objId saved, insert it into the geos table.
- table.insert(geos, v)
- end
- end
- end
- -- Return the GEOs following objId in a table.
- return geos
- end
- function GEO.cleanup(player)
- local m_player = getplayer(player)
- local objId = readdword(m_player, 0x34)
- local geos = GEO.followedBy(objId)
- for k,v in ipairs(geos) do
- v:delete()
- end
- end
- function GEO:velocity(x, y, z)
- GEO[self.n].vx = x or GEO[self.n].vx
- GEO[self.n].vy = y or GEO[self.n].vy
- GEO[self.n].vz = z or GEO[self.n].vz
- end
- function GEO:killzone(bool)
- if bool == true then
- GEO[self.n].kz = true
- elseif bool == false then
- GEO[self.n].kz = false
- elseif bool == nil then
- return GEO[self.n].kz or false
- end
- end
- function GEO:damagezone(bool, damage)
- if bool == true then
- GEO[self.n].damage = damage or 1 -- Amount of damage applied per second.
- elseif bool == false then
- GEO[self.n].damage = nil
- elseif bool == nil then -- If nothing is passed, return true if this GEO is a damagezone, false if not.
- if GEO[self.n].damage then
- return true
- else
- return false
- end
- end
- end
- function GEO:face(orientation, direction)
- -- If this is a rectangular prism...
- if self.t == "rectprism" then
- orientation = orientation or "z"
- direction = direction or "+"
- if orientation == "z" then
- local width = self.lx
- local height = self.ly
- local highlow
- if direction == "+" then
- highlow = self.zhigh
- else
- highlow = self.zlow
- end
- -- Create a new rectangle which overlays the specified face and return that rectangle.
- return GEO.newRect(self.n .. "ZFace" .. os.time(), width, height, self.x, self.y, highlow, orientation)
- elseif orientation == "x" then
- local width = self.ly
- local height = self.lz
- local highlow
- if direction == "+" then
- highlow = self.xhigh
- else
- highlow = self.xlow
- end
- return GEO.newRect(self.n .. "XFace" .. os.time(), width, height, highlow, self.y, self.z, orientation)
- elseif orientation == "y" then
- local width = self.lx
- local height = self.lz
- local highlow
- if direction == "+" then
- highlow = self.yhigh
- else
- highlow = self.ylow
- end
- return GEO.newRect(self.n .. "YFace" .. os.time(), width, height, self.x, highlow, self.z, orientation)
- end
- -- If this is a cylinder...
- elseif self.t == "cylinder" then
- if orientation == "z" then
- local highlow
- if direction == "+" then
- highlow = self.zhigh
- else
- highlow = self.zlow
- end
- -- Return a new circle which overlays the specified face and return that circle.
- return GEO.newCircle(self.n .. "ZFace" .. os.time(), self.r, self.x, self.y, highlow, "z")
- else
- hprintf("You may only retrieve the Z face of a cylinder.")
- end
- end
- end
- function GEO:copy(name)
- name = name or self.n .. "Copy" .. os.time()
- if not GEO[name] then
- GEO[name] = self
- return GEO[name]
- end
- end
- function GEO:monitor(objId)
- if getobject(objId) then
- GEO[self.n].m = GEO[self.n].m or {}
- GEO[self.n].c = GEO[self.n].c or {}
- GEO[self.n].m[objId] = true
- end
- end
- registertimer(10, "GEOTimer")
- function GEOTimer(id, count)
- -- Create a coordinates table for players if it hasn't already been created
- pcoords = pcoords or {}
- -- Loop through the GEO table
- for k,v in pairs(GEO) do
- if type(v) == "table" and k ~= "__index" then
- -- If this GEO is following an object...
- if v.f then
- -- Get the coordinates of the object
- local x, y, z = getobjectcoords(v.f)
- if x then -- If this object exists...
- if v.player then
- local player = objectidtoplayer(v.f)
- if player then
- local m_player = getplayer(player) -- See if the player is still here
- if m_player then -- If they are...
- local time_until_respawn = readdword(m_player, 0x2C) -- Check to see if they're dead
- if time_until_respawn == 0 then -- If they're not...
- if v.p then -- If this GEO has perimeter objects...
- for objId, coords in pairs(v.p) do
- if getobject(objId) then
- local ox, oy, oz = table.unpack(coords)
- local x_diff = x - v.x
- local y_diff = y - v.y
- local z_diff = z - v.z
- local m_object = getobject(objId)
- movobjcoords(objId, ox + x_diff, oy + y_diff, oz + z_diff) -- Move them with the GEO.
- GEO[v.n].p[objId] = {ox + x_diff, oy + y_diff, oz + z_diff}
- end
- end
- end
- v:move(x, y, z) -- Move the GEO to the player's coordinates
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- else -- Otherwise...
- if v.p then -- If this GEO has perimeter objects...
- for objId, coords in pairs(v.p) do
- if getobject(objId) then
- local ox, oy, oz = table.unpack(coords)
- local x_diff = x - v.x
- local y_diff = y - v.y
- local z_diff = z - v.z
- local m_object = getobject(objId)
- movobjcoords(objId, ox + x_diff, oy + y_diff, oz + z_diff) -- Move them with the GEO.
- GEO[v.n].p[objId] = {ox + x_diff, oy + y_diff, oz + z_diff}
- end
- end
- end
- v:move(x, y, z) -- Don't worry about all of that player nonsense and just move the damn GEO.
- end
- else -- Otherwise...
- v:delete() -- Delete the GEO.
- end
- end
- -- If after all of that following nonsense, we still have a GEO...
- if v then
- -- If this GEO is a killzone...
- if v.kz then
- -- Check if anyone is inside of it.
- for i = 0,15 do
- if getplayer(i) then
- local m_player = getplayer(i)
- local objId = readdword(m_player, 0x34)
- if v:contains(objId) then
- kill(i) -- Kill that ho.
- end
- end
- end
- end
- -- If this GEO is a damagezone...
- if v.damage then
- -- Check if anyone is inside of it.
- for i = 0,15 do
- local m_player = getplayer(i)
- if m_player then
- local objId = readdword(m_player, 0x34)
- if v:contains(objId) then
- applydmg(objId, v.damage / 100) -- Apply damage
- end
- end
- end
- end
- -- If this GEO is monitoring for objects entering and exiting it...
- if v.m then
- -- Loop through the table of objects this GEO is monitoring for.
- for objId,_ in pairs(v.m) do
- -- If this object still exists...
- if getobject(objId) then
- -- If this object is inside of the GEO...
- if v:contains(objId) then
- -- If the GEO didn't know this object was inside of it 1/100 of a second ago...
- if not v.c[objId] then
- local player = objectidtoplayer(objId)
- -- Call OnGeoEnter.
- local allow = OnGeoEnter(v, player, objId)
- if allow == 0 or allow == false then
- local hash = gethash(player)
- if pcoords[hash] then
- movobjcoords(objId, table.unpack(pcoords[hash]))
- end
- else
- GEO[k].c[objId] = true
- end
- end
- else -- Otherwise...
- -- If the GEO thought this object was inside of it 1/100 of a second ago...
- if v.c[objId] then
- local player = objectidtoplayer(objId)
- -- Call OnGeoExit.
- local allow = OnGeoExit(v, player, objId)
- if allow == 0 or allow == false then
- local hash = gethash(player)
- if pcoords[hash] then
- movobjcoords(objId, table.unpack(pcoords[hash]))
- end
- else
- GEO[k].c[objId] = nil
- end
- end
- end
- else -- Otherwise...
- GEO[k].m[objId] = nil -- Stop monitoring for this object.
- end
- end
- end
- -- If this GEO has a velocity...
- if v.vx or v.vy or v.vz then
- if v.p then -- If this GEO has perimeter objects...
- for objId, coords in pairs(v.p) do
- if getobject(objId) then
- local ox, oy, oz = table.unpack(coords)
- local m_object = getobject(objId)
- movobjcoords(objId, ox + (v.vx or 0), oy + (v.vy or 0), oz + (v.vz or 0)) -- Move them with the GEO.
- GEO[v.n].p[objId] = {ox + (v.vx or 0), oy + (v.vy or 0), oz + (v.vz or 0)}
- end
- end
- end
- -- Move that ho.
- v:move(v.x + (v.vx or 0) / 100, v.y + (v.vy or 0) / 100, v.z + (v.vz or 0) / 100)
- end
- end
- end
- end
- -- Update coordinates at a slight delay for blocking GEO entry/exit (if there is no delay, players in mid-air could end up dying since they'll just be teleported in mid-air perpetually)
- if count % 25 == 0 then
- for i = 0,15 do
- local m_player = getplayer(i)
- if m_player then
- local hash = gethash(i)
- local objId = readdword(m_player, 0x34)
- if getobject(objId) then
- pcoords[hash] = {getobjectcoords(objId)}
- else
- pcoords[hash] = nil
- end
- end
- end
- end
- return true
- end
- function OnGeoEnter(geo, player, objId)
- return true
- end
- function OnGeoExit(geo, player, objId)
- return true
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement