From 7f50022389f07449ea0476662e87a3c304645ae2 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Mon, 30 Nov 2009 17:53:02 +0000
Subject: [PATCH] plop

git-svn-id: http://svn.net-core.org/repos/t-engine4@76 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engine/Actor.lua                         |  1 +
 game/engine/Autolevel.lua                     | 13 +++++++++++
 game/engine/Game.lua                          |  7 ++++++
 game/engine/Zone.lua                          |  5 +++--
 game/engine/generator/actor/Random.lua        | 10 +++++++++
 game/engine/interface/ActorLevel.lua          | 22 ++++++++++++++++++-
 .../interface/ActorTemporaryEffects.lua       |  8 +++++++
 game/modules/tome/class/Actor.lua             | 11 ++++++++++
 game/modules/tome/class/Game.lua              |  3 +++
 .../tome/data/zones/ancient_ruins/npcs.lua    |  6 +++--
 .../tome/data/zones/ancient_ruins/zone.lua    |  3 ++-
 src/core_lua.c                                |  7 ++++--
 12 files changed, 88 insertions(+), 8 deletions(-)
 create mode 100644 game/engine/Autolevel.lua
 create mode 100644 game/engine/interface/ActorTemporaryEffects.lua

diff --git a/game/engine/Actor.lua b/game/engine/Actor.lua
index 9db31fa683..fd52d39b86 100644
--- a/game/engine/Actor.lua
+++ b/game/engine/Actor.lua
@@ -7,6 +7,7 @@ module(..., package.seeall, class.inherit(Entity))
 
 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
diff --git a/game/engine/Autolevel.lua b/game/engine/Autolevel.lua
new file mode 100644
index 0000000000..502e931378
--- /dev/null
+++ b/game/engine/Autolevel.lua
@@ -0,0 +1,13 @@
+require "engine.class"
+
+--- Handles autoleveling schemes
+-- Proably used mainly for NPCS, although it could also be used for player allies
+-- or players themselves for lazy players/modules
+module(..., package.seeall, class.make)
+
+_M.schemes = {}
+
+function _M:registerScheme(t)
+	assert(t.name, "no autolevel name")
+	assert(t.levelup, "no autolevel levelup function")
+end
diff --git a/game/engine/Game.lua b/game/engine/Game.lua
index a420dc228f..7b3d5e2327 100644
--- a/game/engine/Game.lua
+++ b/game/engine/Game.lua
@@ -65,6 +65,13 @@ function _M:display()
 	end
 end
 
+--- Returns the player
+-- Reimplement it in your module, this can just return nil if you dont want/need
+-- the engine adjusting stuff to the player or if you have many players or whatever
+function _M:getPlayer()
+	return nil
+end
+
 --- This is the "main game loop", do something here
 function _M:tick()
 end
diff --git a/game/engine/Zone.lua b/game/engine/Zone.lua
index de6bbef596..0d3ae41b79 100644
--- a/game/engine/Zone.lua
+++ b/game/engine/Zone.lua
@@ -104,6 +104,9 @@ function _M:newLevel(level_data, lev, game)
 	local level = self.level_class.new(lev, map)
 	level.start = {x=startx, y=starty}
 
+	-- Save level data
+	level.data = level_data
+
 	-- Setup the level in the game
 	game:setLevel(level)
 
@@ -118,7 +121,5 @@ function _M:newLevel(level_data, lev, game)
 		generator:generate()
 	end
 
-	-- Save level data
-	level.data = level_data
 	return level
 end
diff --git a/game/engine/generator/actor/Random.lua b/game/engine/generator/actor/Random.lua
index 89121f13e9..1719b5862a 100644
--- a/game/engine/generator/actor/Random.lua
+++ b/game/engine/generator/actor/Random.lua
@@ -7,7 +7,11 @@ function _M:init(map, level, npc_list, data)
 	engine.Generator.init(self, map)
 	self.level = level
 	self.npc_list = npc_list
+	if data.adjust_level_to_player and game:getPlayer() then
+		self.adjust_level_to_player = {base=game:getPlayer().level, min=data.adjust_level_to_player[1], max=data.adjust_level_to_player[2]}
+	end
 	self.nb_npc = data.nb_npc or {10, 20}
+	self.level_range = data.level_range or {level, level}
 end
 
 function _M:generate()
@@ -22,6 +26,12 @@ function _M:generate()
 		if tries < 100 then
 			m:move(x, y, true)
 			self.level:addEntity(m)
+
+			-- Levelup ?
+			if self.adjust_level_to_player then
+				local newlevel = self.adjust_level_to_player.base + rng.avg(self.adjust_level_to_player.min, self.adjust_level_to_player.max)
+				m:forceLevelup(newlevel)
+			end
 		end
 	end
 end
diff --git a/game/engine/interface/ActorLevel.lua b/game/engine/interface/ActorLevel.lua
index 75397eae7e..9a7af3522d 100644
--- a/game/engine/interface/ActorLevel.lua
+++ b/game/engine/interface/ActorLevel.lua
@@ -16,7 +16,12 @@ _M.exp_chart = function(level)
 end
 
 function _M:init(t)
-	self.level = t.level or 1
+	if t.level_range then
+		self.level = t.level_range[1]
+		self.max_level = t.level_range[2]
+	else
+		self.level = t.level or 1
+	end
 	self.exp = t.exp or 0
 	self.exp_worth = t.exp_worth or 1
 end
@@ -45,6 +50,9 @@ end
 function _M:gainExp(value)
 	self.exp = self.exp + value
 	while self:getExpChart(self.level + 1) and self.exp >= self:getExpChart(self.level + 1) do
+		-- At max level, if any
+		if self.max_level and self.level >= self.max_level then break end
+
 		self.level = self.level + 1
 		self.exp = self.exp - self:getExpChart(self.level)
 		self:levelup()
@@ -60,3 +68,15 @@ end
 --- Method called when leveing up, module author rewrite it to do as you please
 function _M:levelup()
 end
+
+--- Forces an actor to levelup to "lev"
+function _M:forceLevelup(lev)
+	while self.level < lev do
+		-- At max level, if any
+		if self.max_level and self.level >= self.max_level then break end
+
+		self.level = self.level + 1
+		self.exp = 0
+		self:levelup()
+	end
+end
diff --git a/game/engine/interface/ActorTemporaryEffects.lua b/game/engine/interface/ActorTemporaryEffects.lua
new file mode 100644
index 0000000000..ad439428d6
--- /dev/null
+++ b/game/engine/interface/ActorTemporaryEffects.lua
@@ -0,0 +1,8 @@
+require "engine.class"
+
+--- Handles actors temporary effects (temporary boost of a stat, ...)
+module(..., package.seeall, class.make)
+
+function _M:init(t)
+	self.tmp = {}
+end
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index a9117ac1aa..64410f97ac 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -1,5 +1,6 @@
 require "engine.class"
 require "engine.Actor"
+require "engine.interface.ActorTemporaryEffects"
 require "engine.interface.ActorLife"
 require "engine.interface.ActorLevel"
 require "engine.interface.ActorStats"
@@ -11,6 +12,7 @@ require "mod.class.interface.Combat"
 module(..., package.seeall, class.inherit(
 	-- a ToME actor is a complex beast it uses may inetrfaces
 	engine.Actor,
+	engine.interface.ActorTemporaryEffects,
 	engine.interface.ActorLife,
 	engine.interface.ActorLevel,
 	engine.interface.ActorStats,
@@ -22,6 +24,7 @@ module(..., package.seeall, class.inherit(
 
 function _M:init(t)
 	engine.Actor.init(self, t)
+	engine.interface.ActorTemporaryEffects.init(self, t)
 	engine.interface.ActorLife.init(self, t)
 	engine.interface.ActorLevel.init(self, t)
 	engine.interface.ActorStats.init(self, t)
@@ -75,6 +78,14 @@ function _M:levelup()
 	self.max_life = self.max_life + 7
 	self:incMaxMana(7)
 	self:incMaxStamina(7)
+	-- Healp up on new level
+	self.life = self.max_life
+	self.mana = self.max_mana
+	self.stamina = self.man_stamina
+
+	-- Auto levelup ?
+	if self.autolevel then
+	end
 end
 
 --- Notifies a change of stat value
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index fb8ffa946f..269233a3e7 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -113,6 +113,9 @@ function _M:changeLevel(lev)
 	self.level:addEntity(self.player)
 end
 
+function _M:getPlayer()
+	return self.player
+end
 
 function _M:tick()
 	if self.target.target.entity and not self.level:hasEntity(self.target.target.entity) then self.target.target.entity = false end
diff --git a/game/modules/tome/data/zones/ancient_ruins/npcs.lua b/game/modules/tome/data/zones/ancient_ruins/npcs.lua
index b36ca90eb6..d974b1cc44 100644
--- a/game/modules/tome/data/zones/ancient_ruins/npcs.lua
+++ b/game/modules/tome/data/zones/ancient_ruins/npcs.lua
@@ -3,7 +3,8 @@ return {
 {
 	name = "dragon of death",
 	display = "D", color_r=255,
-	level = 10, exp_worth = 1,
+	level_range = {1, 10}, exp_worth = 1,
+	autolevel = "warrior",
 	max_life = 20,
 	max_mana = 1000,
 	energy = { mod=0.5 },
@@ -15,7 +16,8 @@ return {
 	name = "baby dragon",
 	display = "d", color_r=128,
 	faction = "poorsods",
-	level = 10, exp_worth = 1,
+	level_range = {1, 4}, exp_worth = 1,
+	autolevel = "caster",
 	max_life = 30,
 	max_mana = 1000,
 	energy = { mod=0.3 },
diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua
index e253252da9..8032664906 100644
--- a/game/modules/tome/data/zones/ancient_ruins/zone.lua
+++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua
@@ -17,7 +17,8 @@ return {
 		actor = {
 			class = "engine.generator.actor.Random",
 			nb_npc = {400, 400},
-			levelup = {5, 10},
+			level_range = {5, 10},
+			adjust_level_to_player = {-2, 2},
 		},
 	}
 }
diff --git a/src/core_lua.c b/src/core_lua.c
index 8ecdbf6df6..a2c8fcb379 100644
--- a/src/core_lua.c
+++ b/src/core_lua.c
@@ -557,8 +557,11 @@ static int rng_avg(lua_State *L)
 	int i;
 	if (lua_isnumber(L, 3)) nb = luaL_checknumber(L, 3);
 	for (i = 0; i < nb; i++)
-		res += x + rand_div(1 + y - x);
-	lua_pushnumber(L, res / nb);
+	{
+		int r = x + rand_div(1 + y - x);
+		res += r;
+	}
+	lua_pushnumber(L, res / (double)nb);
 	return 1;
 }
 
-- 
GitLab