Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- GEOs (Geometric Environment Objects) 1.01
- -- Create Metatable
- GEO = {}
- GEO.__index = GEO
- -- Set random seed and define infinity
- math.randomseed(os.time())
- math.inf = 1 / 0
- function inSphere(m_objId, x, y, z, r)
- local ox, oy, oz = getobjectcoords(m_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(m_objId, x, y, z, r, orientation)
- local ox, oy, oz = getobjectcoords(m_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(m_objId, x, y, zlow, zhigh, r)
- local ox, oy, oz = getobjectcoords(m_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(m_objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- -- These functions are essentially the same
- return inRectPrism(m_objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- end
- function inRectPrism(m_objId, xlow, xhigh, ylow, yhigh, zlow, zhigh)
- local x, y, z = getobjectcoords(m_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()
- 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, tagType, tagName)
- -- Default tagType and tagName to Full-Spectrum Visions
- tagType = tagType or "eqip"
- tagName = tagName or "powerups\\full-spectrum vision"
- -- 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 m_objId = createobject(tagType, tagName, 0, 0, false, self.x + x, self.y + y, self.z + z)
- GEO[self.n].p[m_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 m_objId = createobject(tagType, tagName, 0, 0, false, self.x + x, self.y + y, self.z + z)
- GEO[self.n].p[m_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(tagType, tagName, 0, 0, false, self.xhigh, self.yhigh, self.z)
- local o2 = createobject(tagType, tagName, 0, 0, false, self.xhigh, self.ylow, self.z)
- local o3 = createobject(tagType, tagName, 0, 0, false, self.xlow, self.yhigh, self.z)
- local o4 = createobject(tagType, tagName, 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(tagType, tagName, 0, 0, false, self.xhigh - (i * self.lx / density), self.yhigh, self.z)
- local derp = createobject(tagType, tagName, 0, 0, false, self.xhigh, self.yhigh - (i * self.ly / density), self.z)
- local weee = createobject(tagType, tagName, 0, 0, false, self.xhigh - (i * self.lx / density), self.ylow, self.z)
- local cheese = createobject(tagType, tagName, 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 m_objId = createobject(tagType, tagName, 0, 0, false, x, y, z)
- GEO[self.n].p[m_objId] = {x, y, z}
- end
- end
- end--]]
- function GEO:contains(m_objId)
- if self.t == "sphere" then
- return inSphere(m_objId, self.x, self.y, self.z, self.r)
- elseif self.t == "rectprism" or self.t == "rectangle" then
- return inRectPrism(m_objId, self.xlow, self.xhigh, self.ylow, self.yhigh, self.zlow, self.zhigh)
- elseif self.t == "circle" then
- return inCircle(m_objId, self.x, self.y, self.z, self.r, self.o)
- elseif self.t == "cylinder" then
- return inCylinder(m_objId, self.x, self.y, self.zlow, self.zhigh, self.r)
- end
- end
- function GEO:follow(m_objId)
- -- If the m_objId exists...
- if getobject(m_objId) then
- GEO[self.n].f = m_objId -- Save it (the GEOTimer will access it)
- -- Check to see if the object is a player
- if objecttoplayer(m_objId) then
- GEO[self.n].player = true
- end
- end
- end
- function GEO:freeze()
- -- Nullify the saved m_objId from GEO:follow()
- GEO[self.n].f = nil
- end
- function GEO.followedBy(m_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 == m_objId then
- -- If this GEO has this m_objId saved, insert it into the geos table.
- table.insert(geos, v)
- end
- end
- end
- -- Return the GEOs following m_objId in a table.
- return geos
- end
- function GEO.cleanup(player)
- local m_player = getplayer(player)
- local m_objId = readdword(m_player, 0x34)
- local geos = GEO.followedBy(m_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, rate, density)
- if bool == true then
- GEO[self.n].dz = rate or 1 -- Default to 1 fire per second
- GEO[self.n].density = density or 1 -- Default to 1 flame projectile per fire
- elseif bool == false then
- GEO[self.n].dz = nil
- GEO[self.n].density = nil
- elseif bool == nil then -- If nothing is passed, return true if this GEO is a damagezone, false if not.
- if GEO[self.n].dz 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(m_objId)
- if getobject(m_objId) then
- GEO[self.n].m = GEO[self.n].m or {}
- GEO[self.n].c = GEO[self.n].c or {}
- GEO[self.n].m[m_objId] = true
- end
- end
- registertimer(10, "GEOTimer")
- function GEOTimer(id, count)
- -- 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 = objecttoplayer(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 m_objId, coords in pairs(v.p) do
- if getobject(m_objId) then
- local ox, oy, oz = unpack(coords)
- local x_diff = x - v.x
- local y_diff = y - v.y
- local z_diff = z - v.z
- local m_object = getobject(m_objId)
- movobjcoords(m_objId, ox + x_diff, oy + y_diff, oz + z_diff) -- Move them with the GEO.
- GEO[v.n].p[m_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 m_objId, coords in pairs(v.p) do
- if getobject(m_objId) then
- local ox, oy, oz = unpack(coords)
- local x_diff = x - v.x
- local y_diff = y - v.y
- local z_diff = z - v.z
- local m_object = getobject(m_objId)
- movobjcoords(m_objId, ox + x_diff, oy + y_diff, oz + z_diff) -- Move them with the GEO.
- GEO[v.n].p[m_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 gethash(i) then
- local m_player = getplayer(i)
- local m_objId = readdword(m_player, 0x34)
- if v:contains(m_objId) then
- kill(i) -- Kill that ho.
- end
- end
- end
- end
- -- If this GEO is a damagezone...
- if v.dz then
- if GEO[k] then
- GEO[k].damagetime = (GEO[k].damagetime or 0) + 0.01
- if GEO[k].damagetime >= 1 / GEO[k].dz then
- GEO[k].damagetime = 0
- -- Create a crapload of flames.
- for i = 1,v.density do
- -- Make the flame projectiles spawn in a random place inside of the GEO.
- local x, y, z = v:randcoords()
- local object = createobject("proj", "weapons\\flamethrower\\flame", 0, 0, false, x, y, z)
- local m_object = getobject(object)
- -- Randomize the velocity
- local obj_x_vel = readfloat(m_object, 0x68) * 100
- local obj_y_vel = readfloat(m_object, 0x6C) * 100
- local obj_z_vel = readfloat(m_object, 0x70) * 100
- local max_vel = math.max(obj_x_vel, obj_y_vel, obj_z_vel)
- local vx = math.random(0, max_vel + 1) / 100
- local vy = math.random(0, max_vel + 1) / 100
- local vz = math.random(0, max_vel + 1) / 100
- writefloat(m_object, 0x68, vx)
- writefloat(m_object, 0x6C, vy)
- writefloat(m_object, 0x70, vz)
- 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 m_objId,_ in pairs(v.m) do
- -- If this object still exists...
- if getobject(m_objId) then
- -- If this object is inside of the GEO...
- if v:contains(m_objId) then
- -- If the GEO didn't know this object was inside of it 1/100 of a second ago...
- if not v.c[m_objId] then
- -- Call OnGeoEnter.
- OnGeoEnter(v, objecttoplayer(m_objId), m_objId)
- GEO[k].c[m_objId] = true
- end
- else -- Otherwise...
- -- If the GEO thought this object was inside of it 1/100 of a second ago...
- if v.c[m_objId] then
- -- Call OnGeoExit.
- OnGeoExit(v, objecttoplayer(m_objId), m_objId)
- GEO[k].c[m_objId] = nil
- end
- end
- else -- Otherwise...
- GEO[k].m[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 m_objId, coords in pairs(v.p) do
- if getobject(m_objId) then
- local ox, oy, oz = unpack(coords)
- local m_object = getobject(m_objId)
- movobjcoords(m_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[m_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
- return 1
- end
- function OnGeoEnter(geo, player, m_objId)
- end
- function OnGeoExit(geo, player, m_objId)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement