From 84333225d0907a757f9fe63e47422432d596d9ff Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Tue, 24 Nov 2009 18:13:11 +0000
Subject: [PATCH]                    factions and map tactical display

git-svn-id: http://svn.net-core.org/repos/t-engine4@34 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/data/gfx/tactical_enemy.png              | Bin 0 -> 214 bytes
 game/data/gfx/tactical_friend.png             | Bin 0 -> 231 bytes
 game/data/gfx/tactical_neutral.png            | Bin 0 -> 213 bytes
 game/engine/Actor.lua                         |   9 +++++
 game/engine/Faction.lua                       |  32 ++++++++++++++++++
 game/engine/Map.lua                           |  32 ++++++++++++------
 game/modules/tome/class/Game.lua              |   1 +
 game/modules/tome/class/Player.lua            |   2 +-
 game/modules/tome/class/interface/Combat.lua  |   1 +
 .../tome/data/zones/ancient_ruins/npcs.lua    |   1 +
 src/core_lua.c                                |  24 +++++++------
 11 files changed, 81 insertions(+), 21 deletions(-)
 create mode 100644 game/data/gfx/tactical_enemy.png
 create mode 100644 game/data/gfx/tactical_friend.png
 create mode 100644 game/data/gfx/tactical_neutral.png
 create mode 100644 game/engine/Faction.lua

diff --git a/game/data/gfx/tactical_enemy.png b/game/data/gfx/tactical_enemy.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a89b8e720e6358785254a67217be21faf9b844b
GIT binary patch
literal 214
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@
z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPggaZV4eqrqB9)p+F(Y64!_l=ltB<
z)VvY~=c3falGGH1^30M91$R&1fbd2>aiAhYPZ!4!i_^(}&L8+NpOMqR$iTqp0pp8T
zhO8b8|0N~<85;(0XqY94^fV<-nj)!r_8h|wd;b4b`(G~sYG&|s^>bP0l+XkKf?GZ5

literal 0
HcmV?d00001

diff --git a/game/data/gfx/tactical_friend.png b/game/data/gfx/tactical_friend.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb823e23b85bc9f92941279f3502a725385ab4aa
GIT binary patch
literal 231
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@
z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPggaZV4fFoyx^3GC(2864!_l=ltB<
z)VvY~=c3falGGH1^30M91$R&1fbd2>aiAh6PZ!4!i_>o}FBD`@;Bme<pYPJ&=SdS4
z1R5UlWmRsvzQZN+%o4S}qMB;k8Sa@fBCHFX;%e?+diy*l=kSj3`%SBg-@Q~5+IrRA
RZzIq&22WQ%mvv4FO#q!wN!b7Z

literal 0
HcmV?d00001

diff --git a/game/data/gfx/tactical_neutral.png b/game/data/gfx/tactical_neutral.png
new file mode 100644
index 0000000000000000000000000000000000000000..72f99400ace9541b1dd3edb7a37fd5b829df8686
GIT binary patch
literal 213
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@
z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPggaZV4eq(SkqRlYl~!C9V-A&iT2y
zsd*&~&PAz-C8;S2<(VZJ3hti10pX2&;y^_Po-U3d7N?U_W_<o{&urw8n38gU{le8`
yt_cj!{`^0G#6fYvjfOx2t~Sr0v?V6i%nT2OMVHTI|M(xMm%-E3&t;ucLK6U`JwGr2

literal 0
HcmV?d00001

diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua
index 37d2c82c8a..980bd7324c 100644
--- a/game/engine/Actor.lua
+++ b/game/engine/Actor.lua
@@ -1,6 +1,7 @@
 require "engine.class"
 local Entity = require "engine.Entity"
 local Map = require "engine.Map"
+local Faction = require "engine.Faction"
 
 module(..., package.seeall, class.inherit(Entity))
 
@@ -8,9 +9,11 @@ function _M:init(t)
 	t = t or {}
 	self.name = t.name or "unknown npc"
 	self.level = t.level or 1
+	self.sight = t.sight or 20
 	self.energy = t.energy or { value=0, mod=1 }
 	self.energy.value = self.energy.value or 0
 	self.energy.mod = self.energy.mod or 0
+	self.faction = t.faction or "enemies"
 	Entity.init(self, t)
 end
 
@@ -45,3 +48,9 @@ function _M:useEnergy(val)
 	val = val or game.energy_to_act
 	self.energy.value = self.energy.value - val
 end
+
+--- What is our reaction toward the target
+-- See Faction:factionReaction()
+function _M:reactionToward(target)
+	return Faction:factionReaction(self.faction, target.faction)
+end
diff --git a/game/engine/Faction.lua b/game/engine/Faction.lua
new file mode 100644
index 0000000000..11ef3f51b5
--- /dev/null
+++ b/game/engine/Faction.lua
@@ -0,0 +1,32 @@
+require "engine.class"
+
+--- Defines factions
+module(..., package.seeall, class.make)
+
+_M.factions = {}
+
+--- Adds a new faction
+-- Static method
+function _M:add(t)
+	assert(t.name, "no faction name")
+	assert(t.short_name, "no faction short_name")
+	t.reaction = t.reaction or {}
+	self.factions[t.short_name] = t
+end
+
+
+--- Returns the status of faction f1 toward f2
+-- @param f1 the source faction
+-- @param f2 the target faction
+-- @return a numerical value representing the reaction, 0 is neutral, <0 is aggressive, >0 is friendly
+function _M:factionReaction(f1, f2)
+	-- Faction always like itself
+	if f1 == f2 then return 100 end
+	if not self.factions[f1] then return 0 end
+	return self.factions[f1].reaction[f2] or 0
+end
+
+-- Add a few default factions
+_M:add{ short_name="players", name="Players", reaction={enemies=-100} }
+_M:add{ short_name="enemies", name="Enemies", reaction={player=-100,poorsods=-100} }
+_M:add{ short_name="poorsods", name="Poor Sods", reaction={} }
diff --git a/game/engine/Map.lua b/game/engine/Map.lua
index 5da2febce9..285943137a 100644
--- a/game/engine/Map.lua
+++ b/game/engine/Map.lua
@@ -1,6 +1,7 @@
 require "engine.class"
 local Entity = require "engine.Entity"
 local Tiles = require "engine.Tiles"
+local Faction = require "engine.Faction"
 
 --- Represents a level map, handles display and various low level map work
 module(..., package.seeall, class.make)
@@ -29,6 +30,15 @@ function _M:setViewPort(w, h, tile_w, tile_h)
 	self.tile_w, self.tile_h = tile_w, tile_h
 end
 
+--- Defines the faction of the person seeing the map
+-- Usualy this will be the player's faction. If you do not want to use tactical display, dont use it
+function _M:setViewerFaction(faction, friend, neutral, enemy)
+	self.view_faction = faction
+	self.faction_friend = "tactical_friend.png"
+	self.faction_neutral = "tactical_neutral.png"
+	self.faction_enemy = "tactical_enemy.png"
+end
+
 --- Creates a map
 -- @param w width (in grids)
 -- @param h height (in grids)
@@ -77,11 +87,6 @@ function _M:fov(x, y, d)
 		for i = 0, self.w * self.h - 1 do self.seens[i] = nil end
 	end
 	self._fov(x, y, d)
-
-	-- Also seen the source itself
-	self.seens(x, y, true)
-	self.lites(x, y, true)
-	self.remembers(x, y, true)
 end
 
 --- Runs the FOV algorithm on the map, ligthing grids to allow rememberance
@@ -95,11 +100,6 @@ function _M:fovLite(x, y, d)
 		for i = 0, self.w * self.h - 1 do self.seens[i] = nil end
 		self._fov_lite(x, y, d)
 	end
-
-	-- Also seen the source itself
-	self.seens(x, y, true)
-	self.lites(x, y, true)
-	self.remembers(x, y, true)
 end
 
 --- Sets/gets a value from the map
@@ -150,6 +150,7 @@ function _M:display()
 		local e, si
 		local z
 		local order
+		local friend
 		for i = 0, self.w - 1 do for j = 0, self.h - 1 do
 			e, si = nil, 1
 			z = i + j * self.w
@@ -163,6 +164,17 @@ function _M:display()
 					elseif self.remembers[z] then
 						self.surface:merge(self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3, e.image), i * self.tile_w, j * self.tile_h)
 					end
+					-- Tactical overlay ?
+					if self.view_faction and e.faction then
+						friend = Faction:factionReaction(self.view_faction, e.faction)
+						if friend > 0 then
+							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_friend), i * self.tile_w, j * self.tile_h)
+						elseif friend < 0 then
+							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_enemy), i * self.tile_w, j * self.tile_h)
+						else
+							self.surface:merge(self.tiles:get(nil, 0,0,0, 0,0,0, self.faction_neutral), i * self.tile_w, j * self.tile_h)
+						end
+					end
 				end
 			end
 		end end
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 352acacfd5..b42b0f37b5 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -22,6 +22,7 @@ function _M:run()
 
 	Zone:setup{npc_class="mod.class.NPC", grid_class="mod.class.Grid", object_class="engine.Entity"}
 	Map:setViewPort(self.w, math.floor(self.h * 0.80), 16, 16)
+	Map:setViewerFaction("players")
 
 	self.zone = Zone.new("ancient_ruins")
 
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 96187d5245..fd6f353415 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -5,7 +5,7 @@ module(..., package.seeall, class.inherit(mod.class.Actor))
 
 function _M:init(t)
 	mod.class.Actor.init(self, t)
-
+	self.faction = "players"
 	self.combat = { dam=10, atk=4, apr=2, def=6, armor=4 }
 end
 
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 77c09ca209..d331987361 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -24,6 +24,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)
 	else
diff --git a/game/modules/tome/data/zones/ancient_ruins/npcs.lua b/game/modules/tome/data/zones/ancient_ruins/npcs.lua
index 7065f30bbc..3044269494 100644
--- a/game/modules/tome/data/zones/ancient_ruins/npcs.lua
+++ b/game/modules/tome/data/zones/ancient_ruins/npcs.lua
@@ -14,6 +14,7 @@ return {
 {
 	name = "baby dragon",
 	display = "d", color_r=128,
+	faction = "poorsods",
 	level = 1, exp_worth = 1,
 	life = 30,
 	mana = 1000,
diff --git a/src/core_lua.c b/src/core_lua.c
index 7ae5fbbe68..df52d60252 100644
--- a/src/core_lua.c
+++ b/src/core_lua.c
@@ -64,7 +64,6 @@ static int lua_new_fov(lua_State *L)
 	fov->opaque_ref = opaque_ref;
 	fov->map_ref = map_ref;
 	fov_settings_init(&(fov->fov_settings));
-	fov_settings_set_shape(&(fov->fov_settings), FOV_SHAPE_CIRCLE);
 	fov_settings_set_opacity_test_function(&(fov->fov_settings), map_opaque);
 	fov_settings_set_apply_lighting_function(&(fov->fov_settings), map_seen);
 
@@ -90,6 +89,7 @@ static int lua_fov(lua_State *L)
 	int radius = luaL_checknumber(L, 4);
 
 	fov_circle(&(fov->fov_settings), fov, NULL, x, y, radius+1);
+	map_seen(fov, x, y, 0, 0, radius, NULL);
 	return 0;
 }
 
@@ -98,14 +98,16 @@ static int lua_fov_calc_circle(lua_State *L)
 	int x = luaL_checknumber(L, 1);
 	int y = luaL_checknumber(L, 2);
 	int radius = luaL_checknumber(L, 3);
-	int map_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-	int apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-	int opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-
 	struct lua_fov fov;
+	fov.map_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+	fov.apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+	fov.opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
 
 	fov_settings_init(&(fov.fov_settings));
+	fov_settings_set_opacity_test_function(&(fov.fov_settings), map_opaque);
+	fov_settings_set_apply_lighting_function(&(fov.fov_settings), map_seen);
 	fov_circle(&(fov.fov_settings), &fov, NULL, x, y, radius+1);
+	map_seen(&fov, x, y, 0, 0, radius, NULL);
 	fov_settings_free(&(fov.fov_settings));
 
 	luaL_unref(L, LUA_REGISTRYINDEX, fov.apply_ref);
@@ -122,9 +124,10 @@ static int lua_fov_calc_beam(lua_State *L)
 	int radius = luaL_checknumber(L, 3);
 	int direction = luaL_checknumber(L, 4);
 	float angle = luaL_checknumber(L, 5);
-	int map_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-	int apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-	int opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+	struct lua_fov fov;
+	fov.map_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+	fov.apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+	fov.opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
 	int dir = 0;
 
 	switch (direction)
@@ -139,10 +142,11 @@ static int lua_fov_calc_beam(lua_State *L)
 	case 9: dir = FOV_NORTHEAST; break;
 	}
 
-	struct lua_fov fov;
-
 	fov_settings_init(&(fov.fov_settings));
+	fov_settings_set_opacity_test_function(&(fov.fov_settings), map_opaque);
+	fov_settings_set_apply_lighting_function(&(fov.fov_settings), map_seen);
 	fov_beam(&(fov.fov_settings), &fov, NULL, x, y, radius+1, dir, angle);
+	map_seen(&fov, x, y, 0, 0, radius, NULL);
 	fov_settings_free(&(fov.fov_settings));
 
 	luaL_unref(L, LUA_REGISTRYINDEX, fov.apply_ref);
-- 
GitLab