Dendro implementation notes #855
Replies: 3 comments 1 reply
-
|
On Maybe what we can do is (still not quite modifiers), instead of: r.Durability = make([]combat.Durability, attributes.ElementDelimAttachable)
r.DecayRate = make([]combat.Durability, attributes.ElementDelimAttachable)Where Durability is basically an array of length number of elements, add a new type say type ReactableModifiers int
const (
ModifierPyro ReactableModifiers = iota
// .. regular stuff
ModifierBurning
ModifierBurningFuel
// .. so on
)
func (r ReactableModifier) Element() attributes.element {
return attributes.Pyro // return whatever element each modifier contains underlying
}It's not very different from just adding it as elements but keeps elements pure and a 1:1 match with in game. |
Beta Was this translation helpful? Give feedback.
-
|
Some additional notes for Burning from Carrier5b5, translated by Koli |
Beta Was this translation helpful? Give feedback.
-
|
Some additional tests from @k0l11 25 dendro -> 25 pyro -> 50 pyro: https://youtu.be/_ZT07HU81xQ Thoma Q lands roughly at frame 200 and ends roughly at frame 920, lasting ~720 frames aka. the full duration of a 50 pyro modifier. This shows that additional pyro application attaches to pyro modifiers and does not affect the burning modifier. |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This is to keep track Dendro implementation notes/thoughts:
Gadgets
Will need to implement generic gadgets to handle proper interaction with Bloom
All gadgets need to implement
combat.Targetinterface. This is to make sure gadgets can be added to the combat system. Gadgets should live for as long as it hasdurabilityor unless adurationis set.Default implementation
Should provide a default template providing common functions that specific gadgets can build upon. Something like:
combat.Targetrefactor requiredWe should remove the following methods of
combat.Target. These methods really aren't useful to gadgets. Only time these methods are used are typically on event hooks, which would check for type == Enemy anyways. In addition,combat.Handlerdoesn't actually need to know if a target is alive or how much hp it has.We can refactor
combat.Targetto the following:This way
AttackWillLandcan handle any dead or alive checks. Alternatively change it so that dead targets are removed from the targets array. Only problem with this is that logging needs to be changed to log not by target index but by some sort of target key and target key cannot be duplicates.Also
AuraContains(e ...attributes.Element) boolcan be moved to a different interface in combat, and the absorb check be changed accordingly:Modifiers
In the current implementation, gcsim is treating auras as some sort of array of buckets attached to each target object. In reality, auras are just modifiers, which are fairly generic properties that are attached to just about anything. The name of the modifier forms a unique key, such that each target can only have on modifier of the same name. Depending on the properly set, reapplying a modifier with the same name when one exist can either replace, refresh certain properties, or do nothing.
Historically for each "aura" (or existing element), you just had one modifier. Usually something like
FireModifierfor attached pyro, orElectroModifierfor attached electro. This made our array of whatever buckets sort of work.However with Burning, we are introducing 2 new modifiers (
burningandburning_fuel) with elements attached BUT:This throws a bit of a wrench into our implementation because gcsim is treating modifiers as having a 1 to 1 relationshp with element types. To fix this we need to refactor the
reactable.Durabilityandreactable.DecayRateslice to reflect modifiers instead. It should look something like the following:This should allow us to have multiple of the same element. However, this also means that any code checking for existing
pyrowill have to check bothreactable.Modifiers[ModifierPyro]andreactable.Modifiers[ModifierBurning]as both can containpyroNote on multiple of the same element
When a reaction occurs and there are multiple modifiers with the same element present (say
ModifierBurningandModifierPyro), all these modifiers will have their elements reduced. The amount of reacted durability is based on the modifier with the max durability.For example, suppose we have a target with the following modifiers:
If we apply 50 anemo to this target, the amount of reacted durability (for the purpose of calculating the resultant swirl attack) is
max(40, 25). However, both modifiers will have their durability reduced by50 * 1/2 = 25(i.e. reaction multiplier for anemo). So the result is, the target will be left with:ModifierPyrohere is fully removed. In addition, we will also get a swirl attack that haspyrodurability of1.25 * 25 + 23.75 = 55.Currently, we have
ModifierBurningandModifierBurningFuelas newly introduced modifiers that have existing elementspyroanddendrorespectively. These modifiers will be affected accordingly if they are present withModifierPyroorModifierDendroQUESTION/TODO: it appears that
ModifierQuickengets treated as if it has elementdendroeven though it's technically a new elementquicken??? Not sure what's going on here.Quicken
Quicken is a new element. It behaves effectively as a
dendroelement for reactions. Can coexist withelectro,dendro, andcryo(because there is nodendro+cryoreactions). Can coexist with burning (QUESTION: does it act as burning fuel in this case?).Reaction multiplier
The reaction has a 1:1 multiplier between
electroanddendroDuration and durability
Quicken have different formula than normal "attachment". Existing code uses this function to handle attachment:
With Quicken specifically, the duration formula is changed to:
12 * dur + 360. So the decay rate is actually:Probably best to just not use the
attachfunction call and leave as is. Realistically theattachfunction should be refactored to handle all cases.Aggravate/Spread
When
quickenreacts withelectroordendro, aggravate and and spread is triggered respectively. Both reactions adds to theAttackInfo.FlatDmgof the triggering attack.Special note about aggravate/spread. The triggering
electro/dendroattack is buffed, however, no durability is consumed on both thequickenand the applyingelectro/dendro. The applyingelectroordendrowill attach to the target normally coexisting with thequicken.The amount of damage added follows the same base reaction damage formula but uses a different EM multiplier. Calculation should be as follows:
Multiplier for aggravate and spread is 1.15 and 1.25 respectively.
Other
quickenreactionsquickenbehaves the same asdendrowhen reacting withhydroorpyro, triggeringbloomandburningrespectivelyBloom
Bloom is the reaction triggered when
dendroreacts withhydro. This one is fairly straightforward. On reaction, a "seed" is generated.The position of the seed (dendro core) appears to be distance 1 from the target, with a random 0 to 60 degree angle. Presuming this is 0 to 60 degree from x-axis on the cartesian plane (in game uses y). The seed then has an initial velocity and a deceleration. Needs more testing on this. For simplicty probably ok to just spawn randomly within 1 radius of target.
Seeds have a lifetime of 5 seconds. From spawn it should be closer to 6 seconds?
Bloom explode
If the dendro core does not come in contact with
pyroorelectro(simple attack collision check), it will explode on expiriy. Radius is 5. AttackInfo is as follows:Burgeon
When the dendro core comes in contact with
pyro,burgeonis triggered, dealing an attack with radius 5. AttackInfo is the same asbloomexcept withcombat.AttackTagBurgeon,combat.AttackTagBurgeonandcombat.ICDTagBurgeonHyperbloom
When dendro core comes in contact with
electro,hyperbloomis triggered, dealing an attack with radius 1. AttackInfo is the same asbloomexcept withcombat.AttackTagHyperbloom,combat.AttackTagHyperbloomandcombat.ICDTagHyperbloomBloom/Burgeon/Hyperbloom self damage
All 3 explosions will trigger an additional attack that damages the player, with AttackInfo as follows:
Radius is the same as each respective type of explosion (i.e. radius 1 for Hyperbloom)
Burning
Probably the most complex reaction to date (way worse than EC or Freeze).... Introdues 2 new modifiers but no additional elements, which technically "breaks" the current implementation but thankfully I think should be ok implementing a hack solution. As long as Hoyoverse doesn't introduce any new reactions. See earlier note on Modifier refactor.
Reaction, Duration, and Durability
When
dendroreacts withpyro, you get two resulting modifiers (or "elements" in our hack solution):burningandburning_fuel.burningalways has 50 durability regardless of the reacted amount. It also does not have a set duration. Instead,burningwill last as long as both:burningdurability > 0, andburning_fuelexists stillburninghas element of typepyroand will react just like normalpyro. However it cannot be topped up by additional pyro application (makes sense since it's a completely different modifier). Any additionalpyroapplication will merely coexist.For our hack implementation, we'll just have to go with:
And then on tick we'll need to check for if
burning_fuelis still present, and if not removeburningburning_fueldurability has a 0.8x multiplier on the reacted amount. So for example:dendro 20, applied from adendro 25attackpyro 25dendro (burning_fuel) 16The duration formula follows the standard
0.1 * d + 7in seconds, or6 * d + 420in frames.In addition, the decay rate is subject to a minimum threshold of at least 10 durability per second. Effectively, you have the following for decay rate:
Note here I'm treating
burning_fuelas it's own element i.e.attributes.BurningFuelwhen that's not actually the case here in game (see modifier discussion about).burning_fuelrefreshUnlike other element attachment, when additional Dendro is applied to existing
burning_fuel, it does not overlap but instead refreshes. This means that the existingburning_fueldurability/duration will be overwritten by the applying Dendro durability/duration. However, the existing decay rate is kept.For example:
dendro 40 (burning_fuel)dendro 25dendro 25 (burning_fuel)So you can actually "shrink" the amount of
dendro (burning_fuel)aura per say.Burning damage
While
burningis active, every 0.25s it will trigger a spherical attack with radius 1, center on the target that is burning.AttackInfo is as follows:
TODO: it's possible that if burning ends early before the next tick happens then the next tick happens right away? not sure
POST STILL WIP
Beta Was this translation helpful? Give feedback.
All reactions