nwnxee / unified

Binaries available under the Releases tab on Github
https://nwnxee.github.io/unified
GNU General Public License v3.0
131 stars 92 forks source link

Damage types - any possibilities of creating custom damages #775

Closed Baaleos closed 4 years ago

Baaleos commented 4 years ago

Just wondering if Damage types are any more flexible than they were in 1.69. Eg: With 2da, tlk changes etc - can we add new custom damage types - such as Psionics Or would this require engine changes? From how the damage plugin works - I know that the ApplyDamgeEffectHandler effect argument takes the damage types as individual int's for each recognised damage type. Eg: 0-15 or something like that.

In this regard, it is probably hardcoded.

Im just wondering if it might be possible to add pseudo support for custom damages by using a custom effect handler?

Eg: We could use the damage plugin to detect incoming damage, cancel it, then apply damage via DealDamage or another custom method (to avoid any reporting) - then report the damage using custom tlk and 2da data?

Eg: I believe there is a iprp_damagetype.2da - which at least allows for creation of damage entries on weapons etc.

I was thinking that perhaps the damage plugin could help with this - perhaps a method called

int RegisterDamage(int tlkId, string color, string name);

Eg: int newDamage = RegisterDamage(1445932,"","Psionic"); effect damage = EffectDamage(20, newDamage,DAMAGE_POWER_ENERGY);

This method could then register into the servers memory that a new damage type called 'Psionic', using tlk entry 1445932 etc, with a specific color tag has been created.

Perhaps from this point on - a builder could use a custom Damage effect or nwnx method to deal damage using custom damages - this could be a way to get around the fact that the damage effect has individual int's for the separate damage types. To use custom damage types, we would probably need to call our own damage handler.

Just realising that color tags are probably handled client side - so registering color tags prob irrelevant.

Anyone got any insight into best way to implement this?

GoLoT commented 4 years ago

I don't think this is possible. Not without a lot of effort to go around the current functions and fixed-size arrays that are used for the damage types. Many places have hardcoded limits on the number of damage types, including some messages passed around internally that expect a specific amount of parameters when (de)serializing. There is also a limit on the number of damage flags passed to the reduction/immunity functions that are stored on a 16 bit variable that holds values for the 3 physical damage types and 12 or 13 elemental damages, leaving no room for more flags.

Hopefully I'm wrong and it's doable (I can think of very complex ways of doing it), but even then the client would probably have to be adapted to receive messages with more damage types. Either that or the new damage types should be handled differently and reported to clients through custom combat log messages, otherwise the client would be unaware of the damage types and wouldn't be able to print the damage.

But as I said, hopefully someone can prove me wrong.

mtijanic commented 4 years ago

This is not possible without clientside (and netcode) changes, unfortunately. What you could do is make some of the existing damage types generic. For example, change divine/sonic to custom1/custom2, and in the tlk entries change their name/tags to <CUSTOM1234> or something. Then, prior to signalling the damage to the client, you set the custom token to the name/color you want.

Aside from being ridiculously complicated, this also means that you can have at most 2 custom types in a single damage event (and sonic/divine are custom now). If you need more, you could move other types to custom as well, but you'll never be able to have an effect that deals 1 damage point of every type (would need to break it into multiple damage events).

Baaleos commented 4 years ago

Sounds like the best that can be achieved on this would be something ad-hoc. Eg: Directly dealing damage via DealDamage (which bypasses reporting) from nwnx_damage and then report it via custom reporting - which would allow for custom name/colors via SendMessageToPC or possibly via nwnx_chat to send server messages etc.