-
Notifications
You must be signed in to change notification settings - Fork 462
Rage Fighter Killing Blow, Beast Uppercut, Chain Drive, Dragon Roar, Phoenix Shot skills completion #683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Rage Fighter Killing Blow, Beast Uppercut, Chain Drive, Dragon Roar, Phoenix Shot skills completion #683
Changes from all commits
50e525d
f7daba5
b16fca4
c20283a
b204f6b
59d3d91
89f9d87
d22890a
b2464fe
e41e616
bb31fab
662d29c
8be617d
966a9f9
2a6b60c
63d4be8
656167e
1166910
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,7 +64,7 @@ protected AttackableNpcBase(MonsterSpawnArea spawnInfo, MonsterDefinition stats, | |
| /// <value> | ||
| /// <c>true</c> if teleporting; otherwise, <c>false</c>. | ||
| /// </value> | ||
| /// <remarks>Teleporting for monsters oor npcs is not implemented yet.</remarks> | ||
| /// <remarks>Teleporting for monsters or npcs is not implemented yet.</remarks> | ||
| public bool IsTeleporting => false; | ||
|
|
||
| /// <inheritdoc /> | ||
|
|
@@ -98,7 +98,7 @@ public int Health | |
| || (this.SpawnArea.SpawnTrigger == SpawnTrigger.AutomaticDuringWave && (this._eventStateProvider?.IsSpawnWaveActive(this.SpawnArea.WaveNumber) ?? false)); | ||
|
|
||
| /// <inheritdoc /> | ||
| public async ValueTask<HitInfo?> AttackByAsync(IAttacker attacker, SkillEntry? skill, bool isCombo, double damageFactor = 1.0) | ||
| public async ValueTask<HitInfo?> AttackByAsync(IAttacker attacker, SkillEntry? skill, bool isCombo, double damageFactor = 1.0, bool? isFinalStreakHit = null) | ||
| { | ||
| if (this.Definition.ObjectKind == NpcObjectKind.Guard) | ||
| { | ||
|
|
@@ -112,7 +112,7 @@ public int Health | |
| attacker.ApplyAmmunitionConsumption(hitInfo); | ||
| } | ||
|
|
||
| await this.HitAsync(hitInfo, attacker, skill?.Skill).ConfigureAwait(false); | ||
| await this.HitAsync(hitInfo, attacker, skill?.Skill, isFinalStreakHit).ConfigureAwait(false); | ||
|
|
||
| if (hitInfo.HealthDamage > 0) | ||
| { | ||
|
|
@@ -181,7 +181,12 @@ protected virtual void OnRemoveFromMap() | |
| /// <param name="hitInfo">The hit information.</param> | ||
| /// <param name="attacker">The attacker.</param> | ||
| /// <param name="skill">The skill.</param> | ||
| protected async ValueTask HitAsync(HitInfo hitInfo, IAttacker attacker, Skill? skill) | ||
| /// <param name="isFinalStreakHit"> | ||
| /// Not <c>null</c> when it's a rage fighter multiple hit skill: | ||
| /// <c>true</c>, if it's the final hit; | ||
| /// <c>false</c>, for other hits. | ||
| /// </param> | ||
| protected async ValueTask HitAsync(HitInfo hitInfo, IAttacker attacker, Skill? skill, bool? isFinalStreakHit = null) | ||
| { | ||
| if (!this.IsAlive) | ||
| { | ||
|
|
@@ -193,6 +198,16 @@ protected async ValueTask HitAsync(HitInfo hitInfo, IAttacker attacker, Skill? s | |
| var player = this.GetHitNotificationTarget(attacker); | ||
| if (player is not null) | ||
| { | ||
| if (isFinalStreakHit.HasValue) | ||
| { | ||
| hitInfo.Attributes |= DamageAttributes.RageFighterStreakHit; | ||
|
|
||
| if (isFinalStreakHit.Value || killed) | ||
| { | ||
| hitInfo.Attributes |= DamageAttributes.RageFighterStreakFinalHit; | ||
| } | ||
| } | ||
|
Comment on lines
+201
to
+209
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. zTeamS6.3, MuMain 5.2 |
||
|
|
||
| await player.InvokeViewPlugInAsync<IShowHitPlugIn>(p => p.ShowHitAsync(this, hitInfo)).ConfigureAwait(false); | ||
| player.GameContext.PlugInManager.GetPlugInPoint<IAttackableGotHitPlugIn>()?.AttackableGotHit(this, attacker, hitInfo); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -675,7 +675,7 @@ public ValueTask ShowBlueMessageAsync(string message) | |
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public async ValueTask<HitInfo?> AttackByAsync(IAttacker attacker, SkillEntry? skill, bool isCombo, double damageFactor = 1.0) | ||
| public async ValueTask<HitInfo?> AttackByAsync(IAttacker attacker, SkillEntry? skill, bool isCombo, double damageFactor = 1.0, bool? isFinalStreakHit = null) | ||
| { | ||
| if (this.Attributes is null) | ||
| { | ||
|
|
@@ -722,7 +722,7 @@ public ValueTask ShowBlueMessageAsync(string message) | |
| this.Attributes[Stats.CurrentMana] = (manaFullyRecovered ? this.Attributes[Stats.MaximumMana] : this.Attributes[Stats.CurrentMana]) - hitInfo.ManaToll; | ||
| } | ||
|
|
||
| await this.HitAsync(hitInfo, attacker, skill?.Skill).ConfigureAwait(false); | ||
| await this.HitAsync(hitInfo, attacker, skill?.Skill, isFinalStreakHit).ConfigureAwait(false); | ||
| await this.DecreaseItemDurabilityAfterHitAsync(hitInfo).ConfigureAwait(false); | ||
|
|
||
| if (attacker as IPlayerSurrogate is { } playerSurrogate) | ||
|
|
@@ -1610,8 +1610,8 @@ IElement AppedMasterSkillPowerUp(SkillEntry masterSkillEntry, PowerUpDefinition | |
| return powerUp; | ||
| } | ||
|
|
||
| if (masterSkillDefinition.TargetAttribute is not { } masterSkillTargetAttribute | ||
| || masterSkillTargetAttribute == powerUpDef.TargetAttribute) | ||
| if (masterSkillDefinition.TargetAttribute is { } masterSkillTargetAttribute | ||
| && masterSkillTargetAttribute == powerUpDef.TargetAttribute) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We no longer blindly add it. Only if the target power-up matches. Like indicated above, if it's null, then it adds to damage and doesn't belong here. |
||
| { | ||
| var additionalValue = new SimpleElement(masterSkillEntry.CalculateValue(), masterSkillEntry.Skill.MasterDefinition?.Aggregation ?? powerUp.AggregateType); | ||
| powerUp = new CombinedElement(powerUp, additionalValue); | ||
|
|
@@ -2085,7 +2085,7 @@ private async ValueTask<ExitGate> GetSpawnGateOfCurrentMapAsync() | |
| ?? throw new InvalidOperationException($"Game map {spawnTargetMapDefinition} has no spawn gate."); | ||
| } | ||
|
|
||
| private async ValueTask HitAsync(HitInfo hitInfo, IAttacker attacker, Skill? skill) | ||
| private async ValueTask HitAsync(HitInfo hitInfo, IAttacker attacker, Skill? skill, bool? isFinalStreakHit = null) | ||
| { | ||
| this.Summon?.Item2.RegisterHit(attacker); | ||
| var healthDamage = hitInfo.HealthDamage; | ||
|
|
@@ -2101,6 +2101,17 @@ private async ValueTask HitAsync(HitInfo hitInfo, IAttacker attacker, Skill? ski | |
| } | ||
|
|
||
| this.Attributes[Stats.CurrentHealth] -= healthDamage; | ||
|
|
||
| if (isFinalStreakHit.HasValue) | ||
| { | ||
| hitInfo.Attributes |= DamageAttributes.RageFighterStreakHit; | ||
|
|
||
| if (isFinalStreakHit.Value || this.Attributes[Stats.CurrentHealth] < 1) | ||
| { | ||
| hitInfo.Attributes |= DamageAttributes.RageFighterStreakFinalHit; | ||
| } | ||
| } | ||
|
Comment on lines
+2105
to
+2113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic for setting the |
||
|
|
||
| await this.InvokeViewPlugInAsync<IShowHitPlugIn>(p => p.ShowHitAsync(this, hitInfo)).ConfigureAwait(false); | ||
| if (attacker is IWorldObserver observer) | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -320,15 +320,22 @@ private async ValueTask PerformAutomaticHitsAsync(Player player, ushort extraTar | |
| private async ValueTask ApplySkillAsync(Player player, SkillEntry skillEntry, IAttackable target, Point targetAreaCenter, bool isCombo) | ||
| { | ||
| skillEntry.ThrowNotInitializedProperty(skillEntry.Skill is null, nameof(skillEntry.Skill)); | ||
| var skill = skillEntry.Skill; | ||
|
|
||
| if (skillEntry.Skill.SkillType == SkillType.Buff) | ||
| if (skill.SkillType == SkillType.Buff) | ||
| { | ||
| await target.ApplyMagicEffectAsync(player, skillEntry).ConfigureAwait(false); | ||
| return; | ||
| } | ||
|
|
||
| var hitInfo = await target.AttackByAsync(player, skillEntry, isCombo).ConfigureAwait(false); | ||
| var hitInfo = await target.AttackByAsync(player, skillEntry, isCombo, 1, skill.NumberOfHitsPerAttack > 1 ? false : null).ConfigureAwait(false); | ||
| await target.TryApplyElementalEffectsAsync(player, skillEntry).ConfigureAwait(false); | ||
|
|
||
| for (int hit = 2; hit <= skill.NumberOfHitsPerAttack; hit++) | ||
| { | ||
| await target.AttackByAsync(player, skillEntry, isCombo, 1, hit == skill.NumberOfHitsPerAttack).ConfigureAwait(false); | ||
| } | ||
|
Comment on lines
+331
to
+337
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for performing a multi-hit attack is duplicated in |
||
|
|
||
| var baseSkill = skillEntry.GetBaseSkill(); | ||
|
|
||
| if (player.GameContext.PlugInManager.GetStrategy<short, IAreaSkillPlugIn>(baseSkill.Number) is { } strategy) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the
TargetAttribute is nullwe assume the skill adds damage. We need to go all the way back to the ancestor master skills because some may add damage.