diff --git a/old/main.lua b/old/main.lua
new file mode 100644
index 0000000..e199e5d
--- /dev/null
+++ b/old/main.lua
@@ -0,0 +1,157 @@
+local bsg = require "ships.bsg"
+local viper = require "ships.viper"
+
+local lg = love.graphics
+
+local images = {}
+local ships = {}
+
+local hx, hy = lg.getWidth() / 2, lg.getHeight() / 2
+
+local scale = 8
+
+local selected
+
+function love.load()
+ lg.setDefaultFilter("linear", "nearest", 1)
+ images.bsg = lg.newImage('img/bsg.png')
+ images.viper = lg.newImage('img/viper.png')
+ lg.setPointSize(10)
+ lg.setPointStyle("rough")
+
+ ships[1] = bsg()
+ for i=1,8 do
+ local v = viper()
+ table.insert(ships, v)
+ ships[1]:dock(v, i)
+ end
+end
+
+local timer = 0
+function love.update(dt)
+ timer = timer + dt
+ if timer >= 33 then
+ timer = timer - 33
+ end
+end
+
+local function drawClock(x, y, r)
+ local time = math.floor(33 - timer)
+ if time == 0 then time = 33 end
+
+ local maxTime = 33
+
+ local segments = 33
+ local segmentRadius = math.pi*2 / segments
+ local dividerRadius = segmentRadius / 2
+ --local time = 33
+
+ lg.setColor(255, 102, 0)
+ for i=1,time do
+ lg.arc("fill", x, y, r, (i-1)*segmentRadius - math.pi/2, i*segmentRadius - dividerRadius - math.pi/2)
+ end
+ lg.setColor(0, 0, 0)
+ lg.circle("fill", x, y, r/1.15)
+
+ -- this looks cool and all, but it is the same function as the outer ring
+ -- instead, use this internal space for displaying things like fuel and water and supplies
+ --[[
+ segments = 12
+ segmentRadius = math.pi*2 / segments
+ dividerRadius = segmentRadius / segments * 2
+ time = math.floor(time/maxTime * segments) --33 -> 12 percentage = time/maxTime..multiply this by 12
+
+ lg.setColor(255, 102, 0)
+ for i=1,time do
+ lg.arc("fill", x, y, r/1.5, (i-1)*segmentRadius - math.pi/2, i*segmentRadius - dividerRadius - math.pi/2)
+ end
+ lg.setColor(0, 0, 0)
+ lg.circle("fill", x, y, r/2)
+ --]]
+
+ --tmp, really each color-dependent section should do this itself!
+ lg.setColor(255, 255, 255)
+end
+
+local drawWheel = require "wheel";
+
+function love.draw()
+ lg.translate(hx, hy)
+
+ for i=1,#ships do
+ lg.draw(images[ships[i].img], ships[i].x * scale, ships[i].y * scale, ships[i].rotation, scale, scale, ships[i].ox, ships[i].oy)
+ end
+
+ if selected then
+ lg.setColor(220, 180, 0)
+ lg.point(selected.x * scale, selected.y * scale)
+ lg.setColor(255, 255, 255)
+ end
+
+ --drawClock(-355, -145, 120)
+ drawWheel(-355, -145, 120, timer)
+end
+
+function love.keypressed(key, unicode)
+ if key == "escape" then
+ love.event.quit()
+ end
+end
+
+local function pointInRadius(x, y, cx, cy, r)
+ cx = cx * scale + hx
+ cy = cy * scale + hy
+ local dx = x - cx
+ local dy = y - cy
+ return r * scale >= math.sqrt(dx * dx + dy * dy)
+end
+
+local function pointInAABB(x, y, cx, cy, s, r)
+ -- THIS IS HORRIBLY WRONG, FIX IT LATER
+ --[[
+ var x=((objects[i].x-objects[renderId].x)*Math.cos(rot)-(objects[i].y-objects[renderId].y)*Math.sin(rot))*scaleFactor;
+ var y=((objects[i].x-objects[renderId].x)*Math.sin(rot)+(objects[i].y-objects[renderId].y)*Math.cos(rot))*scaleFactor;
+ ]]
+ local nx = (x - cx) * math.cos(r) - (y - cy) * math.sin(r)
+ local ny = (x - cx) * math.sin(r) + (y - cy) * math.cos(r)
+ x = nx
+ y = ny
+ cx = cx * scale + hx
+ cy = cy * scale + hy
+ return x >= cx - s.w * scale / 2 and x <= cx + s.w * scale / 2 and y >= cy - s.h * scale / 2 and y <= cy + s.h * scale / 2
+end
+
+function love.mousepressed(x, y, button)
+ if button == "l" then
+ if selected then
+ -- find out where this actually is, now the ship selected is ordered to move to this point
+ selected.ship:moveTo(x * scale + hx, y * scale + hy)
+ else
+ for i=1,#ships do
+ if ships[i].selection.r then
+ if pointInRadius(x, y, ships[i].x, ships[i].y, ships[i].selection.r) then
+ -- selected
+ -- NOW CHECK IF HAS NODES AND IF WE ARE SELECTING A SHIP ON A NODE!
+ selected = {}
+ selected.ship = ships[i]
+ selected.x = ships[i].x
+ selected.y = ships[i].y
+ end
+ else
+ if pointInAABB(x, y, ships[i].x, ships[i].y, ships[i].selection, ships[i].rotation) then
+ -- we are selecting it!
+ -- NOW CHECK IF HAS NODES AND IF WE ARE SELECTING A SHIP ON A NODE!
+ selected = {}
+ selected.ship = ships[i]
+ selected.x = ships[i].x
+ selected.y = ships[i].y
+ end
+ end
+ end
+ end
+ elseif button == "wd" then
+ scale = scale * 1.1
+ elseif button == "wu" then
+ scale = scale * 0.9
+ end
+end
diff --git a/src/wheel.lua b/old/wheel.lua
similarity index 100%
rename from src/wheel.lua
rename to old/wheel.lua
diff --git a/src/lib/inspect.lua b/src/lib/inspect.lua
new file mode 100644
index 0000000..08a44fa
--- /dev/null
+++ b/src/lib/inspect.lua
@@ -0,0 +1,327 @@
+local inspect ={
+ _VERSION = 'inspect.lua 3.0.0',
+ _URL = 'http://github.com/kikito/inspect.lua',
+ _DESCRIPTION = 'human-readable representations of tables',
+ _LICENSE = [[
+ MIT LICENSE
+
+ Copyright (c) 2013 Enrique García Cota
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ]]
+}
+
+inspect.KEY = setmetatable({}, {__tostring = function() return 'inspect.KEY' end})
+inspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end})
+
+-- Apostrophizes the string if it has quotes, but not aphostrophes
+-- Otherwise, it returns a regular quoted string
+local function smartQuote(str)
+ if str:match('"') and not str:match("'") then
+ return "'" .. str .. "'"
+ end
+ return '"' .. str:gsub('"', '\\"') .. '"'
+end
+
+local controlCharsTranslation = {
+ ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n",
+ ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v"
+}
+
+local function escape(str)
+ local result = str:gsub("\\", "\\\\"):gsub("(%c)", controlCharsTranslation)
+ return result
+end
+
+local function isIdentifier(str)
+ return type(str) == 'string' and str:match( "^[_%a][_%a%d]*$" )
+end
+
+local function isSequenceKey(k, length)
+ return type(k) == 'number'
+ and 1 <= k
+ and k <= length
+ and math.floor(k) == k
+end
+
+local defaultTypeOrders = {
+ ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4,
+ ['function'] = 5, ['userdata'] = 6, ['thread'] = 7
+}
+
+local function sortKeys(a, b)
+ local ta, tb = type(a), type(b)
+
+ -- strings and numbers are sorted numerically/alphabetically
+ if ta == tb and (ta == 'string' or ta == 'number') then return a < b end
+
+ local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]
+ -- Two default types are compared according to the defaultTypeOrders table
+ if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]
+ elseif dta then return true -- default types before custom ones
+ elseif dtb then return false -- custom types after default ones
+ end
+
+ -- custom types are sorted out alphabetically
+ return ta < tb
+end
+
+local function getNonSequentialKeys(t)
+ local keys, length = {}, #t
+ for k,_ in pairs(t) do
+ if not isSequenceKey(k, length) then table.insert(keys, k) end
+ end
+ table.sort(keys, sortKeys)
+ return keys
+end
+
+local function getToStringResultSafely(t, mt)
+ local __tostring = type(mt) == 'table' and rawget(mt, '__tostring')
+ local str, ok
+ if type(__tostring) == 'function' then
+ ok, str = pcall(__tostring, t)
+ str = ok and str or 'error: ' .. tostring(str)
+ end
+ if type(str) == 'string' and #str > 0 then return str end
+end
+
+local maxIdsMetaTable = {
+ __index = function(self, typeName)
+ rawset(self, typeName, 0)
+ return 0
+ end
+}
+
+local idsMetaTable = {
+ __index = function (self, typeName)
+ local col = setmetatable({}, {__mode = "kv"})
+ rawset(self, typeName, col)
+ return col
+ end
+}
+
+local function countTableAppearances(t, tableAppearances)
+ tableAppearances = tableAppearances or setmetatable({}, {__mode = "k"})
+
+ if type(t) == 'table' then
+ if not tableAppearances[t] then
+ tableAppearances[t] = 1
+ for k,v in pairs(t) do
+ countTableAppearances(k, tableAppearances)
+ countTableAppearances(v, tableAppearances)
+ end
+ countTableAppearances(getmetatable(t), tableAppearances)
+ else
+ tableAppearances[t] = tableAppearances[t] + 1
+ end
+ end
+
+ return tableAppearances
+end
+
+local copySequence = function(s)
+ local copy, len = {}, #s
+ for i=1, len do copy[i] = s[i] end
+ return copy, len
+end
+
+local function makePath(path, ...)
+ local keys = {...}
+ local newPath, len = copySequence(path)
+ for i=1, #keys do
+ newPath[len + i] = keys[i]
+ end
+ return newPath
+end
+
+local function processRecursive(process, item, path)
+ if item == nil then return nil end
+
+ local processed = process(item, path)
+ if type(processed) == 'table' then
+ local processedCopy = {}
+ local processedKey
+
+ for k,v in pairs(processed) do
+ processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY))
+ if processedKey ~= nil then
+ processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey))
+ end
+ end
+
+ local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE))
+ setmetatable(processedCopy, mt)
+ processed = processedCopy
+ end
+ return processed
+end
+
+
+-------------------------------------------------------------------
+
+local Inspector = {}
+local Inspector_mt = {__index = Inspector}
+
+function Inspector:puts(...)
+ local args = {...}
+ local buffer = self.buffer
+ local len = #buffer
+ for i=1, #args do
+ len = len + 1
+ buffer[len] = tostring(args[i])
+ end
+end
+
+function Inspector:down(f)
+ self.level = self.level + 1
+ f()
+ self.level = self.level - 1
+end
+
+function Inspector:tabify()
+ self:puts(self.newline, string.rep(self.indent, self.level))
+end
+
+function Inspector:alreadyVisited(v)
+ return self.ids[type(v)][v] ~= nil
+end
+
+function Inspector:getId(v)
+ local tv = type(v)
+ local id = self.ids[tv][v]
+ if not id then
+ id = self.maxIds[tv] + 1
+ self.maxIds[tv] = id
+ self.ids[tv][v] = id
+ end
+ return id
+end
+
+function Inspector:putKey(k)
+ if isIdentifier(k) then return self:puts(k) end
+ self:puts("[")
+ self:putValue(k)
+ self:puts("]")
+end
+
+function Inspector:putTable(t)
+ if t == inspect.KEY or t == inspect.METATABLE then
+ self:puts(tostring(t))
+ elseif self:alreadyVisited(t) then
+ self:puts('
')
+ elseif self.level >= self.depth then
+ self:puts('{...}')
+ else
+ if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end
+
+ local nonSequentialKeys = getNonSequentialKeys(t)
+ local length = #t
+ local mt = getmetatable(t)
+ local toStringResult = getToStringResultSafely(t, mt)
+
+ self:puts('{')
+ self:down(function()
+ if toStringResult then
+ self:puts(' -- ', escape(toStringResult))
+ if length >= 1 then self:tabify() end
+ end
+
+ local count = 0
+ for i=1, length do
+ if count > 0 then self:puts(',') end
+ self:puts(' ')
+ self:putValue(t[i])
+ count = count + 1
+ end
+
+ for _,k in ipairs(nonSequentialKeys) do
+ if count > 0 then self:puts(',') end
+ self:tabify()
+ self:putKey(k)
+ self:puts(' = ')
+ self:putValue(t[k])
+ count = count + 1
+ end
+
+ if mt then
+ if count > 0 then self:puts(',') end
+ self:tabify()
+ self:puts(' = ')
+ self:putValue(mt)
+ end
+ end)
+
+ if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing }
+ self:tabify()
+ elseif length > 0 then -- array tables have one extra space before closing }
+ self:puts(' ')
+ end
+
+ self:puts('}')
+ end
+end
+
+function Inspector:putValue(v)
+ local tv = type(v)
+
+ if tv == 'string' then
+ self:puts(smartQuote(escape(v)))
+ elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
+ self:puts(tostring(v))
+ elseif tv == 'table' then
+ self:putTable(v)
+ else
+ self:puts('<',tv,' ',self:getId(v),'>')
+ end
+end
+
+-------------------------------------------------------------------
+
+function inspect.inspect(root, options)
+ options = options or {}
+
+ local depth = options.depth or math.huge
+ local newline = options.newline or '\n'
+ local indent = options.indent or ' '
+ local process = options.process
+
+ if process then
+ root = processRecursive(process, root, {})
+ end
+
+ local inspector = setmetatable({
+ depth = depth,
+ buffer = {},
+ level = 0,
+ ids = setmetatable({}, idsMetaTable),
+ maxIds = setmetatable({}, maxIdsMetaTable),
+ newline = newline,
+ indent = indent,
+ tableAppearances = countTableAppearances(root)
+ }, Inspector_mt)
+
+ inspector:putValue(root)
+
+ return table.concat(inspector.buffer)
+end
+
+setmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })
+
+return inspect
diff --git a/src/lib/middleclass.lua b/src/lib/middleclass.lua
new file mode 100644
index 0000000..57d3644
--- /dev/null
+++ b/src/lib/middleclass.lua
@@ -0,0 +1,182 @@
+local middleclass = {
+ _VERSION = 'middleclass v3.0.1',
+ _DESCRIPTION = 'Object Orientation for Lua',
+ _URL = 'https://github.com/kikito/middleclass',
+ _LICENSE = [[
+ MIT LICENSE
+
+ Copyright (c) 2011 Enrique García Cota
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ ]]
+}
+
+local function _setClassDictionariesMetatables(aClass)
+ local dict = aClass.__instanceDict
+ dict.__index = dict
+
+ local super = aClass.super
+ if super then
+ local superStatic = super.static
+ setmetatable(dict, super.__instanceDict)
+ setmetatable(aClass.static, { __index = function(_,k) return dict[k] or superStatic[k] end })
+ else
+ setmetatable(aClass.static, { __index = function(_,k) return dict[k] end })
+ end
+end
+
+local function _setClassMetatable(aClass)
+ setmetatable(aClass, {
+ __tostring = function() return "class " .. aClass.name end,
+ __index = aClass.static,
+ __newindex = aClass.__instanceDict,
+ __call = function(self, ...) return self:new(...) end
+ })
+end
+
+local function _createClass(name, super)
+ local aClass = { name = name, super = super, static = {}, __mixins = {}, __instanceDict={} }
+ aClass.subclasses = setmetatable({}, {__mode = "k"})
+
+ _setClassDictionariesMetatables(aClass)
+ _setClassMetatable(aClass)
+
+ return aClass
+end
+
+local function _createLookupMetamethod(aClass, name)
+ return function(...)
+ local method = aClass.super[name]
+ assert( type(method)=='function', tostring(aClass) .. " doesn't implement metamethod '" .. name .. "'" )
+ return method(...)
+ end
+end
+
+local function _setClassMetamethods(aClass)
+ for _,m in ipairs(aClass.__metamethods) do
+ aClass[m]= _createLookupMetamethod(aClass, m)
+ end
+end
+
+local function _setDefaultInitializeMethod(aClass, super)
+ aClass.initialize = function(instance, ...)
+ return super.initialize(instance, ...)
+ end
+end
+
+local function _includeMixin(aClass, mixin)
+ assert(type(mixin)=='table', "mixin must be a table")
+ for name,method in pairs(mixin) do
+ if name ~= "included" and name ~= "static" then aClass[name] = method end
+ end
+ if mixin.static then
+ for name,method in pairs(mixin.static) do
+ aClass.static[name] = method
+ end
+ end
+ if type(mixin.included)=="function" then mixin:included(aClass) end
+ aClass.__mixins[mixin] = true
+end
+
+local Object = _createClass("Object", nil)
+
+Object.static.__metamethods = { '__add', '__call', '__concat', '__div', '__ipairs', '__le',
+ '__len', '__lt', '__mod', '__mul', '__pairs', '__pow', '__sub',
+ '__tostring', '__unm'}
+
+function Object.static:allocate()
+ assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
+ return setmetatable({ class = self }, self.__instanceDict)
+end
+
+function Object.static:new(...)
+ local instance = self:allocate()
+ instance:initialize(...)
+ return instance
+end
+
+function Object.static:subclass(name)
+ assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
+ assert(type(name) == "string", "You must provide a name(string) for your class")
+
+ local subclass = _createClass(name, self)
+ _setClassMetamethods(subclass)
+ _setDefaultInitializeMethod(subclass, self)
+ self.subclasses[subclass] = true
+ self:subclassed(subclass)
+
+ return subclass
+end
+
+function Object.static:subclassed(other) end
+
+function Object.static:isSubclassOf(other)
+ return type(other) == 'table' and
+ type(self) == 'table' and
+ type(self.super) == 'table' and
+ ( self.super == other or
+ type(self.super.isSubclassOf) == 'function' and
+ self.super:isSubclassOf(other)
+ )
+end
+
+function Object.static:include( ... )
+ assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'")
+ for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end
+ return self
+end
+
+function Object.static:includes(mixin)
+ return type(mixin) == 'table' and
+ type(self) == 'table' and
+ type(self.__mixins) == 'table' and
+ ( self.__mixins[mixin] or
+ type(self.super) == 'table' and
+ type(self.super.includes) == 'function' and
+ self.super:includes(mixin)
+ )
+end
+
+function Object:initialize() end
+
+function Object:__tostring() return "instance of " .. tostring(self.class) end
+
+function Object:isInstanceOf(aClass)
+ return type(self) == 'table' and
+ type(self.class) == 'table' and
+ type(aClass) == 'table' and
+ ( aClass == self.class or
+ type(aClass.isSubclassOf) == 'function' and
+ self.class:isSubclassOf(aClass)
+ )
+end
+
+
+
+function middleclass.class(name, super, ...)
+ super = super or Object
+ return super:subclass(name, ...)
+end
+
+middleclass.Object = Object
+
+setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end })
+
+return middleclass
diff --git a/src/main.lua b/src/main.lua
index e199e5d..b1749fe 100644
--- a/src/main.lua
+++ b/src/main.lua
@@ -1,95 +1,49 @@
-local bsg = require "ships.bsg"
-local viper = require "ships.viper"
+--tmp
+local inspect = require "lib.inspect"
local lg = love.graphics
-local images = {}
-local ships = {}
-
local hx, hy = lg.getWidth() / 2, lg.getHeight() / 2
-
local scale = 8
+local images = {}
+local fleet = {}
+
+local bsg = require "ships.bsg"
+local viper = require "ships.viper"
+
+--tmp
local selected
function love.load()
lg.setDefaultFilter("linear", "nearest", 1)
images.bsg = lg.newImage('img/bsg.png')
images.viper = lg.newImage('img/viper.png')
+ --tmp
lg.setPointSize(10)
lg.setPointStyle("rough")
- ships[1] = bsg()
+ fleet[1] = bsg()
for i=1,8 do
local v = viper()
- table.insert(ships, v)
- ships[1]:dock(v, i)
+ table.insert(fleet, v)
+ fleet[1]:dock(v, i)
end
end
-local timer = 0
-function love.update(dt)
- timer = timer + dt
- if timer >= 33 then
- timer = timer - 33
- end
-end
-
-local function drawClock(x, y, r)
- local time = math.floor(33 - timer)
- if time == 0 then time = 33 end
-
- local maxTime = 33
-
- local segments = 33
- local segmentRadius = math.pi*2 / segments
- local dividerRadius = segmentRadius / 2
- --local time = 33
-
- lg.setColor(255, 102, 0)
- for i=1,time do
- lg.arc("fill", x, y, r, (i-1)*segmentRadius - math.pi/2, i*segmentRadius - dividerRadius - math.pi/2)
- end
- lg.setColor(0, 0, 0)
- lg.circle("fill", x, y, r/1.15)
-
- -- this looks cool and all, but it is the same function as the outer ring
- -- instead, use this internal space for displaying things like fuel and water and supplies
- --[[
- segments = 12
- segmentRadius = math.pi*2 / segments
- dividerRadius = segmentRadius / segments * 2
- time = math.floor(time/maxTime * segments) --33 -> 12 percentage = time/maxTime..multiply this by 12
-
- lg.setColor(255, 102, 0)
- for i=1,time do
- lg.arc("fill", x, y, r/1.5, (i-1)*segmentRadius - math.pi/2, i*segmentRadius - dividerRadius - math.pi/2)
- end
- lg.setColor(0, 0, 0)
- lg.circle("fill", x, y, r/2)
- --]]
-
- --tmp, really each color-dependent section should do this itself!
- lg.setColor(255, 255, 255)
-end
-
-local drawWheel = require "wheel";
-
function love.draw()
lg.translate(hx, hy)
- for i=1,#ships do
- lg.draw(images[ships[i].img], ships[i].x * scale, ships[i].y * scale, ships[i].rotation, scale, scale, ships[i].ox, ships[i].oy)
+ lg.setColor(255, 255, 255)
+ for i=1,#fleet do
+ lg.draw(images[fleet[i].img], fleet[i].x * scale, fleet[i].y * scale, fleet[i].rotation, scale, scale, fleet[i].ox, fleet[i].oy)
end
+ --tmp
if selected then
lg.setColor(220, 180, 0)
lg.point(selected.x * scale, selected.y * scale)
- lg.setColor(255, 255, 255)
end
-
- --drawClock(-355, -145, 120)
- drawWheel(-355, -145, 120, timer)
end
function love.keypressed(key, unicode)
@@ -97,61 +51,3 @@ function love.keypressed(key, unicode)
love.event.quit()
end
end
-
-local function pointInRadius(x, y, cx, cy, r)
- cx = cx * scale + hx
- cy = cy * scale + hy
- local dx = x - cx
- local dy = y - cy
- return r * scale >= math.sqrt(dx * dx + dy * dy)
-end
-
-local function pointInAABB(x, y, cx, cy, s, r)
- -- THIS IS HORRIBLY WRONG, FIX IT LATER
- --[[
- var x=((objects[i].x-objects[renderId].x)*Math.cos(rot)-(objects[i].y-objects[renderId].y)*Math.sin(rot))*scaleFactor;
- var y=((objects[i].x-objects[renderId].x)*Math.sin(rot)+(objects[i].y-objects[renderId].y)*Math.cos(rot))*scaleFactor;
- ]]
- local nx = (x - cx) * math.cos(r) - (y - cy) * math.sin(r)
- local ny = (x - cx) * math.sin(r) + (y - cy) * math.cos(r)
- x = nx
- y = ny
- cx = cx * scale + hx
- cy = cy * scale + hy
- return x >= cx - s.w * scale / 2 and x <= cx + s.w * scale / 2 and y >= cy - s.h * scale / 2 and y <= cy + s.h * scale / 2
-end
-
-function love.mousepressed(x, y, button)
- if button == "l" then
- if selected then
- -- find out where this actually is, now the ship selected is ordered to move to this point
- selected.ship:moveTo(x * scale + hx, y * scale + hy)
- else
- for i=1,#ships do
- if ships[i].selection.r then
- if pointInRadius(x, y, ships[i].x, ships[i].y, ships[i].selection.r) then
- -- selected
- -- NOW CHECK IF HAS NODES AND IF WE ARE SELECTING A SHIP ON A NODE!
- selected = {}
- selected.ship = ships[i]
- selected.x = ships[i].x
- selected.y = ships[i].y
- end
- else
- if pointInAABB(x, y, ships[i].x, ships[i].y, ships[i].selection, ships[i].rotation) then
- -- we are selecting it!
- -- NOW CHECK IF HAS NODES AND IF WE ARE SELECTING A SHIP ON A NODE!
- selected = {}
- selected.ship = ships[i]
- selected.x = ships[i].x
- selected.y = ships[i].y
- end
- end
- end
- end
- elseif button == "wd" then
- scale = scale * 1.1
- elseif button == "wu" then
- scale = scale * 0.9
- end
-end
diff --git a/src/ships/Node.lua b/src/ships/Node.lua
index 9fda710..0619a3e 100644
--- a/src/ships/Node.lua
+++ b/src/ships/Node.lua
@@ -1,11 +1,35 @@
-return function(x, y, rotation)
- local self = {}
+local class = require "lib.middleclass"
+local Node = class('Node')
+
+function Node:initialize(x, y, rotation)
self.x = x or 0
self.y = y or 0
self.rotation = rotation or 0
- self.docked = false
-
- return self
+ self.dockedShip = false
end
+
+--TODO docking needs to check distance between ships and only allow
+-- docking when close enough
+function Node:dock(Ship)
+ if self.dockedShip or Ship.dockedTo then
+ error("Attempted to dock to Node with something already docked to it!")
+ else
+ self.dockedShip = Ship
+ Ship.dockedTo = self
+
+ Ship:setPosition(self.x, self.y, self.rotation)
+ end
+end
+
+function Node:undock()
+ if not self.dockedShip then
+ error("Attempted to undock a ship from a Node with no docked ship.")
+ else
+ self.dockedShip.dockedTo = false
+ self.dockedShip = false
+ end
+end
+
+return Node
diff --git a/src/ships/Resources.lua b/src/ships/Resources.lua
new file mode 100644
index 0000000..057a080
--- /dev/null
+++ b/src/ships/Resources.lua
@@ -0,0 +1,50 @@
+local class = require "lib.middleclass"
+
+local Resources = class('Resources')
+
+function Resources:initialize()
+ self.ammo = 0
+ self.fuel = 0
+ self.supplies = 0
+ self.water = 0
+ self.food = 0
+ self.metal = 0
+ self.ore = 0
+ self.crew = 0
+
+ self.missiles = 0
+ self.nukes = 0
+
+ self.maxAmmo = 0
+ self.maxFuel = 0
+ self.maxSupplies = 0
+ self.maxWater = 0
+ self.maxFood = 0
+ self.maxMetal = 0
+ self.maxOre = 0
+ self.maxCrew = 0
+
+ self.ammoUse = 0
+ self.fuelUseIdle = 0
+ self.fuelUseMoving = 0
+ self.fuelUseJump = 0
+ self.suppliesUse = 0
+ self.waterUse = 0
+ self.foodUse = 0
+ self.metalUse = 0
+ self.oreUse = 0
+ self.crewUse = 0
+end
+
+function Resources:maxEverything()
+ self.ammo = self.maxAmmo
+ self.fuel = self.maxFuel
+ self.supplies = self.maxSupplies
+ self.water = self.maxWater
+ self.food = self.maxFood
+ self.metal = self.maxMetal
+ self.ore = self.maxOre
+ self.crew = self.maxCrew
+end
+
+return Resources
diff --git a/src/ships/Ship.lua b/src/ships/Ship.lua
new file mode 100644
index 0000000..9bd8326
--- /dev/null
+++ b/src/ships/Ship.lua
@@ -0,0 +1,84 @@
+local class = require "lib.middleclass"
+
+local Resources = require "ships.Resources"
+
+local Ship = class('Ship')
+
+function Ship:initialize(x, y, rotation)
+ self.img = ""
+ --offsets
+ self.ox = 0
+ self.oy = 0
+
+ self.x = x or 0
+ self.y = y or 0
+ self.destination = {
+ x = x or 0,
+ y = y or 0
+ }
+ self.rotation = rotation or 0
+
+ self.selection = {}
+
+ self.node = {}
+
+ self.dockedTo = false
+
+ self.Resources = Resources()
+end
+
+function Ship:dock(targetShip, nodeIndex)
+ if self.node[nodeIndex] then
+ self.node[nodeIndex]:dock(targetShip)
+ else
+ error("Ship attempted to dock to non-existent Node.")
+ end
+end
+
+function Ship:undock(nodeIndex)
+ if self.node[nodeIndex] then
+ self.node[nodeIndex]:undock()
+ else
+ --find which node "nodeIndex" is docked to
+ for i=1,#self.node do
+ if self.node[i].dockedShip == nodeIndex then
+ self.node[i]:undock()
+ return
+ end
+ end
+ error("Ship attempted to undock from non-existent Node.")
+ end
+end
+
+function Ship:dockTo(targetShip, nodeIndex)
+ if targetShip.node[nodeIndex] then
+ targetShip.node[nodeIndex]:dock(self)
+ else
+ error("Ship attempted to dock to non-existent Node.")
+ end
+end
+
+function Ship:undockFromParent()
+ self.dockedTo:undock(self)
+end
+
+function Ship:setPosition(x, y, rotation)
+ self.x = x or self.x
+ self.y = y or self.y
+ self.rotation = rotation or self.rotation
+end
+
+function Ship:moveTo(x, y)
+ if self.dockedTo then
+ self:undockFromParent()
+ end
+ self.destination.x = x
+ self.destination.y = y
+end
+
+function Ship:update(dt)
+ --check our speed, see how far along the "line" we can go, go there
+ -- if reached destination ... WELL SHIT DEST NEEDS TO BE ABLE TO KNOW IF IS SHIP OR WHATEVER
+end
+
+return Ship
diff --git a/src/ships/bsg.lua b/src/ships/bsg.lua
index fbf8327..e3e85ca 100644
--- a/src/ships/bsg.lua
+++ b/src/ships/bsg.lua
@@ -1,18 +1,21 @@
-local Node = require "ships.Node"
+math.randomseed(os.time())
+math.random() math.random()
+local class = require "lib.middleclass"
+
+local Ship = require "ships.Ship"
+local Node = require "ships.Node"
local ninety = 90 * math.pi / 180
-return function(x, y, rotation)
- local self = {}
+local BSG = class('BSG', Ship)
+function BSG:initialize(x, y, rotation)
+ Ship.initialize(self, x, y, rotation)
self.img = "bsg"
+ --offsets
self.ox = 31.5
self.oy = 67
- self.x = x or 0
- self.y = y or 0
- self.rotation = rotation or 0
-
--[[
self.selection = {
w = 54,
@@ -34,33 +37,50 @@ return function(x, y, rotation)
Node(-23, 16.5, -ninety)
}
- self.dock = function(self, ship, node)
- if self.node[node].docked or ship.isDocked then return false end
+ self.Resources.maxAmmo = 1000000
+ self.Resources.maxFuel = 1300000
+ self.Resources.maxSupplies = 40000
+ --what the fuck are jp's ?
+ -- http://www.traditionaloven.com/culinary-arts/cooking/shortening/convert-japanese-cup-measure-of-shortening-to-fluid-ounce-floz-shortening.html
+ -- From show "10 mil JPs water lost, almost 60%"
+ self.Resources.maxWater = 16000000
+ self.Resources.maxFood = 51000
+ self.Resources.maxMetal = 80000
+ --self.Resources.maxOre = 0
+ self.Resources.maxCrew = 5100
- ship.x = self.node[node].x
- ship.y = self.node[node].y
- ship.rotation = self.node[node].rotation
+ self.Resources.ammo = math.random(100, 1300)
+ self.Resources.fuel = math.random(496000, 512000)
+ self.Resources.supplies = math.random(18000,21000)
+ self.Resources.water = math.random(14186500, 14989900)
+ self.Resources.food = math.random(34700, 39200)
+ self.Resources.metal = math.random(19200,21600)
+ --self.Resources.ore = 0
+ self.Resources.crew = math.random(2870, 2960)
- self.node[node].docked = ship
- ship.isDocked = true
- ship.dockedTo = self
- ship.dockedNode = node
- return true
- end
+ self.Resources.missiles = math.random(5, 11)
+ --self.Resources.nukes = 0
- self.undock = function(self, node)
- if not self.node[node].docked then return false end
-
- local ship = self.node[node].docked
- ship.isDocked = false
- ship.dockedTo = false
- ship.dockedNode = false
- self.node[node].docked = false
-
- return ship
- end
-
- self.moveTo = function() end
-
- return self
+ --self.Resources.ammoUse = 0
+ -- a year is 31,556,900 seconds
+ -- for 17 mil water to last ?
+ -- How about 1 water per second?
+ -- 195 days
+ self.Resources.fuelUseIdle = 0.04
+ self.Resources.fuelUseMoving = 0.54
+ self.Resources.fuelUseJump = 4000
+ self.Resources.suppliesUse = 0.0013
+ self.Resources.waterUse = 1
+ -- 45k civs = 82+85+119+304 (590) tons food
+ -- 2.5 mil JPs water
+ -- these are per week numbers
+ -- 604800 seconds, 4.13 water per second
+ -- 1 ton = 2000 pounds
+ -- 1180000 pounds / sec = 1.95 food per second
+ self.Resources.foodUse = 0.099
+ --self.Resources.metalUse = 0.002 -- this # assumes normal repairs, which I'm ignoring for this
+ --self.Resources.oreUse = 0
+ --self.Resources.crewUse = 0
end
+
+return BSG
diff --git a/src/ships/viper.lua b/src/ships/viper.lua
index ce4b6a0..b1d2194 100644
--- a/src/ships/viper.lua
+++ b/src/ships/viper.lua
@@ -1,20 +1,16 @@
-return function(x, y, rotation)
- local self = {}
+local class = require "lib.middleclass"
+local Ship = require "ships.Ship"
+
+local Viper = class('Viper', Ship)
+
+function Viper:initialize(x, y, rotation)
+ Ship.initialize(self, x, y, rotation)
self.img = "viper"
+ --offsets
self.ox = 4.5
self.oy = 7.5
- self.x = x or 0
- self.y = y or 0
- self.rotation = rotation or 0
-
- self.destination = {
- x = x or 0,
- y = y or 0
- }
- self.isMoving = false
-
--[[
self.selection = {
w = 9,
@@ -25,24 +21,15 @@ return function(x, y, rotation)
r = 5
}
- --self.node = false
- self.isDocked = false
- self.dockedTo = false
- self.dockedNode = false
+ self.Resources.maxAmmo = 1800 --10 shots per second? 5s per barrel
+ self.Resources.maxFuel = 30000 --86400s = 1day, x = 1/2 day's thrust
+ self.Resources.maxCrew = 1
- self.moveTo = function(self, x, y)
- if self.isDocked then
- self.dockedTo:undock(self.dockedNode)
- end
- self.destination.x = x
- self.destination.y = y
- self.isMoving = true
- end
+ self.Resources.ammo = math.random(0, 20)
+ self.Resources.fuel = math.random(120, 1500)
- self.update = function(self, dt)
- -- check if moving, check our speed, see how far along the "line" we can go, go there
- -- if reached destination ... WELL SHIT DEST NEEDS TO BE ABLE TO KNOW IF IS SHIP OR WHATEVER
- end
-
- return self
+ self.Resources.fuelUseIdle = 0.09
+ self.Resources.fuelUseMoving = 0.76
end
+
+return Viper