From 48c823ed5e244e826e571c2a7585b56786bbff8f Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Fri, 27 Nov 2009 13:13:09 +0000
Subject: [PATCH] first ability is working !

git-svn-id: http://svn.net-core.org/repos/t-engine4@54 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engine/DamageType.lua                   | 41 ++++++++++++++++++++
 game/engine/interface/ActorAbilities.lua     | 20 +++++++++-
 game/modules/tome/class/Game.lua             | 19 +++++++++
 game/modules/tome/class/interface/Combat.lua |  8 ++++
 game/modules/tome/data/abilities.lua         |  8 ++--
 game/modules/tome/data/damage_types.lua      | 25 ++++++++++++
 6 files changed, 115 insertions(+), 6 deletions(-)
 create mode 100644 game/engine/DamageType.lua
 create mode 100644 game/modules/tome/data/damage_types.lua

diff --git a/game/engine/DamageType.lua b/game/engine/DamageType.lua
new file mode 100644
index 0000000000..5eed8e8f27
--- /dev/null
+++ b/game/engine/DamageType.lua
@@ -0,0 +1,41 @@
+require "engine.class"
+
+--- Handles actors stats
+module(..., package.seeall, class.make)
+
+_M.dam_def = {}
+
+-- Default damage projector
+function _M.defaultProject(x, y, type, dam)
+	print("implement a projector!")
+end
+
+--- Defines new damage type
+-- Static!
+function _M:loadDefinition(file)
+	local f = loadfile(file)
+	setfenv(f, setmetatable({
+		DamageType = _M,
+		Map = require("engine.Map"),
+		defaultProjector = function(fct) self.defaultProjector = fct end,
+		newDamageType = function(t) self:newDamageType(t) end,
+	}, {__index=_G}))
+	f()
+end
+
+--- Defines one ability type(group)
+-- Static!
+function _M:newDamageType(t)
+	assert(t.name, "no ability type name")
+	assert(t.type, "no ability type type")
+	t.type = t.type:upper()
+	t.projector = t.projector or self.defaultProjector
+
+	table.insert(self.dam_def, t)
+	self[t.type] = #self.dam_def
+end
+
+function _M:get(id)
+	assert(_M.dam_def[id], "damage type "..id.." used but undefined")
+	return _M.dam_def[id]
+end
diff --git a/game/engine/interface/ActorAbilities.lua b/game/engine/interface/ActorAbilities.lua
index d989031a70..18cf5b871b 100644
--- a/game/engine/interface/ActorAbilities.lua
+++ b/game/engine/interface/ActorAbilities.lua
@@ -10,10 +10,11 @@ _M.abilities_types_def = {}
 -- Static!
 function _M:loadDefinition(file)
 	local f = loadfile(file)
-	setfenv(f, {
+	setfenv(f, setmetatable({
+		DamageType = require("engine.DamageType"),
 		newAbility = function(t) self:newAbility(t) end,
 		newAbilityType = function(t) self:newAbilityType(t) end,
-	})
+	}, {__index=_G}))
 	f()
 end
 
@@ -22,6 +23,8 @@ end
 function _M:newAbilityType(t)
 	assert(t.name, "no ability type name")
 	assert(t.type, "no ability type type")
+
+	table.insert(self.abilities_types_def, t)
 end
 
 --- Defines one ability
@@ -36,9 +39,22 @@ function _M:newAbility(t)
 	t.mode = t.mode or "activated"
 	assert(t.mode == "activated" or t.mode == "sustained", "wrong ability mode, requires either 'activated' or 'sustained'")
 	assert(t.info, "no ability info")
+
+	table.insert(self.abilities_def, t)
+	self["AB_"..t.short_name] = #self.abilities_def
 end
 
 --- Initialises stats with default values if needed
 function _M:init(t)
 	self.abilities = t.abilities or {}
 end
+
+--- Make the actor use the ability
+function _M:useAbility(id)
+	local ab = _M.abilities_def[id]
+	assert(ab, "trying to cast ability "..tostring(id).." but it is not defined")
+
+	if ab.action then
+		ab.action(self)
+	end
+end
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 13ec489dbb..a9ce7476cf 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -7,6 +7,7 @@ local DebugConsole = require "engine.DebugConsole"
 local Tooltip = require "engine.Tooltip"
 local QuitDialog = require "mod.dialogs.Quit"
 local Calendar = require "engine.Calendar"
+local DamageType = require "engine.DamageType"
 local Zone = require "engine.Zone"
 local Map = require "engine.Map"
 local Target = require "engine.Target"
@@ -28,6 +29,8 @@ function _M:init()
 end
 
 function _M:run()
+	-- Damage types
+	DamageType:loadDefinition("/data/damage_types.lua")
 	-- Actor stats
 	ActorStats:defineStat("Strength",	"str", 10, 1, 100)
 	ActorStats:defineStat("Dexterity",	"dex", 10, 1, 100)
@@ -35,6 +38,7 @@ function _M:run()
 	ActorStats:defineStat("Willpower",	"wil", 10, 1, 100)
 	ActorStats:defineStat("Cunning",	"cun", 10, 1, 100)
 	ActorStats:defineStat("Constitution",	"con", 10, 1, 100)
+	-- 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})
@@ -154,9 +158,22 @@ function _M:targetMode(v, msg)
 	end
 end
 
+function _M:getTarget()
+	if self.target.target.entity then
+		return self.target.target.entity.x, self.target.target.entity.y
+	else
+		return self.target.target.x, self.target.target.y
+	end
+end
+
 function _M:setupCommands()
 	self.key:addCommands
 	{
+		-- ability test
+		_a = function()
+			self.player:useAbility(ActorAbilities.AB_MANATHRUST)
+		end,
+
 		_LEFT = function()
 			if self.player:move(self.player.x - 1, self.player.y) then
 				self.paused = false
@@ -343,6 +360,8 @@ end
 
 --- Ask if we realy want to close, if so, save the game first
 function _M:onQuit()
+	-- HACK for quick test
+	os.exit()
 	if not self.quit_dialog then
 		self.quit_dialog = QuitDialog.new()
 		self:registerDialog(self.quit_dialog)
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index ed02750584..1b75a34d76 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -1,4 +1,5 @@
 require "engine.class"
+local DamageType = require "engine.DamageType"
 local Map = require "engine.Map"
 
 --- Interface to add ToME combat system
@@ -55,3 +56,10 @@ function _M:attackTarget(target)
 		game.logSeen(target, "%s misses %s.", self.name:capitalize(), target.name)
 	end
 end
+
+--- Project damage to a distance
+function _M:project(x, y, type, dam)
+	if dam < 0 then return end
+
+	DamageType:get(type).projector(self, x, y, type, dam)
+end
diff --git a/game/modules/tome/data/abilities.lua b/game/modules/tome/data/abilities.lua
index 520f02118e..19fca6575d 100644
--- a/game/modules/tome/data/abilities.lua
+++ b/game/modules/tome/data/abilities.lua
@@ -8,13 +8,13 @@ newAbility{
 	tactical = {
 		ATTACK = 10,
 	},
-	action = function(user)
-		user:project(game.target.x, game.target.y, Damages.MANA, 10 + user:getMag())
+	action = function(self)
+		self:project(game.target.target.x, game.target.target.y, DamageType.MANA, 10 + self:getMag())
 		return true
 	end,
 	require = { stat = { mag=12 }, },
-	info = function(user)
+	info = function(self)
 		return ([[Conjures up mana into a powerful bolt doing %d",
-		The damage is irresistible and will increase with magic stat]]):format(10 + user:getMag())
+		The damage is irresistible and will increase with magic stat]]):format(10 + self:getMag())
 	end
 }
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
new file mode 100644
index 0000000000..8d825a4620
--- /dev/null
+++ b/game/modules/tome/data/damage_types.lua
@@ -0,0 +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)
+	end
+end)
+
+newDamageType{
+	name = "mana", type = "MANA",
+}
+newDamageType{
+	name = "fire", type = "FIRE",
+}
+newDamageType{
+	name = "cold", type = "COLD",
+}
+newDamageType{
+	name = "nature", type = "NATURE",
+}
+newDamageType{
+	name = "lightning", type = "LIGHTNING",
+}
-- 
GitLab