diff --git a/Makefile b/Makefile
index 1980510fa..9aee96953 100644
--- a/Makefile
+++ b/Makefile
@@ -42,11 +42,10 @@ bin/tmx2lua:
bin/love.app/Contents/MacOS/love:
mkdir -p bin
- $(wget) https://bitbucket.org/kyleconroy/love/downloads/love-sparkle.zip
- unzip -q love-sparkle.zip
- rm -f love-sparkle.zip
+ $(wget) https://bitbucket.org/kyleconroy/love/downloads/love-osx-mavericks-fixed.zip
+ unzip -q love-osx-mavericks-fixed.zip
+ rm -f love-osx-mavericks-fixed.zip
mv love.app bin
- cp osx/dsa_pub.pem bin/love.app/Contents/Resources
cp osx/Info.plist bin/love.app/Contents
/usr/bin/love:
diff --git a/osx/Info.plist b/osx/Info.plist
index 8a67a798c..04fdf64fd 100644
--- a/osx/Info.plist
+++ b/osx/Info.plist
@@ -40,9 +40,5 @@
2006-2012 Hawkthorne Development Team
NSPrincipalClass
NSApplication
- SUFeedURL
- http://example.com
- SUPublicDSAKeyFile
- dsa_pub.pem
diff --git a/src/audio/sfx/fire_thrown.ogg b/src/audio/sfx/fire_thrown.ogg
index 12b7f89ae..c853dd7ac 100644
Binary files a/src/audio/sfx/fire_thrown.ogg and b/src/audio/sfx/fire_thrown.ogg differ
diff --git a/src/character.lua b/src/character.lua
index b728021d5..19b766586 100644
--- a/src/character.lua
+++ b/src/character.lua
@@ -4,172 +4,221 @@ local Timer = require 'vendor/timer'
local sound = require 'vendor/TEsound'
local utils = require 'utils'
-local contents, _ = love.filesystem.read('character_map.json')
-local sprite_map = json.decode(contents)
+local module = {}
-local characters = {}
+-- Just for backwards compat
+module.name = 'abed'
-for i,p in pairs( love.filesystem.enumerate( 'characters' ) ) do
-
- -- bring in the data from the character file
- local contents, _ = love.filesystem.read('characters/' .. p)
- local character = json.decode(contents)
-
- if character.animations then --merge
- local base = utils.deepcopy(character.animations)
- character.animations = utils.deepcopy(sprite_map)
- for k,v in pairs(base) do
- character.animations[k] = v
- end
- else
- character.animations = utils.deepcopy(sprite_map)
- end
-
- -- build the character
- character.beam = love.graphics.newImage( 'images/characters/' .. character.name .. '/beam.png')
- character.beam:setFilter('nearest', 'nearest')
-
- character.count = 1
-
- character.sheets = {}
- character.sheets.base = love.graphics.newImage( 'images/characters/' .. character.name .. '/base.png')
- character.sheets.base:setFilter('nearest', 'nearest')
-
- character.mask = love.graphics.newQuad(0, character.offset, 48, 35, character.sheets.base:getWidth(), character.sheets.base:getHeight())
-
- character.positions = require( 'positions/' .. character.name )
-
- character._grid = anim8.newGrid( 48, 48, character.sheets.base:getWidth(), character.sheets.base:getHeight() )
- character._warp = anim8.newGrid( 36, 300, character.beam:getWidth(), character.beam:getHeight() )
-
- for state, _ in pairs( character.animations ) do
- local data = character.animations[ state ]
- if state == 'warp' then
- character.animations[ state ] = anim8.newAnimation(data[1], character._warp(unpack(data[2])), data[3])
- else
- if type( data[1] ) == 'string' then
- -- positionless
- character.animations[ state ] = anim8.newAnimation(data[1], character._grid(unpack(data[2])), data[3])
- else
- -- positioned
- for i, _ in pairs( data ) do
- character.animations[ state ][i] = anim8.newAnimation(data[i][1], character._grid(unpack(data[i][2])), data[i][3])
- end
- end
- end
- end
-
- character.costumemap = {}
- character.categorytocostumes = {}
- for _,c in pairs( character.costumes ) do
- character.costumemap[ c.sheet ] = c
- character.categorytocostumes[ c.category ] = character.categorytocostumes[ c.category ] or {}
- table.insert( character.categorytocostumes[ c.category ], c )
- end
-
- characters[ character.name ] = character
-end
+local _loaded_character = nil
+local _character = 'abed'
+local _costume = 'base'
local Character = {}
Character.__index = Character
-Character.characters = characters
-
-Character.name = 'abed'
-Character.costume = 'base'
-
-Character.warpin = false
function Character:reset()
- self.state = 'idle'
- self.direction = 'right'
+ self.state = 'idle'
+ self.direction = 'right'
end
-function Character:setCharacter( name )
- if character == self.name then return end
+-- FIXME: Needed for the taco meat item
+-- If a character doesn't have this costume, no effect takes place
+function Character:setCostume(costume)
+ if costume == self.costume then
+ return
+ end
- if self.characters[name] then
- self.name = name
- self.costume = 'base'
- return
- end
+ -- Stuff for magic
+end
- error( "Invalid character ( " .. name .. " ) requested!" )
+function Character:sheet()
+ return self:getSheet(self.costume)
end
-function Character:setCostume( costume )
- if costume == self.costume then return end
+function Character:getSheet(costume)
+ local path = 'images/characters/' .. self.name .. '/' .. costume .. '.png'
- if self:hasCostume(costume) then
- self.costume = costume
- return
- end
-
- error( "Undefined costume ( " .. costume .. " ) requested for character ( " .. self.name .. " )" )
+ if not self.sheets[costume] then
+ self.sheets[costume] = love.graphics.newImage(path)
+ self.sheets[costume]:setFilter('nearest', 'nearest')
+ end
+
+ return self.sheets[costume]
end
-function Character:hasCostume( costume )
- for _,c in pairs( self:current().costumes ) do
- if c.sheet == costume then
- return true
- end
- end
- return false
+function Character:update(dt)
+ self:animation():update(dt)
end
-function Character:current()
- return self.characters[self.name]
+function Character:animation()
+ return self.animations[self.state][self.direction]
end
-function Character:sheet()
- return self:getSheet( self.name, self.costume )
+function Character:warpUpdate(dt)
+ self.animations.warp:update(dt)
end
-function Character:getSheet(char,costume)
- if not self.characters[char].sheets[costume] then
- self.characters[char].sheets[costume] = love.graphics.newImage( 'images/characters/' .. char .. '/' .. costume .. '.png')
- self.characters[char].sheets[costume]:setFilter('nearest', 'nearest')
- end
- return self.characters[char].sheets[costume]
+function Character:respawn()
+ self.warpin = true
+ self.animations.warp:gotoFrame(1)
+ self.animations.warp:resume()
+ sound.playSfx( "respawn" )
+ Timer.add(0.30, function() self.warpin = false end)
end
-function Character:updateAnimation(dt)
- self:animation():update(dt)
+function Character:draw(x, y)
+ self:animation():draw(self:sheet(), x, y)
end
-function Character:animation()
- return self.characters[self.name].animations[self.state][self.direction]
+function Character:getCategory()
+ return self.costumemap[self.costume].category
end
-function Character:warpUpdate(dt)
- self:current().animations.warp:update(dt)
+function Character:getOverworld()
+ return self.costumemap[self.costume].ow
end
-function Character:respawn()
- self.warpin = true
- self:current().animations.warp:gotoFrame(1)
- self:current().animations.warp:resume()
- sound.playSfx( "respawn" )
- Timer.add(0.30, function() self.warpin = false end)
+function module.pick(name, costume)
+ if not love.filesystem.exists("characters/" .. name .. ".json") then
+ error("Unknown character " .. name)
+ end
+
+ if not love.filesystem.exists("images/characters/" .. name .. "/" .. costume .. ".png") then
+ error("Unknown costume " .. costume .. " for character " .. name)
+ end
+
+ _character = name
+ _costume = costume
+ _loaded_character = nil
+end
+
+function module.load(character)
+ if not love.filesystem.exists("characters/" .. character .. ".json") then
+ error("Unknown character " .. character)
+ end
+
+ local contents, _ = love.filesystem.read('characters/' .. character .. ".json")
+ return json.decode(contents)
end
-function Character:draw()
+-- Load the current character. Do all the crazy stuff too
+function module.current()
+ if _loaded_character then
+ return _loaded_character
+ end
+
+ local beamPath = 'images/characters/' .. _character .. '/beam.png'
+ local basePath = 'images/characters/' .. _character .. '/base.png'
+ local characterPath = "characters/" .. _character .. ".json"
+
+ if not love.filesystem.exists(characterPath) then
+ error("Unknown character " .. _character)
+ end
+
+ local contents, _ = love.filesystem.read('character_map.json')
+ local sprite_map = json.decode(contents)
+
+ local contents, _ = love.filesystem.read(characterPath)
+
+ local character = json.decode(contents)
+ setmetatable(character, Character)
+
+ character.name = _character
+ character.costume = _costume
+ character.warpin = false
+
+ if character.animations then --merge
+ local base = utils.deepcopy(character.animations)
+ character.animations = utils.deepcopy(sprite_map)
+ for k,v in pairs(base) do
+ character.animations[k] = v
+ end
+ else
+ character.animations = utils.deepcopy(sprite_map)
+ end
+
+ -- build the character
+ character.beam = love.graphics.newImage(beamPath)
+ character.beam:setFilter('nearest', 'nearest')
+
+ character.count = 1
+
+ character.sheets = {}
+ character.sheets.base = love.graphics.newImage(basePath)
+ character.sheets.base:setFilter('nearest', 'nearest')
+
+ character.mask = love.graphics.newQuad(0, character.offset, 48, 35,
+ character.sheets.base:getWidth(),
+ character.sheets.base:getHeight())
+
+ character.positions = utils.require('positions/' .. character.name)
+
+ character._grid = anim8.newGrid(48, 48,
+ character.sheets.base:getWidth(),
+ character.sheets.base:getHeight())
+
+ character._warp = anim8.newGrid(36, 300, character.beam:getWidth(), character.beam:getHeight())
+
+ for state, _ in pairs(character.animations) do
+ local data = character.animations[state]
+ if state == 'warp' then
+ character.animations[state] = anim8.newAnimation(data[1], character._warp(unpack(data[2])), data[3])
+ else
+ if type( data[1] ) == 'string' then
+ -- positionless
+ character.animations[state] = anim8.newAnimation(data[1], character._grid(unpack(data[2])), data[3])
+ else
+ -- positioned
+ for i, _ in pairs( data ) do
+ character.animations[state][i] = anim8.newAnimation(data[i][1], character._grid(unpack(data[i][2])), data[i][3])
+ end
+ end
+ end
+ end
+
+ character.costumemap = {}
+ character.categorytocostumes = {}
+
+ for _,c in pairs(character.costumes) do
+ character.costumemap[c.sheet] = c
+ character.categorytocostumes[c.category] = character.categorytocostumes[c.category] or {}
+ table.insert(character.categorytocostumes[c.category], c)
+ end
+
+ _loaded_character = character
+ return character
end
-function Character:getCategory()
- return self:current().costumemap[ self.costume ].category
+
+function module.getCostumeImage(character, costume)
+ local path = "images/characters/" .. character .. "/" .. costume .. ".png"
+ return love.graphics.newImage(path)
end
-function Character:getOverworld()
- return self:current().costumemap[ self.costume ].ow
+
+function module.characters()
+ local list = {}
+
+ for _, filename in pairs(love.filesystem.enumerate('characters')) do
+ local name, _ = filename:gsub(".json", "")
+ table.insert(list, name)
+ end
+
+ return list
end
-function Character:findRelatedCostume( char )
- --returns the requested character's costume that is most similar to the current character
- local costumes = self.characters[ char ].categorytocostumes[ self:getCategory() ]
- if costumes then return costumes[math.random(#costumes)].sheet end
- return 'base'
+--returns the requested character's costume that is most similar to the current character
+function module.findRelatedCostume(name, category)
+ local char = module.load(name)
+
+ for _, costume in pairs(char.costumes) do
+ if costume.category == category then
+ return costume.sheet
+ end
+ end
+
+ return 'base'
end
-Character:reset()
-return Character
+return module
diff --git a/src/characterstrip.lua b/src/characterstrip.lua
index 93111beeb..0b0616004 100644
--- a/src/characterstrip.lua
+++ b/src/characterstrip.lua
@@ -3,11 +3,11 @@
-- A single colored strip, on which a character appears for selection.
-- Created by tjvezina
----------------------------------------------------------------------
+local window = require 'window'
local CharacterStrip = {}
CharacterStrip.__index = CharacterStrip
-local window = require 'window'
local stripSize = 35 -- Thickness of the strip
local moveSize = 300 -- Pixels travelled from ratio 0 to 1
diff --git a/src/credits.lua b/src/credits.lua
index 23230daa1..c213f4e93 100644
--- a/src/credits.lua
+++ b/src/credits.lua
@@ -44,6 +44,7 @@ end
state.credits = {
app.i18n('credits'),
'6sutters',
+ '8bitgentleman',
'a8252359',
'aaronpetykowski',
'academania',
diff --git a/src/debugger.lua b/src/debugger.lua
index 91d8293b0..85e19f83c 100644
--- a/src/debugger.lua
+++ b/src/debugger.lua
@@ -115,7 +115,7 @@ function Debugger:draw()
end
love.graphics.setColor( 255, 255, 255, 255 )
fonts.set('big')
- love.graphics.print( math.floor( collectgarbage( 'count' ) / 10 ) / 10 , window.screen_width - 30, window.screen_height - 10,0,0.5,0.5 )
+ love.graphics.print(math.floor(collectgarbage('count')), window.screen_width - 30, window.screen_height - 10,0,0.5,0.5 )
fonts.revert()
end
diff --git a/src/flyin.lua b/src/flyin.lua
index ea057ba9e..a4f97f5ce 100644
--- a/src/flyin.lua
+++ b/src/flyin.lua
@@ -3,62 +3,123 @@ local Gamestate = require 'vendor/gamestate'
local window = require 'window'
local fonts = require 'fonts'
local TunnelParticles = require "tunnelparticles"
-local flyin = Gamestate.new()
local sound = require 'vendor/TEsound'
local Timer = require 'vendor/timer'
-local Character = require 'character'
+local character = require 'character'
local utils = require 'utils'
+local flyin = Gamestate.new()
+
function flyin:init( )
- TunnelParticles:init()
+ TunnelParticles:init()
end
function flyin:enter( prev )
- self.flying = {}
- self.characterorder = {}
- for i,c in pairs(Character.characters) do
- if c.name ~= Character.name then
- table.insert(self.characterorder, c.name)
- end
+ self.flying = {}
+ self.images = {}
+ self.masks = {}
+ self.characterorder = {}
+
+ self.current = character.current()
+
+ -- Only include greendale seven
+ for _, name in pairs({"abed", "annie", "jeff", "pierce", "troy", "britta", "shirley"}) do
+ if name ~= self.current.name then
+ table.insert(self.characterorder, name)
end
- self.characterorder = utils.shuffle( self.characterorder, 5 )
- table.insert( self.characterorder, Character.name )
- local time = 0
- for _,name in pairs( self.characterorder ) do
- Timer.add(time, function()
- table.insert( self.flying, {
- n = name,
- c = name == Character.name and Character.costume or Character:findRelatedCostume(name),
- x = window.width / 2,
- y = window.height / 2,
- t = math.random( ( math.pi * 2 ) * 10000 ) / 10000,
- r = name == Character.name and 0 or ( math.random( 4 ) - 1 ) * ( math.pi / 2 ),
- s = 0.1,
- show = true
- })
- end)
- time = time + 0.4
+ end
+
+ self.characterorder = utils.shuffle(self.characterorder, 5)
+
+ table.insert(self.characterorder, self.current.name)
+
+ local time = 0
+
+ for _, name in pairs(self.characterorder) do
+ local costume_name = self.current.costume
+
+ if name ~= self.current.name then
+ costume_name = character.findRelatedCostume(name, self.current:getCategory())
end
+
+ Timer.add(time, function()
+ table.insert(self.flying, {
+ n = name,
+ c = costume_name,
+ x = window.width / 2,
+ y = window.height / 2,
+ t = math.random((math.pi * 2) * 10000) / 10000,
+ r = name == self.current.name and 0 or (math.random(4) - 1) * (math.pi / 2),
+ s = 0.1,
+ show = true
+ })
+ end)
+ time = time + 0.4
+ end
+end
+
+function flyin:leave()
+ self.current = nil
+ self.flying = {}
+ self.images = {}
+ self.masks = {}
+ self.characterorder = {}
+ TunnelParticles.leave()
+end
+
+function flyin:drawCharacter(flyer, x, y, r, sx, sy, ox, oy)
+ local name = flyer.n
+ local costume = flyer.c
+ local key = name .. costume
+
+
+ -- find costume
+ -- load image
+ -- load mask
+ -- draw
+
+ --local char = self:loadCharacter(name)
+ --local key = name .. char.costume
+
+ if not self.images[key] then
+ self.images[key] = character.getCostumeImage(name, costume)
+ end
+
+ local image = self.images[key]
+
+ if not self.masks[key] then
+ self.masks[key] = love.graphics.newQuad(11 * 48, 4 * 48, 48, 48,
+ image:getWidth(), image:getHeight())
+ end
+
+ local mask = self.masks[key]
+
+ love.graphics.drawq(image, mask, x, y, r, sx, sy, ox, oy)
end
+
function flyin:draw()
- TunnelParticles.draw()
-
- love.graphics.circle( 'fill', window.width / 2, window.height / 2, 30 )
-
- --draw in reverse order, so the older ones get drawn on top of the newer ones
- for i = #flyin.flying, 1, -1 do
- local v = flyin.flying[i]
- if v.show then
- love.graphics.setColor( 255, 255, 255, 255 )
- Character.characters[v.n].animations.flyin:draw( Character:getSheet(v.n,v.c), v.x, v.y, v.r - ( v.r % ( math.pi / 2 ) ), math.min(v.s,5), math.min(v.s,5), 22, 32 )
- -- black mask while coming out of 'tunnel'
- if v.s <= 1 then
- love.graphics.setColor( 0, 0, 0, 255 * ( 1 - v.s ) )
- Character.characters[v.n].animations.flyin:draw( Character:getSheet(v.n,v.c), v.x, v.y, v.r - ( v.r % ( math.pi / 2 ) ), math.min(v.s,5), math.min(v.s,5), 22, 32 )
- end
- end
+ TunnelParticles.draw()
+
+ love.graphics.circle('fill', window.width / 2, window.height / 2, 30)
+
+ -- draw in reverse order, so the older ones get drawn on top of the newer ones
+ for i = #flyin.flying, 1, -1 do
+ local v = flyin.flying[i]
+ if v.show then
+ love.graphics.setColor(255, 255, 255, 255)
+
+ self:drawCharacter(v, v.x, v.y, v.r - (v.r % (math.pi / 2)),
+ math.min(v.s, 5), math.min(v.s, 5), 22, 32)
+ -- black mask while coming out of 'tunnel'
+ if v.s <= 1 then
+ love.graphics.setColor(0, 0, 0, 255 * (1 - v.s ))
+
+ self:drawCharacter(v, v.x, v.y, v.r - (v.r % (math.pi / 2)),
+ math.min(v.s, 5), math.min(v.s, 5), 22, 32)
+ end
end
+ end
end
function flyin:startGame(dt)
@@ -68,27 +129,27 @@ function flyin:startGame(dt)
end
function flyin:keypressed(button)
- Timer.clear()
- self:startGame()
+ Timer.clear()
+ self:startGame()
end
function flyin:update(dt)
- TunnelParticles.update(dt)
- for k,v in pairs(flyin.flying) do
- if v.n ~= Character.name then
- v.x = v.x + ( math.cos( v.t ) * dt * v.s * 90 )
- v.y = v.y + ( math.sin( v.t ) * dt * v.s * 90 )
- end
- v.s = v.s + dt * 4
- v.r = v.r + dt * 5
- if v.s >= 6 then
- v.show = false
- end
+ TunnelParticles.update(dt)
+ for k,v in pairs(flyin.flying) do
+ if v.n ~= self.current.name then
+ v.x = v.x + ( math.cos( v.t ) * dt * v.s * 90 )
+ v.y = v.y + ( math.sin( v.t ) * dt * v.s * 90 )
end
- if not flyin.flying[ #flyin.flying ].show then
- Timer.clear()
- self:startGame()
+ v.s = v.s + dt * 4
+ v.r = v.r + dt * 5
+ if v.s >= 6 then
+ v.show = false
end
+ end
+ if not flyin.flying[#flyin.flying].show then
+ Timer.clear()
+ self:startGame()
+ end
end
return flyin
diff --git a/src/gameover.lua b/src/gameover.lua
index 42b4dcf89..d1d6115d0 100644
--- a/src/gameover.lua
+++ b/src/gameover.lua
@@ -8,59 +8,62 @@ local part = require 'verticalparticles'
local character = require 'character'
function state:init()
- self.text="G A M E O V E R !"
- self.text2="-Press any key to continue-"
- part.init()
- -- The X coordinates of the columns
- self.left = 180
- -- The Y coordinate of the top key
- self.top = 93
- -- Vertical spacing between keys
- self.spacing = 20
+ self.text="G A M E O V E R !"
+ self.text2="-Press any key to continue-"
+ part.init()
+ -- The X coordinates of the columns
+ self.left = 180
+ -- The Y coordinate of the top key
+ self.top = 93
+ -- Vertical spacing between keys
+ self.spacing = 20
end
function state:enter(previous)
- fonts.set( 'big' )
- sound.playMusic( "you-just-lost" )
+ fonts.set('big')
+ sound.playMusic("you-just-lost")
- character.state = 'dead'
- character.direction = 'right'
-
- self.blink=0
-
- camera:setPosition(0, 0)
- self.previous = previous
+ self.character = character:current()
+ self.character.state = 'dead'
+ self.character.direction = 'right'
+
+ self.blink = 0
+
+ camera:setPosition(0, 0)
+ self.previous = previous
end
function state:leave()
- fonts.reset()
+ self.character = nil
+ self.previous = nil
+ fonts.reset()
end
-function state:keypressed( button )
- Gamestate.switch("splash")
+function state:keypressed(button)
+ Gamestate.switch("splash")
end
function state:update(dt)
- character:animation():update(dt)
- part.update(dt)
- self.blink = self.blink + dt
- if self.blink > 1 then
- self.blink = 0
- end
+ self.character:update(dt)
+ part.update(dt)
+ self.blink = self.blink + dt
+ if self.blink > 1 then
+ self.blink = 0
+ end
end
function state:draw()
- love.graphics.setColor( 0, 0, 0, 255 )
- love.graphics.rectangle( "fill", 0, 0, 528, 336 )
- part.draw()
- fonts.set('big')
- love.graphics.print( self.text, self.left - 20, self.top )
- character:animation():draw( character:sheet(), self.left + 60, self.top + 20 )
- fonts.set('ariel')
- if self.blink < 0.5 then
- love.graphics.print( self.text2, self.left + 5, self.top + 80 )
- end
- love.graphics.setColor( 255, 255, 255, 255 )
+ love.graphics.setColor(0, 0, 0, 255)
+ love.graphics.rectangle("fill", 0, 0, 528, 336)
+ part.draw()
+ fonts.set('big')
+ love.graphics.print(self.text, self.left - 20, self.top )
+ self.character:draw(self.left + 60, self.top + 20)
+ fonts.set('ariel')
+ if self.blink < 0.5 then
+ love.graphics.print(self.text2, self.left + 5, self.top + 80)
+ end
+ love.graphics.setColor(255, 255, 255, 255)
end
return state
diff --git a/src/hud.lua b/src/hud.lua
index c30245dd8..57ec274cf 100644
--- a/src/hud.lua
+++ b/src/hud.lua
@@ -1,7 +1,6 @@
local window = require 'window'
local camera = require 'camera'
local fonts = require 'fonts'
-local Character = require 'character'
local utils = require 'utils'
local HUD = {}
@@ -20,10 +19,10 @@ function HUD.new(level)
local hud = {}
setmetatable(hud, HUD)
- local character = level.player.character:current()
+ local character = level.player.character
hud.sheet = level.player.character:sheet()
- hud.character_quad = love.graphics.newQuad( 0, character.offset or 5, 48, 48, hud.sheet:getWidth(), hud.sheet:getHeight() )
+ hud.character_quad = love.graphics.newQuad(0, character.offset or 5, 48, 48, hud.sheet:getWidth(), hud.sheet:getHeight())
hud.character_stencil = function( x, y )
love.graphics.circle( 'fill', x + 31, y + 31, 21 )
@@ -57,21 +56,23 @@ function HUD:draw( player )
0,
255
)
- love.graphics.draw( energy, self.x - ( player.max_health - player.health ) * 2.8, self.y )
- love.graphics.setStencil( self.character_stencil, self.x, self.y )
- love.graphics.setColor( 255, 255, 255, 255 )
+
+ love.graphics.draw(energy, self.x - (player.max_health - player.health) * 5.6, self.y)
+ love.graphics.setStencil(self.character_stencil, self.x, self.y)
+ love.graphics.setColor(255, 255, 255, 255)
+
local currentWeapon = player.inventory:currentWeapon()
if currentWeapon and not player.doBasicAttack and not player.currently_held or (player.holdingAmmo and currentWeapon) then
local position = {x = self.x + 22, y = self.y + 22}
currentWeapon:draw(position, nil,false)
else
- love.graphics.drawq( self.sheet, self.character_quad, self.x + 7, self.y + 17 )
+ love.graphics.drawq(self.sheet, self.character_quad, self.x + 7, self.y + 17)
end
- love.graphics.setStencil( )
- love.graphics.draw( lens, self.x, self.y)
+ love.graphics.setStencil()
+ love.graphics.draw(lens, self.x, self.y)
love.graphics.setColor( 0, 0, 0, 255 )
- love.graphics.print( player.money, self.x + 69, self.y + 41,0,0.5,0.5)
- love.graphics.print( player.character:current().name, self.x + 60, self.y + 15,0,0.5,0.5)
+ love.graphics.print(player.money, self.x + 69, self.y + 41,0,0.5,0.5)
+ love.graphics.print(player.character.name, self.x + 60, self.y + 15,0,0.5,0.5)
love.graphics.setColor( 255, 255, 255, 255 )
fonts.revert()
diff --git a/src/items/consumables/tacomeat.lua b/src/items/consumables/tacomeat.lua
index a06b382f4..6f04e8b85 100644
--- a/src/items/consumables/tacomeat.lua
+++ b/src/items/consumables/tacomeat.lua
@@ -2,7 +2,7 @@ return{
name = 'tacomeat',
type = 'consumable',
MAX_ITEMS = 10,
- use = function( consumable, player )
+ use = function(consumable, player)
local Timer = require('vendor/timer')
local sound = require('vendor/TEsound')
local punchDamage = player.punchDamage
@@ -21,9 +21,7 @@ return{
end)
end
Timer.add(6, function () -- Set costume to zombie and double unarmed player damage.
- if player.character:hasCostume('zombie') then
- player.character:setCostume('zombie')
- end
+ player.character:setCostume('zombie')
player.jumpDamage = player.jumpDamage * 2
player.punchDamage = player.punchDamage * 2
player.slideDamage = player.slideDamage * 2
diff --git a/src/level.lua b/src/level.lua
index a46d1384a..e91944a9f 100644
--- a/src/level.lua
+++ b/src/level.lua
@@ -15,28 +15,17 @@ local HUD = require 'hud'
local utils = require 'utils'
local music = {}
-local node_cache = {}
-local tile_cache = {}
-
local Player = require 'player'
local Floorspace = require 'nodes/floorspace'
local Floorspaces = require 'floorspaces'
local Platform = require 'nodes/platform'
+local Sprite = require 'nodes/sprite'
local Block = require 'nodes/block'
local function limit( x, min, max )
return math.min(math.max(x,min),max)
end
-local function load_tileset(name)
- if tile_cache[name] then
- return tile_cache[name]
- end
-
- local tileset = tmx.load(require("maps/" .. name))
- tile_cache[name] = tileset
- return tileset
-end
local function on_collision(dt, shape_a, shape_b, mtv_x, mtv_y)
if shape_a.player and shape_b.player then return end
@@ -141,6 +130,7 @@ function Level.new(name)
local level = {}
setmetatable(level, Level)
+ level.paused = false
level.over = false
level.state = 'idle' -- TODO: Use state machine
level.name = name
@@ -153,8 +143,9 @@ function Level.new(name)
"Check the documentation for more info."
)
- level.map = require("maps/" .. name)
- level.tileset = load_tileset(name)
+ level.node_cache = {}
+ level.map = utils.require("maps/" .. name)
+ level.tileset = tmx.load(level.map)
level.collider = HC(100, on_collision, collision_stop)
level.offset = getCameraOffset(level.map)
level.music = getSoundtrack(level.map)
@@ -181,13 +172,9 @@ function Level.new(name)
for k,v in pairs(level.map.objectgroups.nodes.objects) do
local nodePath = 'nodes/' .. v.type
- local ok, NodeClass = pcall(require, nodePath)
+ local ok, NodeClass = level:loadNode(nodePath)
- if not ok then
-
- print("WARNING: Can't load " .. nodePath)
-
- else
+ if ok then
local node
if NodeClass and v.type == 'scenetrigger' then
@@ -198,7 +185,7 @@ function Level.new(name)
level:addNode(node)
elseif NodeClass then
v.objectlayer = 'nodes'
- node = NodeClass.new( v, level.collider, level)
+ node = NodeClass.new(v, level.collider, level)
node.drawHeight = v.height
level:addNode(node)
end
@@ -214,7 +201,6 @@ function Level.new(name)
end
end
-
end
if level.map.objectgroups.floorspace then
@@ -252,6 +238,23 @@ function Level.new(name)
return level
end
+-- Return the node from the filesystem
+function Level:loadNode(path)
+ if self.node_cache[path] then
+ return true, self.node_cache[path]
+ end
+
+ local ok, class = pcall(utils.require, path)
+
+ if not ok then
+ print("WARNING: Can't load " .. path)
+ end
+
+ self.node_cache[path] = class
+
+ return true, class
+end
+
function Level:restartLevel()
assert(self.name ~= "overworld","level's name cannot be overworld")
assert(Gamestate.currentState() ~= Gamestate.get("overworld"),"level cannot be overworld")
@@ -270,7 +273,8 @@ function Level:restartLevel()
end
-function Level:enter( previous, door, position )
+function Level:enter(previous, door, position)
+ self.paused = false
self.respawn = false
self.state = 'idle'
@@ -310,7 +314,8 @@ function Level:enter( previous, door, position )
self.player:respawn()
end
if self.doors[ door ].node then
- self.doors[ door ].node:show()
+ -- passing previous will allow the door to check the level against its own
+ self.doors[ door ].node:show(previous)
self.player.freeze = false
end
end
@@ -425,10 +430,6 @@ function Level:quit()
end
end
-function Level:leave()
- self.state = 'idle'
-end
-
function Level:exit(levelName, doorName)
self.respawn = false
if self.state ~= 'idle' then
@@ -535,13 +536,34 @@ function Level:floorspaceNodeDraw()
end
end
+-- Called by Gamestate.switch when changing levels
function Level:leave()
- for i,node in pairs(self.nodes) do
- if node.leave then node:leave() end
- if node.collide_end then
- node:collide_end(self.player)
- end
+ for i,node in pairs(self.nodes) do
+ if node.leave then node:leave() end
+ if node.collide_end then
+ node:collide_end(self.player)
end
+ end
+
+ self.previous = nil
+
+ if not self.paused then
+ self.player = nil
+ self.map = nil
+ self.tileset = nil
+ self.collider = nil
+ self.offset = nil
+ self.music = nil
+ self.spawn = nil
+ self.overworldName = nil
+ self.title = nil
+ self.environment = nil
+ self.boundary = nil
+ self.transition = nil
+ self.events = nil
+ self.nodes = {}
+ self.doors = {}
+ end
end
function Level:keyreleased( button )
@@ -588,8 +610,8 @@ function Level:keypressed( button )
end
if button == 'START' and not self.player.dead and self.player.health > 0 and not self.player.controlState:is('ignorePause') then
- Gamestate.switch('pause', self.player)
- return true
+ Gamestate.stack('pause', self.player)
+ return true
end
end
@@ -639,14 +661,17 @@ function Level:updatePan(dt)
end
function Level:addNode(node)
- if node.containerLevel then
+ -- FIXME: This seems like a very bad idea
+ if node.containerLevel and node.containerLevel.collider then
node.containerLevel.collider:remove(node.bb)
node.containerLevel:removeNode(node)
end
+
node.containerLevel = self
table.insert(self.nodes, node)
end
+
function Level:removeNode(node)
node.containerLevel = nil
for k,v in pairs(self.nodes) do
diff --git a/src/main.lua b/src/main.lua
index 682a42260..407a4cd67 100644
--- a/src/main.lua
+++ b/src/main.lua
@@ -16,7 +16,6 @@ local timer = require 'vendor/timer'
local cli = require 'vendor/cliargs'
local mixpanel = require 'vendor/mixpanel'
-
local debugger = require 'debugger'
local camera = require 'camera'
local fonts = require 'fonts'
@@ -43,7 +42,9 @@ function love.load(arg)
error("Love 0.8.0 is required")
end
- table.remove(arg, 1)
+ -- The Mavericks builds of Love adds too many arguements
+ arg = utils.cleanarg(arg)
+
local state, door, position = 'update', nil, nil
-- SCIENCE!
@@ -105,15 +106,22 @@ function love.load(arg)
if args["position"] ~= "" then
position = args["position"]
end
+
+
+ -- Choose character and costume
+ local char = "abed"
+ local costume = "base"
if args["character"] ~= "" then
- character:setCharacter( args["c"] )
+ char = args["c"]
end
if args["costume"] ~= "" then
- character:setCostume( args["o"] )
+ costume = args["o"]
end
+ character.pick(char, costume)
+
if args["vol-mute"] == 'all' then
sound.disabled = true
elseif args["vol-mute"] == 'music' then
@@ -127,11 +135,11 @@ function love.load(arg)
end
if args["d"] then
- debugger.set( true, false )
+ debugger.set(true, false)
end
if args["b"] then
- debugger.set( true, true )
+ debugger.set(true, true)
end
if args["locale"] ~= "" then
@@ -188,6 +196,10 @@ function love.update(dt)
tween.update(dt > 0 and dt or 0.001)
timer.update(dt)
sound.cleanup()
+
+ if debugger.on then
+ collectgarbage("collect")
+ end
end
function love.keyreleased(key)
@@ -223,6 +235,7 @@ end
function love.draw()
if testing then return end
+
camera:set()
Gamestate.draw()
fonts.set('arial')
@@ -252,6 +265,21 @@ function love.draw()
end
end
+--function love.draw()
+--end
+--
+--function love.update(dt)
+--end
+--
+--function love.load()
+--end
+--
+--function love.keyreleased()
+--end
+--
+--function love.keypressed()
+--end
+
-- Override the default screenshot functionality so we can disable the fps before taking it
local newScreenshot = love.graphics.newScreenshot
function love.graphics.newScreenshot()
diff --git a/src/maps/black-caverns-2.tmx b/src/maps/black-caverns-2.tmx
index c23b11c44..0e82c9378 100644
--- a/src/maps/black-caverns-2.tmx
+++ b/src/maps/black-caverns-2.tmx
@@ -34,7 +34,7 @@
- eJzt2NEKgjAUBmAhu/U9etTeOoQGQ9Q5bZvm98GBLiKl/Z6503UAAMCv9VE9G98L7cV5AMqY67mPRvdyhF5xD2M2+8yCmuKMAgBALVvPSuatjJbyIh9wP3E/qNkDwnVLXfO1UnPCf/D+Futyc5P6/t552tK6DlFRXstZ/NLznXrmj/w255Zas7X9Yc86y8h1pNY97Bs5+Yj3mhJ9iDpye8HR3iEb17F1reb6Rzf5vOXdVDauK+f9g3uocR515gX4b0PD4vzCu6U8MGc6s5AHplIz8qXZlzMtU+YdAJzZB8eyGDg=
+ eJzt2FsKgzAQBVCh7a/76FK76yIoBIkm8ZWI58CAH5ZIcx11ug4AADjaO6hP5WuhvjAPwDliPfdV6Vr20CueYcjmu7DgSmFGAQDgKrnfSuatDJbyIh/wPGE/uLIHTOueteZ3pWKm/+A3FutKc5M6f+s8LbWvXKPmLH7p/j4iGzm9g/ak9mzt+bBln2XkPlL73o9Vko/pN13kHNm4j9JesLd3yMZ95O5VrH90s+OwX+xdj/aUvH/wDDn3/B3WAKCevmLRvundUh6Imc8s5IG51Ix8afblm5Y58w4AWvYH1tAYDg==
@@ -683,7 +683,7 @@
-
+