From 0fd68283d6dd5487c2aca07d306033c9c52df17a Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Sat, 26 Feb 2011 17:30:53 +0000
Subject: [PATCH] Actors now start with 150 Paradox so new players have more
 leeway before they start blowing themselves up Failure, Backfire, and
 Anomalies don't start happening until 200, 300 and 400 paradox Added gamelog
 messages for when paradox thresholds are crossed.

git-svn-id: http://svn.net-core.org/repos/t-engine4@2856 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/modules/tome/class/Actor.lua             | 34 ++++++++++++++++--
 .../data/general/npcs/horror-corrupted.lua    | 20 ++++++-----
 .../tome/data/maps/wilderness/eyal.lua        |  2 +-
 .../data/talents/chronomancy/anomalies.lua    | 36 +++++++++----------
 .../data/talents/chronomancy/chronomancer.lua |  2 +-
 .../talents/chronomancy/spacetime-weaving.lua | 13 +++----
 game/modules/tome/data/timed_effects.lua      |  8 ++---
 7 files changed, 74 insertions(+), 41 deletions(-)

diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 51e1012726..481f950adb 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -157,7 +157,7 @@ function _M:init(t, no_default)
 
 	t.equilibrium = t.equilibrium or 0
 
-	t.paradox = t.paradox or 300
+	t.paradox = t.paradox or 150
 
 	t.money = t.money or 0
 
@@ -1593,6 +1593,34 @@ function _M:paradoxFailChance(pa)
 	return rng.percent(chance), chance
 end
 
+-- Overwrite incParadox to set up threshold log messages
+local previous_incParadox = _M.incParadox
+
+function _M:incParadox(paradox)
+	-- Failure checks
+	if self:getParadox() < 200 and self:getParadox() + paradox >= 200 then
+		game.logPlayer(self, "#LIGHT_RED#You feel the edges of time begin to fray!")
+	end
+	if self:getParadox() > 200 and self:getParadox() + paradox <= 200 then
+		game.logPlayer(self, "#LIGHT_BLUE#Time feels more stable.")
+	end
+	-- Backfire checks
+	if self:getParadox() < 300 and self:getParadox() + paradox >= 300 then
+		game.logPlayer(self, "#LIGHT_RED#You feel the edges of space begin to ripple and bend!")
+	end
+	if self:getParadox() > 300 and self:getParadox() + paradox <= 300 then
+		game.logPlayer(self, "#LIGHT_BLUE#Space feels more stable.")
+	end
+	-- Anomaly checks
+	if self:getParadox() < 400 and self:getParadox() + paradox >= 400 then
+		game.logPlayer(self, "#LIGHT_RED#Space and time both fight against your control!")
+	end	
+	if self:getParadox() > 400 and self:getParadox() + paradox <= 400 then
+		game.logPlayer(self, "#LIGHT_BLUE#Space and time have calmed...  somewhat.")
+	end	
+	return previous_incParadox(self, paradox)
+end
+
 --- Called before a talent is used
 -- Check the actor can cast it
 -- @param ab the talent (not the id, the table)
@@ -1689,13 +1717,13 @@ function _M:preUseTalent(ab, silent, fake)
 	-- Paradox is special, it has no max, but the higher it is the higher the chance of something bad happening
 	if (ab.paradox or ab.sustain_paradox) and not fake then
 		-- Check failure first
-		if not self:attr("no_paradox_fail") and self:paradoxFailChance(ab.paradox or ab.sustain_paradox) then
+		if not self:attr("no_paradox_fail") and self:paradoxFailChance(ab.paradox or ab.sustain_paradox) and self:getParadox() > 200 then
 			if not silent then game.logPlayer(self, "You fail to use %s due to your paradox!", ab.name) end
 			self:incParadox(ab.paradox or ab.sustain_paradox / 10)
 			self:useEnergy()
 			return false
 		-- Now Check Anomalies
-		elseif not game.zone.no_anomalies and not self:attr("no_paradox_fail") and rng.percent(math.pow((self:getParadox()/400), 4)) then
+		elseif not game.zone.no_anomalies and not self:attr("no_paradox_fail") and rng.percent(math.pow((self:getParadox()/400), 4)) and self:getParadox() > 400 then
 			-- Random anomaly
 			self:incParadox(ab.paradox or ab.sustain_paradox / 2)
 			local ts = {}
diff --git a/game/modules/tome/data/general/npcs/horror-corrupted.lua b/game/modules/tome/data/general/npcs/horror-corrupted.lua
index 2a98e1ed72..5dc0deef0b 100644
--- a/game/modules/tome/data/general/npcs/horror-corrupted.lua
+++ b/game/modules/tome/data/general/npcs/horror-corrupted.lua
@@ -44,7 +44,7 @@ newEntity{
 newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 	dredge = 1,
 	name = "dremling", color=colors.SLATE,
-	desc = "A small disfigured humanoid with vaguely dwarven features.  It's waraxe and shield look battered, rusted, and generally in ill repair.",
+	desc = "A small faceless humanoid with vaguely dwarven features.  It's waraxe and shield look battered, rusted, and generally in ill repair.",
 	level_range = {1, nil}, exp_worth = 1,
 
 	combat = { atk=6, dammod={str=0.6} },
@@ -78,7 +78,7 @@ newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 	dredge = 1,
 	name = "drem", color=colors.DARK_SLATE_GRAY,
-	desc = "A giant black-skinned humanoid covered in spikey scabrous deposits.",
+	desc = "A giant black-skinned humanoid covered in spikey scabrous deposits.  Its face is featureless and its eyesockets empty and hollow.",
 	level_range = {3, nil}, exp_worth = 1,
 
 	combat_armor = 4, combat_def = 0,
@@ -115,7 +115,7 @@ newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 	dredge = 1,
 	name = "drem master", color=colors.LIGHT_GREY,
-	desc = "A disfigured humanoid with vaguely dwarven features dressed in patched together and rusted mail armor.  It seems to be in command of the others.",
+	desc = "A disfigured humanoid with vaguely dwarven features dressed in patched together and rusted mail armor.  It seems to be in command of the others though it's mouth is sown shut.",
 	level_range = {3, nil}, exp_worth = 1,
 
 	combat = { atk=10, dammod={str=0.6} },
@@ -158,7 +158,7 @@ newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 
 newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 	name = "brecklorn", color=colors.PINK,  -- gloom bat
-	desc = "A giant hairless bat.  Pestulant sores cover it's malformed body and your heart weakens as it nears.",
+	desc = "A giant hairless bat with the face of a dwarven man twisted into a constant scream.  Pestulant sores cover it's malformed body and your heart weakens as it nears.",
 	level_range = {1, nil}, exp_worth = 1,
 
 	energy = { mod=0.7 },
@@ -188,7 +188,7 @@ newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 
 newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 	name = "grannor'vor", color=colors.GREEN,  -- acid slug
-	desc = "A large sluglike creature that moves slowly, leaving a trail of acid in its wake.",
+	desc = "A large sluglike creature that moves slowly, leaving a trail of acid in its wake.  Its head has strangely humanoid features.",
 	level_range = {2, nil}, exp_worth = 1,
 
 	combat = { dam=5, atk=15, apr=5, damtype=DamageType.ACID },
@@ -203,6 +203,8 @@ newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 	energy = { mod=0.8 },
 
 	resists = { [DamageType.ACID] = 50, [DamageType.DARKNESS] = 20,  [DamageType.LIGHT] = - 20 },
+	
+	clone_on_hit = {min_dam_pct=15, chance=30},
 
 	resolvers.talents{
 		[Talents.T_CRAWL_ACID]=2,
@@ -214,7 +216,7 @@ newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 
 newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 	name = "grannor'vin", color=colors.BLACK,  -- shadow slug
-	desc = "A large sluglike creature that moves slowly.  Shadows seem to be drawn to it's massive form and your light dims as it approaches.",
+	desc = "A large sluglike creature with the face of a man.  Shadows seem to be drawn to it's massive form and your light dims as it approaches.",
 	level_range = {2, nil}, exp_worth = 1,
 
 	combat = { dam=5, atk=15, apr=5, damtype=DamageType.DARKNESS },
@@ -224,16 +226,18 @@ newEntity{ base = "BASE_NPC_CORRUPTED_HORROR",
 
 	rarity = 4,
 	rank = 2,
-	size_category = 3,
+	size_category = 4,
 	autolevel = "caster",
+	ai = "dumb_talented_simple", ai_state = { ai_move="move_dmap", talent_in=2, },
 
 	energy = { mod=0.8 },
 
 	resists = { [DamageType.DARKNESS] = 50,  [DamageType.LIGHT] = - 20 },
 
 	resolvers.talents{
-		[Talents.T_CALL_SHADOWS]=2,
+		[Talents.T_CALL_SHADOWS]=3,
 		[Talents.T_CREEPING_DARKNESS]=2,
+		[Talents.T_DARK_TORRENT]=1,
 	},
 
 	resolvers.sustains_at_birth(),
diff --git a/game/modules/tome/data/maps/wilderness/eyal.lua b/game/modules/tome/data/maps/wilderness/eyal.lua
index 927e4a8725..4a6383d10d 100644
--- a/game/modules/tome/data/maps/wilderness/eyal.lua
+++ b/game/modules/tome/data/maps/wilderness/eyal.lua
@@ -92,7 +92,7 @@ else
 end
 
 -- Zigur is only know from the start to non casters
-if not game.player:knowTalent(game.player.T_MANA_POOL) and not game.player:knowTalent(game.player.T_VIM_POOL) and not game.player:knowTalent(game.player.T_VIM_POOL) and not game.player:knowTalent(game.player.T_NEGATIVE_POOL) and not game.player:knowTalent(game.player.T_POSITIVE_POOL) then
+if not game.player:knowTalent(game.player.T_MANA_POOL) and not game.player:knowTalent(game.player.T_VIM_POOL) and not game.player:knowTalent(game.player.T_VIM_POOL) and not game.player:knowTalent(game.player.T_NEGATIVE_POOL) and not game.player:knowTalent(game.player.T_POSITIVE_POOL) and not game.player:knowTalent(game.player.T_PARADOX_POOL) then
 	quickEntity('zigur', {always_remember = true, show_tooltip=true, name="Zigur (Town)", desc="Ziguranth main training ground", display='*', color={r=255, g=255, b=255}, back_color=colors.DARK_GREEN, image="terrain/town1.png", notice = true, change_level=1, change_zone="town-zigur"})
 else
 	quickEntity('zigur', ')')
diff --git a/game/modules/tome/data/talents/chronomancy/anomalies.lua b/game/modules/tome/data/talents/chronomancy/anomalies.lua
index e37b73def5..322be5db6b 100644
--- a/game/modules/tome/data/talents/chronomancy/anomalies.lua
+++ b/game/modules/tome/data/talents/chronomancy/anomalies.lua
@@ -26,7 +26,7 @@ newTalent{
 	range = 10,
 	direct_hit = true,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/200) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/200) end,
 	getRange = function(self, t) return math.ceil(self:getParadox()/10) end,
 	message = "Reality has shifted.",
 	action = function(self, t)
@@ -66,7 +66,7 @@ newTalent{
 	range = 10,
 	direct_hit = true,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/50) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/50) end,
 	getRange = function(self, t) return math.ceil(self:getParadox()/100) end,
 	message = "@Source@ has caused a hiccup in the fabric of spacetime.",
 	action = function(self, t)
@@ -188,7 +188,7 @@ newTalent{
 	range = 6,
 	direct_hit = true,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/300) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/300) end,
 	getPower = function(self, t) return ((self:getParadox()/15) / 100) end,
 	message = "@Source@ has sped up several threads of time.",
 	action = function(self, t)
@@ -254,7 +254,7 @@ newTalent{
 	type = {"chronomancy/anomalies", 1},
 	points = 1,
 	type_no_req = true,
-	getDamage = function(self, t) return self:getParadox()/25 end,
+	getDamage = function(self, t) return self:getParadox()/40 end,
 	getDuration = function(self, t) return math.ceil (self:getParadox()/50) end,
 	message = "A temporal storm rages around @Source@.",
 	action = function(self, t)
@@ -284,8 +284,8 @@ newTalent{
 	range = 10,
 	direct_hit = true,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/200) end,
-	getSummonTime = function(self, t) return math.floor(self:getParadox()/50) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/200) end,
+	getSummonTime = function(self, t) return math.ceil(self:getParadox()/50) end,
 	message = "Some Time Elementals have been attracted by @Source@'s meddling.",
 	action = function(self, t)
 		local tgts = {}
@@ -371,7 +371,7 @@ newTalent{
 	points = 1,
 	range = 10,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/200) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/200) end,
 	getDuration = function(self, t) return math.ceil(self:getParadox()/100) end,
 	message = "@Source@ has paused a temporal thread.",
 	action = function(self, t)
@@ -469,16 +469,16 @@ newTalent{
 	name = "Anomaly Gravity Spike",
 	type = {"chronomancy/anomalies", 1},
 	points = 1,
-	range = 6,
+	range = 10,
 	direct_hit = true,
 	type_no_req = true,
 	getTargetCount = function(self, t) return 1 end,
-	getRadius = function(self, t) return math.floor(self:getParadox()/100) end,
-	getDamage = function(self, t) return self:getParadox()/10 end,
+	getRadius = function(self, t) return math.ceil(self:getParadox()/100) end,
+	getDamage = function(self, t) return self:getParadox()/20 end,
 	message = "@Source@ has caused a Gravity Spike.",
 	action = function(self, t)
 		local tgts = {}
-		local grids = core.fov.circle_grids(self.x, self.y, 6, true)
+		local grids = core.fov.circle_grids(self.x, self.y, 10, true)
 		for x, yy in pairs(grids) do for y, _ in pairs(grids[x]) do
 			local a = game.level.map(x, y, Map.ACTOR)
 			if a then
@@ -522,9 +522,9 @@ newTalent{
 	range = 6,
 	direct_hit = true,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/100) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/100) end,
 	getPower = function(self, t) return math.ceil(self:getParadox()/50) end,
-	getTalentCount = function(self, t) return math.floor(self:getParadox()/200) end,
+	getTalentCount = function(self, t) return math.ceil(self:getParadox()/200) end,
 	message = "@Source@ has increased local entropy.",
 	action = function(self, t)
 		local tgts = {}
@@ -576,8 +576,8 @@ newTalent{
 	range = 10,
 	direct_hit = true,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/200) end,
-	getSummonTime = function(self, t) return math.floor(self:getParadox()/20) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/200) end,
+	getSummonTime = function(self, t) return math.ceil(self:getParadox()/20) end,
 	message = "Some innocent bystanders have been pulled out of their timeline.",
 	action = function(self, t)
 		local tgts = {}
@@ -686,7 +686,7 @@ newTalent{
 	direct_hit = true,
 	type_no_req = true,
 	getRange = function(self, t) return math.ceil(self:getParadox()/10) end,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/200) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/200) end,
 	message = "Poof!!",
 	action = function(self, t)
 		local tgts = {}
@@ -729,7 +729,7 @@ newTalent{
 	range = 6,
 	direct_hit = true,
 	type_no_req = true,
-	getTargetCount = function(self, t) return math.floor(self:getParadox()/150) end,
+	getTargetCount = function(self, t) return math.ceil(self:getParadox()/150) end,
 	getPower = function(self, t) return (self:getParadox()/30) end,
 	message = "@Source@ has inadvertently weakened several creatures.",
 	action = function(self, t)
@@ -750,7 +750,7 @@ newTalent{
 			table.remove(tgts, id)
 
 			a:setEffect(self.EFF_FLAWED_DESIGN, 10, {power=t.getPower(self, t)})
-			a:setEffect(self.EFF_TURN_BACK_THE_CLOCK, 10, {power=t.getPower(self, t)})
+			a:setEffect(self.EFF_TURN_BACK_THE_CLOCK, 10, {power=t.getPower(self, t)/2})
 			game.level.map:particleEmitter(a.x, a.y, 1, "temporal_teleport")
 			game:playSoundNear(self, "talents/spell_generic")
 		end
diff --git a/game/modules/tome/data/talents/chronomancy/chronomancer.lua b/game/modules/tome/data/talents/chronomancy/chronomancer.lua
index 3c07ebbddd..aae1ade655 100644
--- a/game/modules/tome/data/talents/chronomancy/chronomancer.lua
+++ b/game/modules/tome/data/talents/chronomancy/chronomancer.lua
@@ -114,7 +114,7 @@ checkBackfire = function(self, x, y)
 	
 	local backfire = math.pow (((self:getParadox() - modifier)/300), 3)*((100 + self:combatFatigue()) / 100)
 --	print("[Paradox] Backfire chance: ", backfire, "::", self:getParadox())
-	if rng.percent(backfire) and not self:attr("no_paradox_fail") then
+	if rng.percent(backfire) and self:getParadox() > 300 and not self:attr("no_paradox_fail") then
 		game.logPlayer(self, "The fabric of spacetime ripples and your spell backfires!!")
 		return self.x, self.y
 	else
diff --git a/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua b/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua
index 6670a51570..bc57521388 100644
--- a/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua
+++ b/game/modules/tome/data/talents/chronomancy/spacetime-weaving.lua
@@ -28,6 +28,7 @@ newTalent{
 	no_npc_use = true,
 	no_energy = true,
 	getAnomaly = function(self, t) return 6 - (self:getTalentLevelRaw(self.T_STATIC_HISTORY) or 0) end,
+	getPower = function(self, t) return math.floor(self:getWil()/2) end,
 	action = function(self, t)
 		-- open dialog to get desired paradox
 		local q = engine.dialogs.GetQuantity.new("Retuning the fabric of spacetime...", 
@@ -35,13 +36,13 @@ newTalent{
 			
 			-- get reduction amount and find duration
 			amount = qty - self.paradox
-			local dur = math.floor(math.abs(qty-self.paradox)/self:getWil())
-			
+			local dur = math.floor(math.abs(qty-self.paradox)/t.getPower(self, t))
+						
 			-- set tuning effect
 			if amount >= 0 then
-				self:setEffect(self.EFF_SPACETIME_TUNING, dur, {power = self:getWil()})
+				self:setEffect(self.EFF_SPACETIME_TUNING, dur, {power = t.getPower(self, t)})
 			elseif amount < 0 then
-				self:setEffect(self.EFF_SPACETIME_TUNING, dur, {power = -self:getWil()})
+				self:setEffect(self.EFF_SPACETIME_TUNING, dur, {power = - t.getPower(self, t)})
 			end
 			
 		end)
@@ -50,8 +51,8 @@ newTalent{
 	end,
 	info = function(self, t)
 		local chance = t.getAnomaly(self, t)
-		return ([[Retunes your Paradox towards the desired level and informs you of failure, anomaly, and backfire chances when you finish tuning.  You will be dazed while tuning and each turn your Paradox will increase or decrease by an amount equal to your Willpower stat.
-		Each turn you have a %d%% chance of triggering a temporal anomaly which will end the tuning process.]]):
+		return ([[Retunes your Paradox towards the desired level and informs you of failure, anomaly, and backfire chances when you finish tuning.  You will be dazed while tuning and each turn your Paradox will increase or decrease by an amount equal to one half of your Willpower stat.
+		Each turn you spend increasing Paradox will have a %d%% chance of triggering a temporal anomaly which will end the tuning process.  Decreasing Paradox has no chance of triggering an anomaly.]]):
 		format(chance)
 	end,
 }
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index 89aa90aaa4..e970f9c9dd 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -3385,7 +3385,7 @@ newEffect{
 		local anomaly = t.getAnomaly(self, t)
 
 		-- first check for anomaly
-		if rng.percent(anomaly) and not game.zone.no_anomalies then
+		if rng.percent(anomaly) and not game.zone.no_anomalies and eff.power > 0 then
 			-- Random anomaly
 			local ts = {}
 			for id, t in pairs(self.talents_def) do
@@ -3412,9 +3412,9 @@ newEffect{
 		else
 			modifier = self:getWil()
 		end
-		local failure = math.pow(((self:getParadox() - modifier)/200), 2)*((100 + self:combatFatigue()) / 100)
-		local anomaly = math.pow((self:getParadox()/400), 4)
-		local backfire = math.pow (((self:getParadox() - modifier)/300), 3)*((100 + self:combatFatigue()) / 100)
+		local failure = math.floor( math.pow(((self:getParadox() - modifier)/200), 2)*((100 + self:combatFatigue()) / 100))
+		local anomaly = math.floor(math.pow((self:getParadox()/400), 4))
+		local backfire = math.floor(math.pow (((self:getParadox() - modifier)/300), 3)*((100 + self:combatFatigue()) / 100))
 		self:removeTemporaryValue("dazed", eff.tmpid)
 		game.logPlayer(self, "Your current failure chance is %d%%, your current anomoly chance is %d%%, and your current backfire chance is %d%%.", failure, anomaly, backfire)
 	end,
-- 
GitLab