-
Notifications
You must be signed in to change notification settings - Fork 14
Description
Due to how the engine works in Dota, some type definitions need to include "undefined" or "void" as an exit option. This occurs when the result is not something that you want to change, but rather, tell the engine to change nothing. It occurs mainly on conditional changes, such as client/server checks, or conditional occurrences. I'll detail the following functions with an example.
CastFilterResultTarget: should be changed from "UnitFilterResult" to "UnitFilterResult | undefined".
Example: Checking for a nearby allied unit in radius, which can only be done by the server. In this case, we must do if (!IsServer()) return;
to exit from the client. The filter works regardless of the client's definition.
Example:
CastFilterResultTarget(target: CDOTA_BaseNPC): UnitFilterResult | undefined
{
if (!IsServer()) return;
// Always apply on enemies according to the unit filter
if (target.GetTeamNumber() != this.caster.GetTeamNumber())
{
return UnitFilter(target, this.GetAbilityTargetTeam(), this.GetAbilityTargetType(), this.GetAbilityTargetFlags(), this.caster.GetTeamNumber());
}
else // Check on allies for disable help
{
if (PlayerResource.IsDisableHelpSetForPlayerID(target.GetPlayerOwnerID(), this.caster.GetPlayerOwnerID()))
{
return UnitFilterResult.FAIL_DISABLE_HELP;
}
return UnitFilter(target, this.GetAbilityTargetTeam(), this.GetAbilityTargetType(), this.GetAbilityTargetFlags(), this.caster.GetTeamNumber());
}
}
ParticleManager.SetParticleControlEnt's attachment argument: should be changed from "string" to "string | undefined". This is due to some particles requiring the usage of SetParticleControlEnt, but the attachment is ABSORIGIN_FOLLOW, which has no attachment.
Example: Sven's God's Strength CP1 will only work with SetParticleControlEnt (for some weird reason...), but is set on the origin. It is used correctly in this form:
ParticleManager.SetParticleControlEnt(this.particle_cast_fx, 1, this.caster, ParticleAttachment.ABSORIGIN_FOLLOW, undefined, this.caster.GetAbsOrigin(), true)
CheckState(): should be changed from "Partial<Record<ModifierState, boolean>>" to "Partial<Record<ModifierState, boolean>> | undefined". This is to allow cases where you no longer want to define any state. Returning true or false applies the effect on you (e.g. Invisibility, stunned) based on the priority of other modifier, which may ignore them. Instead, not returning anything (or returning undefined) lets the engine simply ignore this state.
Example:
CheckState(): Partial<Record<ModifierState, boolean>> | undefined
{
if (this.proc_attack)
{
return {[ModifierState.CANNOT_MISS]: true}
}
}
GetActivityTranslationModifiers(): Should be changed from "string" to "string | void". This is due to the fact that sometimes you do not want any translation modifiers to be applied at all.
Example: Night Stalker only applies the "hunter_night" translation at night, otherwise applies no translation:
GetActivityTranslationModifiers(): string | void
{
if (this.ShouldModifierBeActive())
{
return "hunter_night";
}
return;
}
GetModifierPreAttack_CriticalStrike(): Should be changed from "number" to "number | void". Returning 0 still causes heroes that have critical strike animations (such as Phantom Assassin, Wraith King, Juggernaut) to proc those, which makes no sense if they're not actually proccing crits. Simply returning resolves this.
Example:
GetModifierPreAttack_CriticalStrike(event: ModifierAttackEvent): number | void
{
// Does not apply on allies, buildings or wards
if (event.target.GetTeamNumber() == this.parent.GetTeamNumber() || event.target.IsBuilding() || event.target.IsOther()) return;
// some more irrelevant crit calculation logic....
}