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