Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Moon = {}
- Orbit = {}
- Moonbot = {}
- --
- Moon.__index = Moon
- Orbit.__index = Orbit
- Moonbot.__index = Moonbot
- --
- function Moon.ctor(above, below) -- Constructor
- --
- local self = {} -- PUBLIC FUNCTIONS CONTAINER
- -- #PRIVATE FIELDS
- local cd = '[1;30m' -- grey
- local cg = '[1;32m' -- green
- local cm = '[1;35m' -- magenta
- local cn = '[0;30m' -- black
- local cr = '[1;31m' -- red
- local cw = '[1;37m' -- white
- local cy = '[1;33m' -- yellow
- local rc = '[0m' -- reset
- local above = above or -1 -- Number of ticks this moon is visible.
- local below = below or -1 -- Number of ticks this moon is not visible.
- local current = -1 -- Number of ticks left before leaving this part of the sky.
- local gmcp = 1 -- Adjustment based on whether gmcp tick processing is on or off.
- local rising = false -- Indicates whether the moon is above or below the horizon.
- local color = "black" -- color of the display digits returned by the ToString method.
- local ansi = false -- Use ANSI color sequences.
- -- #PRIVATE METHODS
- local function starts(str,strt)
- --
- return str:sub(1,strt:len()) == strt
- --
- end
- local function ends(str,endstr)
- --
- return endstr == '' or str:sub(-endstr:len()) == endstr
- --
- end
- -- #PUBLIC METHODS
- function self.isDefined()
- --
- return current ~= -1
- --
- end
- function self.getColor()
- --
- return color
- --
- end
- function self.getOrbitalInterval()
- --
- return above + below
- --
- end
- function self.getState()
- --
- return rising
- --
- end
- function self.getLocation()
- --
- if self.isDefined() then
- return current * (self.getState() and 1 or -1)
- else
- return 0
- end
- --
- end
- function self.getPosition()
- --
- if rising or not self.isDefined() then return current end
- return current + above
- --
- end
- function self.getTimeAloft()
- --
- return above;
- --
- end
- function self.setPosition(p) -- Useful only during the test phase. Remove afterwards.
- --
- if typeof(p) ~= "number" or p == 0 then return
- current = math.abs(p)
- rising = p > 0
- --
- end
- function self.isANSI()
- --
- return ansi
- --
- end
- function self.isGMCP()
- --
- return gmcp == 0
- --
- end
- function self.moonFalling()
- --
- current = 1 + gmcp
- rising = true
- --
- end
- function self.moonRising()
- --
- current = above + gmcp
- rising = true
- --
- end
- function self.setANSI(status)
- --
- ansi = false
- if type(status) == "boolean" then ansi = status end
- --
- end
- function self.setGMCP(status)
- --
- local b = false
- if type(status) == "boolean" then b = status end
- gmcp = b and 0 or 1
- --
- end
- function self.setColor(color)
- --
- if type(color) == "string" then
- if not ansi or (starts(color,'[') and ends(color,'m')) then color = color end
- end
- --
- end
- function self.stop()
- --
- current = -1
- rising = false
- --
- end
- function self.tick()
- --
- if self.isDefined() then
- current = current - 1
- if current == 0 then
- if rising then
- rising = false
- current = below
- else
- rising = true
- current = above
- end
- end
- end
- --
- end
- function self.show()
- --
- local disp = cd.."Undefined"..rc
- local head = ""
- local tick = "tick"
- if not ansi then disp = "<color gray>Undefined</color>" end
- if current ~= 1 then tick = tick.."s" end
- if self.isDefined() then
- if ansi then
- head = self.getState() and cg.."ON" or cr.."OFF"
- disp = head..cw.." for "..color..current..cw.." "..tick..rc
- else
- head = self.getState() and '"0x00FF00">ON' or "red>OFF"
- disp = "<color "..head.."</color><color white> for </color><color "..color..">"
- disp = disp..current.."</color><color white> "..tick.."</color>"
- end
- end
- return disp
- --
- end
- return self
- --
- end
- --
- setmetatable(Moon, { __call = function(_, ...) return Moon.ctor(...) end })
- --
- function Orbit.ctor(moon)
- --
- --
- local self = {} -- PUBLIC FUNCTIONS CONTAINER
- -- #PRIVATE FIELDS
- local moon = moon or nil -- Reference to the moon object.
- local above = 0 -- Maximum number of ticks this moon is visible.
- local len = 0 -- Length of an orbital cycle.
- local pos = -1 -- Actual moon position at computation time.
- local temp = 0 -- Utility variable.
- -- #PUBLIC METHODS
- function self.setMoon(m)
- --
- moon = m
- above = moon.getTimeAloft()
- len = moon.getOrbitalInterval()
- --
- end
- function self.move(tref)
- --
- temp = (((pos + tref.ticks) % len) + len) % len
- if temp > above or temp == 0 then
- tref.ticks = tref.ticks - 1
- return true
- end
- return false
- --
- end
- function self.reset()
- --
- if moon then
- pos = moon.getPosition()
- end
- --
- end
- function self.track(ticks)
- --
- temp = (((pos + ticks) % len) + len) % len
- if (temp > above or temp == 0) then
- return false
- end
- return true
- --
- end
- if moon then self.setMoon(moon) end
- return self
- --
- end
- --
- setmetatable(Orbit, { __call = function(_, ...) return Orbit.ctor(...) end })
- --
- function Moonbot.ctor()
- --
- local self = {} -- PUBLIC FUNCTIONS CONTAINER
- -- #PRIVATE FIELDS
- local moons = {} -- Moon dictionary.
- local _open = false
- local tickinfo = -1 -- projected number of ticks until tri-moon event.
- local ticklen = -1 -- length, in ticks, of tri-moon event.
- local tref = { ticks = 0 } -- this is the tick reference object.
- local ticks = 0
- local ob -- Orbital object for black moon.
- local og -- Orbital object for grey moon.
- local ow -- Orbital object for white moon.
- local interval = 0
- -- #PRIVATE METHODS
- local function starts(str,strt)
- --
- return str:sub(1,strt:len()) == strt
- --
- end
- local function ends(str,endstr)
- --
- return endstr == '' or str:sub(-endstr:len()) == endstr
- --
- end
- local function init()
- --
- moons = { white = Moon(17,48)
- ,grey = Moon(8 ,22)
- ,black = Moon(13,37)
- }
- og = Orbit(moons.grey)
- ob = Orbit(moons.black)
- ow = Orbit(moons.white)
- _open = true
- --
- end
- -- #PUBLIC METHODS
- function self.displayMoons()
- --
- local mtab = {}
- for k, v in pairs(moons)
- do
- mtab[k] = v.show()
- end
- return mtab
- --
- end
- function self.moonsAreDefined()
- --
- if not _open then return false end
- for _, v in pairs(moons)
- do
- if not v.isDefined() then
- return false
- end
- end
- return true
- --
- end
- function self.getColor(name)
- --
- if type(name) == "string" then
- if moons[name] then
- return moons[name].getColor()
- end
- end
- --
- end
- function self.getMoons()
- --
- local mtab = {}
- for k, v in pairs(moons)
- do
- mtab[k] = v.getLocation()
- end
- return mtab
- --
- end
- function self.isANSI()
- --
- for _, v in pairs(moons)
- do
- if not v.isANSI() then return false end
- end
- return true
- --
- end
- function self.isGMCP()
- --
- for _, v in pairs(moons)
- do
- if not v.isGMCP() then return false end
- end
- return true
- --
- end
- function self.isOpen()
- --
- return _open
- --
- end
- function self.setPosition(moon, pos)
- --
- if type(moon) == "string" and type(pos) == "number" and moons[moon] then
- moons[moon].setPosition(pos)
- end
- --
- end
- function self.predict() -- compute time interval and length of the next tri-moon event.
- --
- tickno = -1
- ticklen = -1
- if self.moonsAreDefined() then
- ob.reset()
- og.reset()
- ow.reset()
- tref.ticks = 0 -- tick count is passed to the move routine by reference.
- while true -- here we loop until all moons are visible in the sky.
- do
- if not og.move(tref) then -- loop until grey moon appears in the sky.
- if not ob.move(tref) then -- loop until black moon appears in the sky.
- if not ow.move(tref) then -- loop until white moon appears in the sky.
- break -- at this point all moons are visible.
- end
- end
- end
- end
- interval = 0
- ticks = tref.ticks
- while true -- here we loop until one of the moons disappears from the sky.
- do
- if not og.track(ticks) then break end -- test grey moon position.
- if not ob.track(ticks) then break end -- test black moon position.
- if not ow.track(ticks) then break end -- test white moon position.
- interval = interval + 1 -- increment tri-moon event interval length.
- ticks = ticks - 1 -- decrement orbital tracking pointer.
- end
- tickno = math.abs(tref.ticks)
- ticklen = interval
- end
- return { tickno = tickno, ticklen = ticklen }
- --
- end
- function self.moonFalling(name)
- --
- if _open then
- if type(name) == "string" then
- if moons[name] then
- moons[name].moonFalling()
- end
- end
- end
- --
- end
- function self.moonRising(name)
- --
- if _open then
- if type(name) == "string" then
- if moons[name] then
- moons[name].moonRising()
- end
- end
- end
- --
- end
- function self.mudTick()
- --
- if _open then
- for _, v in pairs(moons)
- do
- v.tick()
- end
- end
- --
- end
- function self.setANSI(state)
- --
- b = state
- if type(state) ~= "boolean" then b = false end
- for _,v in pairs(moons)
- do
- v.setANSI(b)
- end
- --
- end
- function self.setGMCP(state)
- --
- b = state
- if type(state) ~= "boolean" then b = false end
- for _,v in pairs(moons)
- do
- v.setGMCP(b)
- end
- --
- end
- function self.setStatus(status)
- --
- if type(status) == "boolean" then
- _open = status
- for _, v in pairs(moons)
- do
- v.stop()
- end
- end
- --
- end
- function self.BlackMoon()
- --
- return moons.black.show()
- --
- end
- function self.GreyMoon()
- --
- return moons.grey.show()
- --
- end
- function self.WhiteMoon()
- --
- return moons.white.show()
- --
- end
- init()
- return self
- --
- end
- --
- setmetatable(Moonbot, { __call = function(_, ...) return Moonbot.ctor(...) end })
- --
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement