From 6c3c988b6f4186d0de23ac3cb016ee617a0f0759 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Sat, 28 Nov 2009 14:43:28 +0000 Subject: [PATCH] limit fps but not game ticks flying combat text git-svn-id: http://svn.net-core.org/repos/t-engine4@57 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engine/FlyingText.lua | 50 +++++++++++++++++++ game/engine/Game.lua | 9 ++++ game/engine/Map.lua | 7 +++ game/engine/Savefile.lua | 8 +++ game/engine/interface/ActorLife.lua | 2 +- game/modules/tome/class/Actor.lua | 1 + game/modules/tome/class/Game.lua | 9 ++-- game/modules/tome/class/interface/Combat.lua | 6 +-- game/modules/tome/data/damage_types.lua | 16 +++++- .../tome/data/zones/ancient_ruins/zone.lua | 4 +- game/modules/tome/load.lua | 5 +- game/special/mainmenu/class/Game.lua | 1 - premake4.lua | 4 +- src/core_lua.c | 23 +++++++++ src/display_sdl.h | 1 + src/main.c | 40 +++++++++++++-- 16 files changed, 165 insertions(+), 21 deletions(-) create mode 100644 game/engine/FlyingText.lua diff --git a/game/engine/FlyingText.lua b/game/engine/FlyingText.lua new file mode 100644 index 0000000000..e16a27c5f9 --- /dev/null +++ b/game/engine/FlyingText.lua @@ -0,0 +1,50 @@ +require "engine.class" + +module(..., package.seeall, class.make) + +function _M:init(fontname, fontsize) + self.font = core.display.newFont(fontname or "/data/font/Vera.ttf", fontsize or 8) + self.font_h = self.font:lineSkip() + self.flyers = {} +end + +function _M:add(x, y, duration, xvel, yvel, str, color) + assert(x, "no x flyer") + assert(y, "no y flyer") + assert(str, "no str flyer") + color = color or {255,255,255} + local s = core.display.drawStringNewSurface(self.font, str, color[1], color[2], color[3]) + if not s then return end + self.flyers[{ + x=x, + y=y, + duration=duration or 10, + xvel = xvel or 0, + yvel = yvel or 0, + s = s + }] = true +end + +function _M:empty() + self.flyers = {} +end + +function _M:display() + if not next(self.flyers) then return end + + local dels = {} + + for fl, _ in pairs(self.flyers) do + fl.s:toScreen(fl.x, fl.y) + fl.x = fl.x + fl.xvel + fl.y = fl.y + fl.yvel + fl.duration = fl.duration - 1 + + -- Delete the flyer + if fl.duration == 0 then + dels[#dels+1] = fl + end + end + + for i, fl in ipairs(dels) do self.flyers[fl] = nil end +end diff --git a/game/engine/Game.lua b/game/engine/Game.lua index 9aaf098e8e..1e3d1d62c5 100644 --- a/game/engine/Game.lua +++ b/game/engine/Game.lua @@ -52,6 +52,10 @@ function _M:display() for i, d in ipairs(self.dialogs) do d:display():toScreen(d.display_x, d.display_y) end + + if self.flyers then + self.flyers:display() + end end --- This is the "main game loop", do something here @@ -62,6 +66,11 @@ end function _M:onQuit() end +--- Sets up a text flyers +function _M:setFlyingText(fl) + self.flyers = fl +end + --- Registers a dialog to display function _M:registerDialog(d) table.insert(self.dialogs, d) diff --git a/game/engine/Map.lua b/game/engine/Map.lua index 384691b3cb..a6b80bd568 100644 --- a/game/engine/Map.lua +++ b/game/engine/Map.lua @@ -332,3 +332,10 @@ function _M:getMouseTile(mx, my) local tmy = math.floor((my - self.display_y) / self.tile_h) + self.my return tmx, tmy end + +--- Get the screen position corresponding to a tile +function _M:getTileToScreen(tx, ty) + local x = (tx - self.mx) * self.tile_w + self.display_x + local y = (ty - self.my) * self.tile_h + self.display_y + return x, y +end diff --git a/game/engine/Savefile.lua b/game/engine/Savefile.lua index 5a6dd1e732..0708080117 100644 --- a/game/engine/Savefile.lua +++ b/game/engine/Savefile.lua @@ -36,6 +36,14 @@ function _M:close() self.current_save_main = nil end +--- Delete the savefile, if needed +function _M:delete() + for i, f in ipairs(fs.list(self.save_dir)) do + fs.delete(self.save_dir..f) + end + fs.delete(self.save_dir) +end + function _M:addToProcess(o) if not self.tables[o] then table.insert(self.process, o) diff --git a/game/engine/interface/ActorLife.lua b/game/engine/interface/ActorLife.lua index 95e6fc332f..80ae76bd46 100644 --- a/game/engine/interface/ActorLife.lua +++ b/game/engine/interface/ActorLife.lua @@ -25,7 +25,7 @@ function _M:takeHit(value, src) if self.life <= 0 then game.logSeen(self, "%s killed %s!", src.name:capitalize(), self.name) game.level:removeEntity(self) - self:die(src) + return self:die(src) end end diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 6ac0f4ea28..7b871f2f3a 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -46,6 +46,7 @@ function _M:die(src) end -- Do we get a blooooooody death ? if rng.percent(33) then self:bloodyDeath() end + return true end function _M:levelup() diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index a5b3bf7053..7c8f498e7f 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -1,9 +1,10 @@ require "engine.class" require "engine.GameTurnBased" require "engine.KeyCommand" -require "engine.LogDisplay" +local LogDisplay = require "engine.LogDisplay" local Savefile = require "engine.Savefile" local DebugConsole = require "engine.DebugConsole" +local FlyingText = require "engine.FlyingText" local Tooltip = require "engine.Tooltip" local QuitDialog = require "mod.dialogs.Quit" local Calendar = require "engine.Calendar" @@ -41,9 +42,11 @@ function _M:run() -- Abilities ActorAbilities:loadDefinition("/data/abilities.lua") - self.log = engine.LogDisplay.new(0, self.h * 0.80, self.w * 0.5, self.h * 0.20, nil, nil, nil, {255,255,255}, {30,30,30}) + self.log = LogDisplay.new(0, self.h * 0.80, self.w * 0.5, self.h * 0.20, nil, nil, nil, {255,255,255}, {30,30,30}) self.calendar = Calendar.new("/data/calendar_rivendell.lua", "Today is the %s %s of the %s year of the Fourth Age of Middle-earth.\nThe time is %02d:%02d.", 122) - self.tooltip = engine.Tooltip.new(nil, nil, {255,255,255}, {30,30,30}) + self.tooltip = Tooltip.new(nil, nil, {255,255,255}, {30,30,30}) + self.flyers = FlyingText.new() + self:setFlyingText(self.flyers) self.log("Welcome to #00FF00#Tales of Middle Earth!") self.logSeen = function(e, ...) if e and self.level.map.seens(e.x, e.y) then self.log(...) end end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index eea172f12d..dc6cae1065 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -41,6 +41,7 @@ The ToME combat system has the following attributes: function _M:attackTarget(target) local sc = self.combat local tc = target.combat + local damtype = DamageType.PHYSICAL if not sc then sc = {dam=0, atk=0, apr=0, def=0, armor=0} end if not tc then tc = {dam=0, atk=0, apr=0, def=0, armor=0} end @@ -50,9 +51,7 @@ function _M:attackTarget(target) -- If hit is over 0 it connects, if it is 0 we still have 50% chance if hit > 0 or (hit == 0 and rng.percent(50)) then local dam = rng.avg(sc.dam * 2 / 3, sc.dam) - math.max(0, tc.armor - sc.apr) - if dam < 0 then dam = 0 end - game.logSeen(target, "%s hits %s for #aaaaaa#%0.2f physical damage#ffffff#.", self.name:capitalize(), target.name, dam) - target:takeHit(dam, self) + DamageType:get(damtype).projector(self, target.x, target.y, damtype, dam) else game.logSeen(target, "%s misses %s.", self.name:capitalize(), target.name) end @@ -81,7 +80,6 @@ function _M:project(t, x, y, damtype, dam) if not lx and not ly then lx, ly = x, y end if typ.ball then - print(lx, ly, typ.ball) core.fov.calc_circle(lx, ly, typ.ball, function(self, px, py) -- Deam damage: ball DamageType:get(damtype).projector(self, px, py, damtype, dam) diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua index af22895499..4b0db53e40 100644 --- a/game/modules/tome/data/damage_types.lua +++ b/game/modules/tome/data/damage_types.lua @@ -1,13 +1,25 @@ -- The basic stuff used to damage a grid defaultProjector(function(src, x, y, type, dam) -print(src, x, y, type, dam) local target = game.level.map(x, y, Map.ACTOR) if target then game.logSeen(target, "%s hits %s for #aaaaaa#%0.2f %s damage#ffffff#.", src.name:capitalize(), target.name, dam, DamageType:get(type).name) - target:takeHit(dam, src) + local sx, sy = game.level.map:getTileToScreen(x, y) + if target:takeHit(dam, src) then + if src == game.player or target == game.player then + game.flyers:add(sx, sy, 30, 0.5, -3, "Kill!", {255,0,255}) + end + else + if src == game.player or target == game.player then + game.flyers:add(sx, sy, 30, -0.5, -3, tostring(-dam), {255,0,255}) + end + end end end) +newDamageType{ + name = "physical", type = "PHYSICAL", +} + newDamageType{ name = "arcane", type = "ARCANE", } diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua index 617575782f..087b1349d1 100644 --- a/game/modules/tome/data/zones/ancient_ruins/zone.lua +++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua @@ -2,9 +2,9 @@ return { name = "ancient ruins", max_level = 5, width = 40, height = 30, - all_remembered = true, +-- all_remembered = true, all_lited = true, - persistant = true, +-- persistant = true, generator = { map = { class= "engine.generator.map.Rooms", diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua index 59af8ca1b6..7b73905404 100644 --- a/game/modules/tome/load.lua +++ b/game/modules/tome/load.lua @@ -1,6 +1,9 @@ +-- This file loads the game module, if you name you main Game class +-- the same you do not need to change this file at all + + local Game = require "mod.class.Game" -- Global local game = Game.new() -game:setCurrent() return game diff --git a/game/special/mainmenu/class/Game.lua b/game/special/mainmenu/class/Game.lua index 31d72c7c6b..8bcb86b358 100644 --- a/game/special/mainmenu/class/Game.lua +++ b/game/special/mainmenu/class/Game.lua @@ -124,7 +124,6 @@ function _M:selectStepLoad() table.insert(list, { name=mod.name, font=mod_font, description="", fct=function() end, onSelect=function() self.step:skipSelected() end}) for j, save in ipairs(mod.savefiles) do - print(save.name) save.fct = function() mod.load() local save = Savefile.new(save.short_name) diff --git a/premake4.lua b/premake4.lua index 7c22bd9a1e..f1bb2f522d 100644 --- a/premake4.lua +++ b/premake4.lua @@ -36,12 +36,12 @@ project "TEngine" defines { "_DEFAULT_VIDEOMODE_FLAGS_='SDL_HWSURFACE|SDL_DOUBLEBUF'" } configuration "macosx" - linkoptions { "mac/SDLmain.m", "-framework SDL", "-framework SDL_image", "-framework SDL_ttf", "-framework SDL_mixer", "-framework Cocoa" } + linkoptions { "mac/SDLmain.m", "-framework SDL", "-framework SDL_gfx", "-framework SDL_image", "-framework SDL_ttf", "-framework SDL_mixer", "-framework Cocoa" } files { "mac/SDL*" } targetdir "." configuration "not macosx" - links { "SDL", "SDL_ttf", "SDL_image", "SDL_mixer" } + links { "SDL", "SDL_ttf", "SDL_image", "SDL_gfx", "SDL_mixer" } project "physfs" diff --git a/src/core_lua.c b/src/core_lua.c index 923bc9dcd1..183b776fed 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -348,6 +348,28 @@ static int sdl_surface_drawstring(lua_State *L) return 0; } +static int sdl_surface_drawstring_newsurface(lua_State *L) +{ + TTF_Font **f = (TTF_Font**)auxiliar_checkclass(L, "sdl{font}", 1); + const char *str = luaL_checkstring(L, 2); + int r = luaL_checknumber(L, 3); + int g = luaL_checknumber(L, 4); + int b = luaL_checknumber(L, 5); + + SDL_Color color = {r,g,b}; + SDL_Surface *txt = TTF_RenderUTF8_Solid(*f, str, color); + if (txt) + { + SDL_Surface **s = (SDL_Surface**)lua_newuserdata(L, sizeof(SDL_Surface*)); + auxiliar_setclass(L, "sdl{surface}", -1); + *s = txt; + return 1; + } + + lua_pushnil(L); + return 1; +} + static int sdl_new_surface(lua_State *L) { int w = luaL_checknumber(L, 1); @@ -460,6 +482,7 @@ static const struct luaL_reg displaylib[] = {"size", sdl_screen_size}, {"newFont", sdl_new_font}, {"newSurface", sdl_new_surface}, + {"drawStringNewSurface", sdl_surface_drawstring_newsurface}, {"loadImage", sdl_load_image}, {"setWindowTitle", sdl_set_window_title}, {NULL, NULL}, diff --git a/src/display_sdl.h b/src/display_sdl.h index 80f494681f..2a3583e39b 100644 --- a/src/display_sdl.h +++ b/src/display_sdl.h @@ -35,6 +35,7 @@ #define DISPLAY_SDL_H #include <SDL.h> +#include <SDL_framerate.h> #ifdef __cplusplus extern "C" { diff --git a/src/main.c b/src/main.c index b73d583e1b..e9b1b08410 100644 --- a/src/main.c +++ b/src/main.c @@ -177,11 +177,8 @@ void on_event(SDL_Event *event) } // redraw the screen and update game logics, if any -void on_redraw() +void on_tick() { - static int Frames = 0; - static int T0 = 0; - if (current_game != LUA_NOREF) { lua_rawgeti(L, LUA_REGISTRYINDEX, current_game); @@ -191,6 +188,12 @@ void on_redraw() lua_rawgeti(L, LUA_REGISTRYINDEX, current_game); docall(L, 1, 0); } +} + +void on_redraw() +{ + static int Frames = 0; + static int T0 = 0; sdlLock(screen); SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x00, 0x00)); @@ -247,6 +250,27 @@ void pass_command_args(int argc, char *argv[]) } } +Uint32 redraw_timer(Uint32 interval, void *param) +{ + SDL_Event event; + SDL_UserEvent userevent; + + /* In this example, our callback pushes an SDL_USEREVENT event + into the queue, and causes ourself to be called again at the + same interval: */ + + userevent.type = SDL_USEREVENT; + userevent.code = 0; + userevent.data1 = NULL; + userevent.data2 = NULL; + + event.type = SDL_USEREVENT; + event.user = userevent; + + SDL_PushEvent(&event); + return(interval); +} + /** * Program entry point. */ @@ -297,6 +321,8 @@ int main(int argc, char *argv[]) // Filter events, to catch the quit event SDL_SetEventFilter(event_filter); + SDL_AddTimer(30, redraw_timer, NULL); + bool done = FALSE; SDL_Event event; while ( !done ) @@ -316,13 +342,17 @@ int main(int argc, char *argv[]) /* handle quit requests */ done = TRUE; break; + case SDL_USEREVENT: + if (event.user.code == 0) + on_redraw(); + break; default: break; } } /* draw the scene */ - on_redraw(); + on_tick(); } return 0; -- GitLab