From 0339d1c2b619deb7a04266f6f6d34887160c2db7 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Tue, 23 Apr 2013 19:02:07 +0000
Subject: [PATCH] test

git-svn-id: http://svn.net-core.org/repos/t-engine4@6644 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engines/default/engine/Entity.lua        |  3 +
 game/engines/default/engine/Zone.lua          | 12 ++-
 game/modules/tome/class/Game.lua              |  3 +
 game/modules/tome/class/GameState.lua         | 23 ++++++
 game/modules/tome/class/World.lua             | 10 +++
 .../tome/data/general/npcs/crystal.lua        |  3 +-
 .../tome/data/quests/starter-zones.lua        |  6 +-
 .../modules/tome/data/zones/lake-nur/zone.lua |  4 +-
 .../tome/data/zones/old-forest/events.lua     |  2 +-
 .../tome/data/zones/old-forest/npcs.lua       | 77 ++++++++++++++++---
 .../tome/data/zones/old-forest/zone.lua       |  7 +-
 .../tome/data/zones/rhaloren-camp/zone.lua    |  6 +-
 12 files changed, 137 insertions(+), 19 deletions(-)

diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua
index a04e737201..a7abdcf2f7 100644
--- a/game/engines/default/engine/Entity.lua
+++ b/game/engines/default/engine/Entity.lua
@@ -807,6 +807,8 @@ end
 -- @param loaded an optional table of already loaded files
 -- @usage MyEntityClass:loadList("/data/my_entities_def.lua")
 function _M:loadList(file, no_default, res, mod, loaded)
+	local Zone = require "engine.Zone"
+
 	if type(file) == "table" then
 		res = res or {}
 		for i, f in ipairs(file) do
@@ -839,6 +841,7 @@ function _M:loadList(file, no_default, res, mod, loaded)
 	loaded[file] = true
 
 	local newenv newenv = {
+		currentZone = Zone:getCurrentLoadingZone(),
 		class = self,
 		loaded = loaded,
 		resolvers = resolvers,
diff --git a/game/engines/default/engine/Zone.lua b/game/engines/default/engine/Zone.lua
index 3758ca47b2..cc350705b8 100644
--- a/game/engines/default/engine/Zone.lua
+++ b/game/engines/default/engine/Zone.lua
@@ -82,11 +82,19 @@ function _M:updateBaseLevel()
 end
 
 --- Loads basic entities lists
+local _load_zone = nil
 function _M:loadBaseLists()
+	_load_zone = self
 	self.npc_list = self.npc_class:loadList("/data/zones/"..self.short_name.."/npcs.lua")
 	self.grid_list = self.grid_class:loadList("/data/zones/"..self.short_name.."/grids.lua")
 	self.object_list = self.object_class:loadList("/data/zones/"..self.short_name.."/objects.lua")
 	self.trap_list = self.trap_class:loadList("/data/zones/"..self.short_name.."/traps.lua")
+	_load_zone = nil
+end
+
+--- Gets the currently loading zone
+function _M:getCurrentLoadingZone()
+	return _load_zone
 end
 
 --- Leaves a zone
@@ -575,6 +583,7 @@ function _M:load(dynamic)
 	if not data and not dynamic then
 		local f, err = loadfile("/data/zones/"..self.short_name.."/zone.lua")
 		if err then error(err) end
+		setfenv(f, setmetatable({self=self, short_name=self.short_name}, {__index=_G}))
 		data = f()
 		ret = false
 
@@ -586,14 +595,15 @@ function _M:load(dynamic)
 			self._no_save_fields.trap_list = true
 		end
 
+		for k, e in pairs(data) do self[k] = e end
 		self:onLoadZoneFile("/data/zones/"..self.short_name.."/")
 		if self.on_loaded then self:on_loaded() end
 	elseif not data and dynamic then
 		data = dynamic
 		ret = false
+		for k, e in pairs(data) do self[k] = e end
 		if self.on_loaded then self:on_loaded() end
 	end
-	for k, e in pairs(data) do self[k] = e end
 	return ret
 end
 
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 28409e6a94..7788c1a19b 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -667,6 +667,7 @@ function _M:changeLevelReal(lev, zone, params)
 
 		self.zone:getLevel(self, lev, old_lev, true)
 		self.visited_zones[self.zone.short_name] = true
+		world:seenZone(self.zone.short_name)
 
 		self.level.temp_shift_zone = oz
 		self.level.temp_shift_level = ol
@@ -694,6 +695,7 @@ function _M:changeLevelReal(lev, zone, params)
 		self.level = old.temp_shift_level
 
 		self.visited_zones[self.zone.short_name] = true
+		world:seenZone(self.zone.short_name)
 --		if self.level.map.closed then
 			force_recreate = true
 --		else
@@ -732,6 +734,7 @@ function _M:changeLevelReal(lev, zone, params)
 		end
 		local _, new_level = self.zone:getLevel(self, lev, old_lev)
 		self.visited_zones[self.zone.short_name] = true
+		world:seenZone(self.zone.short_name)
 
 		if new_level then
 			afternicer = self.state:startEvents()
diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua
index 10cc8829ba..67202fd50f 100644
--- a/game/modules/tome/class/GameState.lua
+++ b/game/modules/tome/class/GameState.lua
@@ -2005,3 +2005,26 @@ function _M:startEvents()
 		if game.zone.events_by_level then game.zone.assigned_events = nil end
 	end
 end
+
+function _M:alternateZone(short_name, ...)
+	if not world:hasSeenZone(short_name) and not config.settings.cheat then print("Alternate layout for "..short_name.." refused: never visited") return "DEFAULT" end
+
+	local list = {...}
+	table.insert(list, 1, {"DEFAULT", 1})
+
+	print("[ZONE] Alternate layout computing for")
+	table.print(list)
+
+	local probs = {}
+	for _, kind in ipairs(list) do
+		local p = math.ceil(100 / kind[2])
+		for i = 1, p do probs[#probs+1] = kind[1] end
+	end
+
+	return rng.table(probs)
+end
+
+function _M:alternateZoneTier1(short_name, ...)
+	if not game.state:tier1Killed(1) then return "DEFAULT" end
+	return self:alternateZone(short_name, ...)
+end
\ No newline at end of file
diff --git a/game/modules/tome/class/World.lua b/game/modules/tome/class/World.lua
index a808c68df5..9631401de6 100644
--- a/game/modules/tome/class/World.lua
+++ b/game/modules/tome/class/World.lua
@@ -63,3 +63,13 @@ function _M:gainAchievement(id, src, ...)
 	mod.class.interface.WorldAchievements.gainAchievement(self, id, src, ...)
 	if not knew and self.achieved[id] then game.party.on_death_show_achieved[#game.party.on_death_show_achieved+1] = "Gained new achievement: "..a.name end
 end
+
+function _M:seenZone(short_name)
+	self.seen_zones = self.seen_zones or {}
+	self.seen_zones[short_name] = true
+end
+
+function _M:hasSeenZone(short_name)
+	self.seen_zones = self.seen_zones or {}
+	return self.seen_zones[short_name]
+end
diff --git a/game/modules/tome/data/general/npcs/crystal.lua b/game/modules/tome/data/general/npcs/crystal.lua
index 6d4dd19a6d..0fa1aa8055 100644
--- a/game/modules/tome/data/general/npcs/crystal.lua
+++ b/game/modules/tome/data/general/npcs/crystal.lua
@@ -51,6 +51,7 @@ newEntity{ name = "wisp",
 	no_drops = true, open_door = false,
 	infravision = 10,
 	rarity = false,
+	rarity_summoned_crystal = 1,
 	lite = 4,
 	life_rating = 1, rank = 1, size_category = 1,
 	autolevel = "caster",
@@ -150,7 +151,7 @@ newEntity{ base = "BASE_NPC_CRYSTAL",
 	level_range = {10, nil}, exp_worth = 1,
 	rarity = 5,
 	resists = { [DamageType.LIGHT] = 100 },
-	summon = {{name = "wisp", number=3, hasxp=false}},
+	summon = {{name = "wisp", number=3, hasxp=false, special_rarity="rarity_summoned_crystal"}},
 	resolvers.talents{
 		[Talents.T_SUMMON]=1,
 	}
diff --git a/game/modules/tome/data/quests/starter-zones.lua b/game/modules/tome/data/quests/starter-zones.lua
index 2e79fe0f20..39f7a8324b 100644
--- a/game/modules/tome/data/quests/starter-zones.lua
+++ b/game/modules/tome/data/quests/starter-zones.lua
@@ -27,7 +27,11 @@ desc = function(self, who)
 	desc[#desc+1] = "The Sandworm Lair is to the far west of Derth, near the sea."
 	desc[#desc+1] = "The Daikara is on the eastern borders of the Thaloren forest."
 	if self:isCompleted("old-forest") then
-		desc[#desc+1] = "#LIGHT_GREEN#* You have explored the Old Forest and vanquished Wrathroot.#WHITE#"
+		if self:isCompleted("old-forest-crystal") then
+			desc[#desc+1] = "#LIGHT_GREEN#* You have explored the Old Forest and vanquished Shardskin.#WHITE#"
+		else
+			desc[#desc+1] = "#LIGHT_GREEN#* You have explored the Old Forest and vanquished Wrathroot.#WHITE#"
+		end
 	else
 		desc[#desc+1] = "#SLATE#* You must explore the Old Forest and find out what lurks there and what treasures are to be gained!#WHITE#"
 	end
diff --git a/game/modules/tome/data/zones/lake-nur/zone.lua b/game/modules/tome/data/zones/lake-nur/zone.lua
index 1fe1ed3339..e88728cb65 100644
--- a/game/modules/tome/data/zones/lake-nur/zone.lua
+++ b/game/modules/tome/data/zones/lake-nur/zone.lua
@@ -17,8 +17,8 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
-local p = rng.range(1, 3)
-local is_flooded = p == 3
+local layout = game.state:alternateZone(short_name, {"FLOODED", 2})
+local is_flooded = layout == "FLOODED"
 
 return {
 	name = "Lake of Nur",
diff --git a/game/modules/tome/data/zones/old-forest/events.lua b/game/modules/tome/data/zones/old-forest/events.lua
index 48a2b10d59..11b517713e 100644
--- a/game/modules/tome/data/zones/old-forest/events.lua
+++ b/game/modules/tome/data/zones/old-forest/events.lua
@@ -26,7 +26,7 @@ local events = { one_per_level=true,
 	{name="antimagic-bush", minor=true, percent=40},
 }
 
-if rng.percent(33) then
+if self.is_crystaline then
 	events[#events+1] = {name="crystaline-forest", minor=true, percent=200, max_repeat=3}
 end
 
diff --git a/game/modules/tome/data/zones/old-forest/npcs.lua b/game/modules/tome/data/zones/old-forest/npcs.lua
index 823a0f6078..b03a297575 100644
--- a/game/modules/tome/data/zones/old-forest/npcs.lua
+++ b/game/modules/tome/data/zones/old-forest/npcs.lua
@@ -17,18 +17,76 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
-load("/data/general/npcs/bear.lua", rarity(1))
-load("/data/general/npcs/vermin.lua", rarity(3))
-load("/data/general/npcs/canine.lua", rarity(0))
-load("/data/general/npcs/snake.lua", rarity(0))
-load("/data/general/npcs/swarm.lua", rarity(1))
-load("/data/general/npcs/plant.lua", rarity(0))
-load("/data/general/npcs/ant.lua", rarity(2))
-
-load("/data/general/npcs/all.lua", rarity(4, 35))
+if not currentZone.is_crystaline then
+	load("/data/general/npcs/bear.lua", rarity(1))
+	load("/data/general/npcs/vermin.lua", rarity(3))
+	load("/data/general/npcs/canine.lua", rarity(0))
+	load("/data/general/npcs/snake.lua", rarity(0))
+	load("/data/general/npcs/swarm.lua", rarity(1))
+	load("/data/general/npcs/plant.lua", rarity(0))
+	load("/data/general/npcs/ant.lua", rarity(2))
+
+	load("/data/general/npcs/all.lua", rarity(4, 35))
+else
+	load("/data/general/npcs/crystal.lua", rarity(0))
+	load("/data/general/npcs/bear.lua", rarity(1))
+	load("/data/general/npcs/vermin.lua", rarity(3))
+	load("/data/general/npcs/swarm.lua", rarity(1))
+	load("/data/general/npcs/plant.lua", rarity(0))
+	load("/data/general/npcs/ant.lua", rarity(2))
+
+	load("/data/general/npcs/all.lua", rarity(4, 35))
+end
 
 local Talents = require("engine.interface.ActorTalents")
 
+newEntity{ define_as = "SHARDSKIN",
+	allow_infinite_dungeon = true,
+	type = "giant", subtype = "crystal", unique = true,
+	name = "Shardskin",
+	display = "%", color=colors.VIOLET,
+	image = "npc/immovable_crystal_golden_crystal.png",
+	desc = [[This crystaline structure seems to be filled with a malovelant aura. Thourgh the crystal surface you can still see the remains of what once was a huge tree..]],
+	killer_message = "and integrated into the crystaline structure",
+	level_range = {12, nil}, exp_worth = 2,
+	max_life = 200, life_rating = 17, fixed_rating = true,
+	stats = { str=15, dex=10, cun=8, mag=20, wil=20, con=20 },
+	rank = 4,
+	size_category = 5,
+	infravision = 10,
+	instakill_immune = 1,
+	move_others=true,
+
+	combat = { dam=resolvers.levelup(27, 1, 0.8), atk=10, apr=0, dammod={mag=1.2}, sound="actions/melee_thud" },
+
+	resists = { [DamageType.NATURE] = -50 },
+
+	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
+	resolvers.equip{ {type="armor", subtype="shield", defined="WRATHROOT_SHIELD", random_art_replace={chance=75}, autoreq=true}, },
+	resolvers.drops{chance=100, nb=5, {tome_drops="boss"} },
+
+	resolvers.talents{
+		[Talents.T_ARMOUR_TRAINING]={base=4, every=5, max=15},
+		[Talents.T_STUN]={base=2, every=6, max=6},
+		[Talents.T_ICE_STORM]={base=1, every=6, max=6},
+		[Talents.T_TIDAL_WAVE]={base=1, every=6, max=6},
+		[Talents.T_FREEZE]={base=2, every=6, max=6},
+	},
+
+	autolevel = "caster",
+	ai = "tactical", ai_state = { talent_in=1, ai_move="move_astar", },
+	ai_tactic = resolvers.tactic"ranged",
+	resolvers.inscriptions(1, "rune"),
+
+	on_die = function(self, who)
+		game.state:activateBackupGuardian("SNAPROOT", 3, 50, "Have you heard, the old forest seems to have been claimed by a new evil!")
+		game.player:resolveSource():grantQuest("starter-zones")
+		game.player:resolveSource():setQuestStatus("starter-zones", engine.Quest.COMPLETED, "old-forest")
+		game.player:resolveSource():setQuestStatus("starter-zones", engine.Quest.COMPLETED, "old-forest-crystal")
+	end,
+}
+
+
 newEntity{ define_as = "WRATHROOT",
 	allow_infinite_dungeon = true,
 	type = "giant", subtype = "treant", unique = true,
@@ -79,6 +137,7 @@ newEntity{ define_as = "WRATHROOT",
 	end,
 }
 
+
 newEntity{ base = "BASE_NPC_RODENT",
 	allow_infinite_dungeon = true,
 	name = "cute little bunny", color=colors.SALMON,
diff --git a/game/modules/tome/data/zones/old-forest/zone.lua b/game/modules/tome/data/zones/old-forest/zone.lua
index a027a1a2bf..c01a9c978d 100644
--- a/game/modules/tome/data/zones/old-forest/zone.lua
+++ b/game/modules/tome/data/zones/old-forest/zone.lua
@@ -17,6 +17,10 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
+local layout = game.state:alternateZone(short_name, {"CRYSTALINE", 2})
+layout = "CRYSTALINE"
+local is_crystaline = layout == "CRYSTALINE"
+
 return {
 	name = "Old Forest",
 	level_range = {7, 16},
@@ -34,6 +38,7 @@ return {
 	ambient_music = {"Woods of Eremae.ogg", "weather/rain.ogg"},
 	min_material_level = function() return game.state:isAdvanced() and 3 or 1 end,
 	max_material_level = function() return game.state:isAdvanced() and 4 or 2 end,
+	is_crystaline = is_crystaline,
 	generator =  {
 		map = {
 			class = "engine.generator.map.Roomer",
@@ -51,7 +56,7 @@ return {
 		actor = {
 			class = "mod.class.generator.actor.Random",
 			nb_npc = {20, 30},
-			guardian = "WRATHROOT",
+			guardian = is_crystaline and "SHARDSKIN" or "WRATHROOT",
 		},
 		object = {
 			class = "engine.generator.object.Random",
diff --git a/game/modules/tome/data/zones/rhaloren-camp/zone.lua b/game/modules/tome/data/zones/rhaloren-camp/zone.lua
index 554065bcbc..9325af033d 100644
--- a/game/modules/tome/data/zones/rhaloren-camp/zone.lua
+++ b/game/modules/tome/data/zones/rhaloren-camp/zone.lua
@@ -17,8 +17,8 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
-local p = game.state:tier1Killed(1) and rng.range(1, 2) or 1
-if p == 1 then
+local layout = game.state:alternateZoneTier1(short_name, {"OVERGROUND", 1})
+if layout == "DEFAULT" then
 
 -- Underground
 return {
@@ -88,7 +88,7 @@ return {
 	end,
 }
 
-else
+elseif layout == "OVERGROUND" then
 
 -- Overground
 return {
-- 
GitLab