ToME: the Tales of Maj'Eyal

Everything about ToME
It is currently Thu Aug 16, 2018 12:05 am

All times are UTC




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue Oct 10, 2017 2:54 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
So, against my better judgement, I fired up a couple Possessor characters recently, on the strength of a forum description of them as a "faceplant" (which in my experience translates from forum to English roughly as "might actually survive Normal-mode endgame by some freak miracle" :roll: ). Impressions so far:
  • Y'know what I've done virtually none of while playing a Possessor? Actually possess any bodies. It's exactly the problem I was worried about from the very beginning: a stored body is effectively a non-renewable resource, which means that for all practical purposes you can never use it, because you can never be certain you shouldn't have saved it for a greater need later.
  • What is even the point of limiting the types of creatures the player can possess? It's just another cripplingly limited resource like inscription slots, except the player can't even plan how to use this resource, because there's no way of knowing in advance what kinds of creatures you'll need to be able to possess. (I actually had to resort to source diving to assemble a list of all creature types and pick out a list of types to avoid like "vermin" or "immovable", just to be sure I had enough slots to cover the rest.)
  • Beyond those showstoppers, there are various places that could use a bit more information shown to the player:
    • Various talent tooltips that say, "blah blah only if you have room in your body storage" could stand to include an answer to the obvious question: "…well, do I have room in my body storage?"
    • In various spots that describe or let you select a stored bodies talents, it would be useful to have a note to the effect that, no, you shouldn't bother choosing Flurry if you're not dual-wielding, or Stunning Blow if you're not wielding a two-hander, or Assault if you're not wearing a shield, or pretty much any talent whose on_pre_use() isn't happy.
    • Information about a body's Cannibalize penalty would be useful in various talent tooltips listing bodies.
    • While gaining a level on returning to your own body can be a nice surprise, I'd prefer a bit of advance warning. :wink:

I've never been one to let little things like that stop me, though, :twisted: so without further ado, I present my new Proper Possession addon, which allows healing and regeneration in a possessed body, eliminates the fiddling with creature types, and adds useful possessor-related information in various places. See the Frequently Asked Questions below for more details.

And since I imagine some players might be interested in the informational bits while still inexplicably insisting that Possessors are fine as is, :mrgreen: I also stripped out the offending bits to make a related Possessor Tweaks addon that only includes the informational bits. Further bits of information or other tweaks may also be added to these addons in the future if I find anything else that annoys me.

[Oh, and as per license requirements, be advised that this addon uses a modified version of an image by Lorc from Game-icons.net, under the CC-BY-3.0 license.]

[Technical notes:
Code:
Hooks:
  ToME:load [meatball surgery on various possessor-related effects and talents]
Superload:
  mod.dialogs.AssumeForm:
    generateList() [add pre-use condition notes and selected-talent markers to talents list]
  mod.dialogs.AssumeFormSelectTalents:
    generateList() [add pre-use condition notes to talents list]
    use() [reapply pre-use condition notes as we select/unselect talents]
  mod.class.Birther:
    on_register() [Possessor Tweaks only; show an addon collision dialog if necessary]

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Last edited by Zizzo on Fri May 18, 2018 2:41 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Oct 10, 2017 3:00 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
Frequently Asked Questions:

What's the difference between Proper Possession and Possessor Tweaks? Can I use both?

Proper Possession includes all the functionality of Possessor Tweaks, and so the two should not be used together. The character creation dialog will warn you if you try to create a character with both addons enabled.

What extra information does this addon provide?

Both addons provide the following functionality:
  • If you accumulate enough stored experience while in a possessed body to gain a level, you will be notified via a Stored Level informational effect in the buffs display.
  • The tooltips of the Possess, Assume Form and Destroy Body talents are modified to include the number of bodies in your body storage and its current maximum capacity.
  • The tooltips of the Assume Form and Destroy Body talents are further modified to indicate stored bodies that have a Cannibalize penalty.
  • The icon for the Possess talent on the hotkeys toolbar now displays the number of bodies in your body storage and its current maximum capacity.
  • Body talents listed in the Assume Form and Assume Form: Select Talents dialogs are modified to include annotations like (2H), (Shld) or (Dual) if they require wielding, respectively, a two-handed weapon, a shield, or dual weapons. In addition, a (?) annotation will be added to talents with usage conditions that the player does not satisfy (including the aforementioned wield restrictions).
  • If you have selected talents for a body via the Assume Form: Select Talents dialog, the description of that body in the Assume Talents dialog will add a (+) annotation to the talents you've selected.
  • [new in release 2.1.0] If the game option 'UI | Show body resources in Assume Form dialog' is enabled, descriptions of your stored bodies in the Assume Form dialog will include descriptions of the body's resource levels and resource regeneration rates.

In addition, Proper Possession provides the following functionality not provided by Possessor Tweaks:
  • The Assume Form effect no longer prevents healing or regeneration.
  • The Possess talent no longer restricts the types of creatures you can possess. (To clarify, this refers specifically to creature types like "humanoid" or "undead", not creature ranks like "elite" or "unique", which continue to be constrained by your Possess talent level.)

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Last edited by Zizzo on Mon Jun 11, 2018 1:57 am, edited 2 times in total.

Top
 Profile  
 
PostPosted: Tue Feb 27, 2018 4:39 pm 
Offline
Wayist

Joined: Fri May 16, 2014 6:30 pm
Posts: 29
I got in touch with a very strange problem with the Proper Possession add-on:

If I allow adventurers to use the possession talents (via other addons, obviously), they cannot get healed or regenerated in an assumed form! The stored level effect works just fine, though.

I tested the case for possessor and made sure that healing and regeneration all works, which means that the add-on does function well. I also checked the code in this add-on and found the load.lua that allows healing, but I cannot find anything special for adventure.

Do you have any idea why healing and regeneration do not work on adventurer? Thanks.


Top
 Profile  
 
PostPosted: Wed Feb 28, 2018 2:31 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
wuxiangjinxing wrote:
I got in touch with a very strange problem with the Proper Possession add-on:

If I allow adventurers to use the possession talents (via other addons, obviously), they cannot get healed or regenerated in an assumed form! The stored level effect works just fine, though.

I tested the case for possessor and made sure that healing and regeneration all works, which means that the add-on does function well. I also checked the code in this add-on and found the load.lua that allows healing, but I cannot find anything special for adventure.

Do you have any idea why healing and regeneration do not work on adventurer? Thanks.

[sound F/X: testing] Well, I managed to reproduce the problem once, but I'm pretty sure that was the result of an unrelated bug that caused me to end up with a point in the Possess talent without said talent's callbacks being installed (specifically, the callbackOnTemporaryEffectAdd callback that modifies the Assume Form effect to remove the no-healing flags). I can only guess that's what happened to you.

Seriously, though, I'm surprised you were able to use the possession talents at all with an Adventurer without tripping over a lot of stack traces. Turns out that there are several places in the code, both in my addons and in the original game code, that assume that your bodies storage from the Bodies Reserve talent is already present, which might not be the case for an Adventurer.

For now, I'm pushing out v1a for both addons, with some workarounds for the aforementioned stack traces. It won't fix your current character (We Apologize for the Inconvenience™), but if I'm right about what caused it, it shouldn't happen again for new characters (at least, it's currently working properly for my test characters). And let me know if you get any stack traces for any talent methods that I missed.

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Top
 Profile  
 
PostPosted: Wed Feb 28, 2018 3:42 am 
Offline
Wayist

Joined: Fri May 16, 2014 6:30 pm
Posts: 29
The bodies storage problem you mentioned could be solved by learning Bodies Reserve before Possess.

Besides, could you please spend some time explaining what you did? It may be a good opportunity for me to learn something in modding. Thanks.

Zizzo wrote:
wuxiangjinxing wrote:
I got in touch with a very strange problem with the Proper Possession add-on:

If I allow adventurers to use the possession talents (via other addons, obviously), they cannot get healed or regenerated in an assumed form! The stored level effect works just fine, though.

I tested the case for possessor and made sure that healing and regeneration all works, which means that the add-on does function well. I also checked the code in this add-on and found the load.lua that allows healing, but I cannot find anything special for adventure.

Do you have any idea why healing and regeneration do not work on adventurer? Thanks.

[sound F/X: testing] Well, I managed to reproduce the problem once, but I'm pretty sure that was the result of an unrelated bug that caused me to end up with a point in the Possess talent without said talent's callbacks being installed (specifically, the callbackOnTemporaryEffectAdd callback that modifies the Assume Form effect to remove the no-healing flags). I can only guess that's what happened to you.

Seriously, though, I'm surprised you were able to use the possession talents at all with an Adventurer without tripping over a lot of stack traces. Turns out that there are several places in the code, both in my addons and in the original game code, that assume that your bodies storage from the Bodies Reserve talent is already present, which might not be the case for an Adventurer.

For now, I'm pushing out v1a for both addons, with some workarounds for the aforementioned stack traces. It won't fix your current character (We Apologize for the Inconvenience™), but if I'm right about what caused it, it shouldn't happen again for new characters (at least, it's currently working properly for my test characters). And let me know if you get any stack traces for any talent methods that I missed.


Top
 Profile  
 
PostPosted: Fri Mar 02, 2018 4:07 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
wuxiangjinxing wrote:
The bodies storage problem you mentioned could be solved by learning Bodies Reserve before Possess.

Well, yeah, but I tripped over it often enough during testing, and we don't want to depend on the player doing that in the right order.

wuxiangjinxing wrote:
Besides, could you please spend some time explaining what you did? It may be a good opportunity for me to learn something in modding. Thanks.

Umm… okay? Most of what I did in this release involved modifying existing talents in place, which can be a bit tricky if you're not careful. So for instance, this is a rough mockup of two of the talent changes I made in this release:
Code:
-- We do our work in the ToME:load hook, after talent definitions have been
-- loaded.
class:bindHook('ToME:load', function(self, data)
  local Talents = require 'engine.interface.ActorTalents'
  -- This is where talent definitions are placed by the newEffect{} method.
  -- It's indexed by the talent ID, which is usually "T_" followed by the
  -- talent name in all caps, unless the talent definition specifies
  -- something different.
  local TD = Talents.talents_def

  -- Destroy Body's on_pre_use() method [which, among other things, is used
  -- to determine the highlighting of the talent icon on the hotkeys
  -- toolbar, and thus can break stuff immediately if something goes wrong]
  -- assumes the bodies_storage{} subtable is present.  We modify it to
  -- check first.

  -- We keep the original method so we can call it from our new method.  We
  -- can get away with stowing it in a local variable because it doesn't
  -- have to be persisted into the savefile.
  local orig_destroy_body_on_pre_use = TD.T_DESTROY_BODY.on_pre_use
  -- Now we replace it with our new method.
  TD.T_DESTROY_BODY.on_pre_use = function(self, t, silent)
    -- If we don't have a bodies storage, we obviously can't destroy
    -- anything out of it. ;)
    if not self.bodies_storage then
      if not silent then
        game.logPlayer(self, 'You do not have a bodies storage.')
      end
      return false
    end
    -- Now that we know bodies_storage{} is present, we can safely pass
    -- through to the original method.
    return orig_destroy_body_on_pre_use(self, t, silent)
  end

  -- Similarly, Bodies Reserve has a utility method hasRoom() that's used
  -- in a couple places, and it also assumes bodies_storage{} has been set.
  local orig_bodies_reserve_hasRoom = TD.T_BODIES_RESERVE.hasRoom
  TD.T_BODIES_RESERVE.hasRoom = function(self, t)
    -- In this case we can just check for bodies_storage{} and pass through
    -- to the original method immediately.
    return self.bodies_storage and orig_bodies_reserve_hasRoom(self, t)
  end
end)

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Top
 Profile  
 
PostPosted: Fri Mar 02, 2018 1:40 pm 
Offline
Wayist

Joined: Fri May 16, 2014 6:30 pm
Posts: 29
After a series of try-and-error work, I found out the key codes (in other words, the difference between the new and old versions) to solve the healing problem for adventurer is:

TD.T_POSSESS.info = function(self, t)
local text = t.addon.possessor_fixes.orig_info(self, t)
-- Strip out the bit about limited body types. >;)
local idx = text:find('You may only steal the body of creatures of the following types:')
if idx then text = text:sub(1, idx-1) end
-- Add in current capacity of body storage.
if self.bodies_storage then
local repl = ('new body in your storage (currently %d/%d).'):format(#self.bodies_storage, self.bodies_storage.max)
text = text:gsub('new body in your storage.', repl)
end
return text
end

However, I cannot understand why this is the problem. As you can see this is not even related to removing healing preventer. So could you please explain what happend in the old version and how the problem is solved? Thanks.

Zizzo wrote:
wuxiangjinxing wrote:
The bodies storage problem you mentioned could be solved by learning Bodies Reserve before Possess.

Well, yeah, but I tripped over it often enough during testing, and we don't want to depend on the player doing that in the right order.

wuxiangjinxing wrote:
Besides, could you please spend some time explaining what you did? It may be a good opportunity for me to learn something in modding. Thanks.

Umm… okay? Most of what I did in this release involved modifying existing talents in place, which can be a bit tricky if you're not careful. So for instance, this is a rough mockup of two of the talent changes I made in this release:
Code:
-- We do our work in the ToME:load hook, after talent definitions have been
-- loaded.
class:bindHook('ToME:load', function(self, data)
  local Talents = require 'engine.interface.ActorTalents'
  -- This is where talent definitions are placed by the newEffect{} method.
  -- It's indexed by the talent ID, which is usually "T_" followed by the
  -- talent name in all caps, unless the talent definition specifies
  -- something different.
  local TD = Talents.talents_def

  -- Destroy Body's on_pre_use() method [which, among other things, is used
  -- to determine the highlighting of the talent icon on the hotkeys
  -- toolbar, and thus can break stuff immediately if something goes wrong]
  -- assumes the bodies_storage{} subtable is present.  We modify it to
  -- check first.

  -- We keep the original method so we can call it from our new method.  We
  -- can get away with stowing it in a local variable because it doesn't
  -- have to be persisted into the savefile.
  local orig_destroy_body_on_pre_use = TD.T_DESTROY_BODY.on_pre_use
  -- Now we replace it with our new method.
  TD.T_DESTROY_BODY.on_pre_use = function(self, t, silent)
    -- If we don't have a bodies storage, we obviously can't destroy
    -- anything out of it. ;)
    if not self.bodies_storage then
      if not silent then
        game.logPlayer(self, 'You do not have a bodies storage.')
      end
      return false
    end
    -- Now that we know bodies_storage{} is present, we can safely pass
    -- through to the original method.
    return orig_destroy_body_on_pre_use(self, t, silent)
  end

  -- Similarly, Bodies Reserve has a utility method hasRoom() that's used
  -- in a couple places, and it also assumes bodies_storage{} has been set.
  local orig_bodies_reserve_hasRoom = TD.T_BODIES_RESERVE.hasRoom
  TD.T_BODIES_RESERVE.hasRoom = function(self, t)
    -- In this case we can just check for bodies_storage{} and pass through
    -- to the original method immediately.
    return self.bodies_storage and orig_bodies_reserve_hasRoom(self, t)
  end
end)


Top
 Profile  
 
PostPosted: Sat Mar 03, 2018 12:30 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
wuxiangjinxing wrote:
However, I cannot understand why this is the problem. As you can see this is not even related to removing healing preventer. So could you please explain what happend in the old version and how the problem is solved? Thanks.

Ah, I see. Well, for that, the relevant bit is the callback. Callbacks, if you're not familiar with them, are amazingly useful things. In particular, this addon adds a callbackOnTemporaryEffectAdd() callback to the Possess talent:
Code:
TD.T_POSSESS.callbackOnTemporaryEffectAdd = function(self, t, eff_id, def, p)
  if eff_id == self.EFF_POSSESSION then
    -- Walk the __tmpvals list, removing the vals that prevent healing
    -- and keeping the rest.
    [...]
  end
end

So when the player puts the first talent point into Possess, our callback is installed onto the player, and gets invoked every time the player gains a temporary effect. What our callback does is, if the effect we just gained is the Assume Form effect, we modify it in place, removing the bits that prevent healing and regeneration.

Now, the one time I was able to reproduce the bug as you described it, I saw that I had a point in Possess, but our callback somehow hadn't been installed (and hence healing and regeneration were still being blocked). Since I was still getting the stack traces I described above at this point, my hypothesis was that the stack trace had interrupted the stuff that normally happens when you learn a talent, at a point before callbacks from the talent would have been installed, so the player was left in an inconsistent state. The fix, then, was to prevent the stack traces so that the callback would get installed.

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Top
 Profile  
 
PostPosted: Sat Mar 03, 2018 1:56 pm 
Offline
Wayist

Joined: Fri May 16, 2014 6:30 pm
Posts: 29
That's awesome! Thank you very much for the explanation.


Top
 Profile  
 
PostPosted: Sat Jun 02, 2018 2:29 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
Based on some much-appreciated feedback over on Snarvid's Possessor guide, I'm working on some improvements to this pair of addons. Not ready to release yet, but I can preview one important new feature. See, it turns out that my annotations like (Shld) and (?) on various talents aren't as clear in their meaning to everyone else as they were to me. :oops:

Fortunately, it wasn't too hard to add some explanations to the talent descriptions, both in the Assume Form dialog:
Attachment:
assume-form.png
assume-form.png [ 183.76 KiB | Viewed 1342 times ]

and in the Select Talents dialog:
Attachment:
select-talents.png
select-talents.png [ 225.87 KiB | Viewed 1342 times ]

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Top
 Profile  
 
PostPosted: Tue Jun 05, 2018 2:08 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
And with some trepidation, I release v2 for both addons. In addition to the extra information described above, the main new feature is a significant re-architecting of how we detect equipment preconditions for talents:
  • The range of preconditions we can "scrape" out of a talent's .on_pre_use() is significantly increased, including requiring a cloak (assorted Steamtech/Avoidance talents), light armor, a staff, psiblades, and steamsaws and steamguns (both single and dual).
  • For talents that don't have a .on_pre_use() method, or have one that can't be usefully scraped (archery-related talents are notorious for this), we add extra information of our own about their equipment preconditions. This allows us to cover all of the above cases, plus things like requiring a ranged weapon in general or a sling/bow in particular, and is extensible enough to cover even oddball requirements like an offhand mindstar (Mechanical Arms) or shield plus ranged weapon (various Skirmisher talents).
  • The extra-information mechanism described above is also accessible to addon developers, as described in the documentation.

Now, there's a good chance I've missed some talents (various Temporal Warden talents, for instance, I wasn't really sure what to do with); let me know about them and I'll update to cover them.

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Top
 Profile  
 
PostPosted: Mon Jun 11, 2018 1:04 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
By request, another feature, going out in v2a for both: the descriptions of your stored bodies in the Assume Form dialog can now optionally include descriptions of that body's resources and resource regeneration rates, controlled by new game option 'UI | Show body resources in Assume Form dialog' (off by default, so be sure to turn it on if you're interested in it).

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Top
 Profile  
 
PostPosted: Wed Jun 20, 2018 8:48 am 
Offline
Wayist

Joined: Thu Mar 16, 2017 5:54 am
Posts: 16
This is by no means pressing or anything but I would love to see the Talent Cannibalize be unaffected by the healing debuff from Solipsism. Thanks in advance


Top
 Profile  
 
PostPosted: Sat Jun 23, 2018 12:44 am 
Offline
Sher'Tul Godslayer

Joined: Thu Jan 23, 2003 8:13 pm
Posts: 1553
Location: A shallow water area south of Bree
ScarletDragon wrote:
This is by no means pressing or anything but I would love to see the Talent Cannibalize be unaffected by the healing debuff from Solipsism. Thanks in advance

You mean the thing where some of your healing goes to Psi instead? [sound F/X: source diving] That may be happening at too low a level for this addon to manipulate easily.

_________________
"Blessed are the yeeks, for they shall inherit Arda..."


Top
 Profile  
 
PostPosted: Mon Jul 09, 2018 4:21 am 
Offline
Wayist

Joined: Thu Mar 16, 2017 5:54 am
Posts: 16
That's exactly what I mean. It does seem like a pretty deep interaction so if you can't that's fine. Although if we are thinking outside the box I guess an alternative would be to boost the healing by the amount of the Solipsism reduction. Well if you want to be accurate the boost would itself be affected so the numbers would be 18%-200% based on the level of reduction


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group