From 7dff2e9f60a0fa188e572ba24d4bab9c4f8d1a8a Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Sun, 11 Jul 2010 19:07:29 +0000
Subject: [PATCH] gollllemmmmm

git-svn-id: http://svn.net-core.org/repos/t-engine4@901 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/modules/tome/class/Actor.lua             |  6 --
 .../tome/data/chats/alchemist-golem.lua       | 64 +++++++++++++++
 .../talents/spells/advanced-golemancy.lua     | 34 ++++----
 .../tome/data/talents/spells/golemancy.lua    | 82 +++++++++++--------
 game/modules/tome/data/timed_effects.lua      | 13 +--
 .../tome/data/zones/sandworm-lair/npcs.lua    |  1 +
 6 files changed, 139 insertions(+), 61 deletions(-)
 create mode 100644 game/modules/tome/data/chats/alchemist-golem.lua

diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index dfcfbbaa8b..8c5e4a5298 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -650,12 +650,6 @@ function _M:levelup()
 		rating = rng.range(math.floor(self.life_rating * 0.5), math.floor(self.life_rating * 1.5))
 	end
 	self.max_life = self.max_life + math.max(rating + self:getRankLifeAdjust(), 1)
-		+ (self:knowTalent(self.T_IMPROVED_HEALTH_I) and 1 or 0)
-		+ (self:knowTalent(self.T_IMPROVED_HEALTH_II) and 1 or 0)
-		+ (self:knowTalent(self.T_IMPROVED_HEALTH_III) and 1 or 0)
-		- (self:knowTalent(self.T_DECREASED_HEALTH_I) and 1 or 0)
-		- (self:knowTalent(self.T_DECREASED_HEALTH_II) and 1 or 0)
-		- (self:knowTalent(self.T_DECREASED_HEALTH_III) and 1 or 0)
 
 	self:incMaxMana(self.mana_rating)
 	self:incMaxStamina(self.stamina_rating)
diff --git a/game/modules/tome/data/chats/alchemist-golem.lua b/game/modules/tome/data/chats/alchemist-golem.lua
new file mode 100644
index 0000000000..e6b61c6497
--- /dev/null
+++ b/game/modules/tome/data/chats/alchemist-golem.lua
@@ -0,0 +1,64 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+local change_weapon = function(npc, player)
+	player:showEquipInven("Select a two handed weapon for your golem.", function(o) return o.type == "weapon" and o.twohanded end, function(o, inven, item)
+		player:removeObject(inven, item, true)
+		local ro = npc:wearObject(o, true, true)
+		if ro then
+			if type(ro) == "table" then player:addObject(inven, ro) end
+		elseif not ro then
+			player:addObject(inven, o)
+		else
+			game.logPlayer(player, "Your golem equips: %s.", o:getName{do_color=true, no_count=true})
+		end
+		player:sortInven()
+		player:useEnergy()
+		return true
+	end)
+end
+
+local change_armour = function(npc, player)
+	player:showEquipInven("Select a two handed armour for your golem.", function(o) return o.type == "armor" and o.slot == "BODY" end, function(o, inven, item)
+		player:removeObject(inven, item, true)
+		local ro = npc:wearObject(o, true, true)
+		if ro then
+			if type(ro) == "table" then player:addObject(inven, ro) end
+		elseif not ro then
+			player:addObject(inven, o)
+		else
+			game.logPlayer(player, "Your golem equips: %s.", o:getName{do_color=true, no_count=true})
+		end
+		player:sortInven()
+		player:useEnergy()
+		return true
+	end)
+end
+
+newChat{ id="welcome",
+	text = [[#LIGHT_GREEN#*The golem talks in a monotonous voice*#WHITE#
+Yes master.]],
+	answers = {
+		{"I want to change your weapon.", action=change_weapon},
+		{"I want to change your armour.", action=change_armour},
+		{"Nothing, let's go."},
+	}
+}
+
+return "welcome"
diff --git a/game/modules/tome/data/talents/spells/advanced-golemancy.lua b/game/modules/tome/data/talents/spells/advanced-golemancy.lua
index 4fcac4eee5..2d7ad2f196 100644
--- a/game/modules/tome/data/talents/spells/advanced-golemancy.lua
+++ b/game/modules/tome/data/talents/spells/advanced-golemancy.lua
@@ -74,36 +74,37 @@ newTalent{
 	range = 10,
 	mana = 5,
 	action = function(self, t)
-		if not game.level:hasEntity(self.alchemy_golem) then
+		local mover, golem = getGolem(self)
+		if not golem then
 			game.logPlayer(self, "Your golem is currently inactive.")
 			return
 		end
 
 		local tg = {type="ball", radius=2, range=self:getTalentRange(t)}
-		game.target.source_actor = self.alchemy_golem
+		game.target.source_actor = mover
 		local x, y, target = self:getTarget(tg)
 		game.target.source_actor = self
 		if not x or not y or not target then return nil end
-		if math.floor(core.fov.distance(self.alchemy_golem.x, self.alchemy_golem.y, x, y)) > self:getTalentRange(t) then return nil end
+		if math.floor(core.fov.distance(mover.x, mover.y, x, y)) > self:getTalentRange(t) then return nil end
 
-		local l = line.new(self.alchemy_golem.x, self.alchemy_golem.y, x, y)
+		local l = line.new(mover.x, mover.y, x, y)
 		local lx, ly = l()
-		local tx, ty = self.alchemy_golem.x, self.alchemy_golem.y
+		local tx, ty = mover.x, mover.y
 		lx, ly = l()
 		while lx and ly do
-			if game.level.map:checkAllEntities(lx, ly, "block_move", self.alchemy_golem) then break end
+			if game.level.map:checkAllEntities(lx, ly, "block_move", mover) then break end
 			tx, ty = lx, ly
 			lx, ly = l()
 		end
 
-		self.alchemy_golem:move(tx, ty, true)
+		mover:move(tx, ty, true)
 
 		-- Attack & daze
-		self.alchemy_golem:project({type="ball", radius=2, friendlyfire=false}, tx, ty, function(xx, yy)
+		golem:project({type="ball", radius=2, friendlyfire=false}, tx, ty, function(xx, yy)
 			local target = game.level.map(xx, yy, Map.ACTOR)
-			if target and self.alchemy_golem:attackTarget(target, nil, self.alchemy_golem:combatTalentWeaponDamage(t, 0.4, 1.1), true) then
-				if target:checkHit(self.alchemy_golem:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 10 - self.alchemy_golem:getTalentLevel(t) / 2) and target:canBe("stun") then
-					target:setEffect(target.EFF_DAZED, 2 + self.alchemy_golem:getTalentLevel(t), {})
+			if target and golem:attackTarget(target, nil, golem:combatTalentWeaponDamage(t, 0.4, 1.1), true) then
+				if target:checkHit(golem:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 10 - self:getTalentLevel(t) / 2) and target:canBe("stun") then
+					target:setEffect(target.EFF_DAZED, 2 + self:getTalentLevel(t), {})
 				else
 					game.logSeen(target, "%s resists the dazing blow!", target.name:capitalize())
 				end
@@ -114,7 +115,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		return ([[Your golem rushes to the target, pounding the area, dazing all for %d turns and doing %d%% damage.]]):
-		format(2 + self.alchemy_golem:getTalentLevel(t), 100 * self:combatTalentWeaponDamage(t, 0.4, 1.1))
+		format(2 + self:getTalentLevel(t), 100 * self:combatTalentWeaponDamage(t, 0.4, 1.1))
 	end,
 }
 
@@ -124,13 +125,14 @@ newTalent{
 	require = spells_req4,
 	points = 5,
 	mana = 40,
-	cooldown = 30,
+	cooldown = 60,
 	action = function(self, t)
-		if not game.level:hasEntity(self.alchemy_golem) then
+		local mover, golem = getGolem(self)
+		if not golem then
 			game.logPlayer(self, "Your golem is currently inactive.")
 			return
 		end
-		if math.floor(core.fov.distance(self.x, self.y, self.alchemy_golem.x, self.alchemy_golem.y)) > 1 then
+		if math.floor(core.fov.distance(self.x, self.y, golem.x, golem.y)) > 1 then
 			game.logPlayer(self, "You are too far away from your golem.")
 			return
 		end
@@ -138,7 +140,7 @@ newTalent{
 		-- Create the mount item
 		local mount = game.zone:makeEntityByName(game.level, "object", "ALCHEMIST_GOLEM_MOUNT")
 		if not mount then return end
-		mount.mount.actor = self.alchemy_golem
+		mount.mount.actor = golem
 		self:setEffect(self.EFF_GOLEM_MOUNT, 5 + math.ceil(self:getTalentLevel(t) * 4), {mount=mount})
 
 		return true
diff --git a/game/modules/tome/data/talents/spells/golemancy.lua b/game/modules/tome/data/talents/spells/golemancy.lua
index 436314b652..be3394b2bf 100644
--- a/game/modules/tome/data/talents/spells/golemancy.lua
+++ b/game/modules/tome/data/talents/spells/golemancy.lua
@@ -18,6 +18,14 @@
 -- darkgod@te4.org
 local Chat = require "engine.Chat"
 
+function getGolem(self)
+	if game.level:hasEntity(self.alchemy_golem) then
+		return self.alchemy_golem, self.alchemy_golem
+	elseif self:hasEffect(self.EFF_GOLEM_MOUNT) then
+		return self, self.alchemy_golem
+	end
+end
+
 local function makeGolem()
 	return require("mod.class.NPC").new{
 		type = "construct", subtype = "golem",
@@ -106,7 +114,7 @@ newTalent{
 				return
 			end
 			for i = 1, 2 do self:removeObject(self:getInven("QUIVER"), 1) end
-			self.alchemy_golem:heal(self:combatTalentSpellDamage(t, 15, 150, (ammo.alchemist_power + self:combatSpellpower()) / 2))
+			self.alchemy_golem:heal(self:combatTalentSpellDamage(t, 15, 350, (ammo.alchemist_power + self:combatSpellpower()) / 2))
 
 		-- resurrect the golem
 		else
@@ -154,20 +162,21 @@ newTalent{
 	range = 10,
 	mana = 5,
 	action = function(self, t)
-		if not game.level:hasEntity(self.alchemy_golem) then
+		local mover, golem = getGolem(self)
+		if not golem then
 			game.logPlayer(self, "Your golem is currently inactive.")
 			return
 		end
 
 		local tg = {type="hit", range=self:getTalentRange(t)}
-		game.target.source_actor = self.alchemy_golem
+		game.target.source_actor = mover
 		local x, y, target = self:getTarget(tg)
 		game.target.source_actor = self
-		if not x or not y or not target then print(1) return nil end
-		if math.floor(core.fov.distance(self.alchemy_golem.x, self.alchemy_golem.y, x, y)) > self:getTalentRange(t) then return nil end
+		if not x or not y or not target then return nil end
+		if math.floor(core.fov.distance(mover.x, mover.y, x, y)) > self:getTalentRange(t) then return nil end
 
-		self.alchemy_golem:setTarget(target)
-		target:setTarget(self.alchemy_golem)
+		mover:setTarget(target)
+		target:setTarget(mover)
 		game.logPlayer(self, "Your golem provokes %s to attack it.", target.name:capitalize())
 
 		return true
@@ -186,40 +195,41 @@ newTalent{
 	range = 10,
 	mana = 5,
 	action = function(self, t)
-		if not game.level:hasEntity(self.alchemy_golem) then
+		local mover, golem = getGolem(self)
+		if not golem then
 			game.logPlayer(self, "Your golem is currently inactive.")
 			return
 		end
 
 		local tg = {type="hit", range=self:getTalentRange(t)}
-		game.target.source_actor = self.alchemy_golem
+		game.target.source_actor = mover
 		local x, y, target = self:getTarget(tg)
 		game.target.source_actor = self
 		if not x or not y or not target then return nil end
-		if math.floor(core.fov.distance(self.alchemy_golem.x, self.alchemy_golem.y, x, y)) > self:getTalentRange(t) then return nil end
+		if math.floor(core.fov.distance(mover.x, mover.y, x, y)) > self:getTalentRange(t) then return nil end
 
-		self.alchemy_golem:setTarget(target)
+		mover:setTarget(target)
 
-		local l = line.new(self.alchemy_golem.x, self.alchemy_golem.y, x, y)
+		local l = line.new(mover.x, mover.y, x, y)
 		local lx, ly = l()
-		local tx, ty = self.alchemy_golem.x, self.alchemy_golem.y
+		local tx, ty = mover.x, mover.y
 		lx, ly = l()
 		while lx and ly do
-			if game.level.map:checkAllEntities(lx, ly, "block_move", self.alchemy_golem) then break end
+			if game.level.map:checkAllEntities(lx, ly, "block_move", mover) then break end
 			tx, ty = lx, ly
 			lx, ly = l()
 		end
 
-		self.alchemy_golem:move(tx, ty, true)
+		mover:move(tx, ty, true)
 
 		-- Attack ?
-		if math.floor(core.fov.distance(self.alchemy_golem.x, self.alchemy_golem.y, x, y)) > 1 then return true end
-		local hit = self.alchemy_golem:attackTarget(target, nil, self.alchemy_golem:combatTalentWeaponDamage(t, 0.8, 1.6), true)
+		if math.floor(core.fov.distance(mover.x, mover.y, x, y)) > 1 then return true end
+		local hit = golem:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 0.8, 1.6), true)
 
 		-- Try to knockback !
 		if hit then
-			if target:checkHit(self.alchemy_golem:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 5 - self.alchemy_golem:getTalentLevel(t) / 2) and target:canBe("knockback") then
-				target:knockback(self.alchemy_golem.x, self.alchemy_golem.y, 3)
+			if target:checkHit(golem:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 5 - self:getTalentLevel(t) / 2) and target:canBe("knockback") then
+				target:knockback(mover.x, mover.y, 3)
 			else
 				game.logSeen(target, "%s resists the knockback!", target.name:capitalize())
 			end
@@ -241,40 +251,41 @@ newTalent{
 	range = 10,
 	mana = 5,
 	action = function(self, t)
-		if not game.level:hasEntity(self.alchemy_golem) then
+		local mover, golem = getGolem(self)
+		if not golem then
 			game.logPlayer(self, "Your golem is currently inactive.")
 			return
 		end
 
 		local tg = {type="hit", range=self:getTalentRange(t)}
-		game.target.source_actor = self.alchemy_golem
+		game.target.source_actor = mover
 		local x, y, target = self:getTarget(tg)
 		game.target.source_actor = self
 		if not x or not y or not target then return nil end
-		if math.floor(core.fov.distance(self.alchemy_golem.x, self.alchemy_golem.y, x, y)) > self:getTalentRange(t) then return nil end
+		if math.floor(core.fov.distance(mover.x, mover.y, x, y)) > self:getTalentRange(t) then return nil end
 
-		self.alchemy_golem:setTarget(target)
+		mover:setTarget(target)
 
-		local l = line.new(self.alchemy_golem.x, self.alchemy_golem.y, x, y)
+		local l = line.new(mover.x, mover.y, x, y)
 		local lx, ly = l()
-		local tx, ty = self.alchemy_golem.x, self.alchemy_golem.y
+		local tx, ty = mover.x, mover.y
 		lx, ly = l()
 		while lx and ly do
-			if game.level.map:checkAllEntities(lx, ly, "block_move", self.alchemy_golem) then break end
+			if game.level.map:checkAllEntities(lx, ly, "block_move", mover) then break end
 			tx, ty = lx, ly
 			lx, ly = l()
 		end
 
-		self.alchemy_golem:move(tx, ty, true)
+		mover:move(tx, ty, true)
 
 		-- Attack ?
-		if math.floor(core.fov.distance(self.alchemy_golem.x, self.alchemy_golem.y, x, y)) > 1 then return true end
-		local hit = self.alchemy_golem:attackTarget(target, nil, self.alchemy_golem:combatTalentWeaponDamage(t, 0.8, 1.6), true)
+		if math.floor(core.fov.distance(mover.x, mover.y, x, y)) > 1 then return true end
+		local hit = golem:attackTarget(target, nil, self:combatTalentWeaponDamage(t, 0.8, 1.6), true)
 
 		-- Try to knockback !
 		if hit then
-			if target:checkHit(self.alchemy_golem:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 10 - self.alchemy_golem:getTalentLevel(t) / 2) and target:canBe("stun") then
-				target:setEffect(target.EFF_PINNED, 2 + self.alchemy_golem:getTalentLevel(t), {})
+			if target:checkHit(golem:combatAttackStr(), target:combatPhysicalResist(), 0, 95, 10 - self:getTalentLevel(t) / 2) and target:canBe("stun") then
+				target:setEffect(target.EFF_PINNED, 2 + self:getTalentLevel(t), {})
 			else
 				game.logSeen(target, "%s resists the crushing!", target.name:capitalize())
 			end
@@ -295,7 +306,8 @@ newTalent{
 	mana = 10,
 	cooldown = 20,
 	action = function(self, t)
-		if not game.level:hasEntity(self.alchemy_golem) then
+		local mover, golem = getGolem(self)
+		if not golem then
 			game.logPlayer(self, "Your golem is currently inactive.")
 			return
 		end
@@ -307,8 +319,10 @@ newTalent{
 			return
 		end
 
-		self.alchemy_golem:setEffect(self.alchemy_golem.EFF_MIGHTY_BLOWS, 5, {power=self:combatTalentSpellDamage(t, 15, 50)})
-		self.alchemy_golem:move(x, y, true)
+		golem:setEffect(golem.EFF_MIGHTY_BLOWS, 5, {power=self:combatTalentSpellDamage(t, 15, 50)})
+		if golem == mover then
+			golem:move(x, y, true)
+		end
 		game:playSoundNear(self, "talents/arcane")
 		return true
 	end,
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index 290b973bea..fc23e318e7 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -794,11 +794,14 @@ newEffect{
 	end,
 	deactivate = function(self, eff)
 		if self:removeObject(self.INVEN_MOUNT, 1, true) then
-			-- Find space
-			local x, y = util.findFreeGrid(self.x, self.y, 10, true, {[engine.Map.ACTOR]=true})
-			if x then
-				eff.mount.mount.actor:move(x, y, true)
-				game.level:addEntity(eff.mount.mount.actor)
+			-- Only unmount if dead
+			if not eff.mount.mount.actor.dead then
+				-- Find space
+				local x, y = util.findFreeGrid(self.x, self.y, 10, true, {[engine.Map.ACTOR]=true})
+				if x then
+					eff.mount.mount.actor:move(x, y, true)
+					game.level:addEntity(eff.mount.mount.actor)
+				end
 			end
 		end
 	end,
diff --git a/game/modules/tome/data/zones/sandworm-lair/npcs.lua b/game/modules/tome/data/zones/sandworm-lair/npcs.lua
index 50ed9fa058..e3a5ebef89 100644
--- a/game/modules/tome/data/zones/sandworm-lair/npcs.lua
+++ b/game/modules/tome/data/zones/sandworm-lair/npcs.lua
@@ -41,6 +41,7 @@ newEntity{ define_as = "SANDWORM_TUNNELER",
 	invulnerable = 1,
 	move_body = 1,
 	size_category = 5,
+	no_breath = 1,
 
 	autolevel = "warrior",
 	ai = "sandworm_tunneler", ai_state = {},
-- 
GitLab