Stun Expiration
Starting on fixing the removal logic of stun (the stunning fist version; possibly some monster effects).
This commit should restore the intention of the original logic, which tries to actually match the way the P&P rules say you should count the rounds. It was being fouled up because there's an extra initiative signal sent when the turn wraps around with arguments it didn't account for.
However, the logic is still slightly faulty if the attacker and target have the same initiative number. If the tie is broken with the target going first, they won't actually lose a turn. I'm still trying to figure out how best to solve that, because I don't think enough information is actually stored for the precisely correct behavior.
So, I've been thinking a while about how to make the ticking more precise, but I don't have any ideas that won't be a lot more fiddly and complicated in various ways. The logic that's in there right now is only a problem if you're stunning someone with the same initiative number, or if a lot of people have that initiative. That isn't a likely occurrence unless you go wild delaying turns, so I'm inclined to leave it.
The other option would be to completely replace the ticking with the usual ticker that runs on the target's turn. But I'm not sure I have the right information for that (e.g. the address of the Stunned cond struct).
Well the way the game resolves same initiative is through sub initiative. If there isn't a spare arg you could pack it with bitmasking. Alternatively, maybe consider an aux ticker condition for wider usage... though I suppose that could get hairy.
You're pretty sure that this is the only condition that actually listens to the signal currently?
If I made the initiative tick on every transition with some packing scheme with the subinitiative, that might work. And some logic could be used to try to catch cases where people saved in the middle of combat while someone was stunned. My concern with that was just what other stuff it would affect.
Yeah, pretty sure (are you familiar with the conditions list on the wiki? https://github.com/GrognardsFromHell/DllDocumentation/wiki/Conditions-(List) ) BTW I think you can send the signal with subinitiative on the 2nd arg rather than packing it (though I think toee actually treats it as int64 anyway).
Both args are already taken unfortunately. It sends the old and the new initiative. And I think that's necessary, because even if every turn sends a signal, delayed turns might end up with the exact number being skipped.
Ah ok. So here's a little trick: you can add fields to event objects 🙂 As long as they come after the original fields of course.
It's a D20 signal, though, so it'd probably be better not to add fields to that event object, right?
I don't think it's a big deal to pack the values. You'd have to be doing something seriously degenerate to have an initiative and subinitiative that don't fit in 16 bits each. I think the game uses something like 100*dex for initializing the subinitiative, so you'd need a dexterity score of 656 for it to be a problem.
That's true, I just hate bit packing, always feels so hacky 😛 Adding fields that are after the existing ones shouldn't be an issue. We already hooked all the places that actually create the object, and vanilla code always takes it as a pointer, blissfully unaware that it's a larger struct now.
However, the best approach is probably to make the signal arg a pointer to a suitable struct containing all the relevant info. You could even add time stamps and whatnot.
So, I've been studying this a bit, and there's an additional complication.
The stuff that's been pulled into Temple+ just calls an original function with the relevant initiatives. That function is actually responsible for some BeginRound stuff too, for instance, so it's more complicated than just sending the initiative step signal.
However, initiative stepping in combat also isn't the only place that function is called. When out of combat, the function that handles world time also tries to count initiatives from 25 to 0 every 6 seconds. And that doesn't appear to be replicated, either. Without replacing that, the old sort of signal would still be sent out of combat.
So, obviously, that's a lot more complicated than just sending one different signal that is only listened to by one condition.