Automatically reducing talent levels with requirements

Moderator: Moderator

Post Reply
Message
Author
yufra
Perspiring Physicist
Posts: 1332
Joined: Tue Jul 13, 2010 2:53 pm

Automatically reducing talent levels with requirements

#1 Post by yufra »

The original post of this idea occurred in this thread. I hope this thread will guide the development or discarding of this idea.

The idea is to have talents automatically reduce their talent level as their requirements change. The initial strategy is to include a call to ActorTalent:canLearnTalent the ActorTalent:knowTalent, ActorTalent:getTalentLevel and ActorTalent:getTalentLevelRaw functions. To do so a new function was introduced:

Code: Select all

function _M:getTalentLevelRawNoCheck(id)
   if type(id) == "table" then id = id.id end
	return self.talents[id] or 0
end

function _M:getTalentLevelRaw(id)
   if type(id) == "table" then id = id.id end
   local raw_level = self:getTalentLevelRawNoCheck(id)
   if not self.player then return raw_level end
   local offset = 0
    local t = self.talents_def[id]
   -- Keep reducing the raw talent level until the requirements are met
   while (raw_level + offset > 0) and not self:canLearnTalent(t, offset) do
       offset = offset - 1
        end
   return raw_level + offset
end
The ActorTalent:canLearnTalent needs to call getTalentLevelRawNoCheck to avoid infinite recursion (and actually work).

There have been a few other surprises along the way. First, all of the resource pools and racial talents broke. This is because they are of either the "base/race" or "base/class" categories, which are not actually learned by the player. After adding those two categories to the base birth descriptor (they are hidden, so they never appear in any of the displays) the pools appeared again, but I do not know if this break NPC talents yet.

EDIT: Oh, and one of the main concerns here is performance since the requirements are checked every time the talent level is checked.

EDIT2: I modified the code above so that only the player has its talents reduced.
<DarkGod> lets say it's intended

darkgod
Master of Eyal
Posts: 10751
Joined: Wed Jul 24, 2002 9:26 pm
Location: Angolwen
Contact:

Re: Automatically reducing talent levels with requirements

#2 Post by darkgod »

Yeah this actually probably breaks many things, like escort learned talents which are force-learnt (by design) and so on :/
NPCs are probably really broke too as they are also force learnt
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)

yufra
Perspiring Physicist
Posts: 1332
Joined: Tue Jul 13, 2010 2:53 pm

Re: Automatically reducing talent levels with requirements

#3 Post by yufra »

Well NPCs were an easy fix by putting the "if not self.player then return raw_level" check before checking the requirements. The escort quests are indeed a bit trickier. At first I thought about modifying the ActorTalent:learnTalent force check like this:

Code: Select all

	if not force then
		local ok, err = self:canLearnTalent(t)
		if not ok and err then return nil, err end
	elseif not self:knowTalentType(t.type[1]) then
		self:learnTalentType(t.type[1], true)
	end
That has the obvious drawback of actually teaching the talent type in such a way as the player being able to dump points into it... a definite no. Then I noticed this line in canLearnTalent:

Code: Select all

if not self:knowTalentType(t.type[1]) and not t.type_no_req then
That got me thinking about adding a "talents_minimum_level" table to the ActorTalents init and to support force-learnt talents.

Code: Select all

function _M:canLearnTalent(t, offset)
	-- Check forced-minimum levels
	if self:getMinimumTalentLevelRaw(t) >= self:getTalentLevelRawNoCheck(t) then return true end
	-- Check prerequisites
	if rawget(t, "require") then
...
function _M:getMinimumTalentLevelRaw(id)
	if type(id) == "table" then id = id.id end
	return self.talents_minimum_level[id] or 0
end
...
function _M:learnTalent(t_id, force, nb)
...
	self.talents[t_id] = (self.talents[t_id] or 0) + (nb or 1)
    if force then
        self.talents_minimum_level[t_id] = self.talents[t_id]
    end
	if t.on_learn then t.on_learn(self, t) end

	self.changed = true
	return true
end
This (untested) code would circumvent the canLearnTalent requirement checking if we are below or at a specific talents minimum level, which defaults to zero. Talents that are forcibly learnt reset their minimum level to the raw talent level after they are taught, but other methods could be thought of. I will highlight one potential problem with this mechanism for debate since I am not sure what would be the best strategy:

The player learns heightened senses on their own, using a ring of cunning to meet the requirements. If they remove the ring, they lose the benefits of the talent. They then rescue a repented thief and chose to increase their heigtened senses talent level to 2. This also sets the minimum raw talent level to 2, and therefore they can remove the ring of cunning and have the benefits of both levels.

There is of course still the issue of performance on lower end systems, so if this approach is deemed undesirable DG just say so.
<DarkGod> lets say it's intended

Post Reply