Index: game/engines/default/engine/interface/ActorTalents.lua =================================================================== --- game/engines/default/engine/interface/ActorTalents.lua (revision 6385) +++ game/engines/default/engine/interface/ActorTalents.lua (working copy) @@ -95,7 +95,7 @@ self.sustain_talents = self.sustain_talents or {} self.talents_auto = self.talents_auto or {} self.talents_confirm_use = self.talents_confirm_use or {} - self.talents_learn_vals = {} + self.talents_learn_vals = t.talents_learn_vals or {} end --- Resolve leveling talents @@ -420,9 +420,13 @@ if p.__tmpvals then for i = 1, #p.__tmpvals do self:removeTemporaryValue(p.__tmpvals[i][1], p.__tmpvals[i][2]) end end - self.talents_learn_vals[t.id] = {} - t.passives(self, t, self.talents_learn_vals[t.id]) + if self:knowTalent(t_id) then + self.talents_learn_vals[t.id] = {} + t.passives(self, t, self.talents_learn_vals[t.id]) + else + self.talents_learn_vals[t.id] = nil + end end if self.talents[t_id] == nil then self.talents_auto[t_id] = nil end Index: game/modules/tome/class/Actor.lua =================================================================== --- game/modules/tome/class/Actor.lua (revision 6385) +++ game/modules/tome/class/Actor.lua (working copy) @@ -3100,7 +3100,7 @@ if self:getTalentLevelRaw(t) >= max then self.item_talent_surplus_levels[tid] = self.item_talent_surplus_levels[tid] + 1 else - self:learnTalent(tid, true, 1) + self:learnTalent(tid, true, 1, {no_unlearn = true}) end end @@ -3123,7 +3123,7 @@ if self.item_talent_surplus_levels[tid] > 0 then self.item_talent_surplus_levels[tid] = self.item_talent_surplus_levels[tid] - 1 else - self:unlearnTalent(tid) + self:unlearnTalent(tid, nil, nil, {no_unlearn = true}) end end end @@ -3192,12 +3192,14 @@ --- Actor forgets a talent -- @param t_id the id of the talent to learn -- @return true if the talent was unlearnt, nil and an error message otherwise -function _M:unlearnTalent(t_id, nb, no_unsustain) +function _M:unlearnTalent(t_id, nb, no_unsustain, extra) if not engine.interface.ActorTalents.unlearnTalent(self, t_id, nb) then return false end local t = _M.talents_def[t_id] - if not t.no_unlearn_last and self.last_learnt_talents then + extra = extra or {} + + if not t.no_unlearn_last and self.last_learnt_talents and not extra.no_unlearn then local list = t.generic and self.last_learnt_talents.generic or self.last_learnt_talents.class for i = #list, 1, -1 do if list[i] == t_id then table.remove(list, i) break end Index: game/modules/tome/data/talents/celestial/twilight.lua =================================================================== --- game/modules/tome/data/talents/celestial/twilight.lua (revision 6385) +++ game/modules/tome/data/talents/celestial/twilight.lua (working copy) @@ -60,6 +60,7 @@ type_no_req = true, tactical = { ESCAPE = 2 }, no_npc_use = true, + no_unlearn_last = true, getRange = function(self, t) return math.floor(10 + 3 * self:getTalentLevel(t)) end, -- Check distance in preUseTalent to grey out the talent on_pre_use = function(self, t) @@ -282,6 +283,7 @@ no_npc_use = true, type_no_req = true, tactical = { ESCAPE = 2 }, + no_unlearn_last = true, on_learn = function(self, t) if not self:knowTalent(self.T_JUMPGATE_TELEPORT_TWO) then self:learnTalent(self.T_JUMPGATE_TELEPORT_TWO, nil, nil, {no_unlearn=true}) @@ -335,6 +337,7 @@ getRange = function(self, t) return math.floor(10 + 3 * self:getTalentLevel(t)) end, -- Check distance in preUseTalent to grey out the talent is_teleport = true, + no_unlearn_last = true, on_pre_use = function(self, t) local eff = self.sustain_talents[self.T_JUMPGATE_TWO] return eff and core.fov.distance(self.x, self.y, eff.jumpgate2_x, eff.jumpgate2_y) < t.getRange(self, t) Index: game/modules/tome/data/talents/chronomancy/anomalies.lua =================================================================== --- game/modules/tome/data/talents/chronomancy/anomalies.lua (revision 6385) +++ game/modules/tome/data/talents/chronomancy/anomalies.lua (working copy) @@ -46,6 +46,7 @@ range = 10, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getTargetCount = function(self, t) return math.ceil(self:getParadox()/200) end, getRange = function(self, t) return math.ceil(self:getParadox()/20) end, message = "Reality has shifted.", @@ -87,6 +88,7 @@ direct_hit = true, type_no_req = true, cooldown = 1, + no_unlearn_last = true, 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.", @@ -127,6 +129,7 @@ range = 10, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getTargetCount = function(self, t) return 1 end, getRadius = function(self, t) return getAnomalyRadius(self) end, getStop = function(self, t) return math.ceil(self:getParadox()/100) end, @@ -166,6 +169,7 @@ range = 6, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getTargetCount = function(self, t) return 1 end, getRadius = function(self, t) return getAnomalyRadius(self) end, getSlow = function(self, t) return 1 - 1 / (1 + (self:getParadox()/15) / 100) end, @@ -205,6 +209,7 @@ range = 6, direct_hit = true, type_no_req = true, + no_unlearn_last = true, 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.", @@ -242,6 +247,7 @@ points = 1, type_no_req = true, cooldown = 1, + no_unlearn_last = true, getDamage = function(self, t) return getAnomalyDamage(self)/4 end, getDuration = function(self, t) return math.ceil (self:getParadox()/50) end, message = "A temporal storm rages around @Source@.", @@ -272,6 +278,7 @@ range = 10, direct_hit = true, type_no_req = true, + no_unlearn_last = true, 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.", @@ -359,6 +366,7 @@ points = 1, range = 10, type_no_req = true, + no_unlearn_last = true, 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.", @@ -396,6 +404,7 @@ type = {"chronomancy/anomalies", 1}, points = 1, type_no_req = true, + no_unlearn_last = true, getRadius = function(self, t) return getAnomalyRadius(self) end, message = "Matter turns to dust around @Source@.", action = function(self, t) @@ -416,6 +425,7 @@ points = 1, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getRange = function(self, t) return math.ceil(self:getParadox()/20) end, getConfuseDuration = function(self, t) return math.floor(self:getParadox()/200)end, getConfuseEfficency = function(self, t) return self:getParadox()/10 end, @@ -475,6 +485,7 @@ range = 10, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getTargetCount = function(self, t) return 1 end, getRadius = function(self, t) return getAnomalyRadius(self) end, getDamage = function(self, t) return getAnomalyDamage(self) end, @@ -525,6 +536,7 @@ range = 6, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getTargetCount = function(self, t) return math.ceil(self:getParadox()/100) end, getPower = function(self, t) return math.ceil(self:getParadox()/100) end, getTalentCount = function(self, t) return math.ceil(self:getParadox()/200) end, @@ -579,6 +591,7 @@ range = 10, direct_hit = true, type_no_req = true, + no_unlearn_last = true, 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.", @@ -691,6 +704,7 @@ points = 1, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getRange = function(self, t) return math.ceil(self:getParadox()/30) end, getTargetCount = function(self, t) return math.ceil(self:getParadox()/200) end, message = "Poof!!", @@ -735,6 +749,7 @@ range = 6, direct_hit = true, type_no_req = true, + no_unlearn_last = true, 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.", @@ -774,6 +789,7 @@ range = 6, direct_hit = true, type_no_req = true, + no_unlearn_last = true, getTargetCount = function(self, t) return 1 end, getHastePower = function(self, t) return ((self:getParadox()/15) / 100) end, getRegenPower = function(self, t) return (self:getParadox()/15) end, @@ -813,6 +829,7 @@ type = {"chronomancy/anomalies", 1}, points = 1, type_no_req = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -826,6 +843,7 @@ type = {"chronomancy/anomalies", 1}, points = 1, type_no_req = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -839,6 +857,7 @@ type = {"chronomancy/anomalies", 1}, points = 1, type_no_req = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -852,6 +871,7 @@ type = {"chronomancy/anomalies", 1}, points = 1, type_no_req = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -866,6 +886,7 @@ points = 1, type_no_req = true, no_npc_use = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -880,6 +901,7 @@ points = 1, type_no_req = true, no_npc_use = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -893,6 +915,7 @@ type = {"chronomancy/anomalies", 1}, points = 1, type_no_req = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -907,6 +930,7 @@ points = 1, type_no_req = true, no_npc_use = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -921,6 +945,7 @@ points = 1, type_no_req = true, no_npc_use = true, + no_unlearn_last = true, action = function(self, t) return true end, @@ -935,6 +960,7 @@ points = 1, type_no_req = true, requires_target = true, + no_unlearn_last = true, getSummonTime = function(self, t) return math.floor(self:getParadox()/50) end, action = function(self, t) return true Index: game/modules/tome/data/talents/chronomancy/timetravel.lua =================================================================== --- game/modules/tome/data/talents/chronomancy/timetravel.lua (revision 6385) +++ game/modules/tome/data/talents/chronomancy/timetravel.lua (working copy) @@ -288,6 +288,7 @@ paradox = 25, no_npc_use = true, on_pre_use = function(self, t, silent) if not self:isTalentActive(self.T_DOOR_TO_THE_PAST) then if not silent then game.logPlayer(self, "Door to the Past must be active to use this talent.") end return false end return true end, + no_unlearn_last = true, action = function(self, t) -- Prevent Revision After Death Index: game/modules/tome/data/talents/cunning/poisons.lua =================================================================== --- game/modules/tome/data/talents/cunning/poisons.lua (revision 6385) +++ game/modules/tome/data/talents/cunning/poisons.lua (working copy) @@ -229,6 +229,7 @@ no_break_stealth = true, no_energy = true, tactical = { BUFF = 2 }, + no_unlearn_last = true, getDuration = function(self, t) return 5 + self:getTalentLevel(self.T_VILE_POISONS) end, getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 60) * 0.4 end, proc = function(self, t, target) @@ -262,6 +263,7 @@ no_break_stealth = true, no_energy = true, tactical = { BUFF = 2 }, + no_unlearn_last = true, getDuration = function(self, t) return 5 + self:getTalentLevel(self.T_VILE_POISONS) end, getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 50) * 0.4 end, getEffect = function(self, t) return 10 + self:getTalentLevel(self.T_VILE_POISONS) * 3 end, @@ -296,6 +298,7 @@ no_break_stealth = true, no_energy = true, tactical = { BUFF = 2 }, + no_unlearn_last = true, getDuration = function(self, t) return 5 + self:getTalentLevel(self.T_VILE_POISONS) end, getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 50) * 0.4 end, getEffect = function(self, t) return 30 + self:getTalentLevel(self.T_VILE_POISONS) * 5.5 end, @@ -330,6 +333,7 @@ no_break_stealth = true, no_energy = true, tactical = { BUFF = 2 }, + no_unlearn_last = true, getDuration = function(self, t) return 3 + self:getTalentLevel(self.T_VILE_POISONS) end, getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 50) * 0.4 end, getEffect = function(self, t) return 10 + self:getTalentLevel(self.T_VILE_POISONS) * 3 end, @@ -364,6 +368,7 @@ no_break_stealth = true, no_energy = true, tactical = { BUFF = 2 }, + no_unlearn_last = true, getDuration = function(self, t) return 12 - self:getTalentLevel(self.T_VILE_POISONS) end, getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 30) * 0.4 end, getEffect = function(self, t) return math.ceil(2 + self:getTalentLevel(t) / 2) end, @@ -401,6 +406,7 @@ no_energy = true, is_spell = true, tactical = { BUFF = 2 }, + no_unlearn_last = true, getDuration = function(self, t) return 12 - self:getTalentLevel(self.T_VILE_POISONS) end, getDOT = function(self, t) return 8 + self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 10, 30) * 0.4 end, getEffect = function(self, t) return self:combatTalentStatDamage(self.T_VILE_POISONS, "cun", 15, 35) end, Index: game/modules/tome/data/talents/cunning/traps.lua =================================================================== --- game/modules/tome/data/talents/cunning/traps.lua (revision 6385) +++ game/modules/tome/data/talents/cunning/traps.lua (working copy) @@ -231,6 +231,7 @@ requires_target = true, range = trap_range, tactical = { ATTACKAREA = { FIRE = 2 } }, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) @@ -277,6 +278,7 @@ requires_target = true, range = trap_range, tactical = { DISABLE = { pin = 2 } }, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) @@ -327,6 +329,7 @@ requires_target = true, tactical = { DISABLE = { stun = 2 } }, range = trap_range, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) @@ -383,6 +386,7 @@ requires_target = true, tactical = { DISABLE = { disarm = 2 } }, range = trap_range, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) @@ -433,6 +437,7 @@ tactical = { DISABLE = { stun = 2 } }, requires_target = true, range = trap_range, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) @@ -481,6 +486,7 @@ tactical = { DISABLE = { blind = 1, stun = 1 } }, requires_target = true, range = trap_range, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) @@ -537,6 +543,7 @@ tactical = { ATTACKAREA = { poison = 2 } }, requires_target = true, range = trap_range, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) @@ -595,6 +602,7 @@ requires_target = true, is_spell = true, range = trap_range, + no_unlearn_last = true, action = function(self, t) local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t} local x, y, target = self:getTarget(tg) Index: game/modules/tome/data/talents/psionic/thought-forms.lua =================================================================== --- game/modules/tome/data/talents/psionic/thought-forms.lua (revision 6385) +++ game/modules/tome/data/talents/psionic/thought-forms.lua (working copy) @@ -174,6 +174,7 @@ no_sustain_autoreset = true, cooldown = 24, range = 10, + no_unlearn_last = true, getStatBonus = function(self, t) local t = self:getTalentFromId(self.T_THOUGHT_FORMS) return t.getStatBonus(self, t) @@ -285,6 +286,7 @@ no_sustain_autoreset = true, cooldown = 24, range = 10, + no_unlearn_last = true, getStatBonus = function(self, t) local t = self:getTalentFromId(self.T_THOUGHT_FORMS) return t.getStatBonus(self, t) @@ -386,6 +388,7 @@ no_sustain_autoreset = true, cooldown = 24, range = 10, + no_unlearn_last = true, getStatBonus = function(self, t) local t = self:getTalentFromId(self.T_THOUGHT_FORMS) return t.getStatBonus(self, t) Index: game/modules/tome/data/talents/spells/golem.lua =================================================================== --- game/modules/tome/data/talents/spells/golem.lua (revision 6385) +++ game/modules/tome/data/talents/spells/golem.lua (working copy) @@ -486,6 +486,7 @@ points = 1, range = 0, radius = 4, + no_unlearn_last = true, target = function(self, t) return {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t)} end, @@ -515,6 +516,7 @@ type = {"golem/golem", 1}, mode = "passive", points = 6, + no_unlearn_last = true, getArmorHardiness = function(self, t) return self:getTalentTypeMastery("technique/combat-training") * (self:getTalentLevelRaw(t) * 5 - 15) end, getArmor = function(self, t) return self:getTalentTypeMastery("technique/combat-training") * (self:getTalentLevelRaw(t) * 1.4 - 4.2) end, getCriticalChanceReduction = function(self, t) return self:getTalentTypeMastery("technique/combat-training") * (self:getTalentLevelRaw(t) * 1.9 - 5.7) end, Index: game/modules/tome/data/talents/spells/golemancy.lua =================================================================== --- game/modules/tome/data/talents/spells/golemancy.lua (revision 6385) +++ game/modules/tome/data/talents/spells/golemancy.lua (working copy) @@ -280,8 +280,8 @@ self.alchemy_golem:learnTalent(Talents.T_WEAPONS_MASTERY, true, nil, {no_unlearn=true}) end, on_unlearn = function(self, t) - self.alchemy_golem:unlearnTalent(Talents.T_WEAPON_COMBAT) - self.alchemy_golem:unlearnTalent(Talents.T_WEAPONS_MASTERY) + self.alchemy_golem:unlearnTalent(Talents.T_WEAPON_COMBAT, nil, nil, {no_unlearn=true}) + self.alchemy_golem:unlearnTalent(Talents.T_WEAPONS_MASTERY, nil, nil, {no_unlearn=true}) if self:getTalentLevelRaw(t) == 0 and not self.innate_alchemy_golem then self:unlearnTalent(self.T_REFIT_GOLEM) @@ -314,8 +314,8 @@ self.alchemy_golem.healing_factor = (self.alchemy_golem.healing_factor or 1) + 0.1 end, on_unlearn = function(self, t) - self.alchemy_golem:unlearnTalent(Talents.T_THICK_SKIN) - self.alchemy_golem:unlearnTalent(Talents.T_GOLEM_ARMOUR) + self.alchemy_golem:unlearnTalent(Talents.T_THICK_SKIN, nil, nil, {no_unlearn=true}) + self.alchemy_golem:unlearnTalent(Talents.T_GOLEM_ARMOUR, nil, nil, {no_unlearn=true}) self.alchemy_golem.healing_factor = (self.alchemy_golem.healing_factor or 1) - 0.1 end, info = function(self, t) Index: game/modules/tome/data/talents/techniques/archery.lua =================================================================== --- game/modules/tome/data/talents/techniques/archery.lua (revision 6385) +++ game/modules/tome/data/talents/techniques/archery.lua (working copy) @@ -60,6 +60,7 @@ tactical = { AMMO = 2 }, no_reload_break = true, on_pre_use = function(self, t, silent) if not self:hasAmmo() then if not silent then game.logPlayer(self, "You must have a quiver or pouch equipped.") end return false end return true end, + no_unlearn_last = true, shots_per_turn = function(self, t) local v = math.max(self:getTalentLevelRaw(self.T_BOW_MASTERY), self:getTalentLevelRaw(self.T_SLING_MASTERY)) local add = 0 Index: game/modules/tome/data/talents/uber/mag.lua =================================================================== --- game/modules/tome/data/talents/uber/mag.lua (revision 6385) +++ game/modules/tome/data/talents/uber/mag.lua (working copy) @@ -119,7 +119,7 @@ mode = "passive", on_learn = function(self, t) if self.alchemy_golem then - self.alchemy_golem:learnTalent(self.alchemy_golem.T_CORRUPTED_STRENGTH, true, 1) + self.alchemy_golem:learnTalent(self.alchemy_golem.T_CORRUPTED_STRENGTH, true, 1, {no_unlearn=true}) self.alchemy_golem:learnTalentType("corruption/reaving-combat", true) end end, Index: game/modules/tome/data/talents/uber/str.lua =================================================================== --- game/modules/tome/data/talents/uber/str.lua (revision 6385) +++ game/modules/tome/data/talents/uber/str.lua (working copy) @@ -167,8 +167,8 @@ return q and not q:isCompleted("kill-slasul") and q:isCompleted("kill-drake") end} }, on_learn = function(self, t) - self:learnTalent(self.T_SPIT_POISON, true, 5) - self:learnTalent(self.T_EXOTIC_WEAPONS_MASTERY, true, 5) + self:learnTalent(self.T_SPIT_POISON, true, 5, {no_unlearn=true}) + self:learnTalent(self.T_EXOTIC_WEAPONS_MASTERY, true, 5, {no_unlearn=true}) self.__show_special_talents = self.__show_special_talents or {} self.__show_special_talents[self.T_EXOTIC_WEAPONS_MASTERY] = true self.can_breath = self.can_breath or {} Index: game/modules/tome/data/timed_effects/magical.lua =================================================================== --- game/modules/tome/data/timed_effects/magical.lua (revision 6385) +++ game/modules/tome/data/timed_effects/magical.lua (working copy) @@ -2155,7 +2155,7 @@ local ohk = self.hotkey self.hotkey = nil -- Prevent assigning hotkey, we just did - self:learnTalent(self.T_ICE_STORM, true, eff.lvl) + self:learnTalent(self.T_ICE_STORM, true, eff.lvl, {no_unlearn=true}) self.hotkey = ohk self.replace_display = mod.class.Actor.new{ @@ -2172,7 +2172,7 @@ end end - self:unlearnTalent(self.T_ICE_STORM, eff.lvl) + self:unlearnTalent(self.T_ICE_STORM, eff.lvl, nil, {no_unlearn=true}) self.replace_display = nil self:removeAllMOs() game.level.map:updateMap(self.x, self.y) Index: game/modules/tome/dialogs/LevelupDialog.lua =================================================================== --- game/modules/tome/dialogs/LevelupDialog.lua (revision 6385) +++ game/modules/tome/dialogs/LevelupDialog.lua (working copy) @@ -178,7 +178,7 @@ -- Prodigies if self.on_finish_prodigies then - for tid, ok in pairs(self.on_finish_prodigies) do if ok then self.actor:learnTalent(tid, true) end end + for tid, ok in pairs(self.on_finish_prodigies) do if ok then self.actor:learnTalent(tid, true, nil, {no_unlearn=true}) end end end if not self.on_birth then @@ -300,89 +300,48 @@ function _M:learnTalent(t_id, v) self.talents_learned[t_id] = self.talents_learned[t_id] or 0 local t = self.actor:getTalentFromId(t_id) - if not t.generic then - if v then - if self.actor.unused_talents < 1 then - self:simplePopup("Not enough class talent points", "You have no class talent points left!") - return - end - if not self.actor:canLearnTalent(t) then - self:simplePopup("Cannot learn talent", "Prerequisites not met!") - return - end - if self.actor:getTalentLevelRaw(t_id) >= self:getMaxTPoints(t) then - self:simplePopup("Already known", "You already fully know this talent!") - return - end - self.actor:learnTalent(t_id, true) - self.actor.unused_talents = self.actor.unused_talents - 1 - self.talents_changed[t_id] = true - self.talents_learned[t_id] = self.talents_learned[t_id] + 1 - self.new_talents_changed = true - else - if not self.actor:knowTalent(t_id) then - self:simplePopup("Impossible", "You do not know this talent!") - return - end - if not self:isUnlearnable(t, true) and self.actor_dup:getTalentLevelRaw(t_id) >= self.actor:getTalentLevelRaw(t_id) then - self:simplePopup("Impossible", "You cannot unlearn this talent!") - return - end - self.actor:unlearnTalent(t_id, nil, true) - self.talents_changed[t_id] = true - local _, reason = self.actor:canLearnTalent(t, 0) - local ok, dep_miss, stats_ok = self:checkDeps() - if ok or reason == "not enough stat" or not stats_ok then - self.actor.unused_talents = self.actor.unused_talents + 1 - self.talents_learned[t_id] = self.talents_learned[t_id] - 1 - self.new_talents_changed = true - else - self:simpleLongPopup("Impossible", "You cannot unlearn this talent because of talent(s): "..dep_miss, game.w * 0.4) - self.actor:learnTalent(t_id) - return - end + local t_type, t_index = "class", "unused_talents" + if t.generic then t_type, t_index = "generic", "unused_generics" end + if v then + if self.actor[t_index] < 1 then + self:simplePopup("Not enough "..t_type.." talent points", "You have no "..t_type.." talent points left!") + return end + if not self.actor:canLearnTalent(t) then + self:simplePopup("Cannot learn talent", "Prerequisites not met!") + return + end + if self.actor:getTalentLevelRaw(t_id) >= self:getMaxTPoints(t) then + self:simplePopup("Already known", "You already fully know this talent!") + return + end + self.actor:learnTalent(t_id, true) + self.actor[t_index] = self.actor[t_index] - 1 + self.talents_changed[t_id] = true + self.talents_learned[t_id] = self.talents_learned[t_id] + 1 + self.new_talents_changed = true else - if v then - if self.actor.unused_generics < 1 then - self:simplePopup("Not enough generic talent points", "You have no generic talent points left!") - return - end - if not self.actor:canLearnTalent(t) then - self:simplePopup("Cannot learn talent", "Prerequisites not met!") - return - end - if self.actor:getTalentLevelRaw(t_id) >= self:getMaxTPoints(t) then - self:simplePopup("Already known", "You already fully know this talent!") - return - end - self.actor:learnTalent(t_id) - self.actor.unused_generics = self.actor.unused_generics - 1 - self.talents_changed[t_id] = true - self.talents_learned[t_id] = self.talents_learned[t_id] + 1 + if not self.actor:knowTalent(t_id) then + self:simplePopup("Impossible", "You do not know this talent!") + return + end + if not self:isUnlearnable(t, true) and self.actor_dup:getTalentLevelRaw(t_id) >= self.actor:getTalentLevelRaw(t_id) then + self:simplePopup("Impossible", "You cannot unlearn this talent!") + return + end + self.actor:unlearnTalent(t_id, nil, true, {no_unlearn=true}) + self.talents_changed[t_id] = true + local _, reason = self.actor:canLearnTalent(t, 0) + local ok, dep_miss, stats_ok = self:checkDeps() + self.actor:learnTalent(t_id, true, nil, {no_unlearn=true}) + if ok or reason == "not enough stat" or not stats_ok then + self.actor:unlearnTalent(t_id) + self.actor[t_index] = self.actor[t_index] + 1 + self.talents_learned[t_id] = self.talents_learned[t_id] - 1 self.new_talents_changed = true else - if not self.actor:knowTalent(t_id) then - self:simplePopup("Impossible", "You do not know this talent!") - return - end - if not self:isUnlearnable(t, true) and self.actor_dup:getTalentLevelRaw(t_id) >= self.actor:getTalentLevelRaw(t_id) then - self:simplePopup("Impossible", "You cannot unlearn this talent!") - return - end - self.actor:unlearnTalent(t_id, nil, true) - self.talents_changed[t_id] = true - local _, reason = self.actor:canLearnTalent(t, 0) - local ok, dep_miss, stats_ok = self:checkDeps() - if ok or reason == "not enough stat" or not stats_ok then - self.actor.unused_generics = self.actor.unused_generics + 1 - self.talents_learned[t_id] = self.talents_learned[t_id] - 1 - self.new_talents_changed = true - else - self:simpleLongPopup("Impossible", "You can not unlearn this talent because of talent(s): "..dep_miss, game.w * 0.4) - self.actor:learnTalent(t_id) - return - end + self:simpleLongPopup("Impossible", "You cannot unlearn this talent because of talent(s): "..dep_miss, game.w * 0.4) + return end end self:updateTooltip()