native UnitAlive takes unit u returns boolean
Name | Type | is_array | initial_value |
AE_TmpBoolean | boolean | No | |
AE_TmpDestructible | destructable | Yes | |
AE_TmpGroup | group | Yes | |
AE_TmpHandle | handle | Yes | |
AE_TmpInteger | integer | Yes | |
AE_TmpPlayerGroup | force | Yes | |
AE_TmpPoint | location | Yes | |
AE_TmpReal | real | Yes | |
AE_TmpRealArrayless | real | No | |
AE_TmpString | string | Yes | |
AE_TmpText | texttag | Yes | |
AE_TmpUnit | unit | Yes | |
AfterDamageEvent | real | No | |
AllComputersChosen | boolean | No | |
AMSAmount | real | Yes | |
AnimationResetGroup | group | No | |
AOEDamageEvent | real | No | |
AOEDamageSource | unit | No | |
AOEString | string | No | |
ARMOR_TYPE_ETHEREAL | integer | No | |
ARMOR_TYPE_FLESH | integer | No | |
ARMOR_TYPE_METAL | integer | No | |
ARMOR_TYPE_NONE | integer | No | |
ARMOR_TYPE_STONE | integer | No | |
ARMOR_TYPE_WOOD | integer | No | |
ArmorDamageEvent | real | No | |
ArmorTypeDebugStr | string | Yes | |
ATTACK_TYPE_CHAOS | integer | No | |
ATTACK_TYPE_HERO | integer | No | |
ATTACK_TYPE_MAGIC | integer | No | |
ATTACK_TYPE_NORMAL | integer | No | |
ATTACK_TYPE_PIERCE | integer | No | |
ATTACK_TYPE_SIEGE | integer | No | |
ATTACK_TYPE_SPELLS | integer | No | |
AttackingUnitDamageType | attacktype | No | |
AttackTypeDebugStr | string | Yes | |
BB_RuneCaster | unit | No | |
BB_RuneCount | integer | No | |
BB_RuneDummy | unit | No | |
BB_RuneDummyPoint | location | No | |
BB_RuneGroup | group | No | |
BB_RuneTarget | unit | No | |
BB_TrueGrit | group | No | |
BB_Unit_Thane | unit | No | |
BB_UnitGroup_BronzeStructure | group | No | |
BB_UnitGroup_Shieldbearer | group | No | |
BB_UnitGroup_Steadfast | group | No | |
BB_UnitGroup_Thane | group | No | |
Behavior_IsPlayerBehavior | boolean | No | |
Behavior_OnAllyAttacked | trigger | No | |
Behavior_OnAllyAttacks | trigger | No | |
Behavior_OnAllyCasts | trigger | No | |
Behavior_OnAllyDeath | trigger | No | |
Behavior_OnAllyDmgDealt | trigger | No | |
Behavior_OnAllyDmgTaken | trigger | No | |
Behavior_OnAllyKills | trigger | No | |
Behavior_OnAllyTargeted | trigger | No | |
Behavior_OnAttack | trigger | No | |
Behavior_OnAttacked | trigger | No | |
Behavior_OnCast | trigger | No | |
Behavior_OnDamageDealt | trigger | No | |
Behavior_OnDamageTaken | trigger | No | |
Behavior_OnEnemyAttacked | trigger | No | |
Behavior_OnEnemyAttacks | trigger | No | |
Behavior_OnEnemyCasts | trigger | No | |
Behavior_OnEnemyDeath | trigger | No | |
Behavior_OnEnemyDmgDealt | trigger | No | |
Behavior_OnEnemyDmgTaken | trigger | No | |
Behavior_OnEnemyKills | trigger | No | |
Behavior_OnEnemyTargeted | trigger | No | |
Behavior_OnKill | trigger | No | |
Behavior_OnPeriod | trigger | No | |
Behavior_OnTargeted | trigger | No | |
Behavior_Unit | unit | No | |
Behavior_UnitType | unitcode | No | |
BestowedBlessingsCaster | unit | No | |
BestowedBlessingsCount | integer | No | |
BestowedBlessingsTarget | unit | No | |
BranchedLightningCaster | unit | No | |
BranchedLightningCount | integer | No | |
BranchedLightningTarget | unit | No | |
CargoEvent | real | No | |
CargoTransportGroup | group | Yes | |
CargoTransportUnit | unit | Yes | |
Carrier | unit | Yes | |
CarrierCaster | unit | No | |
CarrierId | integer | No | |
CasterLoc | location | No | |
CEvBlock | boolean | Yes | |
CEvNext | integer | Yes | |
CEvPrev | integer | Yes | |
CEvSpecial | boolean | Yes | |
CEvUnloadTimer | timer | No | |
ChargeHashtable | hashtable | No | |
CheckDeathInList | boolean | Yes | |
CheckDeathList | integer | Yes | |
CheckDeathTimer | timer | No | |
Choice | dialog | Yes | |
chuncks10 | integer | No | |
ClearDamageEvent | trigger | No | |
ClearDamageEvent_Copy | trigger | No | |
ClickingPlayer | player | No | |
ClickingPlayerNumber | integer | No | |
Color_Text | string | Yes | |
ConfirmChoice | real | No | |
CONSTANT_FavourColour | string | No | |cFFAAAAAA |
CONSTANT_FavourCostHigh | integer | No | 40 |
CONSTANT_FavourCostLow | integer | No | 5 |
CONSTANT_FavourEnd | string | No | Favor|r |
CONSTANT_NotEnoughFavour | string | No | |cffffcc00More Dragon Favor required.|r |
CONVERTED_ATTACK_TYPE | attacktype | Yes | |
CONVERTED_DAMAGE_TYPE | damagetype | Yes | |
CorrupterBoolean | boolean | Yes | |
CorrupterGracePeriod | real | Yes | |
CorruptersID | integer | No | |
CP_HiddenItems | item | Yes | |
CP_HiddenItemsIndex | integer | No | |
CP_Item | item | No | |
CP_Point | location | No | |
CP_PointIsWalkable | boolean | No | |
CP_Rect | rect | No | |
CurrentAI | player | No | PlayerNP |
CustomO_Cooldown | real | No | |
CustomO_IsInCooldown | boolean | No | |
CustomO_Location | location | No | |
CustomO_ManaCost | integer | No | |
CustomO_Order | string | No | |
CustomO_OrderId | integer | No | |
CustomO_Priority | integer | No | |
CustomO_Target | unit | No | |
CustomO_Unit | unit | No | |
DAMAGE_FACTOR_BRACERS | real | No | |
DAMAGE_FACTOR_ELUNES | real | No | |
DAMAGE_FACTOR_ETHEREAL | real | No | |
DAMAGE_TYPE_ACID | integer | No | |
DAMAGE_TYPE_COLD | integer | No | |
DAMAGE_TYPE_DEATH | integer | No | |
DAMAGE_TYPE_DEFENSIVE | integer | No | |
DAMAGE_TYPE_DEMOLITION | integer | No | |
DAMAGE_TYPE_DISEASE | integer | No | |
DAMAGE_TYPE_DIVINE | integer | No | |
DAMAGE_TYPE_ENHANCED | integer | No | |
DAMAGE_TYPE_FIRE | integer | No | |
DAMAGE_TYPE_FORCE | integer | No | |
DAMAGE_TYPE_LIGHTNING | integer | No | |
DAMAGE_TYPE_MAGIC | integer | No | |
DAMAGE_TYPE_MIND | integer | No | |
DAMAGE_TYPE_NORMAL | integer | No | |
DAMAGE_TYPE_PLANT | integer | No | |
DAMAGE_TYPE_POISON | integer | No | |
DAMAGE_TYPE_SHADOW_STRIKE | integer | No | |
DAMAGE_TYPE_SLOW_POISON | integer | No | |
DAMAGE_TYPE_SONIC | integer | No | |
DAMAGE_TYPE_SPIRIT_LINK | integer | No | |
DAMAGE_TYPE_UNIVERSAL | integer | No | |
DAMAGE_TYPE_UNKNOWN | integer | No | |
DamageBlockingAbility | abilcode | No | |
DamageBlockingAbility_Copy | abilcode | No | |
DamageEvent | real | No | |
DamageEvent_Copy | real | No | |
DamageEventAmount | real | No | |
DamageEventAOE | integer | No | |
DamageEventAOEGroup | group | No | |
DamageEventArmorPierced | real | No | |
DamageEventArmorT | integer | No | |
DamageEventAttackT | integer | No | |
DamageEventDamageT | integer | No | |
DamageEventDefenseT | integer | No | |
DamageEventLevel | integer | No | |
DamageEventOverride | boolean | No | |
DamageEventPrevAmt | real | No | |
DamageEventSource | unit | No | |
DamageEventsWasted | integer | No | |
DamageEventsWasted_Copy | integer | No | |
DamageEventTarget | unit | No | |
DamageEventTrigger | trigger | No | |
DamageEventType | integer | No | |
DamageEventWeaponT | integer | No | |
DamageFilterAttackT | integer | No | |
DamageFilterDamageT | integer | No | |
DamageFilterFailChance | real | No | |
DamageFilterMinAmount | real | No | |
DamageFilterRunChance | real | No | |
DamageFilterSource | unit | No | |
DamageFilterSourceA | abilcode | No | |
DamageFilterSourceB | buffcode | No | |
DamageFilterSourceC | integer | No | |
DamageFilterSourceI | itemcode | No | |
DamageFilterSourceT | unitcode | No | |
DamageFilterTarget | unit | No | |
DamageFilterTargetA | abilcode | No | |
DamageFilterTargetB | buffcode | No | |
DamageFilterTargetC | integer | No | |
DamageFilterTargetI | itemcode | No | |
DamageFilterTargetT | unitcode | No | |
DamageFilterType | integer | No | |
DamageModifierEvent | real | No | |
DamageScalingUser | real | No | |
DamageScalingWC3 | real | No | |
DamageToVoyager | real | No | |
DamageTypeBlocked | integer | No | |
DamageTypeCode | integer | No | |
DamageTypeCriticalStrike | integer | No | |
DamageTypeDebugStr | string | Yes | |
DamageTypeExplosive | integer | No | |
DamageTypeHeal | integer | No | |
DamageTypePure | integer | No | |
DamageTypePureExplosive | integer | No | |
DamageTypeReduced | integer | No | |
DamageTypeVoid | integer | No | |
DButton1 | real | No | |
DButton2 | real | No | |
DButton3 | real | No | |
DButton4 | real | No | |
DButton5 | real | No | |
DE_NetherRiftABCancel | abilcode | No | |
DE_NetherRiftABLoad | abilcode | No | |
DE_NetherRiftABSellType | unitcode | No | |
DE_NetherRiftABUnload | abilcode | No | |
DE_NetherRiftGroup | group | No | |
DE_NetherRiftHashtable | hashtable | No | |
DE_NetherRifts | group | No | |
DE_NetherRiftSize | integer | No | |
DE_NetherRiftUnload | group | No | |
DeathEvent | real | No | |
DebugInt | integer | No | |
DEFENSE_TYPE_DIVINE | integer | No | |
DEFENSE_TYPE_FORTIFIED | integer | No | |
DEFENSE_TYPE_HEAVY | integer | No | |
DEFENSE_TYPE_HERO | integer | No | |
DEFENSE_TYPE_LIGHT | integer | No | |
DEFENSE_TYPE_MEDIUM | integer | No | |
DEFENSE_TYPE_NORMAL | integer | No | |
DEFENSE_TYPE_UNARMORED | integer | No | |
DefenseTypeDebugStr | string | Yes | |
DetectRemoveAbility | abilcode | No | |
DetectTransformAbility | abilcode | No | |
DEvAbility | abilcode | No | |
DEvAbilityTemp | abilcode | No | |
DEvBlock | boolean | Yes | |
DEvList | integer | Yes | |
DEvRemoved | boolean | Yes | |
DEvTimer | timer | No | |
DF_CustomValue | integer | No | |
DF_DragonGuile | integer | Yes | |
DF_DragonHeart | integer | Yes | |
DF_DragonRage | integer | Yes | |
DF_DragonWisdom | integer | Yes | |
DF_Level | integer | No | |
DF_Player | player | No | |
DF_Players | force | No | |
DF_TmpGroup | group | No | |
DF_TmpString | string | No | |
DF_TmpUnit | unit | No | |
DFavorText | string | Yes | |
DH_BlackDragonGroup | group | No | |
DH_BloodTouLethalFx | effect | Yes | |
DH_BloodTourGracePeriod | real | Yes | |
DH_BloodTourLethalBoolean | boolean | Yes | |
DH_BloodTourLethalGroup | group | No | |
DH_BloodTourLethalID | integer | No | |
DH_ConflictAuraGroup | group | No | |
DH_CunningSkills | integer | No | |
DH_DarkHordeBuilding | group | No | |
DH_DeathwingWill | integer | No | |
DH_DragonBlood | integer | No | |
DH_DragonGroup | group | No | |
DH_DragonscaleGifts | integer | No | |
DH_DragonWalker | unit | No | |
DH_ExploreWhelp | unit | No | |
DH_GoliathGroup | group | No | |
DH_HandoftheDragonGroup | group | No | |
DH_ImpVicLS1 | group | No | |
DH_ImpVicLS2 | group | No | |
DH_ImpVicLS3 | group | No | |
DH_InfernalStoneProc | integer | No | |
DH_MagiDummyGroup | group | No | |
DH_SabOreUnit | unit | No | |
DH_Sacrifice_of_Nafarian | integer | No | |
DH_WarmasterAuraGroup | group | No | |
DH_WarMasterHero | unit | No | |
DI_AttackePosition | location | No | |
DI_AttackPosition | location | No | |
DI_Backstabbed | unit | No | |
DI_ConfluxInt | integer | No | |
DI_Pyromagi | group | No | |
DI_RogueStab | unit | No | |
DI_Shade | unit | No | |
DisplayBar | string | No | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |
DisplayBarAlt | string | No | |cff8080ff|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |
DisplayBarCount | real | No | 50.00 |
DisplayHidden | boolean | No | |
DisplayLoopInteger | integer | No | |
DisplayShieldHealthChanged | boolean | No | |
DisplayShieldTypeColor | string | Yes | |
DisplayUnitNeedsUpdate | boolean | Yes | |
DmgEvBracers | itemcode | No | |
DmgEvLife | real | No | |
DmgEvMana | real | No | |
DmgEvManaMult | real | No | |
DmgEvMSlvl | integer | No | |
DmgEvPrevLife | real | No | |
DmgEvQueued | boolean | No | |
DmgEvRecursionLevel | integer | No | |
DmgEvRecursionN | integer | No | |
DmgEvRecursionN_Copy | integer | No | |
DmgEvRunning | boolean | No | |
DmgEvRunning_Copy | boolean | No | |
DmgEvStarted | boolean | No | |
DmgEvStarted_Copy | boolean | No | |
DmgEvTimer | timer | No | |
DmgEvTimer_Copy | timer | No | |
DmgEvTrig | trigger | No | |
DmgEvTrig_Copy | trigger | No | |
DmgEvUnit | unit | No | |
DmgStr | string | No | |
DoNotClearNext | boolean | No | |
DOT_Attack_Type | attacktype | No | |
DOT_Damage | real | No | |
DOT_Damage_Type | damagetype | No | |
DragonFavourBoard | multiboard | Yes | |
Dummy | unit | No | |
DummyAbility | ability | No | |
ED_AugurAuraGroup | group | No | |
ED_ConvictionGroup | group | No | |
ED_DraeneiBuildingsGroup | group | No | |
ED_GemcraftersGroup | group | No | |
ED_HallowGroup | group | Yes | |
ED_NetherRayGroup | group | No | |
ED_NetherwindsGroup | group | No | |
ED_OrdnanceGroup | group | No | |
ED_StymieChainGroup | group | No | |
ED_SuppressionBeamGroup | group | No | |
EggSpawnArea | rect | No | |
EndOnTargetBounce | boolean | No | |
EnhancedDamageTarget | unit | No | |
EnumCarrier | unit | No | |
EOT_Amount | integer | No | |
EOT_Array_Ability | abilcode | Yes | |
EOT_Array_Ability_Level | integer | Yes | |
EOT_Array_Buff | buffcode | Yes | |
EOT_Array_Buff_Holder | abilcode | Yes | |
EOT_Array_Buff_Holder_Level | integer | Yes | |
EOT_Array_Can_Dispell | boolean | Yes | |
EOT_Array_Duration | real | Yes | |
EOT_Array_Hidden | boolean | Yes | |
EOT_Array_Id | integer | Yes | |
EOT_Array_Interval | real | Yes | |
EOT_Array_Is_Passive | boolean | Yes | |
EOT_Array_On_Period_Trigger | trigger | Yes | |
EOT_Array_Positive | boolean | Yes | |
EOT_Array_Remaining_Duration | real | Yes | |
EOT_Array_Remaining_Interval | real | Yes | |
EOT_Array_Source | unit | Yes | |
EOT_Array_Special_Effect | effect | Yes | |
EOT_Array_Special_Effect_Model | string | Yes | |
EOT_Array_Special_Effect_Point | string | Yes | |
EOT_Array_Subtype | integer | Yes | |
EOT_Array_Subtype2 | integer | Yes | |
EOT_Array_Target | unit | Yes | |
EOT_Array_Type | integer | Yes | |
EOT_Event_An_EOT_Has_Expired | real | No | |
EOT_Event_An_EOT_Is_Created | real | No | |
EOT_Event_An_EOT_Is_Destroyed | real | No | |
EOT_Event_An_EOT_Is_Dispelled | real | No | |
EOT_Event_Creation_After | real | No | |
EOT_Event_Creation_Before | real | No | |
EOT_Event_Destruction_After | real | No | |
EOT_Event_Destruction_Before | real | No | |
EOT_Event_Dispell_After | real | No | |
EOT_Event_Dispell_Before | real | No | |
EOT_Event_Expire_After | real | No | |
EOT_Event_Expire_Before | real | No | |
EOT_Event_Get_Data | real | No | |
EOT_Event_Interval_After | real | No | |
EOT_Event_Interval_Before | real | No | |
EOT_Event_Null_Variables | real | No | |
EOT_Event_On_Interval | real | No | |
EOT_Event_Save_Data | real | No | |
EOT_Hashtable | hashtable | No | |
EOT_Index | integer | No | |
EOT_Param_Ability | abilcode | No | |
EOT_Param_Ability_Level | integer | No | |
EOT_Param_Buff | buffcode | No | |
EOT_Param_Buff_Holder | abilcode | No | |
EOT_Param_Buff_Holder_Level | integer | No | |
EOT_Param_Can_Dispell | boolean | No | |
EOT_Param_Destroy | boolean | No | |
EOT_Param_Destroy_Passive | boolean | No | |
EOT_Param_Duration | real | No | |
EOT_Param_Expire | boolean | No | |
EOT_Param_Force_Destroy | boolean | No | |
EOT_Param_Hidden | boolean | No | |
EOT_Param_Id | integer | No | |
EOT_Param_Interval | real | No | |
EOT_Param_Is_Passive | boolean | No | |
EOT_Param_Negative | boolean | No | |
EOT_Param_Positive | boolean | No | |
EOT_Param_Remaining_Duration | real | No | |
EOT_Param_Remaining_Interval | real | No | |
EOT_Param_Source | unit | No | |
EOT_Param_Special_Effect | effect | No | |
EOT_Param_Special_Effect_Model | string | No | |
EOT_Param_Special_Effect_Point | string | No | |
EOT_Param_Subtype | integer | No | |
EOT_Param_Subtype2 | integer | No | |
EOT_Param_Target | unit | No | |
EOT_Param_Type | integer | No | |
EOT_Timer | timer | No | |
EOT_Trigger_Create_EOT | trigger | No | |
EOT_Trigger_Destroy_EOT | trigger | No | |
EOT_Trigger_Get_Data | trigger | No | |
EOT_Trigger_Remove_EOTs | trigger | No | |
EOT_Trigger_Save_Data | trigger | No | |
EOT_Unique_Id | integer | No | |
ErrorMessage | string | No | |
ErrorPlayer | player | No | |
ErrorSound | sound | No | |
Event_Ally | unit | No | |
Event_Attacker | unit | No | |
Event_Caster | unit | No | |
Event_Enemy | unit | No | |
Event_Killer | unit | No | |
Event_Source | unit | No | |
Event_Target | unit | No | |
Event_Unit | unit | No | |
Event_Victim | unit | No | |
ExiledArrowCaster | unit | No | |
ExiledArrowCount | integer | No | |
ExiledArrowTarget | unit | No | |
ExitLoop | boolean | No | |
FaneQuantity | integer | No | |
FaneUI_Count | integer | No | |
FaneUI_CurrentText | string | No | |
FaneUI_Player | player | No | |
FavourGathered | integer | Yes | |
FavoursLearned | integer | Yes | |
FB_BaneHavocInt | integer | No | |
FB_BlashFlier | integer | No | |
FB_BloodCord | integer | No | |
FB_CrimsonVale | integer | No | |
FB_CrimsonValeBonusChance | integer | No | |
FB_CrimsonValeUnit | unit | No | |
FB_CurseFragility | integer | No | |
FB_DemonfireEffect | effect | Yes | |
FB_DemonfireGroup | group | No | |
FB_FeedingStrike | integer | No | |
FB_FelBarrage | integer | No | |
FB_Feldummy | unit | Yes | |
FB_Int_Helix | integer | Yes | |
FB_LegionGroup | group | No | |
FB_MurderousChamp | unit | No | |
FB_RelishInPain | integer | No | |
FB_ReverseAura | integer | No | |
FB_Unit_Dummy | unit | Yes | |
FB_UnitGroup_Murderous | group | Yes | |
FB_VanguardsGroup | group | No | |
FH_Acrimony | group | No | |
FH_BarbarianGroup | group | No | |
FH_BurningBladeGroup | group | No | |
FH_DrainSoulInt | integer | No | |
FH_ExecutionerGroup | group | No | |
FH_Int_Crossbowman | integer | No | |
FH_Int_Knockout | integer | No | |
FH_UnitGroup_BloodAura | group | No | |
FH_Vendetta | integer | No | |
FH_Vendetta_2 | integer | No | |
FH_WarlordGroup | group | No | |
FH_WarlordHero | unit | No | |
FloatingText_Nesting | texttag | Yes | |
FO_BlackWind | integer | No | |
FO_ExplodingCopies | group | No | |
FO_ManifestedAlliance | unit | No | |
FO_ManifestedUnitBuffed | unit | No | |
FO_Ploy | unit | No | |
FO_Silence | integer | No | |
GDD__Integers | integer | Yes | |
GDD__LeftMapGroup | group | No | |
GDD__TriggerArray | trigger | Yes | |
GDD__UnitArray | unit | Yes | |
GDD_Damage | real | No | |
GDD_DamagedUnit | unit | No | |
GDD_DamageSource | unit | No | |
GDD_Event | real | No | |
GetUnitX | real | No | |
GetUnitY | real | No | |
GMF_Ability | abilcode | Yes | |
GMF_Array | integer | No | |
GMF_Group | group | No | |
GMF_Hashtable | hashtable | No | |
GMF_InitializationMines | group | No | |
GMF_TmpGroup | group | Yes | |
GMF_TmpHandle | handle | No | |
GMF_TmpInteger | integer | Yes | |
GMF_TmpPoint | location | Yes | |
GMF_TmpUnit | unit | Yes | |
GMF_Type | unitcode | Yes | |
Goldmine | unit | No | |
group | group | No | |
GS_InjuredGroup | group | No | |
heal_amount | real | No | |
heal_check | boolean | No | |
HEAL_CHECK_INTERVAL | real | No | |
heal_count | integer | No | |
heal_diff | real | No | |
heal_exitwhen | integer | No | |
heal_indexRef | integer | Yes | |
heal_indices | integer | Yes | |
heal_inSys | boolean | Yes | |
heal_integer | integer | No | |
heal_lastLife | real | Yes | |
heal_life | real | No | |
heal_regen | real | Yes | |
heal_source | unit | No | |
heal_target | unit | No | |
HEAL_THRESHOLD | real | No | |
heal_timer | timer | No | |
HealEvent | real | No | |
HeroHotD | unit | Yes | |
HideDamageFrom | boolean | Yes | |
HostHasChosen | boolean | No | |
hp10 | real | No | |
hpMax | real | No | |
hpMiss | real | No | |
IL_EnvelopingGroup | group | No | |
IL_RestrainingChainsGroup | group | No | |
IL_TidemageGroup | group | No | |
IllidariPlayerGroup | force | No | |
IllidariRace_Int | integer | Yes | |
IllidariUI_Player | player | No | |
IllidariUIBlood_CurrentText | string | No | |
IllidariUIDemon_CurrentText | string | No | |
IllidariUINaga_CurrentText | string | No | |
Int_AbilityLevel | integer | No | |
Int_DieMaxHP | integer | No | |
Int_DieMaxMP | integer | No | |
IsDamageAttack | boolean | No | |
IsDamageCode | boolean | No | |
IsDamageMelee | boolean | No | |
IsDamageRanged | boolean | No | |
IsDamageSpell | boolean | No | |
IsUnitAlive | boolean | Yes | |
IsUnitBeingUnloaded | boolean | Yes | |
IsUnitNew | boolean | Yes | |
IsUnitPreplaced | boolean | Yes | |
IsUnitReincarnating | boolean | Yes | |
IsUnitRemoved | boolean | Yes | |
IsUnitTransforming | boolean | Yes | |
IT_Abjurer | group | No | |
IT_BrokenIdolDummy | unit | No | |
IT_LoaSacrifice | group | No | |
IT_TrainingChargesAbility | abilcode | No | |
IT_TrainingChargesArray | integer | No | |
IT_TrainingChargesAttachment | string | No | |
IT_TrainingChargesBuilding | unitcode | Yes | |
IT_TrainingChargesCD | real | Yes | |
IT_TrainingChargesDummy | unitcode | No | |
IT_TrainingChargesGroup | group | No | |
IT_TrainingChargesHashtable | hashtable | No | |
IT_TrainingChargesLimit | integer | Yes | |
IT_TrainingChargesReady | group | No | |
IT_TrainingChargesSFX | string | No | |
IT_UnitGroup_Bewitch | group | No | |
IT_UnitGroup_BrokenIdol | group | No | |
IT_UnitGroup_CondemnedUnits | group | No | |
IT_UnitGroup_Hoarfrost | group | No | |
IT_UnitGroup_RavenousMonster | group | No | |
IT_UnitGroup_Snowbind | group | No | |
IT_UnitGroup_Stifle | group | No | |
IT_UnitGroup_StolenPower | group | No | |
IT_UnitGroup_Whiteout | group | No | |
KB3D_Accel | real | No | |
KB3D_AllowOutSiding | boolean | No | |
KB3D_Angle | real | No | |
KB3D_AoE | real | No | |
KB3D_AoEDamage | real | No | |
KB3D_AoEEndDamage | real | No | |
KB3D_AoEEndFx | string | No | |
KB3D_AoEKB | boolean | No | |
KB3D_AoEKB_Power | real | No | |
KB3D_Arc | real | No | |
KB3D_Attach | string | No | |
KB3D_AttackType | attacktype | No | |
KB3D_B | boolean | No | |
KB3D_Bounce_Fx | string | No | |
KB3D_Bounce_Power | real | No | |
KB3D_Bounce_Target | boolean | No | |
KB3D_Bounce_Unit | boolean | No | |
KB3D_Counter | integer | No | |
KB3D_CW_HiddenItems | item | Yes | |
KB3D_CW_HiddenItemsIndex | integer | No | |
KB3D_CW_Item | item | No | |
KB3D_D_ALLY | boolean | No | |
KB3D_D_ENEMY | boolean | No | |
KB3D_D_FLYING | boolean | No | |
KB3D_D_MAGIC_IMMINUE | boolean | No | |
KB3D_D_MECHANICAL | boolean | No | |
KB3D_D_RESISTANT | boolean | No | |
KB3D_D_STRUCTURE | boolean | No | |
KB3D_Damager | unit | No | |
KB3D_DamageType | damagetype | No | |
KB3D_DestroyDestructables | boolean | No | |
KB3D_DestroyTree | boolean | No | |
KB3D_DisableUnit | boolean | No | |
KB3D_EndFx | string | No | |
KB3D_EndisNormal | boolean | No | |
KB3D_EndisUnit | boolean | No | |
KB3D_EndisUnpathable | boolean | No | |
KB3D_EndOnObstacle | boolean | No | |
KB3D_EndOnTargetBounce | boolean | No | |
KB3D_EndTrigger | trigger | No | |
KB3D_EndUnit | unit | No | |
KB3D_EndwhenDead | boolean | No | |
KB3D_EndWhenHit | boolean | No | |
KB3D_FaceAngle | boolean | No | |
KB3D_Flyover | boolean | No | |
KB3D_Flyover_Duration | real | No | |
KB3D_Fx | string | No | |
KB3D_Fx_Attach | string | No | |
KB3D_g | group | No | |
KB3D_GroundDamage | boolean | No | |
KB3D_HA | hashtable | No | |
KB3D_Harvester | unit | No | |
KB3D_HomingMissile | boolean | No | |
KB3D_i | integer | No | |
KB3D_iKB | boolean | No | |
KB3D_ImpactDamage | real | No | |
KB3D_Instances | integer | No | |
KB3D_JumpOverCliff | boolean | No | |
KB3D_KBTarget | boolean | No | |
KB3D_KillatEnd | boolean | No | |
KB3D_KillatTime | real | No | |
KB3D_KillifOutSider | boolean | No | |
KB3D_KillWhenHit | boolean | No | |
KB3D_Line_Fx | string | No | |
KB3D_LineDamage | real | No | |
KB3D_Loop | trigger | No | |
KB3D_LoopDamage | real | No | |
KB3D_Paused | boolean | No | |
KB3D_PausedReg | boolean | No | |
KB3D_PauseID | integer | No | |
KB3D_Range | real | No | |
KB3D_Reals | real | Yes | |
KB3D_Registration | trigger | No | |
KB3D_RemoveUnit | unit | No | |
KB3D_Speed | real | No | |
KB3D_Speed_Changer | boolean | No | |
KB3D_StopTime | real | No | |
KB3D_TargetDamage | real | No | |
KB3D_Targeted_Unit | unit | No | |
KB3D_Time | real | No | |
KB3D_Timer | timer | No | |
KB3D_TrailFx | string | No | |
KB3D_Unit | unit | No | |
KB3D_UnpathableStop | boolean | No | |
KB3D_Zoffset | real | No | |
KillerOfUnit | unit | Yes | |
KT_ConcentrationGroup | group | No | |
KT_EnlightenmentGroup | group | No | |
KT_HarmonicGroup | group | No | |
KT_HeadmasterGroup | group | No | |
KT_PrismaticGroup | group | No | |
KT_SageShieldGroup | group | No | |
KT_ScribeGroup | group | No | |
KT_TemporalCloakGroup | group | No | |
KT_TransparencyGroup | group | No | |
LastCreatedShield | integer | No | |
LastDamageHP | real | No | |
LastDamageHP_Copy | real | No | |
LastDmgPrevAmount | real | Yes | |
LastDmgPrevAmount_Copy | real | Yes | |
LastDmgPrevType | integer | Yes | |
LastDmgPrevType_Copy | integer | Yes | |
LastDmgSource | unit | Yes | |
LastDmgSource_Copy | unit | Yes | |
LastDmgTarget | unit | Yes | |
LastDmgTarget_Copy | unit | Yes | |
LastDmgValue | real | Yes | |
LastDmgValue_Copy | real | Yes | |
LastDmgWasSpell | boolean | Yes | |
LastDmgWasSpell_Copy | boolean | Yes | |
LethalBoolean | boolean | Yes | |
LethalDamageEvent | real | No | |
LethalDamageHP | real | No | |
LethalFx | effect | Yes | |
LethalGracePeriod | real | Yes | |
LethalID | integer | No | |
LF_BrightlanceGroup | group | No | |
LF_DragoonGroup | group | No | |
LF_FelcrusherGroup | group | No | |
LF_HeavenRestraintGroup | group | No | |
LF_Lightbearer | unit | No | |
LF_LightbearerGroup | group | No | |
LF_LuminaryGroup | group | No | |
LF_MainStructureGroup | group | No | |
LF_ParagonAuraGroup | group | No | |
LF_ParagonHero | unit | No | |
LF_PartisanGroup | group | No | |
LF_SagittaryGroup | group | No | |
LF_SymbolGroup | group | No | |
LF_VindicatorGroup | group | No | |
LF_WayfinderGroup | group | No | |
List | integer | No | |
LN_BurrowChargeAbility | abilcode | No | |
LN_BurrowChargeDamage | real | Yes | |
LN_BurrowChargeGroup | group | No | |
LN_BurrowChargeHashtable | hashtable | No | |
LN_BurrowChargeRadius | real | Yes | |
LN_EminenceAuraAbility | abilcode | No | |
LN_EminenceAuraAffected | group | No | |
LN_EminenceAuraBuffAbility | abilcode | No | |
LN_EminenceAuraHashtable | hashtable | No | |
LN_EminenceAuraHeal | real | Yes | |
LN_EminenceAuraHero | group | No | |
LN_EminenceAuraResistance | real | Yes | |
LN_EscutcheonAbility | abilcode | No | |
LN_EscutcheonBar | unitcode | No | |
LN_EscutcheonBuff | buffcode | No | |
LN_EscutcheonGroup | group | No | |
LN_EscutcheonHashtable | hashtable | No | |
LN_EscutcheonPercentage | real | Yes | |
LN_EscutcheonShield | real | Yes | |
LN_QueensCargoGroup | group | No | |
LN_ReignAbility | abilcode | No | |
LN_ReignCaster | group | No | |
LN_ReignDamage | real | No | |
LN_ReignDistance | real | No | |
LN_ReignDummy | unitcode | No | |
LN_ReignEffect | abilcode | No | |
LN_ReignFrequency | real | No | |
LN_ReignGroup | group | No | |
LN_ReignHashtable | hashtable | No | |
LN_ReignSpeed | real | No | |
LN_ReignSummon | unitcode | No | |
LookAt_BRONZEBEARD | integer | No | 11 |
LookAt_DALARAN | integer | No | 23 |
LookAt_DARKHORDE | integer | No | 16 |
LookAt_DARKIRON | integer | No | 12 |
LookAt_EXODAR_DRAENEI | integer | No | 17 |
LookAt_FACELESS | integer | No | 7 |
LookAt_FELBLOOD | integer | No | 13 |
LookAt_FELHORDE | integer | No | 15 |
LookAt_FORSAKEN | integer | No | 22 |
LookAt_HIGHELVES | integer | No | 24 |
LookAt_HUMAN | integer | No | 1 |
LookAt_ICE_TROLLS | integer | No | 9 |
LookAt_ILLIDARI | integer | No | 20 |
LookAt_LIGHTFORGED | integer | No | 18 |
LookAt_LIVING_NERUB | integer | No | 5 |
LookAt_LOSTONES | integer | No | 25 |
LookAt_NELF | integer | No | 3 |
LookAt_NIGHTBORNE | integer | No | 19 |
LookAt_ORC | integer | No | 2 |
LookAt_QIRAJI | integer | No | 8 |
LookAt_RANDOM_ALL | integer | No | 26 |
LookAt_RANDOM_CUSTOM | integer | No | 27 |
LookAt_SCARLETCRUSADE | integer | No | 21 |
LookAt_UNDEAD | integer | No | 4 |
LookAt_UNDEAD_NERUB | integer | No | 6 |
LookAt_VOIDELVES | integer | No | 14 |
LookAt_WILDHAMMER | integer | No | 10 |
Messenger | unit | Yes | |
NextDamageIsAttack | boolean | No | |
NextDamageIsMelee | boolean | No | |
NextDamageIsRanged | boolean | No | |
NextDamageOverride | boolean | No | |
NextDamageOverride_Copy | boolean | No | |
NextDamageType | integer | No | |
NextDamageWeaponT | integer | No | |
NextHealAmount | real | No | |
NextHealSource | unit | No | |
NextHealTarget | unit | No | |
NoTrigger | trigger | No | |
OnDamageEvent | real | No | |
PestAttackDummy | unit | Yes | |
PestCaster | unit | Yes | |
PestInitialDummy | unit | Yes | |
Player | player | No | |
PlayerColour | player | Yes | |
PlayerGroup_ComputerAI | force | Yes | |
PlayerGroup_Computers | force | No | |
PlayerGroup_Host | force | No | |
PlayerGroup_SetUI | force | Yes | |
PlayerGroup_Users | force | No | |
PlayerId | integer | No | |
PlayerNum | integer | No | |
PlayerStructure | boolean | Yes | |
PlayerVar | player | Yes | |
Portal_active | boolean | Yes | |
Portal_activeFX | string | Yes | |
Portal_arrivalFX | string | Yes | |
Portal_ConfigIndex | integer | Yes | |
Portal_delay | real | Yes | |
Portal_delayFXAbil | abilcode | Yes | |
Portal_departureFX | string | Yes | |
Portal_dummy | unit | No | |
Portal_FX | effect | Yes | |
Portal_group | group | No | |
Portal_INDEX_CASTER | integer | No | |
Portal_INDEX_TARGET | integer | No | |
Portal_INDEX_TRAVELLER | integer | No | |
Portal_isTeleporting | boolean | Yes | |
Portal_loc1 | location | No | |
Portal_loc2 | location | No | |
Portal_loc3 | location | No | |
Portal_loc4 | location | No | |
Portal_missileDummy | unitcode | Yes | |
Portal_missileFXAbil | abilcode | Yes | |
Portal_missileHeight | real | Yes | |
Portal_missileSpeed | real | Yes | |
Portal_missileTargetable | boolean | Yes | |
Portal_missileUseOwnMovement | boolean | Yes | |
Portal_portal | unit | Yes | |
Portal_preventAllies | boolean | Yes | |
Portal_range | real | Yes | |
Portal_SeverAbility | abilcode | No | |
Portal_targeted | unit | Yes | |
Portal_teleMissiles | group | No | |
Portal_traveller | unit | No | |
PreDamageEvent | real | No | |
QI_BW_Group | group | Yes | |
QI_LethalNeedle | group | Yes | |
RaceBronzebeardClan | real | No | |
RaceChoice_GameReadyBool | boolean | No | |
RaceChoice_TransferID | integer | No | |
RaceChoice_TransferPlayer | player | No | |
RaceDalaran | real | No | |
RaceDarkHorde | real | No | |
RaceDarkIronClan | real | No | |
RaceExodarDraenei | real | No | |
RaceFacelessOnes | real | No | |
RaceFelbloodElves | real | No | |
RaceFelHorde | real | No | |
RaceForsaken | real | No | |
RaceHighElves | real | No | |
RaceHumans | real | No | |
RaceIceTrolls | real | No | |
RaceIllidari | real | No | |
RaceInfoReturn | real | No | |
RaceLightforgedDraenei | real | No | |
RaceLivingNerubian | real | No | |
RaceLookAt | integer | Yes | |
RaceLostOnes | real | No | |
RaceNightborne | real | No | |
RaceNightElves | real | No | |
RaceOrcs | real | No | |
RaceQiraji | real | No | |
RaceScarletCrusade | real | No | |
RaceText | string | No | |
RaceTextInfo | string | No | |
RaceTitle | string | No | |
RaceUndeadNerubian | real | No | |
RaceUndeadScourge | real | No | |
RaceVoidElves | real | No | |
RaceWildhammerClan | real | No | |
RacialUniques | real | No | |
RacialUniques00 | real | No | |
RacialUniques01 | real | No | |
RacialUniques02 | real | No | |
RacialUniques03 | real | No | |
RacialUniques04 | real | No | |
RacialUniques05 | real | No | |
RallyPoint | location | No | |
RandomRaceAll | real | No | |
RandomRaceCustom | real | No | |
Real_Facing | real | No | |
RegCaster | unit | Yes | |
RegDummy | unit | Yes | |
regen_buildup | real | Yes | |
REGEN_EVENT_INTERVAL | real | No | |
REGEN_STRENGTH_VALUE | real | No | |
REGEN_THRESHOLD | real | No | |
regen_timeleft | real | Yes | |
RegInitialDummy | unit | Yes | |
RemainingGold | integer | No | |
RemainingManaCaster | integer | No | |
RemainingManaTarget | integer | No | |
RemoveDamageEvent | boolean | No | |
Reporting | boolean | No | |
ReportLife | real | No | |
ShieldBlockType | trigger | Yes | |
ShieldBreak | trigger | Yes | |
ShieldCaster | unit | Yes | |
ShieldDamaged | trigger | Yes | |
ShieldDuration | real | Yes | |
ShieldedUnit | unit | Yes | |
ShieldEvent | real | No | |
ShieldEventDamagedAmount | real | No | |
ShieldEventOverkillAmount | real | No | |
ShieldExpire | trigger | Yes | |
ShieldFirstOfIDAdded | boolean | No | |
ShieldFunctionInteger | integer | No | |
ShieldFunctionReturnInteger | integer | No | |
ShieldFunctionUnit | unit | No | |
ShieldHealth | real | Yes | |
ShieldHealthMax | real | Yes | |
ShieldIndex | integer | No | |
ShieldIterationTrigger | trigger | No | |
ShieldLastOfIDRemoved | boolean | No | |
ShieldNextDiff | integer | Yes | |
ShieldNextSame | integer | Yes | |
ShieldPeriodic | trigger | Yes | |
ShieldPrevDiff | integer | Yes | |
ShieldPrevSame | integer | Yes | |
ShieldRemoved | trigger | Yes | |
ShieldRemoveWhenBroken | boolean | Yes | |
ShieldTable | hashtable | No | |
ShieldTypeID | integer | Yes | |
ShieldUnitDamaged | trigger | Yes | |
ShieldUnitIndex | integer | No | |
SideFlame01 | boolean | No | |
SideFlame02 | boolean | No | |
SideFlame03 | boolean | No | |
SideFlame04 | boolean | No | |
SideFlameDeactivated | boolean | No | |
SourceDamageEvent | real | No | |
SpellDamageAbility | abilcode | No | |
SpellDamageAbility_Copy | abilcode | No | |
SummonerOfUnit | unit | Yes | |
SystemShieldedUnits | group | No | |
SystemShieldFlaggedRemove | boolean | Yes | |
SystemShieldFreeIndexCurrent | integer | No | |
SystemShieldFreeIndexes | integer | Yes | |
SystemShieldIterationStop | boolean | No | |
SystemShieldListInUse | integer | No | |
SystemShieldMaxIndex | integer | No | -1 |
SystemShieldPeriodicTimer | timer | No | |
SystemShieldsRemovalQueue | integer | Yes | |
SystemShieldsRemovalQueueIndex | integer | No | 0 |
Temp_Unit | unit | No | |
TempAbility | abilcode | No | |
TempestTuskCaster | unit | No | |
TempestTuskCount | integer | No | |
TempestTuskTarget | unit | No | |
TempFloaty | texttag | No | |
TempGroup | group | No | |
TempHLoc | location | No | |
TempHLocX | location | No | |
TempID | integer | No | |
TempInt | integer | Yes | |
TempInteger | integer | No | |
TempInteger_Copy | integer | No | |
tempLoc | location | Yes | |
TempLoc | location | No | |
TempLocation | location | No | |
TempLocX | location | No | |
TempPoint | location | No | |
TempPoint2 | location | No | |
TempReal | real | Yes | |
TempString | string | No | |
TempStrings | string | Yes | |
TempUnit | unit | No | |
TempX | real | No | |
TempY | real | No | |
Timer_AnimationReset | timer | No | |
Timestamp | timer | No | |
TmpPoint1 | location | No | |
TmpPoint2 | location | No | |
TmpReal | real | Yes | |
TmpReal1 | real | No | |
TmpReal2 | real | No | |
TravelerAngle | real | No | 2.79 |
TravelerFacing | real | No | -120.00 |
TravelerOffset | real | No | 60.00 |
UD_EnsnaringWebGroup | group | No | |
UD_EnsnaringWebHashtable | hashtable | No | |
UD_MergeAbominations | group | No | |
UD_MergeGroup | group | No | |
UD_MergeHashtable | hashtable | No | |
UD_NecromancerHashtable | hashtable | No | |
UD_RaiseDeadArray | integer | No | |
UD_RaiseDeadDummyAbility | abilcode | Yes | |
UD_RaiseDeadFood | integer | Yes | |
UD_RaiseDeadGold | integer | Yes | |
UD_RaiseDeadGroup | group | No | |
UD_RaiseDeadHashtable | hashtable | No | |
UD_RaiseDeadLumber | integer | Yes | |
UD_RaiseDeadMainAbility | abilcode | Yes | |
UD_RaiseDeadMana | real | Yes | |
UD_RaiseDeadSoul | integer | Yes | |
UD_RaiseDeadTime | real | Yes | |
UD_RaiseDeadType | unitcode | Yes | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexGen_Copy | integer | No | |
UDexLastRecycled | integer | No | |
UDexMax | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexRecycle_Copy | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UDexWasted_Copy | integer | No | |
UMovNext | integer | Yes | |
UMovPrev | integer | Yes | |
UN_BlightSporeNumber | integer | No | |
UN_UnitGroup_BlackAmbassador | group | No | |
UN_UnitGroup_Guards | group | No | |
UN_UnitGroup_Monitor | group | No | |
UN_UnitGroup_Ravager | group | No | |
UN_Winter_NerubianEggGroup | group | No | |
UNIT_CLASS_ANCIENT | integer | No | |
UNIT_CLASS_ATTACKS_FLYING | integer | No | |
UNIT_CLASS_ATTACKS_GROUND | integer | No | |
UNIT_CLASS_DEAD | integer | No | |
UNIT_CLASS_ETHEREAL | integer | No | |
UNIT_CLASS_FLYING | integer | No | |
UNIT_CLASS_GIANT | integer | No | |
UNIT_CLASS_GROUND | integer | No | |
UNIT_CLASS_HERO | integer | No | |
UNIT_CLASS_MAGIC_IMMUNE | integer | No | |
UNIT_CLASS_MECHANICAL | integer | No | |
UNIT_CLASS_MELEE | integer | No | |
UNIT_CLASS_PEON | integer | No | |
UNIT_CLASS_PLAGUED | integer | No | |
UNIT_CLASS_POISONED | integer | No | |
UNIT_CLASS_POLYMORPHED | integer | No | |
UNIT_CLASS_RANGED | integer | No | |
UNIT_CLASS_RESISTANT | integer | No | |
UNIT_CLASS_SAPPER | integer | No | |
UNIT_CLASS_SLEEPING | integer | No | |
UNIT_CLASS_SNARED | integer | No | |
UNIT_CLASS_STRUCTURE | integer | No | |
UNIT_CLASS_STUNNED | integer | No | |
UNIT_CLASS_SUMMONED | integer | No | |
UNIT_CLASS_TAUREN | integer | No | |
UNIT_CLASS_TOWNHALL | integer | No | |
UNIT_CLASS_UNDEAD | integer | No | |
Unit_StartPoint | unit | No | |
UnitDamageRegistered | boolean | Yes | |
UnitDamageRegistered_Copy | boolean | Yes | |
UnitFirstShield | integer | Yes | |
UnitGroup_ControlledGMFinished | group | No | |
UnitGroup_GoldmineBuild | group | No | |
UnitInAction | boolean | Yes | |
UnitInActionEvent | real | No | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitIndexLock | integer | Yes | |
UnitIndexLock_Copy | integer | Yes | |
UnitKey | integer | Yes | |
UnitLastShield | integer | Yes | |
UnitMovementInterval | real | No | |
UnitMoving | boolean | Yes | |
UnitMovingEvent | real | No | |
UnitMovingInList | boolean | Yes | |
UnitMovingX | real | Yes | |
UnitMovingY | real | Yes | |
UnitName | string | Yes | |
UnitShieldTag | texttag | Yes | |
UnitTypeEvent | real | No | |
UnitTypeOf | unitcode | Yes | |
Upkeep | integer | No | |
VE_AffinityVoidGroup | group | No | |
VE_ApostateGroup | group | No | |
VE_AstroPlateGroup | group | No | |
VE_ChancellorAoEBuffUnit | unit | No | |
VE_ChancellorAuraUnit | unit | No | |
VE_ChancellorHeroGroup | group | No | |
VE_DistrustInt | integer | No | |
VE_EnamorGroup | group | Yes | |
VE_NebulasHasteGroup | group | No | |
VE_ProfusionGroup | group | No | |
VE_ShifterGroup | group | No | |
VE_StarBinderHeroGroup | group | No | |
VE_VoidElvenGroup | group | No | |
VE_VoyagerCount | integer | No | |
VE_VoyagerCountGroup | group | No | |
VE_VoyagerGroup | group | No | |
VE_VoyagerUnit | unit | No | |
WDS_AddUnit | unit | No | |
WDS_Count | integer | No | |
WDS_DockAbilityChannel | abilcode | No | |
WDS_DockAbilityLevel | abilcode | No | |
WDS_DockAlreadyAdded | group | No | |
WDS_DockArray | integer | No | |
WDS_DockChannelerAbility | abilcode | Yes | |
WDS_DockChannelerType | unitcode | Yes | |
WDS_DockEffect | string | Yes | |
WDS_DockHostType | unitcode | Yes | |
WDS_DockLimit | integer | Yes | |
WDS_DockLinked | unit | No | |
WDS_DockOffset | real | No | |
WDS_DockOffsetHost | real | Yes | |
WDS_DockSpot | unit | No | |
WDS_DockStartingAngle | real | Yes | |
WDS_EffectHashtable | hashtable | No | |
WDS_EventDock | real | No | |
WDS_EventDockCheck | real | No | |
WDS_EventDockCount | integer | No | |
WDS_EventDockGroup | group | No | |
WDS_EventDockSource | unit | No | |
WDS_EventDockTarget | unit | No | |
WDS_FoundSpot | boolean | No | |
WDS_GroupChannelers | group | No | |
WDS_GroupDock | group | No | |
WDS_Hashtable | hashtable | No | |
WDS_Limit | integer | No | |
WDS_LoopA | integer | No | |
WDS_LoopB | integer | No | |
WDS_LoopC | integer | No | |
WDS_OrderGroup | group | No | |
WDS_StartPoint | location | Yes | |
WDS_TmpAngle | real | Yes | |
WDS_TmpHandleA | handle | No | |
WDS_TmpHandleB | handle | No | |
WDS_TmpHost | unit | No | |
WDS_TmpInteger | integer | Yes | |
WDS_TmpPoint | location | Yes | |
WDS_TmpReal | real | Yes | |
WDS_TmpTarget | unit | No | |
WEAPON_TYPE_AM_CHOP | integer | No | |
WEAPON_TYPE_CH_SLICE | integer | No | |
WEAPON_TYPE_CL_SLICE | integer | No | |
WEAPON_TYPE_CM_SLICE | integer | No | |
WEAPON_TYPE_MH_BASH | integer | No | |
WEAPON_TYPE_MH_CHOP | integer | No | |
WEAPON_TYPE_MH_SLICE | integer | No | |
WEAPON_TYPE_MH_STAB | integer | No | |
WEAPON_TYPE_ML_CHOP | integer | No | |
WEAPON_TYPE_ML_SLICE | integer | No | |
WEAPON_TYPE_MM_BASH | integer | No | |
WEAPON_TYPE_MM_CHOP | integer | No | |
WEAPON_TYPE_MM_SLICE | integer | No | |
WEAPON_TYPE_MM_STAB | integer | No | |
WEAPON_TYPE_NONE | integer | No | |
WEAPON_TYPE_RH_BASH | integer | No | |
WEAPON_TYPE_WH_BASH | integer | No | |
WEAPON_TYPE_WH_SLICE | integer | No | |
WEAPON_TYPE_WL_BASH | integer | No | |
WEAPON_TYPE_WL_SLICE | integer | No | |
WEAPON_TYPE_WL_STAB | integer | No | |
WEAPON_TYPE_WM_BASH | integer | No | |
WEAPON_TYPE_WM_SLICE | integer | No | |
WEAPON_TYPE_WM_STAB | integer | No | |
WeaponTypeDebugStr | string | Yes | |
WG_HarvestGroup | group | No | |
WG_HarvestHashtable | hashtable | No | |
WH_EvokedBeastGroup | group | No | |
WH_FavorEarthGroup | group | No | |
WH_HallsTraditionWildGroup | group | No | |
WH_LethalGroup | group | No | |
WH_RisingRageLevel | integer | No | |
WH_Soarer | group | No | |
WH_StacksRisingRage | integer | No | |
WH_TraditionWildGroup | group | No | |
WH_TravelGroup | group | No | |
WH_UnitGroup_Clansman | group | No | |
WH_UnitGroup_CloudGuardian | group | No | |
WH_UnitGroup_Elementalist | group | No | |
WH_UnitGroup_Geomancer | group | No | |
WH_UnitGroup_Groundskeeper | group | No | |
WH_UnitGroup_Gryphon | group | No | |
WH_UnitGroup_MountainBerserker | group | No | |
WH_UnitGroup_Mountaineer | group | No | |
WH_UnitGroup_ShamanWild | group | No | |
WH_UnitGroup_Siegebreaker | group | No | |
WH_UnitGroup_Slayer | group | No | |
WH_Vanguard | group | No | |
Winter_CargoHoldGroup | group | No | |
Winter_CargoHoldHandle | handle | No | |
Winter_CargoHoldHashtable | hashtable | No | |
Winter_CargoHoldUnit | unit | No | |
Winter_CargoHoldValue | integer | No | |
Winter_NerubianEggAbility | abilcode | Yes | |
Winter_NerubianEggAnimSpeed | real | No | |
Winter_NerubianEggArray | integer | No | |
Winter_NerubianEggBuildTime | integer | No | |
Winter_NerubianEggCancel | abilcode | No | |
Winter_NerubianEggEffect | string | No | |
Winter_NerubianEggEffectHeight | real | No | |
Winter_NerubianEggGold | integer | No | |
Winter_NerubianEggHandle | handle | No | |
Winter_NerubianEggHashtable | hashtable | No | |
Winter_NerubianEggLoop | integer | No | |
Winter_NerubianEggLumber | integer | No | |
Winter_NerubianEggMorph | abilcode | No | |
Winter_NerubianEggPassive | abilcode | No | |
Winter_NerubianEggTime | real | Yes | |
Winter_NerubianEggTrainedUnit | unitcode | No | |
Winter_NerubianEggTypeA | unitcode | No | |
Winter_NerubianEggTypeB | unitcode | No | |
Winter_NerubianEggUnit | unitcode | Yes | |
Winter_NerubianTmpInteger | integer | Yes | |
Winter_NerubianTmpPoint | location | Yes | |
Winter_NerubianTmpReal | real | Yes | |
Winter_NerubianTmpUnit | unit | Yes | |
WorldMaxX | real | No | |
WorldMaxY | real | No | |
X | real | No | |
Y | real | No | |
Z_Debug | boolean | No | |
Z_SaturationCap | integer | No | |
Z_SaturationGroup | group | No | |
Z_SaturationHashtable | hashtable | No | |
ZeroDamageEvent | real | No | |
ZOffset | real | No | 45.00 |
function Trig_ShieldBlockFront_Conditions takes nothing returns boolean
local unit source = udg_DamageEventSource
local unit target = udg_DamageEventTarget
local real x2 = GetUnitX(source)
local real y2 = GetUnitY(source)
local real x1 = GetUnitX(target)
local real y1 = GetUnitY(target)
local real arc = 180
local real angle = Atan2(y2 - y1, x2 - x1)*bj_RADTODEG
local real anglefacing = GetUnitFacing(target)
local real angledifference
// if anglefacing > 180 then
// set anglefacing = -(360 -anglefacing)
// endif
set angledifference = ModuloReal(angle-(anglefacing+180),360) - 180
// call BJDebugMsg("AngleDifference: " +R2S(angledifference))
set source = null
set target = null
if angledifference <= arc/2.0 and angledifference >= -arc/2.0 then
return true
endif
return false
endfunction
function Trig_ShieldBlockFront_Actions takes nothing returns nothing
endfunction
//===========================================================================
function InitTrig_ShieldBlockFront takes nothing returns nothing
set gg_trg_ShieldBlockFront = CreateTrigger( )
call TriggerAddCondition( gg_trg_ShieldBlockFront, Condition( function Trig_ShieldBlockFront_Conditions ) )
call TriggerAddAction( gg_trg_ShieldBlockFront, function Trig_ShieldBlockFront_Actions )
endfunction
function Trig_ShieldBlockByEffect60_Conditions takes nothing returns boolean
local effect e = LoadEffectHandle(udg_ShieldTable, udg_ShieldIndex, StringHash("ShieldEffect"))
local unit source = udg_DamageEventSource
local unit target = udg_DamageEventTarget
local real x2 = GetUnitX(source)
local real y2 = GetUnitY(source)
local real x1 = GetUnitX(target)
local real y1 = GetUnitY(target)
local real x3 = BlzGetLocalSpecialEffectX(e)
local real y3 = BlzGetLocalSpecialEffectY(e)
local real arc = 120
local real angle = Atan2(y2 - y1, x2 - x1)*bj_RADTODEG
local real anglefacing = Atan2(y3 - y1, x3 - x1)*bj_RADTODEG
local real angledifference
set angledifference = ModuloReal(angle-(anglefacing+180),360) - 180
//call BJDebugMsg("AngleDifference: " +R2S(angledifference))
set source = null
set target = null
if angledifference <= arc/2.0 and angledifference >= -arc/2.0 then
return true
endif
return false
endfunction
//===========================================================================
function InitTrig_ShieldBlockByEffect120 takes nothing returns nothing
set gg_trg_ShieldBlockByEffect120 = CreateTrigger( )
call TriggerAddCondition( gg_trg_ShieldBlockByEffect120, Condition( function Trig_ShieldBlockByEffect60_Conditions ) )
endfunction
function Trig_ShieldPeriodicEval_Actions takes nothing returns nothing
local integer unitcount = BlzGroupGetSize(udg_SystemShieldedUnits)
local integer counter = 0
local unit u
local real shieldcurrenthp
local real shieldmaxhp
loop
exitwhen counter >= unitcount
set u = BlzGroupUnitAt(udg_SystemShieldedUnits, counter)
set udg_ShieldUnitIndex = GetUnitUserData(u)
set udg_ShieldIterationTrigger = gg_trg_ShieldPeriodicIterationTrigger
call TriggerExecute( gg_trg_ForAllShieldsOfUnit )
set udg_ShieldUnitIndex = GetUnitUserData(u)
set udg_ShieldEvent = 0.00
set udg_ShieldEvent = 4.00
set counter = counter + 1
endloop
set u = null
endfunction
//===========================================================================
function InitTrig_ShieldPeriodicEval takes nothing returns nothing
set gg_trg_ShieldPeriodicEval = CreateTrigger( )
call TriggerRegisterTimerExpireEventBJ( gg_trg_ShieldPeriodicEval, udg_SystemShieldPeriodicTimer )
call TriggerAddAction( gg_trg_ShieldPeriodicEval, function Trig_ShieldPeriodicEval_Actions )
endfunction
function Trig_RemoveShield_Actions takes nothing returns nothing
local integer shieldindex = udg_ShieldIndex
if ( udg_ShieldIndex != 0 ) then
if ( udg_SystemShieldListInUse <= 1 ) then
set udg_ShieldLastOfIDRemoved = false
set udg_ShieldUnitIndex = GetUnitUserData(udg_ShieldedUnit[udg_ShieldIndex])
// Adjust shield lists
if ( udg_ShieldNextSame[udg_ShieldIndex] == 0 ) then
// Next same does not exist
if ( udg_ShieldPrevSame[udg_ShieldIndex] == 0 ) then
// Next same, Prev same do not exist
// Last of type being removed
set udg_ShieldLastOfIDRemoved = true
// Check diff shield values, to see if it's head, tail, or middle removal
if ( udg_ShieldNextDiff[udg_ShieldIndex] == 0 ) then
if ( udg_ShieldPrevDiff[udg_ShieldIndex] == 0 ) then
// Only buff remaining
set udg_UnitFirstShield[udg_ShieldUnitIndex] = 0
set udg_UnitLastShield[udg_ShieldUnitIndex] = 0
call GroupRemoveUnitSimple( udg_ShieldedUnit[udg_ShieldIndex], udg_SystemShieldedUnits )
else
// no next, has prev, is on tail end of diff list
set udg_UnitLastShield[udg_ShieldUnitIndex] = udg_ShieldPrevDiff[udg_ShieldIndex]
set udg_ShieldNextDiff[udg_ShieldPrevDiff[udg_ShieldIndex]] = 0
endif
else
if ( udg_ShieldPrevDiff[udg_ShieldIndex] == 0 ) then
// Has next, no prev. Is head of diff list
set udg_UnitFirstShield[udg_ShieldUnitIndex] = udg_ShieldNextDiff[udg_ShieldIndex]
set udg_ShieldPrevDiff[udg_ShieldNextDiff[udg_ShieldIndex]] = 0
else
// has next, has prev, is in middle of diff list
set udg_ShieldPrevDiff[udg_ShieldNextDiff[udg_ShieldIndex]] = udg_ShieldPrevDiff[udg_ShieldIndex]
set udg_ShieldNextDiff[udg_ShieldPrevDiff[udg_ShieldIndex]] = udg_ShieldNextDiff[udg_ShieldIndex]
endif
endif
else
// On tail end of same list
set udg_ShieldNextSame[udg_ShieldPrevSame[udg_ShieldIndex]] = 0
endif
else
// Next same exists
if ( udg_ShieldPrevSame[udg_ShieldIndex] == 0 ) then
// On head of same list
set udg_ShieldPrevSame[udg_ShieldNextSame[udg_ShieldIndex]] = 0
if ( udg_ShieldNextDiff[udg_ShieldIndex] == 0 ) then
if ( udg_ShieldPrevDiff[udg_ShieldIndex] == 0 ) then
// No next, no prev. Only type
set udg_UnitFirstShield[udg_ShieldUnitIndex] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_UnitLastShield[udg_ShieldUnitIndex] = udg_ShieldNextSame[udg_ShieldIndex]
else
// no next, has prev, is on tail end of diff list
set udg_UnitLastShield[udg_ShieldUnitIndex] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_ShieldNextDiff[udg_ShieldPrevDiff[udg_ShieldIndex]] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_ShieldPrevDiff[udg_ShieldNextSame[udg_ShieldIndex]] = udg_ShieldPrevDiff[udg_ShieldIndex]
endif
else
if ( udg_ShieldPrevDiff[udg_ShieldIndex] == 0 ) then
// Has next, no prev. Is head of diff list
set udg_UnitFirstShield[udg_ShieldUnitIndex] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_ShieldPrevDiff[udg_ShieldNextDiff[udg_ShieldIndex]] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_ShieldNextDiff[udg_ShieldNextSame[udg_ShieldIndex]] = udg_ShieldNextDiff[udg_ShieldIndex]
else
// has next, has prev, is in middle of diff list
set udg_ShieldPrevDiff[udg_ShieldNextDiff[udg_ShieldIndex]] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_ShieldNextDiff[udg_ShieldPrevDiff[udg_ShieldIndex]] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_ShieldNextDiff[udg_ShieldNextSame[udg_ShieldIndex]] = udg_ShieldNextDiff[udg_ShieldIndex]
set udg_ShieldPrevDiff[udg_ShieldNextSame[udg_ShieldIndex]] = udg_ShieldPrevDiff[udg_ShieldIndex]
endif
endif
else
// In middle of same list
set udg_ShieldNextSame[udg_ShieldPrevSame[udg_ShieldIndex]] = udg_ShieldNextSame[udg_ShieldIndex]
set udg_ShieldPrevSame[udg_ShieldNextSame[udg_ShieldIndex]] = udg_ShieldPrevSame[udg_ShieldIndex]
endif
endif
call TriggerExecute( udg_ShieldRemoved[udg_ShieldIndex] )
set udg_ShieldIndex = shieldindex
set udg_ShieldEvent = 0.00
set udg_ShieldEvent = 2.00
// Just in case the event somehow changed the shieldindex
set udg_ShieldIndex = shieldindex
set udg_SystemShieldFreeIndexCurrent = ( udg_SystemShieldFreeIndexCurrent - 1 )
set udg_SystemShieldFreeIndexes[udg_SystemShieldFreeIndexCurrent] = udg_ShieldIndex
call FlushChildHashtable(udg_ShieldTable, udg_ShieldIndex)
//call BJDebugMsg("Shield removed: "+I2S(udg_ShieldIndex))
else
// If list in use, do not remove entries yet, could affect traversal of list
// Add shields to be removed into a queue
if udg_SystemShieldFlaggedRemove[udg_ShieldIndex] == false then
set udg_SystemShieldFlaggedRemove[udg_ShieldIndex] = true
set udg_SystemShieldsRemovalQueueIndex = ( udg_SystemShieldsRemovalQueueIndex + 1 )
set udg_SystemShieldsRemovalQueue[udg_SystemShieldsRemovalQueueIndex] = udg_ShieldIndex
endif
endif
else
endif
endfunction
//===========================================================================
function InitTrig_RemoveShield takes nothing returns nothing
set gg_trg_RemoveShield = CreateTrigger( )
call TriggerAddAction( gg_trg_RemoveShield, function Trig_RemoveShield_Actions )
endfunction
function Trig_ForAllShieldsOfUnit_Actions takes nothing returns nothing
local integer counter
local integer previndex = udg_ShieldIndex
local integer shieldindex
local trigger iterationtrigger = udg_ShieldIterationTrigger
local integer unitindex = udg_ShieldUnitIndex
local integer topshield = udg_UnitFirstShield[udg_ShieldUnitIndex]
local integer queuedshields
local boolean baseiteration = false
if ( udg_SystemShieldListInUse == 0 ) then
set udg_SystemShieldsRemovalQueueIndex = -1
set baseiteration = true
endif
set udg_SystemShieldListInUse = ( udg_SystemShieldListInUse + 1 )
set udg_ShieldIndex = udg_UnitFirstShield[udg_ShieldUnitIndex]
set udg_SystemShieldIterationStop = false
loop
exitwhen topshield == 0 or udg_SystemShieldIterationStop
set udg_ShieldIndex = topshield
loop
exitwhen udg_ShieldIndex == 0 or udg_SystemShieldIterationStop
if udg_SystemShieldFlaggedRemove[udg_ShieldIndex] == false or udg_ShieldIterationTrigger == gg_trg_RemoveShield then
set shieldindex = udg_ShieldIndex
set udg_ShieldIterationTrigger = iterationtrigger
call TriggerExecute( udg_ShieldIterationTrigger )
set udg_ShieldIndex = shieldindex
endif
set udg_ShieldIndex = udg_ShieldNextSame[udg_ShieldIndex]
endloop
set topshield = udg_ShieldNextDiff[topshield]
endloop
// If any shields were queued to be removed, remove them after list traversal is done
if ( baseiteration and udg_SystemShieldsRemovalQueueIndex >= 0 ) then
call BJDebugMsg("Index: "+I2S(udg_SystemShieldsRemovalQueueIndex))
call BJDebugMsg("Removing shields in queue")
set counter = 0
loop
exitwhen counter > udg_SystemShieldsRemovalQueueIndex
set udg_ShieldIndex = udg_SystemShieldsRemovalQueue[counter]
set queuedshields = udg_SystemShieldsRemovalQueueIndex
call TriggerExecute( gg_trg_RemoveShield )
set udg_SystemShieldsRemovalQueueIndex = queuedshields
set counter = counter + 1
endloop
else
endif
set udg_ShieldUnitIndex = unitindex
set iterationtrigger = null
set udg_SystemShieldListInUse = ( udg_SystemShieldListInUse - 1 )
set udg_ShieldIndex = previndex
endfunction
//===========================================================================
function InitTrig_ForAllShieldsOfUnit takes nothing returns nothing
set gg_trg_ForAllShieldsOfUnit = CreateTrigger( )
call TriggerAddAction( gg_trg_ForAllShieldsOfUnit, function Trig_ForAllShieldsOfUnit_Actions )
endfunction
function Trig_ForAllShieldsOfUnitDisplayOrder_Actions takes nothing returns nothing
local integer counter
local integer shieldindex
local trigger iterationtrigger = udg_ShieldIterationTrigger
local integer unitindex = udg_ShieldUnitIndex
local integer topshield = udg_UnitFirstShield[udg_ShieldUnitIndex]
local integer queuedshields
local boolean baseiteration = false
if ( udg_SystemShieldListInUse == 0 ) then
set udg_SystemShieldsRemovalQueueIndex = -1
set baseiteration = true
endif
set udg_SystemShieldListInUse = ( udg_SystemShieldListInUse + 1 )
set udg_ShieldIndex = udg_UnitFirstShield[udg_ShieldUnitIndex]
set udg_SystemShieldIterationStop = false
loop
exitwhen topshield == 0 or udg_SystemShieldIterationStop
set udg_ShieldIndex = topshield
loop
exitwhen udg_ShieldNextSame[udg_ShieldIndex] == 0
set udg_ShieldIndex = udg_ShieldNextSame[udg_ShieldIndex]
endloop
loop
exitwhen udg_ShieldIndex == 0 or udg_SystemShieldIterationStop
if udg_SystemShieldFlaggedRemove[udg_ShieldIndex] == false or udg_ShieldIterationTrigger == gg_trg_RemoveShield then
set shieldindex = udg_ShieldIndex
set udg_ShieldIterationTrigger = iterationtrigger
call TriggerExecute( udg_ShieldIterationTrigger )
set udg_ShieldIndex = shieldindex
endif
set udg_ShieldIndex = udg_ShieldPrevSame[udg_ShieldIndex]
endloop
set topshield = udg_ShieldNextDiff[topshield]
endloop
// If any shields were queued to be removed, remove them after list traversal is done
if ( baseiteration and udg_SystemShieldsRemovalQueueIndex >= 0 ) then
call BJDebugMsg("Index: "+I2S(udg_SystemShieldsRemovalQueueIndex))
call BJDebugMsg("Removing shields in queue")
set counter = 0
loop
exitwhen counter > udg_SystemShieldsRemovalQueueIndex
set udg_ShieldIndex = udg_SystemShieldsRemovalQueue[counter]
set queuedshields = udg_SystemShieldsRemovalQueueIndex
call TriggerExecute( gg_trg_RemoveShield )
set udg_SystemShieldsRemovalQueueIndex = queuedshields
set counter = counter + 1
endloop
else
endif
set udg_ShieldUnitIndex = unitindex
set iterationtrigger = null
set udg_SystemShieldListInUse = ( udg_SystemShieldListInUse - 1 )
endfunction
//===========================================================================
function InitTrig_ForAllShieldsOfUnitDisplayOrder takes nothing returns nothing
set gg_trg_ForAllShieldsOfUnitDisplayOrder = CreateTrigger( )
call TriggerAddAction( gg_trg_ForAllShieldsOfUnitDisplayOrder, function Trig_ForAllShieldsOfUnitDisplayOrder_Actions )
endfunction
function Trig_ForAllShieldsOfUnitBackward_Actions takes nothing returns nothing
local integer counter
local integer shieldindex
local trigger iterationtrigger = udg_ShieldIterationTrigger
local integer unitindex = udg_ShieldUnitIndex
local integer topshield = udg_UnitLastShield[udg_ShieldUnitIndex]
local integer queuedshields
local boolean baseiteration = false
if ( udg_SystemShieldListInUse == 0 ) then
set udg_SystemShieldsRemovalQueueIndex = -1
set baseiteration = true
endif
set udg_SystemShieldListInUse = ( udg_SystemShieldListInUse + 1 )
set udg_ShieldIndex = udg_UnitLastShield[udg_ShieldUnitIndex]
set udg_SystemShieldIterationStop = false
loop
exitwhen topshield == 0 or udg_SystemShieldIterationStop
set udg_ShieldIndex = topshield
loop
exitwhen udg_ShieldNextSame[udg_ShieldIndex] == 0
set udg_ShieldIndex = udg_ShieldNextSame[udg_ShieldIndex]
endloop
loop
exitwhen udg_ShieldIndex == 0 or udg_SystemShieldIterationStop
if udg_SystemShieldFlaggedRemove[udg_ShieldIndex] == false or udg_ShieldIterationTrigger == gg_trg_RemoveShield then
set shieldindex = udg_ShieldIndex
set udg_ShieldIterationTrigger = iterationtrigger
call TriggerExecute( udg_ShieldIterationTrigger )
set udg_ShieldIndex = shieldindex
endif
set udg_ShieldIndex = udg_ShieldPrevSame[udg_ShieldIndex]
endloop
set topshield = udg_ShieldPrevDiff[topshield]
endloop
// If any shields were queued to be removed, remove them after list traversal is done
if ( baseiteration and udg_SystemShieldsRemovalQueueIndex >= 0 ) then
call BJDebugMsg("Index: "+I2S(udg_SystemShieldsRemovalQueueIndex))
call BJDebugMsg("Removing shields in queue")
set counter = 0
loop
exitwhen counter > udg_SystemShieldsRemovalQueueIndex
set udg_ShieldIndex = udg_SystemShieldsRemovalQueue[counter]
set queuedshields = udg_SystemShieldsRemovalQueueIndex
call TriggerExecute( gg_trg_RemoveShield )
set udg_SystemShieldsRemovalQueueIndex = queuedshields
set counter = counter + 1
endloop
else
endif
set udg_ShieldUnitIndex = unitindex
set iterationtrigger = null
set udg_SystemShieldListInUse = ( udg_SystemShieldListInUse - 1 )
endfunction
//===========================================================================
function InitTrig_ForAllShieldsOfUnitBackward takes nothing returns nothing
set gg_trg_ForAllShieldsOfUnitBackward = CreateTrigger( )
call TriggerAddAction( gg_trg_ForAllShieldsOfUnitBackward, function Trig_ForAllShieldsOfUnitBackward_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function KB3D_Features_JASS takes nothing returns nothing
// Those Values are Required for the KB
// ------------------------------------------------
// ------------------------
// Knock-Backed Unit, the Knock-Backed Unit who all actions orbit around
set udg_KB3D_Unit = null
// Requires: NONE
// ------------------------
// Max Range, Maximum Range possible of the Knock-Back
set udg_KB3D_Range = 0.00
// Requires: NONE
// ------------------------
// Base KB Speed, Base Speed when starting the Knock-Back
set udg_KB3D_Speed = 0.00
// Requires: NONE
// ------------------------
// Angle, The KB's line angle, this will be useless if KB3D_Targeted_Unit is not null
set udg_KB3D_Angle = 0.00
// Requires: NONE
// ------------------------
// ------------------------------------------------
// Those Values are Optional for the KB
// NOTE: some values may depend on other to function, like LineDamage that needs "Damager, AttackType, DamageType, AoE" to function
// ------------------------------------------------
// ------------------------
// Targets Allowed
// ------------------------
// Filter Damages and AoEKB with those values, if true, each one will allow filtering of Structures, Mechanicals, Magic Imminues, Allies
// ------------------------
set udg_KB3D_D_MAGIC_IMMINUE = false
set udg_KB3D_D_ALLY = false
set udg_KB3D_D_MECHANICAL = false
set udg_KB3D_D_STRUCTURE = false
set udg_KB3D_D_ENEMY = true
set udg_KB3D_D_FLYING = false
set udg_KB3D_D_RESISTANT = false
// Requires: AoEKB, or, Damagers, or, BounceTarget
// ------------------------
// Speed Changer, makes the unit move forward with a bonus speed equal to the KB speed, negative speed also works
set udg_KB3D_Speed_Changer = false
// Requires: NONE, Disables Angle
// ------------------------
// Homing Missile, automatically sets needed features of KB3D for a homing missile
set udg_KB3D_HomingMissile = true
// Requires: NONE, Disables Angle
// ------------------------
// Bounce Unit, Makes the KBed unit bounce on unpathable areas and units
set udg_KB3D_Bounce_Unit = false
// Requires: NONE
// ------------------------
// Bounce Targets, Bounces units that encounter the KBed unit
set udg_KB3D_Bounce_Target = false
// Requires: AoE
// ------------------------
// End on Target Bounce, when hits a unit, ends the KB
set udg_KB3D_EndOnTargetBounce = false
// Requires: Bounce_Target
// ------------------------
// Bounce Power, intensity of the Bounce
set udg_KB3D_Bounce_Power = 1.00
// Requires: Bounce
// ------------------------
// Bounce Effect, Effect created on units that get Bounced
set udg_KB3D_Bounce_Fx = ""
// Requires: Bounce
// ------------------------
// Destroy Destructibles, Destroys any destructibles on the path of the KB, does not destroy platforms, bridges, elevators
set udg_KB3D_DestroyDestructables = false
// Requires: Line Damage
// ------------------------
// Line Effect, Effect created on units damaged by Line Damage
set udg_KB3D_Line_Fx = ""
// Requires: Line Damage
// ------------------------
// End Trigger, This trigger will be excecuted at the end of the KB, you can use KB3D_Unit and KB3D_Targeted_Unit variables in the trigger
set udg_KB3D_EndTrigger = udg_KB3D_EndTrigger
// Requires: NONE
// ------------------------
// End on Obstacle, Immediatly Ends the KB if the KBed unit encounters an unpathable area
set udg_KB3D_EndOnObstacle = false
// Requires: NONE
// ------------------------
// Arc, Arc of the Angle of the KB, does not work with homing KB
set udg_KB3D_Arc = 0.00
// Requires: Angle
// ------------------------
// Ending Effect, an Effect created at the End of the KB on the KBed Unit
set udg_KB3D_EndFx = ""
// Requires: AoE
// ------------------------
// AoE End Damage, Damage dealt to enemy units in the AoE at the End of the KB
set udg_KB3D_AoEEndDamage = 0.00
// Requires: AoE, Damager, AType, DType
// ------------------------
// AoE KB, if true, KBs Enemy units within the AoE, Range, Speed, Angle, are automatic
set udg_KB3D_AoEKB = false
// Requires: AoE
// ------------------------
// AoE KB Power, The Power of the AoE KB, default value is 1.00 (normal), Min value: 0.01, Max value: 3.00
set udg_KB3D_AoEKB_Power = 0.00
// Requires: AoEKB
// ------------------------
// End when Dead, if true, the KB will end if the KBed unit is dead, TRUE by default
set udg_KB3D_EndwhenDead = true
// Requires: NONE
// ------------------------
// Ground Damage, Damages the Unit When it hits the Ground, Damage dealt is KB3D_ImpactDamage
set udg_KB3D_GroundDamage = false
// Requires: Damager, ImpactDamage, AType, DType
// ------------------------
// KB the Target, When the Targeted Unit is hit, it will be KBed depending on the speed of the original KB
set udg_KB3D_KBTarget = false
// Requires: Targeted_Unit
// ------------------------
// Stop Time, Maximum Time the KB will last, Note that if the KBed unit is flying at this time, it will be stuck
set udg_KB3D_StopTime = 0.00
// Requires: NONE
// ------------------------
// Kill at End, Kills the KBed Unit at the End of the KB
set udg_KB3D_KillatEnd = false
// Requires: NONE
// ------------------------
// Kill at Time, When this time is reached, the KBed unit will be killed, if this number is higher than KB3D_StopTime, EndWhenDead will be automatically turned on no matter what
set udg_KB3D_KillatTime = 0.00
// Requires: NONE
// ------------------------
// Acceleration, Speed Added/s to the KB speed
set udg_KB3D_Accel = 0.00
// Requires: NONE
// ------------------------
// Allow going outside playable bounds, Allows the KBed unit to go out of the Playable Bounds, SAFETY notice: this will not crash the game
set udg_KB3D_AllowOutSiding = false
// Requires: NONE
// ------------------------
// Area of Effect, Range where the Line Damage is applied to units
set udg_KB3D_AoE = 0.00
// Requires: NONE
// ------------------------
// Area of Effect Damage, Makes the KB3D_Damager, damage enemy units within KB3D_AoE by this value as a DPS
set udg_KB3D_AoEDamage = 0.00
// Requires: AoE, Damager, DType, AType
// ------------------------
// Attack Type, Attack type of ALL damagings in the Instance
set udg_KB3D_AttackType = ATTACK_TYPE_MELEE
// Requires: NONE
// ------------------------
// Damage Type, Damage type of ALL damagings in the Instance
set udg_KB3D_DamageType = DAMAGE_TYPE_MAGIC
// Requires: NONE
// ------------------------
// Damager, Source of ALL damagings in the Instance
set udg_KB3D_Damager = null
// Requires: NONE
// ------------------------
// Destroy Trees?, Destroy Trees around the KBed unit while he is KBed?
set udg_KB3D_DestroyTree = true
// Requires: NONE
// ------------------------
// Disable Unit?, Disable the KBed Unit's Movement and Turning?
set udg_KB3D_DisableUnit = false
// Requires: NONE
// ------------------------
// End When Hit?, Ends the KB if the KBed Unit hits the Targeted Unit
set udg_KB3D_EndWhenHit = false
// Requires: Targeted_Unit
// ------------------------
// Face KB Anlge, makes the KBed Unit Face the Anlge of the KB during the KB
set udg_KB3D_FaceAngle = false
// Requires: NONE
// ------------------------
// Effect, Effect created on the Unit's Location if he is not flying, and applied on the Unit if he is flying on the Attach Point
set udg_KB3D_Fx = ""
// Requires: Attach
// ------------------------
// Attachment Point, location on the KBed unit where Effects are attached
set udg_KB3D_Attach = ""
// Requires: NONE
// ------------------------
// AoE End Effect, Effect Created on target units in the AoE at the End of the KB
set udg_KB3D_AoEEndFx = ""
// Requires: AoE, Attach
// ------------------------
// Impact Damage, Damaged dealt to the KBed Unit if he hits an obstacle
set udg_KB3D_ImpactDamage = 0.00
// Requires: Damager
// ------------------------
// intelligent KB, Enables the intelligent features of KB3D, see Main Code Comments for more info
set udg_KB3D_iKB = true
// Requires: NONE
// ------------------------
// Kill When Hit?, Kills the KBed Unit if he hits the Targeted Unit, Automatically set EndWhenHit to true
set udg_KB3D_KillWhenHit = false
// Requires: Targeted_Unit
// ------------------------
// Kill if Out of Playable Bounds, Kills the KBed Unit if he gets out of Playable Bounds, this automatically sets KB3D_AllowOutSiding to TRUE
set udg_KB3D_KillifOutSider = false
// Requires: AllowOutSiding
// ------------------------
// Line Damage, Damage dealt to enemy units in the AoE around the KBed Unit
set udg_KB3D_LineDamage = 0.00
// Requires: Damager, AoE
// ------------------------
// Loop Damage, DPS dealt to the KBed Unit
set udg_KB3D_LoopDamage = 0.00
// Requires: Damager, AoE
// ------------------------
// Jump over Cliff, Allows the KBed unit to go over cliffs if he has more than 150 fly height and IF there is a possible location where he can land in a pathable point, not recommended with >0 Acceleration
set udg_KB3D_JumpOverCliff = false
// Requires: NONE
// ------------------------
// Target Damage, Damage dealt to the Targeted Unit when both KBed Unit and Targeted Unit hit each other, only happens once
set udg_KB3D_TargetDamage = 0.00
// Requires: Targeted_Unit, Damager
// ------------------------
// Targeted Unit, if not null, makes the KBed Unit act like a homing missile targeting this unit, it also used for other functions
set udg_KB3D_Targeted_Unit = null
// Requires: NONE
// ------------------------
// Trail Effect, Effect Attached on the KBed Unit all along the Knock-Back and Destroyed at the end of the KB
set udg_KB3D_TrailFx = ""
// Requires: Attach
// ------------------------
// Stop at Unpathable, Makes it impossible for the KBed Unit to path throught Unpathable Terrain
set udg_KB3D_UnpathableStop = true
// Requires: NONE
// ------------------------
// Z Offset, Max Flying Height reached while Knockbacking
set udg_KB3D_Zoffset = 0.00
// Requires: NONE
// ------------------------
// ------------------------------------------------
// Registed All of the Settings
call ExecuteFunc( "KB3D_Registration" )
// You can use the following to know how much the knock-back will last -- this can vary if the KB is homed on a moving unit
set udg_KB3D_Time = udg_KB3D_Time
endfunction
//===========================================================================
function InitTrig_KB3D_Features_JASS takes nothing returns nothing
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////
// //
// Knock-Back 3D [JASS - GUI] V. 3.2.1 //
// Multi-Movement System 3D //
// by Jad aka DotCa and T.D.W. //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// System's Hidden Features: //
// //
// 1. To know if a unit is being KBed by the System, Use: //
// - LoadBoolean(udg_KB3D_HA, GetHandleId(Unit), GetHandleId(Unit)) //
// True means that the unit is being KBed, also works in GUI //
// 2. Use udg_KB3D_Time variable after registring the KB to actually //
// know how much the KB will last, NOTE that this the time may //
// varry if you have a Homing KB (using KB3D_Targeted_Unit) //
// 3. Some Variables in the System has default values, but useful; //
// in Example, "udg_KB3D_Attach" is "origin" even without setting //
// it, so you won't need to change it before Registering a KB //
// 4. You can get the ID of a Knockback after registrating it by //
// using the value of KB3D_Counter //
// 5. You can remove any KB on a specific unit by setting KB3D_Remove //
// KB3D_RemoveUnit to this Unit, and then calling the function: //
// "KB3D_RemoveUnit() //
// 6. You can know what caused the end of a KB in the EndTrigger by //
// checking those variables: KB3D_EndisUnit / KB3D_EndisUnpathable //
// KB3D_EndisNormal //
// 7. You can use the following Pause/Resume functions on a specific //
// KB instance or on all the system //
// - KB3D_Pause( ID ) Applies on a single KB //
// - KB3D_Resume( ID ) Applies on a single KB //
// - KB3D_PauseAll() Applies on a All KB Instances //
// - KB3D_ResumeAll() Applies on a All KB Instances //
// - KB3D_PauseRegistration() Applies on a All KB Instances //
// - KB3D_ResumeRegistration() Applies on a All KB Instances //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// System Informations: //
// //
// The System is a well performing, ultra-purpose knockback (see uses //
// below ) Coded in JASS making it possible for all users to take //
// advantage of it, and GUI friendly to use, see Examples in the triggers //
// above //
// Configurations that have default values: //
// //
// - KB3D_EndWhenDead ==> TRUE by default //
// - KB3D_UnpathableStop ==> TRUE by default //
// - KB3D_iKB ==> TRUE by default //
// - KB3D_D_ENEMY ==> TRUE by default //
// - KB3D_DestroyTree ==> TRUE by default //
// - KB3D_AttackType ==> ATTACK_TYPE_NORMAL by default //
// - KB3D_DamageType ==> DAMAGE_TYPE_MAGIC by default //
// - KB3D_AoEKB_Power ==> 1.00 by default //
// - KB3D_Attach ==> "origin" by default //
// - Other Booleans ==> FALSE by default //
// //
// The System also uses Always positive values for some configurations //
// to not make the knockback go wrong, those configurations are: //
// //
// "KB3D_Range" - "KB3D_Speed" - "KB3D_ZOffset" - "KB3D_AoE" //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// HomingMissile, Accessibility feature //
// //
// When true, there will be no need to set the range and some other //
// features, since they will be automatically set to fit a homing //
// missile: //
// - KB3D_Zoffset - KB3D_Range - KB3D_KillatEnd - KB3D_EndWhenHit - //
// - KB3D_FaceAngle - KB3D_UnpathableStop - KB3D_KillWhenHit - //
// //
// This feature allows to skip the configurations of some features //
// needed for a homing missile, Note that Targeted_Unit needs to be set //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// iKB, intelligent KB informations: //
// //
// iKB, makes some features in KB3D act intelligently, those features: //
// //
// -Range: usually always positive, it will be available in negative //
// values, it will, if negative, flip the Angle (+180 d) //
// -Speed: usually always positive, it will be available in negative //
// values, it will act normally, just the KBed unit will //
// move backward if the current speed is negative //
// -Height: usually always positive, it will be available in negative//
// values, it will, if negative, make the unit go down //
// instead of up //
// -Damages: //
// AoEEndDamage, AoEDamage, LineDamage, ImpactDamage, TargetDamage //
// //
// All those values ^ will turn intelligent, by this, it means //
// that if the Target of the Damage is not in approximated //
// height (Z) of the KBed Unit, the damage won't occur //
// -AoEKB, usually KBs all units in the AoE, it will choose only //
// Units that are close to it by the height, Z offset //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// System Requirements: Basic WE - (NONE) //
// //
// The System uses implemented CheckWalkability System by PurgeandFire //
// You "can" remove the initialization trigger of PnF's System since //
// it is directly implemented in the System, all will work fine with or //
// without removing your Initializer trigger //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// Credits: //
// //
// *WEHZ & TS Helpers Group for helping in Script Fixes //
// *Barry the Moose for helping in main codes and fixes //
// *PurgeandFire for his CheckWalkability System //
// *Vexorian / Nestharus for the GetCollision function //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// How to Import? //
// //
// 1. Check that Create Unknown Variables is ticked in your WE Settings //
// 2. Copy the Paste the Knock-Back 3D Folder //
// 3. Delete the Variable Creator Trigger and learn how to use the System //
// by reading the documentation in the 2 Features Triggers (GUI - JASS)//
// Congratulations, the System is now implemented in your map //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// How to Use? //
// //
// 1. There are many Examples of use in the KB3D Example Folder //
// 2. Documentations are there in the Features Triggers to help you //
// 3. The KB3D System is an Ultra-Purpose System where you can use it for://
// -Projectiles, the system supports homing so a projectile is easy //
// -Jump, the System's smoothness in the fly is useful for a jump spell//
// -And of course, a 2D Knock-Back //
// -And More depending on your imagination //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// Bug Reports - Feedbacks //
// //
// * We count on you to report bugs in the system, also telling the source//
// * Feedbacks about the system are much appreciated //
// * We mostly hope suggestions about enhancements for the System //
// //
/////////////////////////////////////////////////////////////////////////////
function KB3D_AlwaysNeg takes real R returns real
if R > 0 then
return -R
endif
return R
endfunction
function KB3D_InBetween takes real Min, real R, real Max returns real
return RMaxBJ(RMinBJ(R, Max), Min)
endfunction
function KB3D_IsInBetween takes real Min, real R, real Max returns boolean
return R > Min and R < Max
endfunction
function KB3D_CW_Loop takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set udg_CP_HiddenItems[udg_CP_HiddenItemsIndex] = GetEnumItem()
call SetItemVisible(udg_CP_HiddenItems[udg_CP_HiddenItemsIndex], false)
set udg_CP_HiddenItemsIndex = ( udg_CP_HiddenItemsIndex + 1 )
endif
endfunction
function KB3D_CW takes real x, real y returns boolean
local real x2 = 0
local real y2 = 0
//---------------------------
call MoveRectTo(udg_CP_Rect, x, y)
call EnumItemsInRect(udg_CP_Rect, null, function KB3D_CW_Loop )
call SetItemPosition(udg_CP_Item, x, y)
set x2 = GetItemX(udg_CP_Item)
set y2 = GetItemY(udg_CP_Item)
call SetItemVisible(udg_CP_Item, false)
//---------------------------
loop
exitwhen udg_CP_HiddenItemsIndex == 0
set udg_CP_HiddenItemsIndex = udg_CP_HiddenItemsIndex - 1
call SetItemVisible(udg_CP_HiddenItems[udg_CP_HiddenItemsIndex], true)
set udg_CP_HiddenItems[udg_CP_HiddenItemsIndex] = null
endloop
//---------------------------
return (((x2-x)*(x2-x) + (y2-y)*(y2-y) <= 75) and (not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)))
endfunction
function KB3D_GetCoordinatesZ takes real x, real y returns real
local location L = Location(x,y)
local real r = 0
local integer I = 0
local integer t = 12
local boolean B = true
loop
exitwhen I == 12
if GetPlayerSlotState(Player(I)) != ConvertPlayerSlotState(1) then
set t = t - 1
else
if IsLocationFoggedToPlayer( L , Player(I)) then
set B = false
set t = t - 1
endif
endif
set I = I + 1
endloop
if B or t == 0 then
set r = GetLocationZ(L)
endif
call RemoveLocation(L)
set L = null
return r
endfunction
function KB3D_Approx takes unit U, unit U2, integer Loop returns boolean
local real r = KB3D_InBetween(50, LoadReal(udg_KB3D_HA, 29, Loop) / 2, 1000)
local real r1 = GetUnitFlyHeight(U2)
//---------------------------
return KB3D_IsInBetween(r1-r, GetUnitFlyHeight(U), r1+r)
endfunction
function KB3D_Filter takes unit U, unit U1, integer Loop returns boolean
if not IsUnitType(U, UNIT_TYPE_DEAD) then
//---------------------------
if not(LoadBoolean(udg_KB3D_HA, 48, Loop)) and ( IsUnitType(U, UNIT_TYPE_STRUCTURE)) then
return false
elseif not((LoadBoolean(udg_KB3D_HA, 48, Loop)) and ( IsUnitType(U, UNIT_TYPE_STRUCTURE))) then
if not(LoadBoolean(udg_KB3D_HA, 49, Loop)) and ( IsUnitType(U, UNIT_TYPE_MECHANICAL)) then
return false
endif
endif
//---------------------------
if not(LoadBoolean(udg_KB3D_HA, 50, Loop)) and ( IsUnitType(U, UNIT_TYPE_MAGIC_IMMUNE)) then
return false
endif
//---------------------------
if not(LoadBoolean(udg_KB3D_HA, 51, Loop)) and ( IsUnitAlly(U, GetOwningPlayer(U1))) then
return false
endif
//---------------------------
if not(LoadBoolean(udg_KB3D_HA, 63, Loop)) and ( IsUnitEnemy(U, GetOwningPlayer(U1))) then
return false
endif
//---------------------------
if not(LoadBoolean(udg_KB3D_HA, 64, Loop)) and ( IsUnitType(U, UNIT_TYPE_RESISTANT)) then
return false
endif
//---------------------------
if not(LoadBoolean(udg_KB3D_HA, 65, Loop)) and ( IsUnitType(U, UNIT_TYPE_FLYING)) then
return false
endif
//---------------------------
return true
endif
//---------------------------
return false
endfunction
function KB3D_RegisterUnitCollision takes unit u, real x, real y, integer i returns real
local real l = 0
local real h = 300
local real m = 150
local real nm
//---------------------------
loop
if (IsUnitInRangeXY(u, x+m, y, 0)) then
set l = m
else
set h = m
endif
set nm = (l+h)/2
exitwhen nm+.001 > m and nm-.001 < m
set m = nm
endloop
//---------------------------
set m = R2I(m*10)/10.
call SaveReal( udg_KB3D_HA, 16, GetUnitTypeId(u), m )
//---------------------------
return m
endfunction
function KB3D_GetUnitCollision takes unit u returns real
local integer i = GetUnitTypeId(u)
//---------------------------
if HaveSavedReal( udg_KB3D_HA, 16, i) then
return LoadReal(udg_KB3D_HA, 16, i)
endif
//---------------------------
return KB3D_RegisterUnitCollision(u, GetUnitX(u), GetUnitY(u), i)
endfunction
function KB3D_Tree_Check takes destructable D returns boolean
return IssueTargetOrderById( udg_KB3D_Harvester, 852018, D ) and IssueImmediateOrderById(udg_KB3D_Harvester, 851972)
endfunction
function KB3D_KillEnumDest takes nothing returns nothing
local destructable D = GetEnumDestructable()
//---------------------------
if GetDestructableLife(D)>0 and ( KB3D_Tree_Check(D) ) and (GetUnitFlyHeight(LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0]))) < GetDestructableOccluderHeight(D)) and LoadBoolean(udg_KB3D_HA, 8, R2I(udg_KB3D_Reals[0])) then
call KillDestructable(D)
elseif /*not(KB3D_CW(GetDestructableX(D),GetDestructableY(D))) and*/ GetDestructableLife(D)>0 and not(KB3D_Tree_Check(D)) and LoadBoolean(udg_KB3D_HA, 56, R2I(udg_KB3D_Reals[0])) then
call KillDestructable(D)
endif
set D = null
endfunction
function KB3D_CircleTreeKill takes real radius, real x, real y returns nothing
local rect r = Rect(x-radius, y-radius, x+radius, y+radius)
//---------------------------
call EnumDestructablesInRect(r, null, function KB3D_KillEnumDest)
//---------------------------
call RemoveRect(r)
set r = null
endfunction
function KB3D_BounceOnUnit takes unit u, unit U, integer Loop returns nothing
set udg_KB3D_Angle = (Atan2(GetUnitY(u) - GetUnitY(U), GetUnitX(u) - GetUnitX(U)) *57.29578) + GetRandomReal(-15,15)
set udg_KB3D_Speed = LoadReal(udg_KB3D_HA, 2, Loop) / .03125 * .25 * LoadReal(udg_KB3D_HA, 59, Loop)
set udg_KB3D_DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
set udg_KB3D_Fx = LoadStr(udg_KB3D_HA, 9, Loop)
set udg_KB3D_Attach = LoadStr(udg_KB3D_HA, 10, Loop)
set udg_KB3D_Range = 1.5*udg_KB3D_Speed*udg_KB3D_Bounce_Power
set udg_KB3D_Unit = u
set udg_KB3D_Bounce_Fx = LoadStr(udg_KB3D_HA, 62, Loop)
set udg_KB3D_Accel = -udg_KB3D_Speed*.6
set udg_KB3D_Bounce_Unit = true
call TriggerEvaluate(udg_KB3D_Registration)
call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, LoadEffectHandle(udg_KB3D_HA, 14, Loop))
endfunction
function KB3D_Bounce_Filter takes nothing returns boolean
local boolean b = not(IsUnitInGroup(GetFilterUnit(), LoadGroupHandle(udg_KB3D_HA, 68, R2I(udg_KB3D_Reals[0])))) or KB3D_Filter(LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0])),LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0])),R2I(udg_KB3D_Reals[0]))
if b then
call GroupAddUnit(LoadGroupHandle(udg_KB3D_HA, 68, R2I(udg_KB3D_Reals[0])), GetFilterUnit())
endif
return b
endfunction
function KB3D_FilterGrp takes nothing returns boolean
return KB3D_Filter(GetFilterUnit(), LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0])),R2I(udg_KB3D_Reals[0]))
endfunction
function KB3D_ClearInstance takes integer i returns nothing
local integer x = 0
//---------------------------
call DestroyGroup(LoadGroupHandle(udg_KB3D_HA, 27, i))
call DestroyGroup(LoadGroupHandle(udg_KB3D_HA, 67, i))
//---------------------------
loop
exitwhen x > 100
call RemoveSavedHandle(udg_KB3D_HA, x, i)
call SaveReal(udg_KB3D_HA, x, i, 0)
set x = x +1
endloop
endfunction
function KB3D_isPossiblePathability takes real x, real y, real RADangle, real MaxDist returns boolean
local real X = x
local real Y = y
local real max = RAbsBJ(MaxDist)
local real dist = max
//---------------------------
loop
exitwhen (dist <= 0)
set dist = dist - max/300
set X = x + ( dist * Cos(RADangle) )
set Y = y + ( dist * Sin(RADangle) )
if KB3D_CW(X,Y) then
return true
endif
endloop
//---------------------------
return false
endfunction
function MoveUnit_3D takes unit U, real x, real y, real z, real MaxZ, boolean P, boolean OS, boolean KiOS, real Angle, real S, real time, integer Loop returns boolean
local boolean B = false
local boolean b = true
local real tz
// CREEPY FUNCTION ALERT
if LoadBoolean(udg_KB3D_HA, 57, Loop) then
if LoadBoolean(udg_KB3D_HA, 44, Loop) then
set tz = KB3D_GetCoordinatesZ(x,y) - LoadReal(udg_KB3D_HA, 68, Loop)
set z = z - tz
call SaveReal(udg_KB3D_HA, 68, Loop, KB3D_GetCoordinatesZ(x,y))
if LoadReal(udg_KB3D_HA, 3, Loop)<0 and GetUnitDefaultFlyHeight(U)<z then
call SetUnitFlyHeight(U, KB3D_InBetween(-999,z,GetUnitDefaultFlyHeight(U)), 0)
else
call SetUnitFlyHeight(U, z, 0)
endif
else
call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z, 9999), 0)
endif
endif
//---------------------------
if ( not(P) or ( KB3D_CW(x, y) ) ) then
set B = true
if (OS) then
call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[6], x, udg_KB3D_Reals[5]))
call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[8], y, udg_KB3D_Reals[7]))
set b = false
if (KiOS) and (not(KB3D_IsInBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1])) or not(KB3D_IsInBetween(udg_KB3D_Reals[4], x, udg_KB3D_Reals[3]))) then
call KillUnit(U)
endif
else
call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1]))
call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[4], y, udg_KB3D_Reals[3]))
set b = false
endif
elseif LoadBoolean(udg_KB3D_HA, 52, Loop) and P and not(KB3D_CW(x, y)) then
if GetUnitFlyHeight(U) != 0 then
if KB3D_isPossiblePathability(GetUnitX(U),GetUnitY(U), Angle, S*time/0.03125) and LoadBoolean(udg_KB3D_HA, 44, Loop) then
set B = true
//call SaveBoolean(udg_KB3D_HA, 53, Loop, true)
if (OS) then
call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[6], x, udg_KB3D_Reals[5]))
call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[8], y, udg_KB3D_Reals[7]))
set b = false
if (KiOS) and (not(KB3D_IsInBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1])) or not(KB3D_IsInBetween(udg_KB3D_Reals[4], x, udg_KB3D_Reals[3]))) then
call KillUnit(U)
endif
else
call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1]))
call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[4], y, udg_KB3D_Reals[3]))
set b = false
endif
else
call SaveBoolean(udg_KB3D_HA, 52, Loop, false)
endif
else
endif
endif
if b then
set udg_KB3D_B = true
if LoadBoolean(udg_KB3D_HA, 66, Loop) then
set udg_KB3D_EndisUnpathable = true
set udg_KB3D_EndisNormal = false
return true
endif
endif
return false
endfunction
function KB3D_LineDamageLoop takes unit U, group g returns nothing
local integer Loop = R2I(udg_KB3D_Reals[0])
local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
local real LineD = LoadReal(udg_KB3D_HA, 28, Loop)
local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
local group G = LoadGroupHandle(udg_KB3D_HA, 27, Loop)
//---------------------------
if KB3D_Filter(U, U1, Loop) and not ( IsUnitInGroup(U, G) ) then
call GroupAddUnit(G, U)
if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
call UnitDamageTarget(Damager, U, LineD, true, false, AType, DType, null)
call DestroyEffect(AddSpecialEffectTarget(LoadStr(udg_KB3D_HA, 58, Loop), U, LoadStr(udg_KB3D_HA, 10, Loop)))
elseif KB3D_Approx(U, U1, Loop) then
call UnitDamageTarget(Damager, U, LineD, true, false, AType, DType, null)
call DestroyEffect(AddSpecialEffectTarget(LoadStr(udg_KB3D_HA, 58, Loop), U, LoadStr(udg_KB3D_HA, 10, Loop)))
endif
endif
//---------------------------
set G = null
set U1 = null
set Damager = null
set AType = null
set DType = null
endfunction
function KB3D_AoEDamageLoop takes unit U, group g returns nothing
local integer Loop = R2I(udg_KB3D_Reals[0])
local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
local real AoED = LoadReal(udg_KB3D_HA, 32, Loop)
local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
//---------------------------
if KB3D_Filter(U, U1, Loop) then
if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
call UnitDamageTarget(Damager, U, AoED * 0.031250000, true, false, AType, DType, null)
elseif KB3D_Approx(U, U1, Loop) then
call UnitDamageTarget(Damager, U, AoED * 0.031250000, true, false, AType, DType, null)
endif
endif
//---------------------------
set U1 = null
set Damager = null
set AType = null
set DType = null
endfunction
function KB3D_AoEEndDamage takes unit U, group g returns nothing
local integer Loop = R2I(udg_KB3D_Reals[0])
local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
local real D = LoadReal(udg_KB3D_HA, 38, Loop)
local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
//---------------------------
if KB3D_Filter(U, U1, Loop) then
if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
call UnitDamageTarget(Damager, U, D, true, false, AType, DType, null)
elseif KB3D_Approx(U, U1, Loop) then
call UnitDamageTarget(Damager, U, D, true, false, AType, DType, null)
endif
endif
//---------------------------
call GroupRemoveUnit(g, U)
//---------------------------
set U1 = null
set Damager = null
set AType = null
set DType = null
endfunction
function KB3D_GiveKBto takes unit U1, unit U2, integer Loop returns nothing
set udg_KB3D_AoEEndDamage = LoadReal(udg_KB3D_HA, 38, Loop)
set udg_KB3D_EndwhenDead = LoadBoolean(udg_KB3D_HA, 35, Loop)
set udg_KB3D_Speed = LoadReal(udg_KB3D_HA, 2, Loop)/0.031250000*.5
set udg_KB3D_Accel = -udg_KB3D_Speed
set udg_KB3D_AllowOutSiding = LoadBoolean(udg_KB3D_HA, 34, Loop)
set udg_KB3D_Angle = (LoadReal(udg_KB3D_HA, 5, Loop)*180/3.14159)
set udg_KB3D_AoE = LoadReal(udg_KB3D_HA, 29, Loop)
set udg_KB3D_AoEDamage = LoadReal(udg_KB3D_HA, 32, Loop)
set udg_KB3D_AttackType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
set udg_KB3D_DamageType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
set udg_KB3D_Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
set udg_KB3D_DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
set udg_KB3D_DisableUnit = LoadBoolean(udg_KB3D_HA, 6, Loop)
set udg_KB3D_FaceAngle = LoadBoolean(udg_KB3D_HA, 31, Loop)
set udg_KB3D_Fx = LoadStr(udg_KB3D_HA, 9, Loop)
set udg_KB3D_Attach = LoadStr(udg_KB3D_HA, 10, Loop)
set udg_KB3D_ImpactDamage = LoadReal(udg_KB3D_HA, 17, Loop)
set udg_KB3D_LineDamage = LoadReal(udg_KB3D_HA, 28, Loop)
set udg_KB3D_LoopDamage = LoadReal(udg_KB3D_HA, 18, Loop)/0.031250000
set udg_KB3D_Range = 99999
set udg_KB3D_Unit = U1
if LoadBoolean(udg_KB3D_HA, 57, Loop) then
set udg_KB3D_Zoffset = LoadReal(udg_KB3D_HA, 3, Loop)/1.85 - GetUnitDefaultFlyHeight(U2)
endif
//---------------------------
call TriggerEvaluate( udg_KB3D_Registration )
endfunction
function KB3D_AoEGiveKBto takes unit U1, unit U2, integer Loop returns nothing
local real x1 = GetUnitX(U1)
local real y1 = GetUnitY(U1)
local real x2 = GetUnitX(U2)
local real y2 = GetUnitY(U2)
local real P = LoadReal(udg_KB3D_HA, 43, Loop)
//---------------------------
set udg_KB3D_AoE = LoadReal(udg_KB3D_HA, 29, Loop)
set udg_KB3D_EndwhenDead = LoadBoolean(udg_KB3D_HA, 35, Loop)
set udg_KB3D_Accel = -550*P
set udg_KB3D_AllowOutSiding = LoadBoolean(udg_KB3D_HA, 34, Loop)
set udg_KB3D_Angle = Atan2(y1 - y2, x1 - x2)*180/3.14159
set udg_KB3D_AoEDamage = LoadReal(udg_KB3D_HA, 32, Loop)
set udg_KB3D_AttackType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
set udg_KB3D_DamageType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
set udg_KB3D_Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
set udg_KB3D_DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
set udg_KB3D_DisableUnit = LoadBoolean(udg_KB3D_HA, 6, Loop)
set udg_KB3D_FaceAngle = LoadBoolean(udg_KB3D_HA, 31, Loop)
set udg_KB3D_Fx = LoadStr(udg_KB3D_HA, 9, Loop)
set udg_KB3D_Attach = LoadStr(udg_KB3D_HA, 10, Loop)
set udg_KB3D_ImpactDamage = LoadReal(udg_KB3D_HA, 17, Loop)
set udg_KB3D_LineDamage = LoadReal(udg_KB3D_HA, 28, Loop)
set udg_KB3D_LoopDamage = LoadReal(udg_KB3D_HA, 18, Loop)/0.031250000
set udg_KB3D_Speed = udg_KB3D_AoE*2*P
set udg_KB3D_Range = udg_KB3D_Speed*2
set udg_KB3D_Unit = U1
if LoadBoolean(udg_KB3D_HA, 57, Loop) then
set udg_KB3D_Zoffset = (udg_KB3D_AoE - SquareRoot(x2 * x1 + y2 * y1)*3.14159/180)*P
endif
//---------------------------
call TriggerEvaluate( udg_KB3D_Registration )
endfunction
function KB3D_AoEKB takes unit U, group g returns nothing
local integer Loop = R2I(udg_KB3D_Reals[0])
local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
local real r
//---------------------------
if KB3D_Filter(U, U1, Loop) then
if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
call KB3D_AoEGiveKBto(U, U1, Loop)
elseif KB3D_Approx(U, U1, Loop) then
call KB3D_AoEGiveKBto(U, U1, Loop)
endif
endif
//---------------------------
call GroupRemoveUnit(g, U)
//---------------------------
set U1 = null
endfunction
function KB3D_AoEEndFx takes unit U, string A, string F, group g returns nothing
local integer Loop = R2I(udg_KB3D_Reals[0])
local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
local real x
local real y
//---------------------------
if KB3D_Filter(U, U1, Loop) and (U != null) then
if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
if ( GetUnitFlyHeight(U) > 20 ) then
call DestroyEffect(AddSpecialEffectTarget(F, U, A))
else
set x = GetUnitX(U)
set y = GetUnitY(U)
call DestroyEffect(AddSpecialEffect(F, x, y))
endif
elseif KB3D_Approx(U, U1, Loop) then
if ( GetUnitFlyHeight(U) > 20 ) then
call DestroyEffect(AddSpecialEffectTarget(F, U, A))
else
set x = GetUnitX(U)
set y = GetUnitY(U)
call DestroyEffect(AddSpecialEffect(F, x, y))
endif
endif
endif
//---------------------------
call GroupRemoveUnit(g, U)
//---------------------------
set U1 = null
endfunction
function KB3D_Grpto takes nothing returns nothing
call GroupAddUnit(udg_KB3D_g, GetEnumUnit())
endfunction
function KB3D_PointBounce takes real BAngle, real x, real y returns real
local real BAngle1 //bounce angle 1
local real BAngle2 //bounce angle 2
local real q //quadrant
set BAngle = BAngle*0.01745329251994329576923690768489
if 0<BAngle and BAngle<90 then
set q = 1
elseif 90<BAngle and BAngle<180 then
set q = 2
elseif 180<BAngle and BAngle<270 then
set q = 3
elseif 270<BAngle and BAngle<360 then
set q = 4
else
set q = BAngle/90 + 2
endif
set BAngle1 = q*90 - BAngle
set BAngle2 = - q*90 + BAngle + 90
if KB3D_isPossiblePathability(x, y, (BAngle - 2*BAngle2), 40) then
set BAngle = BAngle - 2*BAngle2
elseif KB3D_isPossiblePathability(x, y, (BAngle + 2*BAngle1), 40) then
set BAngle = BAngle + 2*BAngle1
endif
return BAngle
endfunction
function KB3D_Flyover takes real Zi, real Zf, real Yi, real Yf, real Xi, real Xf, real Speed, real dur, integer Loop returns nothing
local location Li = Location(Xi, Yi)
local location Lf = Location(Xf, Yf)
local real Xmax = Speed/0.03125*dur
local real Ymax = (GetLocationZ(Lf) - GetLocationZ(Li))*GetLocationZ(Lf)/Speed*Xmax ////BEWARE LOCATIONZ
if (GetLocationZ(Lf) - GetLocationZ(Li)) > 0.5 then
call SaveReal( udg_KB3D_HA, 74, Loop, GetLocationZ(Li) )
call BJDebugMsg("Sup")
elseif (GetLocationZ(Lf) - GetLocationZ(Li)) < -0.5 then
set Ymax = -(GetLocationZ(Lf) - LoadReal( udg_KB3D_HA, 74, Loop))*GetLocationZ(Lf)/Speed*Xmax
call SaveBoolean( udg_KB3D_HA, 75, Loop, false)
call BJDebugMsg(R2S(Ymax))
endif
endfunction
function KB3D_Loop takes integer Loop returns nothing
//Create all the nessesary locals
local unit U = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
local real X = GetUnitX(U)
local real Y = GetUnitY(U)
local real Z = GetUnitFlyHeight(U)
local real x = X
local real y = Y
local real z = Z
local real Range = LoadReal(udg_KB3D_HA, 1, Loop)
local real Speed = LoadReal(udg_KB3D_HA, 2, Loop)
local real Zoffset = LoadReal(udg_KB3D_HA, 3, Loop)
local real Accel = LoadReal(udg_KB3D_HA, 4, Loop)
local real Angle
local real ZSpeed = LoadReal(udg_KB3D_HA, 12, Loop)
local real ZAccel = LoadReal(udg_KB3D_HA, 13, Loop)
local real ImpactD = LoadReal(udg_KB3D_HA, 17, Loop)
local real LoopD = LoadReal(udg_KB3D_HA, 18, Loop)
local real TargetD = LoadReal(udg_KB3D_HA, 19, Loop)
local real LineD = LoadReal(udg_KB3D_HA, 28, Loop)
local real AoE = LoadReal(udg_KB3D_HA, 29, Loop)
local real ZT = LoadReal(udg_KB3D_HA, 26, Loop)
local real AoED = LoadReal(udg_KB3D_HA, 32, Loop)
local real Time = LoadReal(udg_KB3D_HA, 41, Loop) + 0.031250000
local real KillatTime = LoadReal(udg_KB3D_HA, 36, Loop)
local real StopTime = LoadReal(udg_KB3D_HA, 37, Loop)
local real AoEEndDamage = LoadReal(udg_KB3D_HA, 38, Loop)
local real Flyover_dur = LoadReal(udg_KB3D_HA, 73, Loop)
local unit Target = LoadUnitHandle(udg_KB3D_HA, 5, Loop)
local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
local unit u
local boolean DisableUnit = LoadBoolean(udg_KB3D_HA, 6, Loop)
local boolean UnpathableStop = LoadBoolean(udg_KB3D_HA, 7, Loop)
local boolean DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
local boolean KillWhenHit = LoadBoolean(udg_KB3D_HA, 24, Loop)
local boolean EndWhenHit = LoadBoolean(udg_KB3D_HA, 25, Loop)
local boolean KiOS = LoadBoolean(udg_KB3D_HA, 33, Loop)
local boolean OS = LoadBoolean(udg_KB3D_HA, 34, Loop)
local boolean b = true
local boolean EndwhenDead = LoadBoolean(udg_KB3D_HA, 35, Loop)
local boolean KBTarget = LoadBoolean(udg_KB3D_HA, 39, Loop)
local boolean AoEKB = LoadBoolean(udg_KB3D_HA, 40, Loop)
local boolean KillatEnd = LoadBoolean(udg_KB3D_HA, 46, Loop)
local boolean GroundDamage = LoadBoolean(udg_KB3D_HA, 47, Loop)
local boolean EndB = false
local boolean EndOnObstacle = false
local boolean Flyover = LoadBoolean(udg_KB3D_HA, 72, Loop)
local string Fx = LoadStr(udg_KB3D_HA, 9, Loop)
local string Attach = LoadStr(udg_KB3D_HA, 10, Loop)
local string EndFx = LoadStr(udg_KB3D_HA, 42, Loop)
local string AoEEndFx = LoadStr(udg_KB3D_HA, 54, Loop)
local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
local trigger EndT = LoadTriggerHandle(udg_KB3D_HA, 55, Loop)
//end of locals
//Loop Damage Execution
if LoopD != 0 and Damager != null then
call UnitDamageTarget(Damager, U, LoopD, true, false, AType, DType, null)
endif
//Calculate the Angle
if ( Target == null ) then
set Angle = LoadReal(udg_KB3D_HA, 5, Loop) + LoadReal(udg_KB3D_HA, 30, Loop)//if there is no unit target
else
set Angle = Atan2(GetUnitY(Target) - Y, GetUnitX(Target) - X)//if there is a unit target
endif
//
if LoadBoolean(udg_KB3D_HA, 16, Loop) then
set Angle = GetUnitFacing(U)*0.0174533
if LoadBoolean(udg_KB3D_HA, 44, Loop) then
if GetUnitCurrentOrder(U) != 851986 and GetUnitCurrentOrder(U) != 851971 then
set b = false
endif
else
set b = false
endif
endif
//Make Unit Face Angle
if LoadBoolean(udg_KB3D_HA, 31, Loop) then
call SetUnitFacing(U, Angle * 3.141592)
endif
//Calculate 3D coordinates
if b then
set Speed = Speed + ( Accel )//Increase the KB speed depending on the Acceleration
set Range = Range - ( RAbsBJ(Speed) )//Decrease distance traveled
set x = X + ( Speed * Cos(Angle) )//new X location of the KBed unit
set y = Y + ( Speed * Sin(Angle) )//new Y location of the KBed unit
set ZSpeed = ZSpeed + ( ZAccel )//change the fly changing rate //Acceleration is for smoothness
set z = Z + ( ZSpeed * 0.031250000 )//new Z Offset of the KBed unit
set ZT = ZT + ( ZSpeed * 0.031250000 )//Total Height Changings
endif
set b = false
if z >= Zoffset then
call SaveReal(udg_KB3D_HA, 12, Loop, -ZSpeed)
endif
//Flyover Feature
//if Flyover then
// if LoadBoolean(udg_KB3D_HA, 75, Loop) then
// if z-LoadReal(udg_KB3D_HA, 71, Loop) <= 0 and (Speed/0.03125*Flyover_dur) <= Range then
// call KB3D_Flyover(Z, z, Y, y, X, x, Speed, Flyover_dur, Loop)
// endif
// endif
//endif
//Destroy Trees around the Unit depending on the unit's Collision Size
if (DestroyTree) or (LoadBoolean(udg_KB3D_HA, 56, Loop)) then
set udg_KB3D_Reals[0] = I2R(Loop)
call KB3D_CircleTreeKill( KB3D_InBetween(2*Speed, 5 * KB3D_GetUnitCollision(U), Speed*4), x, y )
endif
//Move the unit according to the X, Y, Z
set EndOnObstacle = MoveUnit_3D(U, x, y, z, Zoffset, UnpathableStop, OS, KiOS, Angle, Speed, LoadReal(udg_KB3D_HA, 11, Loop)-Time, Loop)
//Bounce on Point
if udg_KB3D_B and LoadBoolean(udg_KB3D_HA, 60, Loop) then
set udg_KB3D_B = false
set Speed=Speed*.85
set Angle = KB3D_PointBounce(Angle,x,y)
if LoadReal(udg_KB3D_HA, 76, Loop) <= 0 then
call DestroyEffect(AddSpecialEffect(LoadStr(udg_KB3D_HA, 62, Loop), GetUnitX(U), GetUnitY(U)))
call SaveReal(udg_KB3D_HA, 76, Loop, 10)
endif
endif
//Create the Effect on the unit
if (Fx != "") then
if ( z > 20 ) then
if (Attach != "") then
call DestroyEffect(AddSpecialEffectTarget(Fx, U, Attach))//attach the effect on the unit if he is flying
endif
else
call DestroyEffect(AddSpecialEffect(Fx, x, y))//create the effect on his location if he is not flying
endif
endif
//Initiate Impact Damage
if ( (UnpathableStop) and not ( KB3D_CW(x, y) ) ) and ( (ImpactD != 0) and (Damager != null ) ) then//if the terrain is unpathable or if unpathable stop is disabled then..
if ( KB3D_CW(x, y) ) then
call SaveBoolean(udg_KB3D_HA, 23, Loop, true)
endif
if ( LoadBoolean(udg_KB3D_HA, 23, Loop) ) then
call UnitDamageTarget(Damager, U, ImpactD, true, false, AType, DType, null)//Apply Impact Damage to the unit
call SaveBoolean(udg_KB3D_HA, 23, Loop, false)
endif
endif
//Create AoE Grp
if (AoE != 0) and ((LineD != 0) or (AoED != 0) or LoadBoolean(udg_KB3D_HA, 61, Loop) or LoadBoolean(udg_KB3D_HA, 60, Loop)) then
set udg_KB3D_g = CreateGroup()
set udg_KB3D_Reals[0] = I2R(Loop)
call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), Filter(function KB3D_FilterGrp))
//----------------------------------
loop
set u = FirstOfGroup(udg_KB3D_g)
exitwhen (u == null)
if (Damager != null) then
if (LineD != 0) then
call KB3D_LineDamageLoop(u, udg_KB3D_g)
endif
if (AoED != 0) then
call KB3D_AoEDamageLoop(u, udg_KB3D_g)
endif
endif
if not IsUnitInGroup(u, LoadGroupHandle(udg_KB3D_HA, 67, Loop)) and RAbsBJ(AoE)>SquareRoot((GetUnitX(u) - GetUnitX(U)) * (GetUnitX(u) - GetUnitX(U)) + (GetUnitY(u) - GetUnitY(U)) * (GetUnitY(u) - GetUnitY(U))) then
if LoadBoolean(udg_KB3D_HA, 61, Loop) then
call KB3D_BounceOnUnit(u, U, Loop)
call GroupAddUnit(LoadGroupHandle(udg_KB3D_HA, 67, Loop),u)
call DestroyEffect(AddSpecialEffect(LoadStr(udg_KB3D_HA, 62, Loop), GetUnitX(u), GetUnitY(u)))
if LoadBoolean(udg_KB3D_HA, 70, Loop) then
set b = true
set udg_KB3D_EndisUnit = true
set udg_KB3D_EndisNormal = false
set udg_KB3D_EndUnit = u
endif
endif
if LoadBoolean(udg_KB3D_HA, 60, Loop) then
set Angle = (Atan2(GetUnitY(u) - GetUnitY(U), GetUnitX(u) - GetUnitX(U))) + Deg2Rad(GetRandomReal(-15,15) + 180)
set Speed = Speed*.85
call DestroyEffect(AddSpecialEffect(LoadStr(udg_KB3D_HA, 62, Loop), GetUnitX(U), GetUnitY(U)))
endif
endif
call GroupRemoveUnit(udg_KB3D_g,u)
endloop
//----------------------------------
call DestroyGroup(udg_KB3D_g)
set udg_KB3D_g = null
endif
//Disable the unit partially
if ( DisableUnit ) then
call SetUnitPropWindow(U, 0)
call SetUnitTurnSpeed(U, 0)
endif
//Initiate Target-Related Actions
if (Target != null) then
if (SquareRoot ( ( GetUnitX(Target) - x ) * ( GetUnitX(Target) - x ) + ( GetUnitY(Target) - y ) * ( GetUnitY(Target) - y ) ) < Speed+2) then//when the target and the unit are close
if not (TargetD == 0) and not(Damager == null) then//Damage the Target
call UnitDamageTarget(Damager, Target, TargetD, true, false, AType, DType, null)
call SaveReal(udg_KB3D_HA, 19, Loop, 0)
endif
if KBTarget then//KB the Target
call KB3D_GiveKBto(Target, U, Loop)
call SaveBoolean( udg_KB3D_HA, 39, udg_KB3D_Counter, false )
endif
if (KillWhenHit) then//Kill the Unit
call KillUnit(U)
endif
if (EndWhenHit) then//End the KB
call SaveReal(udg_KB3D_HA, 4, Loop, KB3D_AlwaysNeg(Speed))
call SaveReal(udg_KB3D_HA, 3, Loop, GetUnitFlyHeight(U) - ZT)
endif
set udg_KB3D_EndisUnit = true
set udg_KB3D_EndisNormal = false
endif
endif
//Kill the Unit at the time
if (KillatTime != 0) and ( Time > KillatTime ) then
call KillUnit(U)
endif
//Save Changes in the Hashtable
call SaveReal(udg_KB3D_HA, 1, Loop, Range)
call SaveReal(udg_KB3D_HA, 2, Loop, Speed)
call SaveReal(udg_KB3D_HA, 5, Loop, Angle)
call SaveReal(udg_KB3D_HA, 12, Loop, ZSpeed)
call SaveReal(udg_KB3D_HA, 26, Loop, ZT)
call SaveReal(udg_KB3D_HA, 41, Loop, Time)
call SaveReal(udg_KB3D_HA, 76, Loop, LoadReal(udg_KB3D_HA, 76, Loop)-1)
//Inititate End of the KB
if ( b or (LoadBoolean(udg_KB3D_HA, 45, Loop) and (Speed <= 2.34)) or ( Range <= 0 ) or ( (StopTime != 0) and ( Time > StopTime ) ) or EndOnObstacle ) then
call SaveBoolean(udg_KB3D_HA, 100, Loop, false)
set udg_KB3D_Instances = udg_KB3D_Instances - 1
if IsUnitType(U, UNIT_TYPE_DEAD) then
call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
endif
call SetUnitPropWindow(U, LoadReal(udg_KB3D_HA, 15, Loop)*3.14159/180)
call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
if HaveSavedHandle(udg_KB3D_HA, 14, Loop) and not EndB then
call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
endif
set b = true
elseif IsUnitType(U, UNIT_TYPE_DEAD) and (EndwhenDead) then
call SaveBoolean(udg_KB3D_HA, 100, Loop, false)
set udg_KB3D_Instances = udg_KB3D_Instances - 1
if IsUnitType(U, UNIT_TYPE_DEAD) then
call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
endif
call SetUnitPropWindow(U, LoadReal(udg_KB3D_HA, 15, Loop)*3.14159/180)
call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
if HaveSavedHandle(udg_KB3D_HA, 14, Loop) and not EndB then
call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
endif
set b = true
endif
//variable b refers to if the KB has ended
if b then
call SetUnitFlyHeight(U, GetUnitFlyHeight(U)-KB3D_InBetween(0,ZT-LoadReal(udg_KB3D_HA, 71, Loop),999), 500)
if LoadBoolean(udg_KB3D_HA, 44, Loop) then
call SetUnitFlyHeight(U, GetUnitFlyHeight(U)-KB3D_InBetween(0,(LoadReal(udg_KB3D_HA, 69, Loop)-KB3D_GetCoordinatesZ(x,y)),9999), RAbsBJ(ZSpeed))
endif
//----------
call SaveInteger(udg_KB3D_HA, -5, GetHandleId(U), LoadInteger(udg_KB3D_HA, -5, GetHandleId(U))-1)
if LoadInteger(udg_KB3D_HA, -5, GetHandleId(udg_KB3D_Unit)) == 0 then
call SaveBoolean(udg_KB3D_HA, GetHandleId(U), GetHandleId(U), false)
endif
//----------
if (AoEEndDamage != 0) and (Damager != null) and (AoE != 0) then
set udg_KB3D_g = CreateGroup()
set udg_KB3D_Reals[0] = I2R(Loop)
call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
loop
set u = FirstOfGroup(udg_KB3D_g)
call KB3D_AoEEndDamage(u, udg_KB3D_g)
exitwhen (u == null)
endloop
call DestroyGroup(udg_KB3D_g)
set udg_KB3D_g = null
endif
//----------
if (AoEKB) and (AoE != 0) then
set udg_KB3D_g = CreateGroup()
set udg_KB3D_Reals[0] = I2R(Loop)
call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
loop
set u = FirstOfGroup(udg_KB3D_g)
call KB3D_AoEKB(u, udg_KB3D_g)
exitwhen (u == null)
endloop
call DestroyGroup(udg_KB3D_g)
set udg_KB3D_g = null
endif
//----------
if (EndFx != "") then
if ( z > 20 ) and (Attach != "") then
call DestroyEffect(AddSpecialEffectTarget(EndFx, U, Attach))//attach the effect on the unit if he is flying
else
call DestroyEffect(AddSpecialEffect(EndFx, x, y))//create the effect on his location if he is not flying
endif
endif
//----------
if (AoEEndFx != "") and (Attach != "") and (AoE > 0) then
set udg_KB3D_g = CreateGroup()
set udg_KB3D_Reals[0] = I2R(Loop)
call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
loop
set u = FirstOfGroup(udg_KB3D_g)
call KB3D_AoEEndFx(u, Attach, AoEEndFx, udg_KB3D_g)
exitwhen (u == null)
endloop
call DestroyGroup(udg_KB3D_g)
set udg_KB3D_g = null
endif
//----------
if (AoEEndFx != "") and (Attach != "") and (AoE > 0) then
set udg_KB3D_g = CreateGroup()
set udg_KB3D_Reals[0] = I2R(Loop)
call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
loop
set u = FirstOfGroup(udg_KB3D_g)
call KB3D_AoEEndFx(u, Attach, AoEEndFx, udg_KB3D_g)
exitwhen (u == null)
endloop
call DestroyGroup(udg_KB3D_g)
set udg_KB3D_g = null
endif
//----------
if GroundDamage and (ImpactD != 0) and z < 75 and (Damager != null) then
call UnitDamageTarget(Damager, U, ImpactD, true, false, AType, DType, null)
endif
//----------
if (KillatEnd) and not EndB then
call KillUnit(U)
endif
//----------
if (EndT != null) then
set udg_KB3D_Unit = U
set udg_KB3D_Targeted_Unit = Target
call ConditionalTriggerExecute(EndT)
set udg_KB3D_Unit = null
set udg_KB3D_Targeted_Unit = null
set udg_KB3D_EndUnit = null
set udg_KB3D_EndisUnpathable = false
set udg_KB3D_EndisUnit = false
set udg_KB3D_EndisNormal = true
endif
endif
//Function to know if the unit is being KBed by the system
call SaveInteger(udg_KB3D_HA, -2, GetHandleId(udg_KB3D_Unit), LoadInteger(udg_KB3D_HA, -2, GetHandleId(udg_KB3D_Unit))-1)
call SaveBoolean(udg_KB3D_HA, -1, GetHandleId(udg_KB3D_Unit), LoadInteger(udg_KB3D_HA, -2, GetHandleId(udg_KB3D_Unit))!=0)
//Clear Instance
if b then
call KB3D_ClearInstance(Loop)
endif
//Clear locals
set udg_KB3D_B = false
set U = null
set Target = null
set Damager = null
endfunction
function KB3D_Loop_Actions takes nothing returns nothing
local integer x = 0
if udg_KB3D_Paused then
else
loop
exitwhen x >= udg_KB3D_Counter
set x = x + 1
if ( LoadBoolean(udg_KB3D_HA, 100, x) and not(LoadBoolean(udg_KB3D_HA, 77, x))) then
call KB3D_Loop(x)
endif
endloop
if ( udg_KB3D_Instances == 0 ) then
set udg_KB3D_Counter = 0
call PauseTimer(udg_KB3D_Timer)
endif
endif
endfunction
function KB3D_ClearVar takes nothing returns nothing
set udg_KB3D_HomingMissile = false
set udg_KB3D_EndOnTargetBounce = false
set udg_KB3D_Speed_Changer = false
set udg_KB3D_AoEEndFx = ""
set udg_KB3D_D_STRUCTURE = false
set udg_KB3D_D_MECHANICAL = false
set udg_KB3D_D_ALLY = false
set udg_KB3D_D_MAGIC_IMMINUE = false
set udg_KB3D_D_ENEMY = true
set udg_KB3D_D_RESISTANT = false
set udg_KB3D_D_FLYING = false
set udg_KB3D_Accel = 0.00
set udg_KB3D_AllowOutSiding = false
set udg_KB3D_Flyover = false
set udg_KB3D_Flyover_Duration = 0.00
set udg_KB3D_Angle = 0.00
set udg_KB3D_AoE = 0.00
set udg_KB3D_Arc = 0.00
set udg_KB3D_AoEDamage = 0.00
set udg_KB3D_AttackType = ATTACK_TYPE_NORMAL
set udg_KB3D_DamageType = DAMAGE_TYPE_MAGIC
set udg_KB3D_Damager = null
set udg_KB3D_DestroyTree = true
set udg_KB3D_DisableUnit = false
set udg_KB3D_EndWhenHit = false
set udg_KB3D_Fx = ""
set udg_KB3D_Fx_Attach = ""
set udg_KB3D_EndFx = ""
set udg_KB3D_Attach = "origin"
set udg_KB3D_ImpactDamage = 0.00
set udg_KB3D_KillWhenHit = false
set udg_KB3D_FaceAngle = false
set udg_KB3D_KillifOutSider = false
set udg_KB3D_LineDamage = 0.00
set udg_KB3D_LoopDamage = 0.00
set udg_KB3D_Range = 0.00
set udg_KB3D_Speed = 0.00
set udg_KB3D_TargetDamage = 0.00
set udg_KB3D_Targeted_Unit = null
set udg_KB3D_TrailFx = ""
set udg_KB3D_Unit = null
set udg_KB3D_UnpathableStop = true
set udg_KB3D_Zoffset = 0.00
set udg_KB3D_AoEEndDamage = 0.00
set udg_KB3D_AoEKB = false
set udg_KB3D_EndwhenDead = true
set udg_KB3D_KBTarget = false
set udg_KB3D_StopTime = 0.00
set udg_KB3D_KillatTime = 0.00
set udg_KB3D_AoEKB_Power = 1.00
set udg_KB3D_iKB = true
set udg_KB3D_KillatEnd = false
set udg_KB3D_GroundDamage = false
set udg_KB3D_EndTrigger = null
set udg_KB3D_JumpOverCliff = false
set udg_KB3D_DestroyDestructables = false
set udg_KB3D_Line_Fx = ""
set udg_KB3D_Bounce_Target = false
set udg_KB3D_Bounce_Unit = false
set udg_KB3D_Bounce_Power = 1.00
set udg_KB3D_Bounce_Fx = ""
set udg_KB3D_EndOnObstacle = false
set udg_KB3D_EndUnit = null
set udg_KB3D_RemoveUnit = null
set udg_KB3D_EndisUnpathable = false
set udg_KB3D_EndisUnit = false
set udg_KB3D_EndisNormal = true
endfunction
function KB3D_Registration takes nothing returns boolean
local real Time
local real R
local real R1
local real dx
local real dy
if udg_KB3D_PausedReg then
return false
endif
//------------------------
if udg_KB3D_Unit == null then
return false
endif
//------------------------
if udg_KB3D_Fx_Attach != "" then
set udg_KB3D_Fx = udg_KB3D_Fx_Attach
endif
//------------------------
if udg_KB3D_HomingMissile and udg_KB3D_Targeted_Unit != null then
set udg_KB3D_Zoffset = GetUnitFlyHeight(udg_KB3D_Targeted_Unit)
set dx = GetUnitX(udg_KB3D_Unit)-GetUnitX(udg_KB3D_Targeted_Unit)
set dy = GetUnitY(udg_KB3D_Unit)-GetUnitY(udg_KB3D_Targeted_Unit)
if udg_KB3D_Zoffset == 0 then
set udg_KB3D_Zoffset = 100
set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*1.25
else
set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*2
endif
set udg_KB3D_KillatEnd = true
set udg_KB3D_KillWhenHit = true
set udg_KB3D_EndWhenHit = true
set udg_KB3D_FaceAngle = true
set udg_KB3D_UnpathableStop = false
endif
//------------------------
set udg_KB3D_Arc = KB3D_InBetween(-10, udg_KB3D_Arc, 10)
set udg_KB3D_AoEKB_Power = KB3D_InBetween(0.01, udg_KB3D_AoEKB_Power, 3)
//------------------------
if IsUnitType(udg_KB3D_Unit, UNIT_TYPE_FLYING) then
set udg_KB3D_UnpathableStop = false
endif
//------------------------
if (udg_KB3D_iKB) and udg_KB3D_Range < 0 then
if ( udg_KB3D_Targeted_Unit == null ) then
set udg_KB3D_Angle = udg_KB3D_Angle + 180
else
set udg_KB3D_Speed = -1*(udg_KB3D_Speed)
endif
endif
//------------------------
set udg_KB3D_Range = KB3D_InBetween(0.0000001, RAbsBJ(udg_KB3D_Range), RAbsBJ(udg_KB3D_Range))
//------------------------
if (udg_KB3D_iKB) and udg_KB3D_Speed < 0 then
set udg_KB3D_Speed = KB3D_InBetween(udg_KB3D_Speed, udg_KB3D_Speed, 0)
else
set udg_KB3D_Speed = KB3D_InBetween(0.0, RAbsBJ(udg_KB3D_Speed), RAbsBJ(udg_KB3D_Speed))
endif
//------------------------
set udg_KB3D_Counter = udg_KB3D_Counter + 1
set udg_KB3D_Instances = udg_KB3D_Instances + 1
call SaveBoolean(udg_KB3D_HA, -1, GetHandleId(udg_KB3D_Unit), true)
call SaveBoolean(udg_KB3D_HA, 57, udg_KB3D_Counter, (udg_KB3D_Zoffset != 0))
//------------------------
if not udg_KB3D_iKB then
set udg_KB3D_Zoffset = RAbsBJ(udg_KB3D_Zoffset)
elseif GetUnitFlyHeight(udg_KB3D_Unit)+udg_KB3D_Zoffset < 0 then
set udg_KB3D_Zoffset = -GetUnitFlyHeight(udg_KB3D_Unit)
endif
//------------------------
set udg_KB3D_StopTime = RAbsBJ(udg_KB3D_StopTime)
set udg_KB3D_KillatTime = RAbsBJ(udg_KB3D_KillatTime)
set udg_KB3D_AoE = RAbsBJ(udg_KB3D_AoE)
//------------------------
//------------------------
call SaveUnitHandle( udg_KB3D_HA, 0, udg_KB3D_Counter, udg_KB3D_Unit )
call SaveReal( udg_KB3D_HA, 1, udg_KB3D_Counter, udg_KB3D_Range )
call SaveReal( udg_KB3D_HA, 2, udg_KB3D_Counter, udg_KB3D_Speed * 0.031250000 )
call SaveReal( udg_KB3D_HA, 4, udg_KB3D_Counter, udg_KB3D_Accel * 0.031250000 * 0.031250000 )
//------------------------
if ( udg_KB3D_Targeted_Unit == null ) then
call SaveReal( udg_KB3D_HA, 5, udg_KB3D_Counter, udg_KB3D_Angle * 3.14159 / 180 )
else
call SaveUnitHandle( udg_KB3D_HA, 5, udg_KB3D_Counter, udg_KB3D_Targeted_Unit )
set udg_KB3D_JumpOverCliff = false
endif
//------------------------
call SaveBoolean( udg_KB3D_HA, 6, udg_KB3D_Counter, udg_KB3D_DisableUnit )
call SaveBoolean( udg_KB3D_HA, 7, udg_KB3D_Counter, udg_KB3D_UnpathableStop )
call SaveBoolean( udg_KB3D_HA, 8, udg_KB3D_Counter, udg_KB3D_DestroyTree )
call SaveStr( udg_KB3D_HA, 9, udg_KB3D_Counter, udg_KB3D_Fx )
call SaveStr( udg_KB3D_HA, 10, udg_KB3D_Counter, udg_KB3D_Attach )
call SaveBoolean( udg_KB3D_HA, 45, udg_KB3D_Counter, udg_KB3D_Speed>0 )
//------------------------
//------------------------
set udg_KB3D_Speed = KB3D_InBetween(0.01, RAbsBJ(udg_KB3D_Speed), RAbsBJ(udg_KB3D_Speed))
//------------------------
if ( udg_KB3D_Accel == 0.00 ) then
set Time = udg_KB3D_Range / (udg_KB3D_Speed)//calculating time for the knockback if Acceleration = 0
else
if ( udg_KB3D_Accel > 0 ) then
set Time = (-udg_KB3D_Speed-SquareRoot(udg_KB3D_Speed*udg_KB3D_Speed + 2*udg_KB3D_Accel*udg_KB3D_Range))/-udg_KB3D_Accel//calculating time for the knockback if Acceleration > 0*/
endif
if ( udg_KB3D_Accel < 0 ) then
set Time = (-udg_KB3D_Speed+SquareRoot(udg_KB3D_Speed*udg_KB3D_Speed + 2*udg_KB3D_Accel*udg_KB3D_Range))/udg_KB3D_Accel
endif
endif
//------------------------
call SaveReal( udg_KB3D_HA, 11, udg_KB3D_Counter, Time )
call SaveBoolean( udg_KB3D_HA, 100, udg_KB3D_Counter, true )
//------------------------
if UnitAddAbility(udg_KB3D_Unit, 'Amrf') then
call UnitRemoveAbility(udg_KB3D_Unit, 'Amrf')
endif
//------------------------
call SaveReal( udg_KB3D_HA, 3, udg_KB3D_Counter, udg_KB3D_Zoffset )
call SaveReal( udg_KB3D_HA, 12, udg_KB3D_Counter, (2*udg_KB3D_Zoffset / ( Time / 2)) )
call SaveReal( udg_KB3D_HA, 13, udg_KB3D_Counter, ( -2 * udg_KB3D_Zoffset / ( Time / 2) ) / ( Time / 2) * 0.031250000 )
//------------------------
if not (udg_KB3D_TrailFx == "") and not (udg_KB3D_Attach == "") then
call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, AddSpecialEffectTarget(udg_KB3D_TrailFx, udg_KB3D_Unit, udg_KB3D_Attach))
endif
//------------------------
call SaveReal( udg_KB3D_HA, 15, udg_KB3D_Counter, GetUnitDefaultPropWindow(udg_KB3D_Unit) )
call SaveBoolean(udg_KB3D_HA, 16, udg_KB3D_Counter, udg_KB3D_Speed_Changer)
call SaveReal( udg_KB3D_HA, 17, udg_KB3D_Counter, udg_KB3D_ImpactDamage )
call SaveReal( udg_KB3D_HA, 18, udg_KB3D_Counter, udg_KB3D_LoopDamage * 0.031250000 )
call SaveReal( udg_KB3D_HA, 19, udg_KB3D_Counter, udg_KB3D_TargetDamage )
call SaveInteger( udg_KB3D_HA, 20, udg_KB3D_Counter, GetHandleId(udg_KB3D_AttackType))
call SaveInteger( udg_KB3D_HA, 21, udg_KB3D_Counter, GetHandleId(udg_KB3D_DamageType))
call SaveUnitHandle( udg_KB3D_HA, 22, udg_KB3D_Counter, udg_KB3D_Damager )
call SaveBoolean( udg_KB3D_HA, 23, udg_KB3D_Counter, true )
call SaveBoolean( udg_KB3D_HA, 24, udg_KB3D_Counter, udg_KB3D_KillWhenHit )
call SaveBoolean( udg_KB3D_HA, 25, udg_KB3D_Counter, udg_KB3D_EndWhenHit )
// 26 used
call SaveGroupHandle(udg_KB3D_HA, 27, udg_KB3D_Counter, CreateGroup() )
call SaveReal( udg_KB3D_HA, 28, udg_KB3D_Counter, udg_KB3D_LineDamage )
call SaveReal( udg_KB3D_HA, 29, udg_KB3D_Counter, RAbsBJ(udg_KB3D_AoE) )
call SaveReal( udg_KB3D_HA, 30, udg_KB3D_Counter, udg_KB3D_Arc * (3.14159/180) )
call SaveBoolean( udg_KB3D_HA, 31, udg_KB3D_Counter, udg_KB3D_FaceAngle )
call SaveReal( udg_KB3D_HA, 32, udg_KB3D_Counter, udg_KB3D_AoEDamage )
call SaveBoolean( udg_KB3D_HA, 33, udg_KB3D_Counter, udg_KB3D_KillifOutSider )
//------------------------
set udg_KB3D_AllowOutSiding = udg_KB3D_KillifOutSider
//------------------------
call SaveBoolean( udg_KB3D_HA, 34, udg_KB3D_Counter, udg_KB3D_AllowOutSiding )
//------------------------
if not udg_KB3D_EndwhenDead then
set udg_KB3D_EndwhenDead = udg_KB3D_KillatTime > udg_KB3D_StopTime
endif
//------------------------
call SaveBoolean( udg_KB3D_HA, 35, udg_KB3D_Counter, udg_KB3D_EndwhenDead )
call SaveReal( udg_KB3D_HA, 36, udg_KB3D_Counter, udg_KB3D_KillatTime )
call SaveReal( udg_KB3D_HA, 37, udg_KB3D_Counter, udg_KB3D_StopTime )
call SaveReal( udg_KB3D_HA, 38, udg_KB3D_Counter, udg_KB3D_AoEEndDamage )
call SaveBoolean( udg_KB3D_HA, 39, udg_KB3D_Counter, udg_KB3D_KBTarget )
call SaveBoolean( udg_KB3D_HA, 40, udg_KB3D_Counter, udg_KB3D_AoEKB )
//41 used
call SaveStr(udg_KB3D_HA, 42, udg_KB3D_Counter, udg_KB3D_EndFx )
call SaveReal( udg_KB3D_HA, 43, udg_KB3D_Counter, udg_KB3D_AoEKB_Power )
call SaveBoolean( udg_KB3D_HA, 44, udg_KB3D_Counter, udg_KB3D_iKB )
call SaveBoolean( udg_KB3D_HA, 46, udg_KB3D_Counter, udg_KB3D_KillatEnd )
call SaveBoolean( udg_KB3D_HA, 47, udg_KB3D_Counter, udg_KB3D_GroundDamage )
call SaveBoolean( udg_KB3D_HA, 48, udg_KB3D_Counter, udg_KB3D_D_STRUCTURE )
call SaveBoolean( udg_KB3D_HA, 49, udg_KB3D_Counter, udg_KB3D_D_MECHANICAL )
call SaveBoolean( udg_KB3D_HA, 50, udg_KB3D_Counter, udg_KB3D_D_MAGIC_IMMINUE )
call SaveBoolean( udg_KB3D_HA, 51, udg_KB3D_Counter, udg_KB3D_D_ALLY )
call SaveBoolean( udg_KB3D_HA, 52, udg_KB3D_Counter, udg_KB3D_JumpOverCliff )
//call SaveBoolean( udg_KB3D_HA, 53, udg_KB3D_Counter, false )
call SaveStr( udg_KB3D_HA, 54, udg_KB3D_Counter, udg_KB3D_AoEEndFx )
call SaveTriggerHandle( udg_KB3D_HA, 55, udg_KB3D_Counter, udg_KB3D_EndTrigger )
call SaveBoolean( udg_KB3D_HA, 56, udg_KB3D_Counter, udg_KB3D_DestroyDestructables )
//57 used
call SaveStr( udg_KB3D_HA, 58, udg_KB3D_Counter, udg_KB3D_Line_Fx )
call SaveReal( udg_KB3D_HA, 59, udg_KB3D_Counter, udg_KB3D_Bounce_Power )
call SaveBoolean( udg_KB3D_HA, 60, udg_KB3D_Counter, udg_KB3D_Bounce_Unit )
call SaveBoolean( udg_KB3D_HA, 61, udg_KB3D_Counter, udg_KB3D_Bounce_Target )
call SaveStr( udg_KB3D_HA, 62, udg_KB3D_Counter, udg_KB3D_Bounce_Fx )
call SaveBoolean( udg_KB3D_HA, 63, udg_KB3D_Counter, udg_KB3D_D_ENEMY )
call SaveBoolean( udg_KB3D_HA, 64, udg_KB3D_Counter, udg_KB3D_D_RESISTANT )
call SaveBoolean( udg_KB3D_HA, 65, udg_KB3D_Counter, udg_KB3D_D_FLYING )
call SaveBoolean( udg_KB3D_HA, 66, udg_KB3D_Counter, udg_KB3D_EndOnObstacle )
//------------------------
if udg_KB3D_Bounce_Target then
call SaveGroupHandle(udg_KB3D_HA, 67, udg_KB3D_Counter, CreateGroup())
endif
//------------------------
call SaveReal( udg_KB3D_HA, 68, udg_KB3D_Counter, KB3D_GetCoordinatesZ(GetUnitX(udg_KB3D_Unit), GetUnitY(udg_KB3D_Unit)) )
call SaveReal( udg_KB3D_HA, 69, udg_KB3D_Counter, KB3D_GetCoordinatesZ(GetUnitX(udg_KB3D_Unit), GetUnitY(udg_KB3D_Unit)) )
call SaveBoolean( udg_KB3D_HA, 70, udg_KB3D_Counter, udg_KB3D_EndOnTargetBounce )
call SaveReal(udg_KB3D_HA, 71, udg_KB3D_Counter, GetUnitFlyHeight(udg_KB3D_Unit))
call SaveBoolean(udg_KB3D_HA, 72, udg_KB3D_Counter, udg_KB3D_Flyover)
call SaveReal(udg_KB3D_HA, 73, udg_KB3D_Counter, udg_KB3D_Flyover_Duration)
//74 used
call SaveBoolean(udg_KB3D_HA, 75, udg_KB3D_Counter, udg_KB3D_Flyover)
call SaveReal(udg_KB3D_HA, 76, udg_KB3D_Counter, 0)
call SaveBoolean(udg_KB3D_HA, 77, udg_KB3D_Counter, false)
//------------------------
if ( udg_KB3D_Counter == 1 ) then
call TimerStart(udg_KB3D_Timer, 0.031250000, true, function KB3D_Loop_Actions )
endif
//------------------------
set udg_KB3D_Time = Time
//------------------------
//------------------------
call SaveInteger(udg_KB3D_HA, -5, GetHandleId(udg_KB3D_Unit), LoadInteger(udg_KB3D_HA, -5, GetHandleId(udg_KB3D_Unit))+1)
call SaveBoolean(udg_KB3D_HA, GetHandleId(udg_KB3D_Unit), GetHandleId(udg_KB3D_Unit), true)
//------------------------
//------------------------
//------------------------
call KB3D_ClearVar()
return false
endfunction
function KB3D_RemoveUnit takes nothing returns nothing
local integer x = 1
loop
exitwhen x > udg_KB3D_Counter
if LoadUnitHandle(udg_KB3D_HA, 0, x) == udg_KB3D_RemoveUnit then
call SaveReal(udg_KB3D_HA, 1, x, 0)
endif
set x = x + 1
endloop
endfunction
function KB3D_Pause takes nothing returns nothing
call SaveBoolean(udg_KB3D_HA, 77, udg_KB3D_PauseID, true)
set udg_KB3D_PauseID = -1
endfunction
function KB3D_Resume takes nothing returns nothing
call SaveBoolean(udg_KB3D_HA, 77, udg_KB3D_PauseID, false)
set udg_KB3D_PauseID = -1
endfunction
function KB3D_PauseAll takes nothing returns nothing
set udg_KB3D_Paused = true
endfunction
function KB3D_ResumeAll takes nothing returns nothing
set udg_KB3D_Paused = false
endfunction
function KB3D_PauseRegistration takes nothing returns nothing
set udg_KB3D_PausedReg = true
endfunction
function KB3D_ResumeRegistration takes nothing returns nothing
set udg_KB3D_PausedReg = false
endfunction
//===========================================================================
function InitTrig_KB3D takes nothing returns nothing
////////REGISTRATION
set udg_KB3D_Registration = CreateTrigger( )
call TriggerAddCondition( udg_KB3D_Registration, Condition(function KB3D_Registration) )
set udg_KB3D_Harvester = CreateUnit(Player(15), 'hpea', 0, 0, 0)
call ShowUnit(udg_KB3D_Harvester, false)
call UnitAddAbility(udg_KB3D_Harvester, 'Aloc')
call UnitAddAbility(udg_KB3D_Harvester, 'Ahar')
call UnitRemoveAbility(udg_KB3D_Harvester, 'Amov')
set udg_KB3D_HA = InitHashtable()
////////Check Walkability System by PnF
set udg_CP_Rect = Rect(0, 0, 128.00, 128.00)
set udg_CP_Item = CreateItem('wtlg', 0, 0)
call SetItemVisible( udg_CP_Item, false )
////////InitReals
set udg_KB3D_Reals[1] = GetRectMaxX(bj_mapInitialPlayableArea)
set udg_KB3D_Reals[2] = GetRectMinX(bj_mapInitialPlayableArea)
set udg_KB3D_Reals[3] = GetRectMaxY(bj_mapInitialPlayableArea)
set udg_KB3D_Reals[4] = GetRectMinY(bj_mapInitialPlayableArea)
set udg_KB3D_Reals[5] = GetRectMaxX(GetWorldBounds())
set udg_KB3D_Reals[6] = GetRectMinX(GetWorldBounds())
set udg_KB3D_Reals[7] = GetRectMaxY(GetWorldBounds())
set udg_KB3D_Reals[8] = GetRectMinY(GetWorldBounds())
//Initiate Default Values
call KB3D_ClearVar()
endfunction
//===========================================================================
//
// Damage Engine 5.9.0.0 - update requires re-copying the Damage Engine category.
//
/*
Three GUI Damage systems for the community of The Hive,
Seven vJass Damage systems for the JASS-heads on their pedestals high,
Nine competing Damage systems, doomed to die,
One for Bribe on his dark throne
In the Land of the Hive where the Workshop lies.
One Damage Engine to rule them all, One Damage Engine to find them,
One Damage Engine to bring them all and in cross-compatibility unite them.
*/
//! novjass
JASS API (work in progress - I have a lot of documentation to go through):
struct Damage extends array
readonly static unit source //stores udg_DamageEventSource
readonly static unit target //stores udg_DamageEventTarget
static real amount //stores udg_DamageEventAmount
readonly unit sourceUnit //stores udg_DamageEventSource by index
readonly unit targetUnit //stores udg_DamageEventTarget by index
real damage //stores udg_DamageEventAmount by index
readonly real prevAmt //stores udg_DamageEventPrevAmt by index
attacktype attackType //stores udg_DamageEventAttackT by index
damagetype damageType //stores udg_DamageEventDamageT by index
weapontype weaponType //stores udg_DamageEventWeaponT by index
integer userType //stores udg_DamageEventType by index
readonly integer eFilter //replaces the previous eventFilter variable
readonly boolean isAttack //stores udg_IsDamageAttack by index
readonly boolean isCode //stores udg_IsDamageCode by index
readonly boolean isMelee //stores udg_IsDamageMelee by index
readonly boolean isRanged //stores udg_IsDamageRanged by index
readonly boolean isSpell //stores udg_IsDamageSpell by index
real armorPierced //stores udg_DamageEventArmorPierced by index
integer armorType //stores udg_DamageEventArmorT by index
integer defenseType //stores udg_DamageEventDefenseT by index
static boolean operator enabled
- Set to false to disable the damage event triggers/false to reverse that
static method apply takes unit src, unit tgt, real amt, boolean a, boolean r, attacktype at, damagetype dt, weapontype wt returns Damage
- Same arguments as "UnitDamageTarget" but has the benefit of being performance-friendly during recursive events.
- Will automatically cause the damage to be registered as Code damage.
static method applySpell takes unit src, unit tgt, real amt, damagetype dt returns Damage
- A simplified version of the above function that autofills in the booleans, attack type and weapon type.
static method applyAttack takes unit src, unit tgt, real amt, boolean ranged, attacktype at, weapontype wt returns Damage
- A different variation of the above which autofills the "attack" boolean and sets the damagetype to DAMAGE_TYPE_NORMAL.
struct DamageTrigger extends array
method operator filter= takes integer filter returns nothing
// Apply primary filters such as DamageEngine_FILTER_MELEE/RANGED/SPELL which are based off of limitop handles to enable easier access for GUI folks
// Full filter list:
- global integer DamageEngine_FILTER_ATTACK
- global integer DamageEngine_FILTER_MELEE
- global integer DamageEngine_FILTER_OTHER
- global integer DamageEngine_FILTER_RANGED
- global integer DamageEngine_FILTER_SPELL
- global integer DamageEngine_FILTER_CODE
boolean configured //set to True after configuring any filters listed below.
method configure takes nothing returns nothing
// Apply custom filters after setting any desired udg_DamageFilter variables (for GUI).
// Alternatively, vJass users can set these instead. Just be mindful to set the variable
// "configured" to true after settings these.
unit source
unit target
integer sourceType
integer targetType
integer sourceBuff
integer targetBuff
real damageMin
integer attackType
integer damageType
integer userType
//The string in the aruments below requires the following API:
// "" for standard damage event
// "Modifier(or Mod if you prefer)/After/Lethal/AOE" for the others
static method registerTrigger takes trigger whichTrig, string var, real value returns nothing
static method unregister takes trigger t, string eventName, real value, boolean reset returns boolean
static method getIndex takes trigger t, string eventName, real value returns integer
//If you already have the index of the trigger you want to unregister.
method unregisterByIndex takes boolean reset returns boolean
// Converts a code argument to a trigger, while checking if the same code had already been registered before.
static method operator [] takes code c returns trigger
//The accepted strings here use the same criteria as DamageTrigger.getIndex/registerTrigger/unregister
function TriggerRegisterDamageEngineEx takes trigger whichTrig, string eventName, real value, integer f returns nothing
function TriggerRegisterDamageEngine takes trigger whichTrig, string eventName, real value returns nothing
function RegisterDamageEngineEx takes code c, string eventName, real value, integer f returns nothing
function RegisterDamageEngine takes code c, string eventName, real value returns nothing
//! endnovjass
//===========================================================================
library DamageEngine
globals
private constant boolean USE_GUI = true //If you don't use any of the GUI events, set to false to slightly improve performance
private constant boolean USE_SCALING = USE_GUI //If you don't need or want to use DamageScalingUser/WC3 then set this to false
private constant boolean USE_EXTRA = true //If you don't use DamageEventLevel or AOEDamageEvent, set this to false
private constant boolean USE_ARMOR_MOD = true //If you do not modify nor detect armor/defense, set this to false
private constant boolean USE_MELEE_RANGE= true //If you do not detect melee nor ranged damage, set this to false
private constant boolean USE_LETHAL = true //If you do not use LethalDamageEvent nor negative damage (explosive) types, set this to false
private constant integer LIMBO = 16 //When manually-enabled recursion is enabled via DamageEngine_recurion, the engine will never go deeper than LIMBO.
public constant integer TYPE_CODE = 1 //Must be the same as udg_DamageTypeCode, or 0 if you prefer to disable the automatic flag.
public constant integer TYPE_PURE = 2 //Must be the same as udg_DamageTypePure
private constant real DEATH_VAL = 0.405 //In case Blizz ever changes this, it'll be a quick fix here.
private timer alarm = null
private boolean alarmSet = false
//Values to track the original pre-spirit Link/defensive damage values
private Damage lastInstance = 0
private boolean canKick = true
private boolean totem = false
private boolean array attacksImmune
private boolean array damagesImmune
//Made global in order to use enable/disable behavior.
private trigger t1 = null
private trigger t2 = null
private trigger t3 = null //Catches, stores recursive events
//These variables coincide with Blizzard's "limitop" type definitions so as to enable users (GUI in particular) with some nice performance perks.
public constant integer FILTER_ATTACK = 0 //LESS_THAN
public constant integer FILTER_MELEE = 1 //LESS_THAN_OR_EQUAL
public constant integer FILTER_OTHER = 2 //EQUAL
public constant integer FILTER_RANGED = 3 //GREATER_THAN_OR_EQUAL
public constant integer FILTER_SPELL = 4 //GREATER_THAN
public constant integer FILTER_CODE = 5 //NOT_EQUAL
public constant integer FILTER_MAX = 6
private integer eventFilter = FILTER_OTHER
public boolean inception = false //When true, it allows your trigger to potentially go recursive up to LIMBO. However it must be set per-trigger throughout the game and not only once per trigger during map initialization.
private boolean dreaming = false
private integer sleepLevel = 0
private group proclusGlobal = null //track sources of recursion
private group fischerMorrow = null //track targets of recursion
private boolean kicking = false
private boolean eventsRun = false
private keyword run
private keyword trigFrozen
private keyword levelsDeep
private keyword inceptionTrig
private boolean hasLethal = false
endglobals
native UnitAlive takes unit u returns boolean
//GUI Vars:
/*
Retained from 3.8 and prior:
----------------------------
unit udg_DamageEventSource
unit udg_DamageEventTarget
unit udg_EnhancedDamageTarget
group udg_DamageEventAOEGroup
integer udg_DamageEventAOE
integer udg_DamageEventLevel
real udg_DamageModifierEvent
real udg_DamageEvent
real udg_AfterDamageEvent
real udg_DamageEventAmount
real udg_DamageEventPrevAmt
real udg_AOEDamageEvent
boolean udg_DamageEventOverride
boolean udg_NextDamageType
boolean udg_DamageEventType
boolean udg_IsDamageSpell
//Added in 5.0:
boolean udg_IsDamageMelee
boolean udg_IsDamageRanged
unit udg_AOEDamageSource
real udg_LethalDamageEvent
real udg_LethalDamageHP
real udg_DamageScalingWC3
integer udg_DamageEventAttackT
integer udg_DamageEventDamageT
integer udg_DamageEventWeaponT
//Added in 5.1:
boolean udg_IsDamageCode
//Added in 5.2:
integer udg_DamageEventArmorT
integer udg_DamageEventDefenseT
//Addded in 5.3:
real DamageEventArmorPierced
real udg_DamageScalingUser
//Added in 5.4.2 to allow GUI users to re-issue the exact same attack and damage type at the attacker.
attacktype array udg_CONVERTED_ATTACK_TYPE
damagetype array udg_CONVERTED_DAMAGE_TYPE
//Added after Reforged introduced the new native BlzGetDamageIsAttack
boolean udg_IsDamageAttack
//Added in 5.6 to give GUI users control over the "IsDamageAttack", "IsDamageRanged" and "DamageEventWeaponT" field
boolean udg_NextDamageIsAttack //The first boolean value in the UnitDamageTarget native
boolean udg_NextDamageIsMelee //Flag the damage classification as melee
boolean udg_NextDamageIsRanged //The second boolean value in the UnitDamageTarget native
integer udg_NextDamageWeaponT //Allows control over damage sound effect
//Added in 5.7 to enable efficient, built-in filtering (see the below "checkConfig" method - I recommend commenting-out anything you don't need in your map)
integer udg_DamageFilterAttackT
integer udg_DamageFilterDamageT //filter for a specific attack/damage type
unit udg_DamageFilterSource
unit udg_DamageFilterTarget //filter for a specific source/target
integer udg_DamageFilterSourceT
integer udg_DamageFilterTargetT //unit type of source/target
integer udg_DamageFilterType //which DamageEventType was used
integer udg_DamageFilterSourceB
integer udg_DamageFilterTargetB //if source/target has a buff
real udg_DamageFilterMinAmount //only allow a minimum damage threshold
//Added in 5.8:
boolean udg_RemoveDamageEvent //Allow GUI users to more fully unregister a damage event trigger. Can only be used from within a damage event (of any kind).
integer udg_DamageFilterSourceA
integer udg_DamageFilterTargetA //Check if a source or target have a specific ability (will overwrite any source or target buff check, I need to use this because GUI differentiates ability ID and buff ID)
integer udg_DamageFilterSourceI
integer udg_DamageFilterTargetI //Check if a source or target have a specific type of item
integer udg_DamageFilterSourceC
integer udg_DamageFilterTargetC //Classification of source/target (e.g. hero, treant, ward)
*/
struct DamageTrigger extends array
static method checkItem takes unit u, integer id returns boolean
local integer i
if IsUnitType(u, UNIT_TYPE_HERO) then
set i = UnitInventorySize(u)
loop
exitwhen i <= 0
set i = i - 1
if GetItemTypeId(UnitItemInSlot(u, i)) == id then
return true
endif
endloop
endif
return false
endmethod
//Map-makers should comment-out any lines they will never need to check for and move to the top any lines
//that are checked more frequently in their map.
method checkConfig takes nothing returns boolean
//call BJDebugMsg("Checking configuration")
if this.sourceType != 0 and GetUnitTypeId(udg_DamageEventSource) != this.sourceType then
elseif this.targetType != 0 and GetUnitTypeId(udg_DamageEventTarget) != this.targetType then
elseif this.sourceBuff != 0 and GetUnitAbilityLevel(udg_DamageEventSource, this.sourceBuff) == 0 then
elseif this.targetBuff != 0 and GetUnitAbilityLevel(udg_DamageEventTarget, this.targetBuff) == 0 then
elseif this.failChance > 0.00 and GetRandomReal(0.00, 1.00) <= this.failChance then
elseif this.userType != 0 and udg_DamageEventType != this.userType then
elseif this.source != null and this.source != udg_DamageEventSource then
elseif this.target != null and this.target != udg_DamageEventTarget then
elseif this.attackType >= 0 and this.attackType != udg_DamageEventAttackT then
elseif this.damageType >= 0 and this.damageType != udg_DamageEventDamageT then
elseif this.sourceItem != 0 and not .checkItem(udg_DamageEventSource, this.sourceItem) then
elseif this.targetItem != 0 and not .checkItem(udg_DamageEventTarget, this.targetItem) then
elseif this.sourceClass >= 0 and not IsUnitType(udg_DamageEventSource, ConvertUnitType(this.sourceClass)) then
elseif this.targetClass >= 0 and not IsUnitType(udg_DamageEventTarget, ConvertUnitType(this.targetClass)) then
elseif udg_DamageEventAmount >= this.damageMin then
//call BJDebugMsg("Configuration passed")
return true
endif
//call BJDebugMsg("Checking failed")
return false
endmethod
//The below variables are to be treated as constant
readonly static thistype MOD = 1
readonly static thistype SHIELD = 4
readonly static thistype DAMAGE = 5
readonly static thistype ZERO = 6
readonly static thistype AFTER = 7
readonly static thistype LETHAL = 8
readonly static thistype AOE = 9
private static integer count = 9
static thistype lastRegistered = 0
private static thistype array trigIndexStack
static thistype eventIndex = 0
static boolean array filters
readonly string eventStr
readonly real weight
boolean usingGUI
//The below variables are to be treated as private
private thistype next
private trigger rootTrig
boolean trigFrozen //Whether the trigger is currently disabled due to recursion
integer levelsDeep //How deep the user recursion currently is.
boolean inceptionTrig //Added in 5.4.2 to simplify the inception variable for very complex DamageEvent trigger.
//configuration variables:
boolean configured
unit source
unit target
integer sourceType
integer targetType
integer sourceBuff
integer targetBuff
integer sourceItem
integer targetItem
integer sourceClass
integer targetClass
real damageMin
real failChance
integer attackType
integer damageType
integer userType
method operator runChance takes nothing returns real
return 1.00 - this.failChance
endmethod
method operator runChance= takes real r returns nothing
set this.failChance = 1.00 - r
endmethod
method configure takes nothing returns nothing
set this.attackType = udg_DamageFilterAttackT
set this.damageType = udg_DamageFilterDamageT
set this.source = udg_DamageFilterSource
set this.target = udg_DamageFilterTarget
set this.sourceType = udg_DamageFilterSourceT
set this.targetType = udg_DamageFilterTargetT
set this.sourceItem = udg_DamageFilterSourceI
set this.targetItem = udg_DamageFilterTargetI
set this.sourceClass = udg_DamageFilterSourceC
set this.targetClass = udg_DamageFilterTargetC
set this.userType = udg_DamageFilterType
set this.damageMin = udg_DamageFilterMinAmount
set this.failChance = 1.00 - (udg_DamageFilterRunChance - udg_DamageFilterFailChance)
if udg_DamageFilterSourceA > 0 then
set this.sourceBuff = udg_DamageFilterSourceA
set udg_DamageFilterSourceA = 0
else
set this.sourceBuff = udg_DamageFilterSourceB
endif
if udg_DamageFilterTargetA > 0 then
set this.targetBuff = udg_DamageFilterTargetA
set udg_DamageFilterTargetA = 0
else
set this.targetBuff = udg_DamageFilterTargetB
endif
set udg_DamageFilterAttackT = -1
set udg_DamageFilterDamageT = -1
set udg_DamageFilterSource = null
set udg_DamageFilterTarget = null
set udg_DamageFilterSourceT = 0
set udg_DamageFilterTargetT = 0
set udg_DamageFilterType = 0
set udg_DamageFilterSourceB = 0
set udg_DamageFilterTargetB = 0
set udg_DamageFilterSourceC = -1
set udg_DamageFilterTargetC = -1
set udg_DamageFilterSourceI = 0
set udg_DamageFilterTargetI = 0
set udg_DamageFilterMinAmount = 0.00
set udg_DamageFilterFailChance = 0.00
set udg_DamageFilterRunChance = 1.00
set this.configured = true
endmethod
static method setGUIFromStruct takes boolean full returns nothing
set udg_DamageEventAmount = Damage.index.damage
set udg_DamageEventAttackT = GetHandleId(Damage.index.attackType)
set udg_DamageEventDamageT = GetHandleId(Damage.index.damageType)
set udg_DamageEventWeaponT = GetHandleId(Damage.index.weaponType)
set udg_DamageEventType = Damage.index.userType
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set udg_DamageEventArmorPierced = Damage.index.armorPierced
set udg_DamageEventArmorT = Damage.index.armorType
set udg_DamageEventDefenseT = Damage.index.defenseType
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if full then
set udg_DamageEventSource = Damage.index.sourceUnit
set udg_DamageEventTarget = Damage.index.targetUnit
set udg_DamageEventPrevAmt = Damage.index.prevAmt
set udg_IsDamageAttack = Damage.index.isAttack
set udg_IsDamageCode = Damage.index.isCode
set udg_IsDamageSpell = Damage.index.isSpell
static if USE_MELEE_RANGE then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set udg_IsDamageMelee = Damage.index.isMelee
set udg_IsDamageRanged = Damage.index.isRanged
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endif
endmethod
static method setStructFromGUI takes nothing returns nothing
set Damage.index.damage = udg_DamageEventAmount
set Damage.index.attackType = ConvertAttackType(udg_DamageEventAttackT)
set Damage.index.damageType = ConvertDamageType(udg_DamageEventDamageT)
set Damage.index.weaponType = ConvertWeaponType(udg_DamageEventWeaponT)
set Damage.index.userType = udg_DamageEventType
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set Damage.index.armorPierced = udg_DamageEventArmorPierced
set Damage.index.armorType = udg_DamageEventArmorT
set Damage.index.defenseType = udg_DamageEventDefenseT
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endmethod
static method getVerboseStr takes string eventName returns string
if eventName == "Modifier" or eventName == "Mod" then
return "udg_DamageModifierEvent"
endif
return "udg_" + eventName + "DamageEvent"
endmethod
private static method getStrIndex takes string var, real lbs returns thistype
local integer root = R2I(lbs)
if (var == "udg_DamageModifierEvent" and root < 4) or var == "udg_PreDamageEvent" then
set root = MOD
elseif var == "udg_DamageModifierEvent" or var == "udg_ArmorDamageEvent" then
set root = SHIELD
elseif (var == "udg_DamageEvent" and root == 2 or root == 0) or var == "udg_ZeroDamageEvent" then
set root = ZERO
elseif var == "udg_DamageEvent" or var == "udg_OnDamageEvent" then
set root = DAMAGE
elseif var == "udg_AfterDamageEvent" then
set root = AFTER
elseif var == "udg_LethalDamageEvent" then
set root = LETHAL
elseif var == "udg_AOEDamageEvent" or var == "udg_SourceDamageEvent" then
set root = AOE
else
set root = 0
//! runtextmacro optional DAMAGE_EVENT_REG_PLUGIN_GDD()
//! runtextmacro optional DAMAGE_EVENT_REG_PLUGIN_PDD()
//! runtextmacro optional DAMAGE_EVENT_REG_PLUGIN_01()
//! runtextmacro optional DAMAGE_EVENT_REG_PLUGIN_02()
//! runtextmacro optional DAMAGE_EVENT_REG_PLUGIN_03()
//! runtextmacro optional DAMAGE_EVENT_REG_PLUGIN_04()
//! runtextmacro optional DAMAGE_EVENT_REG_PLUGIN_05()
endif
return root
endmethod
private method toggleAllFilters takes boolean flag returns nothing
set filters[this + FILTER_ATTACK] = flag
set filters[this + FILTER_MELEE] = flag
set filters[this + FILTER_OTHER] = flag
set filters[this + FILTER_RANGED] = flag
set filters[this + FILTER_SPELL] = flag
set filters[this + FILTER_CODE] = flag
endmethod
method operator filter= takes integer f returns nothing
set this = this*FILTER_MAX
if f == FILTER_OTHER then
call this.toggleAllFilters(true)
else
if f == FILTER_ATTACK then
set filters[this + FILTER_ATTACK] = true
set filters[this + FILTER_MELEE] = true
set filters[this + FILTER_RANGED] = true
else
set filters[this + f] = true
endif
endif
endmethod
static method registerVerbose takes trigger whichTrig, string var, real lbs, boolean GUI, integer filt returns thistype
local thistype index= getStrIndex(var, lbs)
local thistype i = 0
local thistype id = 0
if index == 0 then
return 0
elseif lastRegistered.rootTrig == whichTrig and lastRegistered.usingGUI then
set filters[lastRegistered*FILTER_MAX + filt] = true //allows GUI to register multiple different types of Damage filters to the same trigger
return 0
endif
if not hasLethal and index == LETHAL then
set hasLethal = true
endif
if trigIndexStack[0] == 0 then
set count = count + 1 //List runs from index 10 and up
set id = count
else
set id = trigIndexStack[0]
set trigIndexStack[0] = trigIndexStack[id]
endif
set lastRegistered = id
set id.filter = filt
set id.rootTrig = whichTrig
set id.usingGUI = GUI
set id.weight = lbs
set id.eventStr = var
//Next 2 lines added to fix a bug when using manual vJass configuration,
//discovered and solved by lolreported
set id.attackType = -1
set id.damageType = -1
//they will probably bug out with class types as well, so I should add them, just in case:
set id.sourceClass = -1
set id.targetClass = -1
loop
set i = index.next
exitwhen i == 0 or lbs < i.weight
set index = i
endloop
set index.next = id
set id.next = i
//call BJDebugMsg("Registered " + I2S(id) + " to " + I2S(index) + " and before " + I2S(i))
return lastRegistered
endmethod
static method registerTrigger takes trigger t, string var, real lbs returns thistype
return registerVerbose(t, DamageTrigger.getVerboseStr(var), lbs, false, FILTER_OTHER)
endmethod
private static thistype prev = 0
static method getIndex takes trigger t, string eventName, real lbs returns thistype
local thistype index = getStrIndex(getVerboseStr(eventName), lbs)
loop
set prev = index
set index = index.next
exitwhen index == 0 or index.rootTrig == t
endloop
return index
endmethod
method unregisterByIndex takes boolean reset returns boolean
if this == 0 then
return false
endif
set prev.next = this.next
set trigIndexStack[this] = trigIndexStack[0]
set trigIndexStack[0] = this
if reset then
call this.configure()
set this.configured = false
call thistype(this*FILTER_MAX).toggleAllFilters(false)
endif
return true
endmethod
static method unregister takes trigger t, string eventName, real lbs, boolean reset returns boolean
return getIndex(t, eventName, lbs).unregisterByIndex(reset)
endmethod
method run takes nothing returns nothing
local integer cat = this
local Damage d = Damage.index
static if USE_GUI then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
local boolean structUnset = false
local boolean guiUnset = false
local boolean mod = cat <= DAMAGE
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if dreaming then
return
endif
set dreaming = true
call DisableTrigger(t1)
call DisableTrigger(t2)
call EnableTrigger(t3)
//call BJDebugMsg("Start of event running")
loop
set this = this.next
exitwhen this == 0
exitwhen cat == MOD and (udg_DamageEventOverride or udg_DamageEventType == TYPE_PURE)
exitwhen cat == SHIELD and udg_DamageEventAmount <= 0.00
static if USE_LETHAL then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
exitwhen cat == LETHAL and udg_LethalDamageHP > DEATH_VAL
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set eventIndex = this
if (not this.trigFrozen) and filters[this*FILTER_MAX + d.eFilter] and IsTriggerEnabled(this.rootTrig) and ((not this.configured) or (this.checkConfig())) and (cat != AOE or udg_DamageEventAOE > 1 or this.eventStr == "udg_SourceDamageEvent") then
static if USE_GUI then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if mod then
if this.usingGUI then
if guiUnset then
set guiUnset = false
call setGUIFromStruct(false)
endif
//! runtextmacro optional DAMAGE_EVENT_FILTER_PLUGIN_PDD()
elseif structUnset then
set structUnset = false
call setStructFromGUI()
endif
endif
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
//! runtextmacro optional DAMAGE_EVENT_FILTER_PLUGIN_01()
//! runtextmacro optional DAMAGE_EVENT_FILTER_PLUGIN_02()
//! runtextmacro optional DAMAGE_EVENT_FILTER_PLUGIN_03()
//! runtextmacro optional DAMAGE_EVENT_FILTER_PLUGIN_04()
//! runtextmacro optional DAMAGE_EVENT_FILTER_PLUGIN_05()
//JASS users who do not use actions can modify the below block to just evaluate.
//It should not make any perceptable difference in terms of performance.
if TriggerEvaluate(this.rootTrig) then
call TriggerExecute(this.rootTrig)
endif
//! runtextmacro optional DAMAGE_EVENT_MOD_PLUGIN_01()
//! runtextmacro optional DAMAGE_EVENT_MOD_PLUGIN_02()
//! runtextmacro optional DAMAGE_EVENT_MOD_PLUGIN_03()
//! runtextmacro optional DAMAGE_EVENT_MOD_PLUGIN_04()
//! runtextmacro optional DAMAGE_EVENT_MOD_PLUGIN_05()
static if USE_GUI then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if mod then
if this.usingGUI then
//! runtextmacro optional DAMAGE_EVENT_MOD_PLUGIN_PDD()
if cat != MOD then
set d.damage = udg_DamageEventAmount
else
set structUnset = true
endif
elseif cat != MOD then
set udg_DamageEventAmount = d.damage
else
set guiUnset = true
endif
endif
if udg_RemoveDamageEvent then
set udg_RemoveDamageEvent = false
call this.unregisterByIndex(true)
endif
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endif
endloop
static if USE_GUI then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if structUnset then
call setStructFromGUI()
endif
if guiUnset then
call setGUIFromStruct(false)
endif
else// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call setGUIFromStruct(false)
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
//call BJDebugMsg("End of event running")
call DisableTrigger(t3)
call EnableTrigger(t1)
call EnableTrigger(t2)
set dreaming = false
endmethod
static trigger array autoTriggers
static boolexpr array autoFuncs
static integer autoN = 0
static method operator [] takes code c returns trigger
local integer i = 0
local boolexpr b = Filter(c)
loop
if i == autoN then
set autoTriggers[i] = CreateTrigger()
set autoFuncs[i] = b
call TriggerAddCondition(autoTriggers[i], b)
exitwhen true
endif
set i = i + 1
exitwhen b == autoFuncs[i]
endloop
return autoTriggers[i]
endmethod
endstruct
//! runtextmacro optional DAMAGE_EVENT_USER_STRUCT_PLUGIN_01()
//! runtextmacro optional DAMAGE_EVENT_USER_STRUCT_PLUGIN_02()
//! runtextmacro optional DAMAGE_EVENT_USER_STRUCT_PLUGIN_03()
//! runtextmacro optional DAMAGE_EVENT_USER_STRUCT_PLUGIN_04()
//! runtextmacro optional DAMAGE_EVENT_USER_STRUCT_PLUGIN_05()
struct Damage extends array
readonly unit sourceUnit //stores udg_DamageEventSource
readonly unit targetUnit //stores udg_DamageEventTarget
real damage //stores udg_DamageEventAmount
readonly real prevAmt //stores udg_DamageEventPrevAmt
attacktype attackType //stores udg_DamageEventAttackT
damagetype damageType //stores udg_DamageEventDamageT
weapontype weaponType //stores udg_DamageEventWeaponT
integer userType //stores udg_DamageEventType
readonly boolean isAttack //stores udg_IsDamageAttack
readonly boolean isCode //stores udg_IsDamageCode
readonly boolean isSpell //stores udg_IsDamageSpell
static if USE_MELEE_RANGE then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
readonly boolean isMelee //stores udg_IsDamageMelee
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
readonly boolean isRanged //stores udg_IsDamageRanged
readonly integer eFilter //stores the previous eventFilter variable
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
real armorPierced //stores udg_DamageEventArmorPierced
integer armorType //stores udg_DamageEventArmorT
integer defenseType //stores udg_DamageEventDefenseT
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
readonly static Damage index = 0
private static Damage damageStack = 0
private static Damage prepped = 0
private static integer count = 0 //The number of currently-running queued or sequential damage instances
private Damage stackRef
private DamageTrigger recursiveTrig
private integer prevArmorT
private integer prevDefenseT
static method operator source takes nothing returns unit
return udg_DamageEventSource
endmethod
static method operator target takes nothing returns unit
return udg_DamageEventTarget
endmethod
static method operator amount takes nothing returns real
return Damage.index.damage
endmethod
static method operator amount= takes real r returns nothing
set Damage.index.damage = r
endmethod
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
private method setArmor takes boolean reset returns nothing
local real pierce
local integer at
local integer dt
if reset then
set pierce = udg_DamageEventArmorPierced
set at = Damage.index.prevArmorT
set dt = Damage.index.prevDefenseT
set udg_DamageEventArmorPierced = 0.00
set this.armorPierced = 0.00
else
set pierce = -udg_DamageEventArmorPierced
set at = udg_DamageEventArmorT
set dt = udg_DamageEventDefenseT
endif
if not (pierce == 0.00) then //Changed condition thanks to bug reported by BLOKKADE
call BlzSetUnitArmor(udg_DamageEventTarget, BlzGetUnitArmor(udg_DamageEventTarget) + pierce)
endif
if Damage.index.prevArmorT != udg_DamageEventArmorT then
call BlzSetUnitIntegerField(udg_DamageEventTarget, UNIT_IF_ARMOR_TYPE, at)
endif
if Damage.index.prevDefenseT != udg_DamageEventDefenseT then
call BlzSetUnitIntegerField(udg_DamageEventTarget, UNIT_IF_DEFENSE_TYPE, dt)
endif
endmethod
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
static if USE_EXTRA then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
private static method onAOEEnd takes nothing returns nothing
call DamageTrigger.AOE.run()
set udg_DamageEventAOE = 1
set udg_DamageEventLevel = 1
set udg_EnhancedDamageTarget = null
set udg_AOEDamageSource = null
call GroupClear(udg_DamageEventAOEGroup)
endmethod
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
private static method afterDamage takes nothing returns nothing
if udg_DamageEventDamageT != 0 and not (udg_DamageEventPrevAmt == 0.00) then
call DamageTrigger.AFTER.run()
set udg_DamageEventDamageT = 0
set udg_DamageEventPrevAmt = 0.00
endif
endmethod
private method doPreEvents takes boolean natural returns boolean
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set this.armorType = BlzGetUnitIntegerField(this.targetUnit, UNIT_IF_ARMOR_TYPE)
set this.defenseType = BlzGetUnitIntegerField(this.targetUnit, UNIT_IF_DEFENSE_TYPE)
set this.prevArmorT = this.armorType
set this.prevDefenseT = this.defenseType
set this.armorPierced = 0.00
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set Damage.index = this
call DamageTrigger.setGUIFromStruct(true)
call GroupAddUnit(proclusGlobal, udg_DamageEventSource)
call GroupAddUnit(fischerMorrow, udg_DamageEventTarget)
//! runtextmacro optional DAMAGE_EVENT_PRE_VARS_PLUGIN_01()
//! runtextmacro optional DAMAGE_EVENT_PRE_VARS_PLUGIN_02()
//! runtextmacro optional DAMAGE_EVENT_PRE_VARS_PLUGIN_03()
//! runtextmacro optional DAMAGE_EVENT_PRE_VARS_PLUGIN_04()
//! runtextmacro optional DAMAGE_EVENT_PRE_VARS_PLUGIN_05()
if not (udg_DamageEventAmount == 0.00) then
set udg_DamageEventOverride = udg_DamageEventDamageT == 0
call DamageTrigger.MOD.run()
static if not USE_GUI then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call DamageTrigger.setGUIFromStruct(false)
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if natural then
call BlzSetEventAttackType(this.attackType)
call BlzSetEventDamageType(this.damageType)
call BlzSetEventWeaponType(this.weaponType)
call BlzSetEventDamage(udg_DamageEventAmount)
endif
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call this.setArmor(false)
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
return false
endif
return true
endmethod
private static method unfreeze takes nothing returns nothing
local Damage i = damageStack
loop
exitwhen i == 0
set i = i - 1
set i.stackRef.recursiveTrig.trigFrozen = false
set i.stackRef.recursiveTrig.levelsDeep = 0
endloop
call EnableTrigger(t1)
call EnableTrigger(t2)
set kicking = false
set damageStack = 0
set prepped = 0
set dreaming = false
set sleepLevel = 0
call GroupClear(proclusGlobal)
call GroupClear(fischerMorrow)
//call BJDebugMsg("Cleared up the groups")
endmethod
static method finish takes nothing returns nothing
local Damage i = 0
local integer exit
if eventsRun then
set eventsRun = false
call afterDamage()
endif
if canKick and not kicking then
if damageStack != 0 then
set kicking = true
loop
set sleepLevel = sleepLevel + 1
set exit = damageStack
loop
set prepped = i.stackRef
if UnitAlive(prepped.targetUnit) then //Added just in case dead units had issues.
call prepped.doPreEvents(false) //don't evaluate the pre-event
if prepped.damage > 0.00 then
call DisableTrigger(t1) //Force only the after armor event to run.
call EnableTrigger(t2) //in case the user forgot to re-enable this
set totem = true
call UnitDamageTarget(prepped.sourceUnit, prepped.targetUnit, prepped.damage, prepped.isAttack, prepped.isRanged, prepped.attackType, prepped.damageType, prepped.weaponType)
else
//No new events run at all in this case
if udg_DamageEventDamageT != 0 then
call DamageTrigger.DAMAGE.run()
endif
if prepped.damage < 0.00 then
//No need for BlzSetEventDamage here
call SetWidgetLife(prepped.targetUnit, GetWidgetLife(prepped.targetUnit) - prepped.damage)
endif
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call prepped.setArmor(true)
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endif
call afterDamage()
endif
set i = i + 1
exitwhen i == exit
endloop
exitwhen i == damageStack
endloop
endif
call unfreeze()
endif
endmethod
private static method failsafeClear takes nothing returns nothing
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call Damage.index.setArmor(true)
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set canKick = true
set kicking = false
set totem = false
if udg_DamageEventDamageT != 0 then
call DamageTrigger.DAMAGE.run()
set eventsRun = true
endif
call finish()
endmethod
static method operator enabled= takes boolean b returns nothing
if b then
if dreaming then
call EnableTrigger(t3)
else
call EnableTrigger(t1)
call EnableTrigger(t2)
endif
else
if dreaming then
call DisableTrigger(t3)
else
call DisableTrigger(t1)
call DisableTrigger(t2)
endif
endif
endmethod
static method operator enabled takes nothing returns boolean
return IsTriggerEnabled(t1)
endmethod
private static boolean arisen = false
private static method getOutOfBed takes nothing returns nothing
if totem then
call failsafeClear() //WarCraft 3 didn't run the DAMAGED event despite running the DAMAGING event.
else
set canKick = true
set kicking = false
call finish()
endif
static if USE_EXTRA then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call onAOEEnd()
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set arisen = true
endmethod
private static method wakeUp takes nothing returns nothing
set dreaming = false
set Damage.enabled = true
call ForForce(bj_FORCE_PLAYER[0], function thistype.getOutOfBed) //Moved to a new thread in case of a thread crash
if not arisen then
//call BJDebugMsg("DamageEngine issue: thread crashed!")
call unfreeze()
else
set arisen = false
endif
set Damage.count = 0
set Damage.index = 0
set alarmSet = false
//call BJDebugMsg("Timer wrapped up")
endmethod
private method addRecursive takes nothing returns nothing
if not (this.damage == 0.00) then
set this.recursiveTrig = DamageTrigger.eventIndex
if not this.isCode then
set this.isCode = true
set this.userType = TYPE_CODE
endif
set inception = inception or DamageTrigger.eventIndex.inceptionTrig
if kicking and IsUnitInGroup(this.sourceUnit, proclusGlobal) and IsUnitInGroup(this.targetUnit, fischerMorrow) then
if not inception then
set DamageTrigger.eventIndex.trigFrozen = true
elseif not DamageTrigger.eventIndex.trigFrozen then
set DamageTrigger.eventIndex.inceptionTrig = true
if DamageTrigger.eventIndex.levelsDeep < sleepLevel then
set DamageTrigger.eventIndex.levelsDeep = DamageTrigger.eventIndex.levelsDeep + 1
if DamageTrigger.eventIndex.levelsDeep >= LIMBO then
set DamageTrigger.eventIndex.trigFrozen = true
endif
endif
endif
endif
set damageStack.stackRef = this
set damageStack = damageStack + 1
//call BJDebugMsg("damageStack: " + I2S(damageStack) + " levelsDeep: " + I2S(DamageTrigger.eventIndex.levelsDeep) + " sleepLevel: " + I2S(sleepLevel))
endif
set inception = false
endmethod
private static method clearNexts takes nothing returns nothing
set udg_NextDamageIsAttack = false
set udg_NextDamageType = 0
set udg_NextDamageWeaponT = 0
static if USE_MELEE_RANGE then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set udg_NextDamageIsMelee = false
set udg_NextDamageIsRanged = false
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endmethod
static method create takes unit src, unit tgt, real amt, boolean a, attacktype at, damagetype dt, weapontype wt returns Damage
local Damage d = Damage.count + 1
set Damage.count = d
set d.sourceUnit = src
set d.targetUnit = tgt
set d.damage = amt
set d.prevAmt = amt
set d.attackType = at
set d.damageType = dt
set d.weaponType = wt
set d.isAttack = udg_NextDamageIsAttack or a
set d.isSpell = d.attackType == null and not d.isAttack
return d
endmethod
private static method createFromEvent takes nothing returns Damage
local Damage d = create(GetEventDamageSource(), GetTriggerUnit(), GetEventDamage(), BlzGetEventIsAttack(), BlzGetEventAttackType(), BlzGetEventDamageType(), BlzGetEventWeaponType())
set d.isCode = udg_NextDamageType != 0 or udg_NextDamageIsAttack or udg_NextDamageIsRanged or udg_NextDamageIsMelee or d.damageType == DAMAGE_TYPE_MIND or udg_NextDamageWeaponT != 0 or (d.damageType == DAMAGE_TYPE_UNKNOWN and not (d.damage == 0.00))
if d.isCode then
if udg_NextDamageType != 0 then
set d.userType = udg_NextDamageType
else
set d.userType = TYPE_CODE
endif
static if USE_MELEE_RANGE then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set d.isMelee = udg_NextDamageIsMelee
set d.isRanged = udg_NextDamageIsRanged
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set d.eFilter = FILTER_CODE
if udg_NextDamageWeaponT != 0 then
set d.weaponType = ConvertWeaponType(udg_NextDamageWeaponT)
set udg_NextDamageWeaponT = 0
endif
else
set d.userType = 0
if d.damageType == DAMAGE_TYPE_NORMAL and d.isAttack then
static if USE_MELEE_RANGE then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set d.isMelee = IsUnitType(d.sourceUnit, UNIT_TYPE_MELEE_ATTACKER)
set d.isRanged = IsUnitType(d.sourceUnit, UNIT_TYPE_RANGED_ATTACKER)
if d.isMelee and d.isRanged then
set d.isMelee = d.weaponType != null // Melee units play a sound when damaging
set d.isRanged = not d.isMelee // In the case where a unit is both ranged and melee, the ranged attack plays no sound.
endif
if d.isMelee then
set d.eFilter = FILTER_MELEE
elseif d.isRanged then
set d.eFilter = FILTER_RANGED
else
set d.eFilter = FILTER_ATTACK
endif
else
set d.eFilter = FILTER_ATTACK
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
else
if d.isSpell then
set d.eFilter = FILTER_SPELL
else
set d.eFilter = FILTER_OTHER
endif
static if USE_MELEE_RANGE then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set d.isMelee = false
set d.isRanged = false
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endif
endif
call clearNexts()
return d
endmethod
private static method onRecursion takes nothing returns boolean //New in 5.7
local Damage d = Damage.createFromEvent()
call d.addRecursive()
call BlzSetEventDamage(0.00)
return false
endmethod
private static method onDamaging takes nothing returns boolean
local Damage d = Damage.createFromEvent()
//call BJDebugMsg("Pre-damage event running for " + GetUnitName(GetTriggerUnit()))
if alarmSet then
if totem then //WarCraft 3 didn't run the DAMAGED event despite running the DAMAGING event.
if d.damageType == DAMAGE_TYPE_SPIRIT_LINK or d.damageType == DAMAGE_TYPE_DEFENSIVE or d.damageType == DAMAGE_TYPE_PLANT then
set totem = false
set lastInstance= Damage.index
set canKick = false
else
call failsafeClear() //Not an overlapping event - just wrap it up
endif
else
call finish() //wrap up any previous damage index
endif
static if USE_EXTRA then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if d.sourceUnit != udg_AOEDamageSource then
call onAOEEnd()
set udg_AOEDamageSource = d.sourceUnit
elseif d.targetUnit == udg_EnhancedDamageTarget then
set udg_DamageEventLevel= udg_DamageEventLevel + 1
elseif not IsUnitInGroup(d.targetUnit, udg_DamageEventAOEGroup) then
set udg_DamageEventAOE = udg_DamageEventAOE + 1
endif
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
else
call TimerStart(alarm, 0.00, false, function Damage.wakeUp)
set alarmSet = true
static if USE_EXTRA then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set udg_AOEDamageSource = d.sourceUnit
set udg_EnhancedDamageTarget= d.targetUnit
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endif
static if USE_EXTRA then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call GroupAddUnit(udg_DamageEventAOEGroup, d.targetUnit)
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if d.doPreEvents(true) then
call DamageTrigger.ZERO.run()
set canKick = true
call finish()
endif
set totem = lastInstance == 0 or attacksImmune[udg_DamageEventAttackT] or damagesImmune[udg_DamageEventDamageT] or not IsUnitType(udg_DamageEventTarget, UNIT_TYPE_MAGIC_IMMUNE)
return false
endmethod
private static method onDamaged takes nothing returns boolean
local real r = GetEventDamage()
local Damage d = Damage.index
//call BJDebugMsg("Second damage event running for " + GetUnitName(GetTriggerUnit()))
if prepped > 0 then
set prepped = 0
elseif dreaming or d.prevAmt == 0.00 then
return false
elseif totem then
set totem = false
else
//This should only happen for stuff like Spirit Link or Thorns Aura/Carapace
call afterDamage()
set Damage.index = lastInstance
set lastInstance = 0
set d = Damage.index
set canKick = true
call DamageTrigger.setGUIFromStruct(true)
endif
static if USE_ARMOR_MOD then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call d.setArmor(true)
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
static if USE_SCALING then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if not (udg_DamageEventAmount == 0.00) and not (r == 0.00) then
set udg_DamageScalingWC3 = r / udg_DamageEventAmount
elseif udg_DamageEventAmount > 0.00 then
set udg_DamageScalingWC3 = 0.00
else
set udg_DamageScalingWC3 = 1.00
if udg_DamageEventPrevAmt == 0.00 then
set udg_DamageScalingUser = 0.00
else
set udg_DamageScalingUser = udg_DamageEventAmount/udg_DamageEventPrevAmt
endif
endif
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set udg_DamageEventAmount = r
set d.damage = r
//! runtextmacro optional DAMAGE_EVENT_VARS_PLUGIN_GDD()
//! runtextmacro optional DAMAGE_EVENT_VARS_PLUGIN_PDD()
//! runtextmacro optional DAMAGE_EVENT_VARS_PLUGIN_01()
//! runtextmacro optional DAMAGE_EVENT_VARS_PLUGIN_02()
//! runtextmacro optional DAMAGE_EVENT_VARS_PLUGIN_03()
//! runtextmacro optional DAMAGE_EVENT_VARS_PLUGIN_04()
//! runtextmacro optional DAMAGE_EVENT_VARS_PLUGIN_05()
if udg_DamageEventAmount > 0.00 then
call DamageTrigger.SHIELD.run()
static if not USE_GUI then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
set udg_DamageEventAmount = d.damage
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
static if USE_LETHAL then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if hasLethal or udg_DamageEventType < 0 then
set udg_LethalDamageHP = GetWidgetLife(udg_DamageEventTarget) - udg_DamageEventAmount
if udg_LethalDamageHP <= DEATH_VAL then
if hasLethal then
call DamageTrigger.LETHAL.run()
set udg_DamageEventAmount = GetWidgetLife(udg_DamageEventTarget) - udg_LethalDamageHP
set d.damage = udg_DamageEventAmount
endif
if udg_DamageEventType < 0 and udg_LethalDamageHP <= DEATH_VAL then
call SetUnitExploded(udg_DamageEventTarget, true)
endif
endif
endif
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
static if USE_SCALING then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if udg_DamageEventPrevAmt == 0.00 or udg_DamageScalingWC3 == 0.00 then
set udg_DamageScalingUser = 0.00
else
set udg_DamageScalingUser = udg_DamageEventAmount/udg_DamageEventPrevAmt/udg_DamageScalingWC3
endif
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
endif
if udg_DamageEventDamageT != 0 then
call DamageTrigger.DAMAGE.run()
endif
call BlzSetEventDamage(udg_DamageEventAmount)
set eventsRun = true
if udg_DamageEventAmount == 0.00 then
call finish()
endif
return false
endmethod
static method apply takes unit src, unit tgt, real amt, boolean a, boolean r, attacktype at, damagetype dt, weapontype wt returns Damage
local Damage d
if udg_NextDamageType == 0 then
set udg_NextDamageType = TYPE_CODE
endif
if dreaming then
set d = create(src, tgt, amt, a, at, dt, wt)
set d.isCode = true
set d.eFilter = FILTER_CODE
set d.userType = udg_NextDamageType
static if USE_MELEE_RANGE then// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
if not d.isSpell then
set d.isRanged = udg_NextDamageIsRanged or r
set d.isMelee = not d.isRanged
endif
endif// \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ /
call d.addRecursive()
else
call UnitDamageTarget(src, tgt, amt, a, r, at, dt, wt)
set d = Damage.index
call finish()
endif
call clearNexts()
return d
endmethod
static method applySpell takes unit src, unit tgt, real amt, damagetype dt returns Damage
return apply(src, tgt, amt, false, false, null, dt, null)
endmethod
static method applyAttack takes unit src, unit tgt, real amt, boolean ranged, attacktype at, weapontype wt returns Damage
return apply(src, tgt, amt, true, ranged, at, DAMAGE_TYPE_NORMAL, wt)
endmethod
//===========================================================================
private static method onInit takes nothing returns nothing
set alarm = CreateTimer()
set proclusGlobal = CreateGroup()
set fischerMorrow = CreateGroup()
set t1 = CreateTrigger()
set t2 = CreateTrigger()
set t3 = CreateTrigger() //Moved from globals block as per request of user Ricola3D
call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_DAMAGING)
call TriggerAddCondition(t1, Filter(function Damage.onDamaging))
call TriggerRegisterAnyUnitEventBJ(t2, EVENT_PLAYER_UNIT_DAMAGED)
call TriggerAddCondition(t2, Filter(function Damage.onDamaged))
//For recursion
call TriggerRegisterAnyUnitEventBJ(t3, EVENT_PLAYER_UNIT_DAMAGING)
call TriggerAddCondition(t3, Filter(function Damage.onRecursion))
call DisableTrigger(t3)
//For preventing Thorns/Defensive glitch.
//Data gathered from https://www.hiveworkshop.com/threads/repo-in-progress-mapping-damage-types-to-their-abilities.316271/
set attacksImmune[0] = false //ATTACK_TYPE_NORMAL
set attacksImmune[1] = true //ATTACK_TYPE_MELEE
set attacksImmune[2] = true //ATTACK_TYPE_PIERCE
set attacksImmune[3] = true //ATTACK_TYPE_SIEGE
set attacksImmune[4] = false //ATTACK_TYPE_MAGIC
set attacksImmune[5] = true //ATTACK_TYPE_CHAOS
set attacksImmune[6] = true //ATTACK_TYPE_HERO
set damagesImmune[0] = true //DAMAGE_TYPE_UNKNOWN
set damagesImmune[4] = true //DAMAGE_TYPE_NORMAL
set damagesImmune[5] = true //DAMAGE_TYPE_ENHANCED
set damagesImmune[8] = false //DAMAGE_TYPE_FIRE
set damagesImmune[9] = false //DAMAGE_TYPE_COLD
set damagesImmune[10] = false //DAMAGE_TYPE_LIGHTNING
set damagesImmune[11] = true //DAMAGE_TYPE_POISON
set damagesImmune[12] = true //DAMAGE_TYPE_DISEASE
set damagesImmune[13] = false //DAMAGE_TYPE_DIVINE
set damagesImmune[14] = false //DAMAGE_TYPE_MAGIC
set damagesImmune[15] = false //DAMAGE_TYPE_SONIC
set damagesImmune[16] = true //DAMAGE_TYPE_ACID
set damagesImmune[17] = false //DAMAGE_TYPE_FORCE
set damagesImmune[18] = false //DAMAGE_TYPE_DEATH
set damagesImmune[19] = false //DAMAGE_TYPE_MIND
set damagesImmune[20] = false //DAMAGE_TYPE_PLANT
set damagesImmune[21] = false //DAMAGE_TYPE_DEFENSIVE
set damagesImmune[22] = true //DAMAGE_TYPE_DEMOLITION
set damagesImmune[23] = true //DAMAGE_TYPE_SLOW_POISON
set damagesImmune[24] = false //DAMAGE_TYPE_SPIRIT_LINK
set damagesImmune[25] = false //DAMAGE_TYPE_SHADOW_STRIKE
set damagesImmune[26] = true //DAMAGE_TYPE_UNIVERSAL
endmethod
//! runtextmacro optional DAMAGE_EVENT_STRUCT_PLUGIN_DMGPKG()
//! runtextmacro optional DAMAGE_EVENT_STRUCT_PLUGIN_01()
//! runtextmacro optional DAMAGE_EVENT_STRUCT_PLUGIN_02()
//! runtextmacro optional DAMAGE_EVENT_STRUCT_PLUGIN_03()
//! runtextmacro optional DAMAGE_EVENT_STRUCT_PLUGIN_04()
//! runtextmacro optional DAMAGE_EVENT_STRUCT_PLUGIN_05()
endstruct
public function DebugStr takes nothing returns nothing
local integer i = 0
loop
set udg_CONVERTED_ATTACK_TYPE[i] = ConvertAttackType(i)
exitwhen i == 6
set i = i + 1
endloop
set i = 0
loop
set udg_CONVERTED_DAMAGE_TYPE[i] = ConvertDamageType(i)
exitwhen i == 26
set i = i + 1
endloop
set udg_AttackTypeDebugStr[0] = "SPELLS" //ATTACK_TYPE_NORMAL in JASS
set udg_AttackTypeDebugStr[1] = "NORMAL" //ATTACK_TYPE_MELEE in JASS
set udg_AttackTypeDebugStr[2] = "PIERCE"
set udg_AttackTypeDebugStr[3] = "SIEGE"
set udg_AttackTypeDebugStr[4] = "MAGIC"
set udg_AttackTypeDebugStr[5] = "CHAOS"
set udg_AttackTypeDebugStr[6] = "HERO"
set udg_DamageTypeDebugStr[0] = "UNKNOWN"
set udg_DamageTypeDebugStr[4] = "NORMAL"
set udg_DamageTypeDebugStr[5] = "ENHANCED"
set udg_DamageTypeDebugStr[8] = "FIRE"
set udg_DamageTypeDebugStr[9] = "COLD"
set udg_DamageTypeDebugStr[10] = "LIGHTNING"
set udg_DamageTypeDebugStr[11] = "POISON"
set udg_DamageTypeDebugStr[12] = "DISEASE"
set udg_DamageTypeDebugStr[13] = "DIVINE"
set udg_DamageTypeDebugStr[14] = "MAGIC"
set udg_DamageTypeDebugStr[15] = "SONIC"
set udg_DamageTypeDebugStr[16] = "ACID"
set udg_DamageTypeDebugStr[17] = "FORCE"
set udg_DamageTypeDebugStr[18] = "DEATH"
set udg_DamageTypeDebugStr[19] = "MIND"
set udg_DamageTypeDebugStr[20] = "PLANT"
set udg_DamageTypeDebugStr[21] = "DEFENSIVE"
set udg_DamageTypeDebugStr[22] = "DEMOLITION"
set udg_DamageTypeDebugStr[23] = "SLOW_POISON"
set udg_DamageTypeDebugStr[24] = "SPIRIT_LINK"
set udg_DamageTypeDebugStr[25] = "SHADOW_STRIKE"
set udg_DamageTypeDebugStr[26] = "UNIVERSAL"
set udg_WeaponTypeDebugStr[0] = "NONE" //WEAPON_TYPE_WHOKNOWS in JASS
set udg_WeaponTypeDebugStr[1] = "METAL_LIGHT_CHOP"
set udg_WeaponTypeDebugStr[2] = "METAL_MEDIUM_CHOP"
set udg_WeaponTypeDebugStr[3] = "METAL_HEAVY_CHOP"
set udg_WeaponTypeDebugStr[4] = "METAL_LIGHT_SLICE"
set udg_WeaponTypeDebugStr[5] = "METAL_MEDIUM_SLICE"
set udg_WeaponTypeDebugStr[6] = "METAL_HEAVY_SLICE"
set udg_WeaponTypeDebugStr[7] = "METAL_MEDIUM_BASH"
set udg_WeaponTypeDebugStr[8] = "METAL_HEAVY_BASH"
set udg_WeaponTypeDebugStr[9] = "METAL_MEDIUM_STAB"
set udg_WeaponTypeDebugStr[10] = "METAL_HEAVY_STAB"
set udg_WeaponTypeDebugStr[11] = "WOOD_LIGHT_SLICE"
set udg_WeaponTypeDebugStr[12] = "WOOD_MEDIUM_SLICE"
set udg_WeaponTypeDebugStr[13] = "WOOD_HEAVY_SLICE"
set udg_WeaponTypeDebugStr[14] = "WOOD_LIGHT_BASH"
set udg_WeaponTypeDebugStr[15] = "WOOD_MEDIUM_BASH"
set udg_WeaponTypeDebugStr[16] = "WOOD_HEAVY_BASH"
set udg_WeaponTypeDebugStr[17] = "WOOD_LIGHT_STAB"
set udg_WeaponTypeDebugStr[18] = "WOOD_MEDIUM_STAB"
set udg_WeaponTypeDebugStr[19] = "CLAW_LIGHT_SLICE"
set udg_WeaponTypeDebugStr[20] = "CLAW_MEDIUM_SLICE"
set udg_WeaponTypeDebugStr[21] = "CLAW_HEAVY_SLICE"
set udg_WeaponTypeDebugStr[22] = "AXE_MEDIUM_CHOP"
set udg_WeaponTypeDebugStr[23] = "ROCK_HEAVY_BASH"
set udg_DefenseTypeDebugStr[0] = "LIGHT"
set udg_DefenseTypeDebugStr[1] = "MEDIUM"
set udg_DefenseTypeDebugStr[2] = "HEAVY"
set udg_DefenseTypeDebugStr[3] = "FORTIFIED"
set udg_DefenseTypeDebugStr[4] = "NORMAL" //Typically deals flat damage to all armor types
set udg_DefenseTypeDebugStr[5] = "HERO"
set udg_DefenseTypeDebugStr[6] = "DIVINE"
set udg_DefenseTypeDebugStr[7] = "UNARMORED"
set udg_ArmorTypeDebugStr[0] = "NONE" //ARMOR_TYPE_WHOKNOWS in JASS, added in 1.31
set udg_ArmorTypeDebugStr[1] = "FLESH"
set udg_ArmorTypeDebugStr[2] = "METAL"
set udg_ArmorTypeDebugStr[3] = "WOOD"
set udg_ArmorTypeDebugStr[4] = "ETHEREAL"
set udg_ArmorTypeDebugStr[5] = "STONE"
// -
// Added 25 July 2017 to allow detection of things like Bash or Pulverize or AOE spread
// -
set udg_DamageEventAOE = 1
set udg_DamageEventLevel = 1
// -
// In-game World Editor doesn't allow Attack Type and Damage Type comparisons. Therefore I need to code them as integers into GUI
// -
set udg_ATTACK_TYPE_SPELLS = 0
set udg_ATTACK_TYPE_NORMAL = 1
set udg_ATTACK_TYPE_PIERCE = 2
set udg_ATTACK_TYPE_SIEGE = 3
set udg_ATTACK_TYPE_MAGIC = 4
set udg_ATTACK_TYPE_CHAOS = 5
set udg_ATTACK_TYPE_HERO = 6
// -
set udg_DAMAGE_TYPE_UNKNOWN = 0
set udg_DAMAGE_TYPE_NORMAL = 4
set udg_DAMAGE_TYPE_ENHANCED = 5
set udg_DAMAGE_TYPE_FIRE = 8
set udg_DAMAGE_TYPE_COLD = 9
set udg_DAMAGE_TYPE_LIGHTNING = 10
set udg_DAMAGE_TYPE_POISON = 11
set udg_DAMAGE_TYPE_DISEASE = 12
set udg_DAMAGE_TYPE_DIVINE = 13
set udg_DAMAGE_TYPE_MAGIC = 14
set udg_DAMAGE_TYPE_SONIC = 15
set udg_DAMAGE_TYPE_ACID = 16
set udg_DAMAGE_TYPE_FORCE = 17
set udg_DAMAGE_TYPE_DEATH = 18
set udg_DAMAGE_TYPE_MIND = 19
set udg_DAMAGE_TYPE_PLANT = 20
set udg_DAMAGE_TYPE_DEFENSIVE = 21
set udg_DAMAGE_TYPE_DEMOLITION = 22
set udg_DAMAGE_TYPE_SLOW_POISON = 23
set udg_DAMAGE_TYPE_SPIRIT_LINK = 24
set udg_DAMAGE_TYPE_SHADOW_STRIKE = 25
set udg_DAMAGE_TYPE_UNIVERSAL = 26
// -
// The below variables don't affect damage amount, but do affect the sound played
// They also give important information about the type of attack used.
// They can differentiate between ranged and melee for units who are both
// -
set udg_WEAPON_TYPE_NONE = 0
// Metal Light/Medium/Heavy
set udg_WEAPON_TYPE_ML_CHOP = 1
set udg_WEAPON_TYPE_MM_CHOP = 2
set udg_WEAPON_TYPE_MH_CHOP = 3
set udg_WEAPON_TYPE_ML_SLICE = 4
set udg_WEAPON_TYPE_MM_SLICE = 5
set udg_WEAPON_TYPE_MH_SLICE = 6
set udg_WEAPON_TYPE_MM_BASH = 7
set udg_WEAPON_TYPE_MH_BASH = 8
set udg_WEAPON_TYPE_MM_STAB = 9
set udg_WEAPON_TYPE_MH_STAB = 10
// Wood Light/Medium/Heavy
set udg_WEAPON_TYPE_WL_SLICE = 11
set udg_WEAPON_TYPE_WM_SLICE = 12
set udg_WEAPON_TYPE_WH_SLICE = 13
set udg_WEAPON_TYPE_WL_BASH = 14
set udg_WEAPON_TYPE_WM_BASH = 15
set udg_WEAPON_TYPE_WH_BASH = 16
set udg_WEAPON_TYPE_WL_STAB = 17
set udg_WEAPON_TYPE_WM_STAB = 18
// Claw Light/Medium/Heavy
set udg_WEAPON_TYPE_CL_SLICE = 19
set udg_WEAPON_TYPE_CM_SLICE = 20
set udg_WEAPON_TYPE_CH_SLICE = 21
// Axe Medium
set udg_WEAPON_TYPE_AM_CHOP = 22
// Rock Heavy
set udg_WEAPON_TYPE_RH_BASH = 23
// -
// Since GUI still doesn't provide Defense Type and Armor Types, I needed to include the below
// -
set udg_ARMOR_TYPE_NONE = 0
set udg_ARMOR_TYPE_FLESH = 1
set udg_ARMOR_TYPE_METAL = 2
set udg_ARMOR_TYPE_WOOD = 3
set udg_ARMOR_TYPE_ETHEREAL = 4
set udg_ARMOR_TYPE_STONE = 5
// -
set udg_DEFENSE_TYPE_LIGHT = 0
set udg_DEFENSE_TYPE_MEDIUM = 1
set udg_DEFENSE_TYPE_HEAVY = 2
set udg_DEFENSE_TYPE_FORTIFIED = 3
set udg_DEFENSE_TYPE_NORMAL = 4
set udg_DEFENSE_TYPE_HERO = 5
set udg_DEFENSE_TYPE_DIVINE = 6
set udg_DEFENSE_TYPE_UNARMORED = 7
// -
set udg_UNIT_CLASS_HERO = 0
set udg_UNIT_CLASS_DEAD = 1
set udg_UNIT_CLASS_STRUCTURE = 2
// -
set udg_UNIT_CLASS_FLYING = 3
set udg_UNIT_CLASS_GROUND = 4
// -
set udg_UNIT_CLASS_ATTACKS_FLYING = 5
set udg_UNIT_CLASS_ATTACKS_GROUND = 6
// -
set udg_UNIT_CLASS_MELEE = 7
set udg_UNIT_CLASS_RANGED = 8
// -
set udg_UNIT_CLASS_GIANT = 9
set udg_UNIT_CLASS_SUMMONED = 10
set udg_UNIT_CLASS_STUNNED = 11
set udg_UNIT_CLASS_PLAGUED = 12
set udg_UNIT_CLASS_SNARED = 13
// -
set udg_UNIT_CLASS_UNDEAD = 14
set udg_UNIT_CLASS_MECHANICAL = 15
set udg_UNIT_CLASS_PEON = 16
set udg_UNIT_CLASS_SAPPER = 17
set udg_UNIT_CLASS_TOWNHALL = 18
set udg_UNIT_CLASS_ANCIENT = 19
// -
set udg_UNIT_CLASS_TAUREN = 20
set udg_UNIT_CLASS_POISONED = 21
set udg_UNIT_CLASS_POLYMORPHED = 22
set udg_UNIT_CLASS_SLEEPING = 23
set udg_UNIT_CLASS_RESISTANT = 24
set udg_UNIT_CLASS_ETHEREAL = 25
set udg_UNIT_CLASS_MAGIC_IMMUNE = 26
// -
set udg_DamageFilterAttackT = -1
set udg_DamageFilterDamageT = -1
set udg_DamageFilterSourceC = -1
set udg_DamageFilterTargetC = -1
set udg_DamageFilterRunChance = 1.00
endfunction
//===========================================================================
//
// Setup of automatic events from GUI and custom ones from JASS alike
//
//===========================================================================
public function RegisterFromHook takes trigger whichTrig, string var, limitop op, real value returns nothing
call DamageTrigger.registerVerbose(whichTrig, var, value, true, GetHandleId(op))
endfunction
hook TriggerRegisterVariableEvent RegisterFromHook
function TriggerRegisterDamageEngineEx takes trigger whichTrig, string eventName, real value, integer f returns DamageTrigger
return DamageTrigger.registerVerbose(whichTrig, DamageTrigger.getVerboseStr(eventName), value, false, f)
endfunction
function TriggerRegisterDamageEngine takes trigger whichTrig, string eventName, real value returns DamageTrigger
return DamageTrigger.registerTrigger(whichTrig, eventName, value)
endfunction
function RegisterDamageEngineEx takes code c, string eventName, real value, integer f returns DamageTrigger
return TriggerRegisterDamageEngineEx(DamageTrigger[c], eventName, value, f)
endfunction
//Similar to TriggerRegisterDamageEvent, although takes code instead of trigger as the first argument.
function RegisterDamageEngine takes code c, string eventName, real value returns DamageTrigger
return RegisterDamageEngineEx(c, eventName, value, FILTER_OTHER)
endfunction
//For GUI to tap into more powerful vJass event filtering:
//! textmacro DAMAGE_TRIGGER_CONFIG
if not DamageTrigger.eventIndex.configured then
//! endtextmacro
//! textmacro DAMAGE_TRIGGER_CONFIG_END
call DamageTrigger.eventIndex.configure()
endif
if not DamageTrigger.eventIndex.checkConfig() then
return
endif
//! endtextmacro
endlibrary
// Arcing Text Tag v1.0.0.3 by Maker
library FloatingTextArc
globals
private constant real SIZE_MIN = 0.018 // Minimum size of text
private constant real SIZE_BONUS = 0.012 // Text size increase
private constant real TIME_LIFE = 1.0 // How long the text lasts
private constant real TIME_FADE = 0.8 // When does the text start to fade
private constant real Z_OFFSET = 50 // Height above unit
private constant real Z_OFFSET_BON = 50 // How much extra height the text gains
private constant real VELOCITY = 2 // How fast the text move in x/y plane
private constant real ANGLE = bj_PI/2 // Movement angle of the text. Does not apply if
// ANGLE_RND is true
private constant boolean ANGLE_RND = true // Is the angle random or fixed
private timer TMR = CreateTimer()
endglobals
struct ArcingTextTag extends array
private texttag tt
private real as // angle, sin component
private real ac // angle, cos component
private real ah // arc height
private real t // time
private real x // origin x
private real y // origin y
private string s // text
private static integer array next
private static integer array prev
private static integer array rn
private static integer ic = 0 // Instance count
private static method update takes nothing returns nothing
local thistype this=next[0]
local real p
loop
set p = Sin(bj_PI*.t)
set .t = .t - 0.03125
set .x = .x + .ac
set .y = .y + .as
call SetTextTagPos(.tt, .x, .y, Z_OFFSET + Z_OFFSET_BON * p)
call SetTextTagText(.tt, .s, SIZE_MIN + SIZE_BONUS * p)
if .t <= 0 then
set .tt = null
set next[prev[this]] = next[this]
set prev[next[this]] = prev[this]
set rn[this] = rn[0]
set rn[0] = this
if next[0]==0 then
call PauseTimer(TMR)
endif
endif
set this = next[this]
exitwhen this == 0
endloop
endmethod
public static method create takes string s, unit u returns thistype
local thistype this = rn[0]
static if ANGLE_RND then
local real a = GetRandomReal(0, 2*bj_PI)
else
local real a = ANGLE
endif
if this == 0 then
set ic = ic + 1
set this = ic
else
set rn[0] = rn[this]
endif
set next[this] = 0
set prev[this] = prev[0]
set next[prev[0]] = this
set prev[0] = this
set .s = s
set .x = GetUnitX(u)
set .y = GetUnitY(u)
set .t = TIME_LIFE
set .as = Sin(a)*VELOCITY
set .ac = Cos(a)*VELOCITY
set .ah = 0.
if IsUnitVisible(u, GetLocalPlayer()) then
set .tt = CreateTextTag()
call SetTextTagPermanent(.tt, false)
call SetTextTagLifespan(.tt, TIME_LIFE)
call SetTextTagFadepoint(.tt, TIME_FADE)
call SetTextTagText(.tt, s, SIZE_MIN)
call SetTextTagPos(.tt, .x, .y, Z_OFFSET)
endif
if prev[this] == 0 then
call TimerStart(TMR, 0.03125, true, function thistype.update)
endif
return this
endmethod
endstruct
endlibrary
//TESH.scrollpos=75
//TESH.alwaysfold=0
function IsUnitMovementTracked takes integer i returns boolean
return udg_UMovPrev[i] != 0 or udg_UMovNext[0] == i
endfunction
function UnitMovementRegister takes nothing returns boolean
local integer i = udg_UDex
if not IsUnitMovementTracked(i) and TriggerEvaluate(gg_trg_Is_Unit_Moving_Config) then
set udg_UMovPrev[udg_UMovNext[0]] = i
set udg_UMovNext[i] = udg_UMovNext[0]
set udg_UMovNext[0] = i
set udg_UnitMovingX[i] = GetUnitX(udg_UDexUnits[i])
set udg_UnitMovingY[i] = GetUnitY(udg_UDexUnits[i])
endif
return false
endfunction
function UnitMovementUnregister takes nothing returns boolean
local integer i = udg_UDex
if IsUnitMovementTracked(i) then
set udg_UnitMoving[i] = false
set udg_UMovNext[udg_UMovPrev[i]] = udg_UMovNext[i]
set udg_UMovPrev[udg_UMovNext[i]] = udg_UMovPrev[i]
set udg_UMovPrev[i] = 0
endif
return false
endfunction
function RunUnitMovementEvent takes integer i, real e returns nothing
local integer pdex = udg_UDex
if e == 1.00 then
set udg_UnitMoving[i] = true
else
set udg_UnitMoving[i] = false
endif
set udg_UDex = i
set udg_UnitMovingEvent = e
set udg_UnitMovingEvent = 0.00
set udg_UDex = pdex
endfunction
//===========================================================================
// This function runs periodically to check if units are actually moving.
//
function UnitMovementTracker takes nothing returns nothing
local integer i = 0
local integer n
local real x
local real y
loop
set i = udg_UMovNext[i]
exitwhen i == 0
set x = GetUnitX(udg_UDexUnits[i])
set y = GetUnitY(udg_UDexUnits[i])
if x != udg_UnitMovingX[i] or y != udg_UnitMovingY[i] then
set udg_UnitMovingX[i] = x
set udg_UnitMovingY[i] = y
if not udg_UnitMoving[i] then
if GetUnitTypeId(udg_UDexUnits[i]) != 0 then
call RunUnitMovementEvent(i, 1.00)
else
set n = udg_UDex
set udg_UDex = i
set i = udg_UMovPrev[i] //avoid skipping checks
call UnitMovementUnregister()
set udg_UDex = n
endif
endif
elseif udg_UnitMoving[i] then
call RunUnitMovementEvent(i, 2.00)
endif
endloop
endfunction
//===========================================================================
function InitTrig_Is_Unit_Moving takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 1.00)
call TriggerAddCondition(t, Filter(function UnitMovementRegister))
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, 2.00)
call TriggerAddCondition(t, Filter(function UnitMovementUnregister))
if gg_trg_Is_Unit_Moving_Config != null then
call TriggerExecute(gg_trg_Is_Unit_Moving_Config)
else
call ExecuteFunc("Trig_Is_Unit_Moving_Config_Actions")
endif
call TimerStart(CreateTimer(), udg_UnitMovementInterval, true, function UnitMovementTracker)
endfunction
//===========================================================================
function UnitEventDestroyGroup takes integer i returns nothing
if udg_CargoTransportGroup[i] != null then
call DestroyGroup(udg_CargoTransportGroup[i])
set udg_CargoTransportGroup[i] = null
endif
endfunction
function UnitEventCheckAfter takes nothing returns nothing
local integer i = 0
loop
set i = udg_CheckDeathList[i]
exitwhen i == 0
if udg_IsUnitNew[i] then
//The unit was just created.
set udg_IsUnitNew[i] = false
elseif udg_IsUnitTransforming[i] then
//Added 21 July 2017 to fix the issue re-adding this ability in the same instant
set udg_UDex = i
set udg_UnitTypeEvent = 0.00
set udg_UnitTypeEvent = 1.00
set udg_UnitTypeOf[i] = GetUnitTypeId(udg_UDexUnits[i]) //Set this afterward to give the user extra reference
set udg_IsUnitTransforming[i] = false
call UnitAddAbility(udg_UDexUnits[i], udg_DetectTransformAbility)
elseif udg_IsUnitAlive[i] then
//The unit has started reincarnating.
set udg_IsUnitReincarnating[i] = true
set udg_IsUnitAlive[i] = false
set udg_UDex = i
set udg_DeathEvent = 0.50
set udg_DeathEvent = 0.00
endif
set udg_CheckDeathInList[i] = false
endloop
//Empty the list
set udg_CheckDeathList[0] = 0
endfunction
function UnitEventCheckAfterProxy takes integer i returns nothing
if udg_CheckDeathList[0] == 0 then
call TimerStart(udg_CheckDeathTimer, 0.00, false, function UnitEventCheckAfter)
endif
if not udg_CheckDeathInList[i] then
set udg_CheckDeathList[i] = udg_CheckDeathList[0]
set udg_CheckDeathList[0] = i
set udg_CheckDeathInList[i] = true
endif
endfunction
function UnitEventOnUnload takes nothing returns nothing
local integer i = udg_UDex
call GroupRemoveUnit(udg_CargoTransportGroup[GetUnitUserData(udg_CargoTransportUnit[i])], udg_UDexUnits[i])
set udg_IsUnitBeingUnloaded[i] = true
set udg_CargoEvent = 0.00
set udg_CargoEvent = 2.00
set udg_CargoEvent = 0.00
set udg_IsUnitBeingUnloaded[i] = false
if not IsUnitLoaded(udg_UDexUnits[i]) or IsUnitType(udg_CargoTransportUnit[i], UNIT_TYPE_DEAD) or GetUnitTypeId(udg_CargoTransportUnit[i]) == 0 then
set udg_CargoTransportUnit[i] = null
endif
endfunction
function UnitEventOnDeath takes nothing returns boolean
local integer pdex = udg_UDex
set udg_UDex = GetUnitUserData(GetTriggerUnit())
if udg_UDex != 0 then
set udg_KillerOfUnit[udg_UDex] = GetKillingUnit() //Added 29 May 2017 for GIMLI_2
set udg_IsUnitAlive[udg_UDex] = false
set udg_DeathEvent = 0.00
set udg_DeathEvent = 1.00
set udg_DeathEvent = 0.00
set udg_KillerOfUnit[udg_UDex] = null
if udg_CargoTransportUnit[udg_UDex] != null then
call UnitEventOnUnload()
endif
endif
set udg_UDex = pdex
return false
endfunction
function UnitEventOnOrder takes nothing returns boolean
local integer pdex = udg_UDex
local unit u = GetFilterUnit()
local integer i = GetUnitUserData(u)
if i > 0 then
set udg_UDex = i
if GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
if not udg_IsUnitRemoved[i] then
set udg_IsUnitRemoved[i] = true
set udg_IsUnitAlive[i] = false
set udg_SummonerOfUnit[i] = null
//For backwards-compatibility:
set udg_DeathEvent = 0.00
set udg_DeathEvent = 3.00
set udg_DeathEvent = 0.00
//Fire deindex event for UDex:
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 2.00
set udg_UnitIndexEvent = 0.00
set udg_UDexNext[udg_UDexPrev[i]] = udg_UDexNext[i]
set udg_UDexPrev[udg_UDexNext[i]] = udg_UDexPrev[i]
// Recycle the index for later use
set udg_UDexUnits[i] = null
set udg_UDexPrev[i] = udg_UDexLastRecycled
set udg_UDexLastRecycled = i
call UnitEventDestroyGroup(i)
endif
elseif not udg_IsUnitAlive[i] then
if not IsUnitType(u, UNIT_TYPE_DEAD) then
set udg_IsUnitAlive[i] = true
set udg_DeathEvent = 0.00
set udg_DeathEvent = 2.00
set udg_DeathEvent = 0.00
set udg_IsUnitReincarnating[i] = false
endif
elseif IsUnitType(u, UNIT_TYPE_DEAD) then
if udg_IsUnitNew[i] then
//This unit was created as a corpse.
set udg_IsUnitAlive[i] = false
set udg_DeathEvent = 0.00
set udg_DeathEvent = 1.00
set udg_DeathEvent = 0.00
elseif udg_CargoTransportUnit[i] == null or not IsUnitType(u, UNIT_TYPE_HERO) then
//The unit may have just started reincarnating.
call UnitEventCheckAfterProxy(i)
endif
elseif GetUnitAbilityLevel(u, udg_DetectTransformAbility) == 0 and not udg_IsUnitTransforming[i] then
set udg_IsUnitTransforming[i] = true
call UnitEventCheckAfterProxy(i) //This block has been updated on 21 July 2017
endif
if udg_CargoTransportUnit[i] != null and not udg_IsUnitBeingUnloaded[i] and not IsUnitLoaded(u) or IsUnitType(u, UNIT_TYPE_DEAD) then
call UnitEventOnUnload()
endif
set udg_UDex = pdex
endif
set u = null
return false
endfunction
function UnitEventOnSummon takes nothing returns boolean
local integer pdex = udg_UDex
set udg_UDex = GetUnitUserData(GetTriggerUnit())
if udg_IsUnitNew[udg_UDex] then
set udg_SummonerOfUnit[udg_UDex] = GetSummoningUnit()
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 0.50
set udg_UnitIndexEvent = 0.00
endif
set udg_UDex = pdex
return false
endfunction
function UnitEventOnLoad takes nothing returns boolean
local integer pdex = udg_UDex
local integer i = GetUnitUserData(GetTriggerUnit())
local integer index
if i != 0 then
set udg_UDex = i
if udg_CargoTransportUnit[i] != null then
call UnitEventOnUnload()
endif
//Loaded corpses do not issue an order when unloaded, therefore must
//use the enter-region event method taken from Jesus4Lyf's Transport.
if not udg_IsUnitAlive[i] then
call SetUnitX(udg_UDexUnits[i], udg_WorldMaxX)
call SetUnitY(udg_UDexUnits[i], udg_WorldMaxY)
endif
set udg_CargoTransportUnit[i] = GetTransportUnit()
set index = GetUnitUserData(udg_CargoTransportUnit[i])
if udg_CargoTransportGroup[index] == null then
set udg_CargoTransportGroup[index] = CreateGroup()
endif
call GroupAddUnit(udg_CargoTransportGroup[index], udg_UDexUnits[i])
set udg_CargoEvent = 0.00
set udg_CargoEvent = 1.00
set udg_CargoEvent = 0.00
set udg_UDex = pdex
endif
return false
endfunction
function UnitEventEnter takes nothing returns boolean
local integer pdex = udg_UDex
local integer i = udg_UDexLastRecycled
local unit u = GetFilterUnit()
if udg_UnitIndexerEnabled and GetUnitAbilityLevel(u, udg_DetectRemoveAbility) == 0 then
//Generate a unique integer index for this unit
if i == 0 then
set i = udg_UDexMax + 1
set udg_UDexMax = i
else
set udg_UDexLastRecycled = udg_UDexPrev[i]
endif
//Link index to unit, unit to index
set udg_UDexUnits[i] = u
call SetUnitUserData(u, i)
//For backwards-compatibility, add the unit to a linked list
set udg_UDexNext[i] = udg_UDexNext[0]
set udg_UDexPrev[udg_UDexNext[0]] = i
set udg_UDexNext[0] = i
set udg_UDexPrev[i] = 0
set udg_CheckDeathInList[i] = false
call UnitAddAbility(u, udg_DetectRemoveAbility)
call UnitMakeAbilityPermanent(u, true, udg_DetectRemoveAbility)
call UnitAddAbility(u, udg_DetectTransformAbility)
set udg_UnitTypeOf[i] = GetUnitTypeId(u)
set udg_IsUnitNew[i] = true
set udg_IsUnitAlive[i] = true
set udg_IsUnitRemoved[i] = false
set udg_IsUnitReincarnating[i] = false
set udg_IsUnitPreplaced[i] = udg_IsUnitPreplaced[0] //Added 29 May 2017 for Spellbound
call UnitEventCheckAfterProxy(i)
//Fire index event for UDex
set udg_UDex = i
set udg_UnitIndexEvent = 0.00
set udg_UnitIndexEvent = 1.00
set udg_UnitIndexEvent = 0.00
else
set udg_UDex = GetUnitUserData(u)
if udg_CargoTransportUnit[udg_UDex] != null and not IsUnitLoaded(u) then
//The unit was dead, but has re-entered the map.
call UnitEventOnUnload()
endif
endif
set udg_UDex = pdex
set u = null
return false
endfunction
//===========================================================================
function UnitEventInit takes nothing returns nothing
local integer i = bj_MAX_PLAYER_SLOTS //update to make it work with 1.29
local player p
local trigger t = CreateTrigger()
local trigger load = CreateTrigger()
local trigger death = CreateTrigger()
local trigger summon = CreateTrigger()
local rect r = GetWorldBounds()
local region re = CreateRegion()
local boolexpr enterB = Filter(function UnitEventEnter)
local boolexpr orderB = Filter(function UnitEventOnOrder)
set udg_WorldMaxX = GetRectMaxX(r)
set udg_WorldMaxY = GetRectMaxY(r)
call RegionAddRect(re, r)
call RemoveRect(r)
call UnitEventDestroyGroup(0)
call UnitEventDestroyGroup(1)
set udg_CheckDeathList[0] = 0
set udg_UnitIndexerEnabled = true
call TriggerRegisterEnterRegion(CreateTrigger(), re, enterB)
call TriggerAddCondition(load, Filter(function UnitEventOnLoad))
call TriggerAddCondition(death, Filter(function UnitEventOnDeath))
call TriggerAddCondition(summon, Filter(function UnitEventOnSummon))
loop
set i = i - 1
set p = Player(i)
call SetPlayerAbilityAvailable(p, udg_DetectRemoveAbility, false)
call SetPlayerAbilityAvailable(p, udg_DetectTransformAbility, false)
call TriggerRegisterPlayerUnitEvent(summon, p, EVENT_PLAYER_UNIT_SUMMON, null)
call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_UNIT_ISSUED_ORDER, orderB)
call TriggerRegisterPlayerUnitEvent(death, p, EVENT_PLAYER_UNIT_DEATH, null)
call TriggerRegisterPlayerUnitEvent(load, p, EVENT_PLAYER_UNIT_LOADED, null)
call GroupEnumUnitsOfPlayer(bj_lastCreatedGroup, p, enterB)
exitwhen i == 0
endloop
set summon = null
set death = null
set load = null
set re = null
set enterB = null
set orderB = null
set p = null
set r = null
set t = null
endfunction
function InitTrig_Unit_Event takes nothing returns nothing
endfunction
//============================================================================
// SpellEffectEvent
// - Version 1.1.0.0
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table
//============================================================================
private module M
static if LIBRARY_Table then
static Table tb
else
static hashtable ht = InitHashtable()
endif
static method onCast takes nothing returns nothing
static if LIBRARY_Table then
call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
else
call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set .tb = Table.create()
endif
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
static if LIBRARY_Table then
if not S.tb.handle.has(abil) then
set S.tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
else
if not HaveSavedHandle(S.ht, 0, abil) then
call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
endif
call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
endif
endfunction
endlibrary
/*****************************************************************************
*
* RegisterNativeEvent v1.1.1.2
* by Bannar
*
* Storage of trigger handles for native events.
*
******************************************************************************
*
* Optional requirements:
*
* Table by Bribe
* hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
*
******************************************************************************
*
* Important:
*
* Avoid using TriggerSleepAction within functions registered.
* Destroy native event trigger on your own responsibility.
*
******************************************************************************
*
* Core:
*
* function IsNativeEventRegistered takes integer whichIndex, integer whichEvent returns boolean
* Whether index whichIndex has already been attached to event whichEvent.
*
* function RegisterNativeEventTrigger takes integer whichIndex, integer eventId returns boolean
* Registers whichIndex within whichEvent scope and assigns new trigger handle for it.
*
* function GetIndexNativeEventTrigger takes integer whichIndex, integer whichEvent returns trigger
* Retrieves trigger handle for event whichEvent specific to provided index whichIndex.
*
* function GetNativeEventTrigger takes integer whichEvent returns trigger
* Retrieves trigger handle for event whichEvent.
*
*
* Custom events:
*
* function CreateNativeEvent takes nothing returns integer
* Returns unique id for new event and registers it with RegisterNativeEvent.
*
* function RegisterIndexNativeEvent takes integer whichIndex, integer whichEvent, code func returns nothing
* Registers new event handler func for event whichEvent specific to index whichIndex.
*
* function RegisterNativeEvent takes integer whichEvent, code func returns nothing
* Registers new event handler func for specified event whichEvent.
*
*****************************************************************************/
library RegisterNativeEvent uses optional Table
globals
private integer eventIndex = 500 // 0-499 reserved for Blizzard native events
endglobals
private module NativeEventInit
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set table = TableArray[0x2000]
endif
endmethod
endmodule
private struct NativeEvent extends array
static if LIBRARY_Table then
static TableArray table
else
static hashtable table = InitHashtable()
endif
implement NativeEventInit
endstruct
function IsNativeEventRegistered takes integer whichIndex, integer whichEvent returns boolean
static if LIBRARY_Table then
return NativeEvent.table[whichEvent].trigger.has(whichIndex)
else
return HaveSavedHandle(NativeEvent.table, whichEvent, whichIndex)
endif
endfunction
function RegisterNativeEventTrigger takes integer whichIndex, integer whichEvent returns boolean
if not IsNativeEventRegistered(whichIndex, whichEvent) then
static if LIBRARY_Table then
set NativeEvent.table[whichEvent].trigger[whichIndex] = CreateTrigger()
else
call SaveTriggerHandle(NativeEvent.table, whichEvent, whichIndex, CreateTrigger())
endif
return true
endif
return false
endfunction
function GetIndexNativeEventTrigger takes integer whichIndex, integer whichEvent returns trigger
static if LIBRARY_Table then
return NativeEvent.table[whichEvent].trigger[whichIndex]
else
return LoadTriggerHandle(NativeEvent.table, whichEvent, whichIndex)
endif
endfunction
function GetNativeEventTrigger takes integer whichEvent returns trigger
return GetIndexNativeEventTrigger(bj_MAX_PLAYER_SLOTS, whichEvent)
endfunction
function CreateNativeEvent takes nothing returns integer
local integer eventId = eventIndex
call RegisterNativeEventTrigger(bj_MAX_PLAYER_SLOTS, eventId)
set eventIndex = eventIndex + 1
return eventId
endfunction
function RegisterIndexNativeEvent takes integer whichIndex, integer whichEvent, code func returns nothing
call RegisterNativeEventTrigger(whichIndex, whichEvent)
call TriggerAddCondition(GetIndexNativeEventTrigger(whichIndex, whichEvent), Condition(func))
endfunction
function RegisterNativeEvent takes integer whichEvent, code func returns nothing
call RegisterIndexNativeEvent(bj_MAX_PLAYER_SLOTS, whichEvent, func)
endfunction
endlibrary
/*****************************************************************************
*
* RegisterPlayerUnitEvent v1.0.3.2
* by Bannar
*
* Register version of TriggerRegisterPlayerUnitEvent.
*
* Special thanks to Magtheridon96, Bribe, azlier and BBQ for the original library version.
*
******************************************************************************
*
* Requirements:
*
* RegisterNativeEvent by Bannar
* hiveworkshop.com/threads/snippet-registerevent-pack.250266/
*
******************************************************************************
*
* Functions:
*
* function GetAnyPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
* Retrieves trigger handle for playerunitevent whichEvent.
*
* function GetPlayerUnitEventTrigger takes player whichPlayer, playerunitevent whichEvent returns trigger
* Retrieves trigger handle for playerunitevent whichEvent specific to player whichPlayer.
*
* function RegisterAnyPlayerUnitEvent takes playerunitevent whichEvent, code func returns nothing
* Registers generic playerunitevent whichEvent adding code func as callback.
*
* function RegisterPlayerUnitEvent takes player whichPlayer, playerunitevent whichEvent, code func returns nothing
* Registers playerunitevent whichEvent for player whichPlayer adding code func as callback.
*
*****************************************************************************/
library RegisterPlayerUnitEvent requires RegisterNativeEvent
function GetAnyPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
return GetNativeEventTrigger(GetHandleId(whichEvent))
endfunction
function GetPlayerUnitEventTrigger takes player whichPlayer, playerunitevent whichEvent returns trigger
return GetIndexNativeEventTrigger(GetPlayerId(whichPlayer), GetHandleId(whichEvent))
endfunction
function RegisterAnyPlayerUnitEvent takes playerunitevent whichEvent, code func returns nothing
local integer eventId = GetHandleId(whichEvent)
local integer index = 0
local trigger t = null
if RegisterNativeEventTrigger(bj_MAX_PLAYER_SLOTS, eventId) then
set t = GetNativeEventTrigger(eventId)
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index), whichEvent, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
set t = null
endif
call RegisterNativeEvent(eventId, func)
endfunction
function RegisterPlayerUnitEvent takes player whichPlayer, playerunitevent whichEvent, code func returns nothing
local integer playerId = GetPlayerId(whichPlayer)
local integer eventId = GetHandleId(whichEvent)
if RegisterNativeEventTrigger(playerId, eventId) then
call TriggerRegisterPlayerUnitEvent(GetIndexNativeEventTrigger(playerId, eventId), whichPlayer, whichEvent, null)
endif
call RegisterIndexNativeEvent(playerId, eventId, func)
endfunction
endlibrary
/***************************************
*
* GroupTools
* v1.1.2.2
* By Magtheridon96
*
* - Original version by Rising_Dusk
*
* - Recycles groups, and allows the
* enumeration of units while taking
* into account collision.
*
* API:
* ----
*
* - group ENUM_GROUP
*
* - function NewGroup takes nothing returns group
* - function ReleaseGroup takes group g returns nothing
* - Get and release group handles
*
* - function GroupRefresh takes group g returns nothing
* - Refresh a group so that null units are removed
*
* - function GroupUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
* - Groups units while taking into account collision
*
***************************************/
library GroupTools
globals
// The highest collision size you're using in your map.
constant real MAX_COLLISION_SIZE = 197.
// Data Variables
private group array groups
private group gT = null
private integer gN = 0
private boolean f = false
// Global Group (Change it to CreateGroup() if you want)
group ENUM_GROUP = CreateGroup()
endglobals
static if DEBUG_MODE then
private struct V extends array
debug static hashtable ht = InitHashtable()
endstruct
endif
private function AE takes nothing returns nothing
if (f) then
call GroupClear(gT)
set f = false
endif
call GroupAddUnit(gT,GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
debug if null==g then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Attempt to refresh null group!")
debug return
debug endif
set f = true
set gT = g
call ForGroup(gT,function AE)
if (f) then
call GroupClear(g)
endif
endfunction
function NewGroup takes nothing returns group
if 0==gN then
return CreateGroup()
endif
set gN = gN - 1
debug call SaveBoolean(V.ht,GetHandleId(groups[gN]),0,false)
return groups[gN]
endfunction
function ReleaseGroup takes group g returns nothing
debug if null==g then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Attempt to release null group!")
debug return
debug endif
debug if LoadBoolean(V.ht,GetHandleId(g),0) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Double free!")
debug return
debug endif
debug call SaveBoolean(V.ht,GetHandleId(g),0,true)
call GroupClear(g)
set groups[gN] = g
set gN = gN + 1
endfunction
function GroupEnumUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
local unit u
debug if null==whichGroup then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Null group passed to GroupUnitsInArea!")
debug return
debug endif
call GroupEnumUnitsInRange(ENUM_GROUP,x,y,radius+MAX_COLLISION_SIZE,null)
loop
set u = FirstOfGroup(ENUM_GROUP)
exitwhen null==u
if IsUnitInRangeXY(u,x,y,radius) then
call GroupAddUnit(whichGroup,u)
endif
call GroupRemoveUnit(ENUM_GROUP,u)
endloop
endfunction
endlibrary
library WorldBounds /* v2.0.0.0
************************************************************************************
*
* struct WorldBounds extends array
*
* Fields
* -------------------------
*
* readonly static integer maxX
* readonly static integer maxY
* readonly static integer minX
* readonly static integer minY
*
* readonly static integer centerX
* readonly static integer centerY
*
* readonly static rect world
* readonly static region worldRegion
*
************************************************************************************/
private module WorldBoundInit
private static method onInit takes nothing returns nothing
set world=GetWorldBounds()
set maxX = R2I(GetRectMaxX(world))
set maxY = R2I(GetRectMaxY(world))
set minX = R2I(GetRectMinX(world))
set minY = R2I(GetRectMinY(world))
set centerX = R2I((maxX + minX)/2)
set centerY = R2I((minY + maxY)/2)
set worldRegion = CreateRegion()
call RegionAddRect(worldRegion, world)
endmethod
endmodule
struct WorldBounds extends array
readonly static integer maxX
readonly static integer maxY
readonly static integer minX
readonly static integer minY
readonly static integer centerX
readonly static integer centerY
readonly static rect world
readonly static region worldRegion
implement WorldBoundInit
endstruct
endlibrary
library TimerUtils initializer init
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+) 2.0
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3c.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* set t=NewTimerEx(x) : Get a timer (alternative to CreateTimer), call
//* Initialize timer data as x, instead of 0.
//*
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Multi-flavor:
//* Set USE_HASH_TABLE to true if you don't want to complicate your life.
//*
//* If you like speed and giberish try learning about the other flavors.
//*
//********************************************************************
//================================================================
globals
//How to tweak timer utils:
// USE_HASH_TABLE = true (new blue)
// * SAFEST
// * SLOWEST (though hash tables are kind of fast)
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true (orange)
// * kinda safe (except there is a limit in the number of timers)
// * ALMOST FAST
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
// * THE FASTEST (though is only faster than the previous method
// after using the optimizer on the map)
// * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
// work)
//
private constant boolean USE_HASH_TABLE = true
private constant boolean USE_FLEXIBLE_OFFSET = false
private constant integer OFFSET = 0x100000
private integer VOFFSET = OFFSET
//Timers to preload at map init:
private constant integer QUANTITY = 256
//Changing this to something big will allow you to keep recycling
// timers even when there are already AN INCREDIBLE AMOUNT of timers in
// the stack. But it will make things far slower so that's probably a bad idea...
private constant integer ARRAY_SIZE = 8190
endglobals
//==================================================================================================
globals
private integer array data[ARRAY_SIZE]
private hashtable ht
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
static if(USE_HASH_TABLE) then
// new blue
call SaveInteger(ht,0,GetHandleId(t), value)
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-VOFFSET]=value
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-OFFSET]=value
endif
endfunction
function GetTimerData takes timer t returns integer
static if(USE_HASH_TABLE) then
// new blue
return LoadInteger(ht,0,GetHandleId(t) )
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-VOFFSET]
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-OFFSET]
endif
endfunction
//==========================================================================================
globals
private timer array tT[ARRAY_SIZE]
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
private boolean didinit = false
endglobals
private keyword init
//==========================================================================================
// I needed to decide between duplicating code ignoring the "Once and only once" rule
// and using the ugly textmacros. I guess textmacros won.
//
//! textmacro TIMERUTIS_PRIVATE_NewTimerCommon takes VALUE
// On second thought, no.
//! endtextmacro
function NewTimerEx takes integer value returns timer
if (tN==0) then
if (not didinit) then
//This extra if shouldn't represent a major performance drawback
//because QUANTITY rule is not supposed to be broken every day.
call init.evaluate()
set tN = tN - 1
else
//If this happens then the QUANTITY rule has already been broken, try to fix the
// issue, else fail.
debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
set tT[0]=CreateTimer()
static if( not USE_HASH_TABLE) then
debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
static if( USE_FLEXIBLE_OFFSET) then
if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
else
if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
endif
endif
endif
else
set tN=tN-1
endif
call SetTimerData(tT[tN],value)
return tT[tN]
endfunction
function NewTimer takes nothing returns timer
return NewTimerEx(0)
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==ARRAY_SIZE) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function init takes nothing returns nothing
local integer i=0
local integer o=-1
local boolean oops = false
if ( didinit ) then
return
else
set didinit = true
endif
static if( USE_HASH_TABLE ) then
set ht = InitHashtable()
loop
exitwhen(i==QUANTITY)
set tT[i]=CreateTimer()
call SetTimerData(tT[i], HELD)
set i=i+1
endloop
set tN = QUANTITY
else
loop
set i=0
loop
exitwhen (i==QUANTITY)
set tT[i] = CreateTimer()
if(i==0) then
set VOFFSET = GetHandleId(tT[i])
static if(USE_FLEXIBLE_OFFSET) then
set o=VOFFSET
else
set o=OFFSET
endif
endif
if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
exitwhen true
endif
if (GetHandleId(tT[i])-o>=0) then
set i=i+1
endif
endloop
set tN = i
exitwhen(tN == QUANTITY)
set oops = true
exitwhen not USE_FLEXIBLE_OFFSET
debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")
endloop
if(oops) then
static if ( USE_FLEXIBLE_OFFSET) then
debug call BJDebugMsg("The problem has been fixed.")
//If this message doesn't appear then there is so much
//handle id fragmentation that it was impossible to preload
//so many timers and the thread crashed! Therefore this
//debug message is useful.
elseif(DEBUG_MODE) then
call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
endif
endif
endif
endfunction
endlibrary
library Table /* made by Bribe, special thanks to Vexorian & Nestharus, version 4.1.0.2.
One map, one hashtable. Welcome to NewTable 4.1.0.2
This newest iteration of Table introduces the new HashTable struct.
You can now instantiate HashTables which enables the use of large
parent and large child keys, just like a standard hashtable. Previously,
the user would have to instantiate a Table to do this on their own which -
while doable - is something the user should not have to do if I can add it
to this resource myself (especially if they are inexperienced).
This library was originally called NewTable so it didn't conflict with
the API of Table by Vexorian. However, the damage is done and it's too
late to change the library name now. To help with damage control, I
have provided an extension library called TableBC, which bridges all
the functionality of Vexorian's Table except for 2-D string arrays &
the ".flush(integer)" method. I use ".flush()" to flush a child hash-
table, because I wanted the API in NewTable to reflect the API of real
hashtables (I thought this would be more intuitive).
API
------------
struct Table
| static method create takes nothing returns Table
| create a new Table
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush all stored values inside of it
|
| method remove takes integer key returns nothing
| remove the value at index "key"
|
| method operator []= takes integer key, $TYPE$ value returns nothing
| assign "value" to index "key"
|
| method operator [] takes integer key returns $TYPE$
| load the value at index "key"
|
| method has takes integer key returns boolean
| whether or not the key was assigned
|
----------------
struct TableArray
| static method operator [] takes integer array_size returns TableArray
| create a new array of Tables of size "array_size"
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush and destroy it
|
| method operator size takes nothing returns integer
| returns the size of the TableArray
|
| method operator [] takes integer key returns Table
| returns a Table accessible exclusively to index "key"
*/
globals
private integer less = 0 //Index generation for TableArrays (below 0).
private integer more = 8190 //Index generation for Tables.
//Configure it if you use more than 8190 "key" variables in your map (this will never happen though).
private hashtable ht = InitHashtable()
private key sizeK
private key listK
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return sizeK
endmethod
static method operator list takes nothing returns Table
return listK
endmethod
endstruct
private struct handles extends array
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private struct agents extends array
method operator []= takes integer key, agent value returns nothing
call SaveAgentHandle(ht, this, key, value)
endmethod
endstruct
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSaved$SUPER$(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSaved$SUPER$(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$Handle(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$Handle(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//Run these textmacros to include the entire hashtable API as wrappers.
//Don't be intimidated by the number of macros - Vexorian's map optimizer is
//supposed to kill functions which inline (all of these functions inline).
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//New textmacro to allow table.integer[] syntax for compatibility with textmacros that might desire it.
//! runtextmacro NEW_ARRAY_BASIC("Integer", "Integer", "integer")
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
//! runtextmacro NEW_ARRAY("Frame", "framehandle")
struct Table extends array
// Implement modules for intuitive syntax (tb.handle; tb.unit; etc.)
implement realm
implement integerm
implement booleanm
implement stringm
implement playerm
implement widgetm
implement destructablem
implement itemm
implement unitm
implement abilitym
implement timerm
implement triggerm
implement triggerconditionm
implement triggeractionm
implement eventm
implement forcem
implement groupm
implement locationm
implement rectm
implement boolexprm
implement soundm
implement effectm
implement unitpoolm
implement itempoolm
implement questm
implement questitemm
implement defeatconditionm
implement timerdialogm
implement leaderboardm
implement multiboardm
implement multiboarditemm
implement trackablem
implement dialogm
implement buttonm
implement texttagm
implement lightningm
implement imagem
implement ubersplatm
implement regionm
implement fogstatem
implement fogmodifierm
implement hashtablem
implement framehandlem
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
//set this = tb[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key) //return this.integer[key]
endmethod
//set tb[389034] = 8192
method operator []= takes integer key, Table tb returns nothing
call SaveInteger(ht, this, key, tb) //set this.integer[key] = tb
endmethod
//set b = tb.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key) //return this.integer.has(key)
endmethod
//call tb.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key) //call this.integer.remove(key)
endmethod
//Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
//local Table tb = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set this = more + 1
set more = this
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this) //Clear hashed memory
endif
debug set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call tb.destroy()
//
method destroy takes nothing returns nothing
debug if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
debug return
debug endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
//! runtextmacro optional TABLE_BC_METHODS()
endstruct
//! runtextmacro optional TABLE_BC_STRUCTS()
struct TableArray extends array
//Returns a new TableArray to do your bidding. Simply use:
//
// local TableArray ta = TableArray[array_size]
//
static method operator [] takes integer array_size returns TableArray
local Table tb = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = tb[0] //The last-destroyed TableArray that had this array size
debug if array_size <= 0 then
debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
debug return 0
debug endif
if this == 0 then
set this = less - array_size
set less = this
else
set tb[0] = tb[this] //Set the last destroyed to the last-last destroyed
call tb.remove(this) //Clear hashed memory
endif
set dex.size[this] = array_size //This remembers the array size
return this
endmethod
//Returns the size of the TableArray
method operator size takes nothing returns integer
return dex.size[this]
endmethod
//This magic method enables two-dimensional[array][syntax] for Tables,
//similar to the two-dimensional utility provided by hashtables them-
//selves.
//
//ta[integer a].unit[integer b] = unit u
//ta[integer a][integer c] = integer d
//
//Inline-friendly when not running in debug mode
//
method operator [] takes integer key returns Table
static if DEBUG_MODE then
local integer i = this.size
if i == 0 then
call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
return 0
elseif key < 0 or key >= i then
call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
return 0
endif
endif
return this + key
endmethod
//Destroys a TableArray without flushing it; I assume you call .flush()
//if you want it flushed too. This is a public method so that you don't
//have to loop through all TableArray indices to flush them if you don't
//need to (ie. if you were flushing all child-keys as you used them).
//
method destroy takes nothing returns nothing
local Table tb = dex.size[this.size]
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
debug return
debug endif
if tb == 0 then
//Create a Table to index recycled instances with their array size
set tb = Table.create()
set dex.size[this.size] = tb
endif
call dex.size.remove(this) //Clear the array size from hash memory
set tb[this] = tb[0]
set tb[0] = this
endmethod
private static Table tempTable
private static integer tempEnd
//Avoids hitting the op limit
private static method clean takes nothing returns nothing
local Table tb = .tempTable
local integer end = tb + 0x1000
if end < .tempEnd then
set .tempTable = end
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
else
set end = .tempEnd
endif
loop
call tb.flush()
set tb = tb + 1
exitwhen tb == end
endloop
endmethod
//Flushes the TableArray and also destroys it. Doesn't get any more
//similar to the FlushParentHashtable native than this.
//
method flush takes nothing returns nothing
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
set .tempTable = this
set .tempEnd = this + this.size
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
call this.destroy()
endmethod
endstruct
//NEW: Added in Table 4.0. A fairly simple struct but allows you to do more
//than that which was previously possible.
struct HashTable extends array
//Enables myHash[parentKey][childKey] syntax.
//Basically, it creates a Table in the place of the parent key if
//it didn't already get created earlier.
method operator [] takes integer index returns Table
local Table t = Table(this)[index]
if t == 0 then
set t = Table.create()
set Table(this)[index] = t //whoops! Forgot that line. I'm out of practice!
endif
return t
endmethod
//You need to call this on each parent key that you used if you
//intend to destroy the HashTable or simply no longer need that key.
method remove takes integer index returns nothing
local Table t = Table(this)[index]
if t != 0 then
call t.destroy()
call Table(this).remove(index)
endif
endmethod
//Added in version 4.1
method has takes integer index returns boolean
return Table(this).has(index)
endmethod
//HashTables are just fancy Table indices.
method destroy takes nothing returns nothing
call Table(this).destroy()
endmethod
//Like I said above...
static method create takes nothing returns thistype
return Table.create()
endmethod
endstruct
endlibrary
library GetLocZ
globals
private constant location loc = Location(0., 0.)
endglobals
function GetLocZ takes real x, real y returns real
call MoveLocation(loc, x, y)
return GetLocationZ(loc)
endfunction
endlibrary
library InitTOCFiles
private module init
private static method onInit takes nothing returns nothing
call BlzLoadTOCFile("UI\\CustomUI.toc")
endmethod
endmodule
private struct InitTOCFiles
implement init
endstruct
endlibrary
library SimError initializer init
//**************************************************************************************************
//*
//* SimError
//*
//* Mimic an interface error message
//* call SimError(ForPlayer, msg)
//* ForPlayer : The player to show the error
//* msg : The error
//*
//* To implement this function, copy this trigger and paste it in your map.
//* Unless of course you are actually reading the library from wc3c's scripts section, then just
//* paste the contents into some custom text trigger in your map.
//*
//**************************************************************************************************
//==================================================================================================
globals
private sound error
endglobals
//====================================================================================================
function SimError takes player ForPlayer, string msg returns nothing
set msg="\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n|cffffcc00"+msg+"|r"
if (GetLocalPlayer() == ForPlayer) then
call ClearTextMessages()
call DisplayTimedTextToPlayer( ForPlayer, 0.52, 0.96, 2.00, msg )
call StartSound( error )
endif
endfunction
private function init takes nothing returns nothing
set error=CreateSoundFromLabel("InterfaceError",false,false,false,10,10)
//call StartSound( error ) //apparently the bug in which you play a sound for the first time
//and it doesn't work is not there anymore in patch 1.22
endfunction
endlibrary
library Colour
globals
Colour COLOUR_PHYSICAL_DMG = 0
Colour COLOUR_MAGICAL_DMG = 0
Colour COLOUR_HEAL = 0
Colour COLOUR_SHIELD = 0
Colour COLOUR_GOLD = 0
Colour COLOUR_LUMBER = 0
endglobals
private module InitColour
private static method onInit takes nothing returns nothing
//Setup colours
set COLOUR_PHYSICAL_DMG = Colour.create(255, 0, 50, 255)
set COLOUR_MAGICAL_DMG = Colour.create(50, 200, 255, 255)
set COLOUR_HEAL = Colour.create(50, 255, 100, 255)
set COLOUR_SHIELD = Colour.create(255, 40, 225, 255)
set COLOUR_GOLD = Colour.create(255, 220, 0, 255)
set COLOUR_LUMBER = Colour.create(0, 200, 80, 255)
endmethod
endmodule
struct Colour
integer r
integer g
integer b
integer a
static method create takes integer red, integer green, integer blue, integer alpha returns thistype
local thistype this = allocate()
set .r = red
set .g = green
set .b = blue
set .a = alpha
return this
endmethod
implement InitColour
endstruct
endlibrary
library ResourceOverTime uses TimerUtils, Colour, DFavour
globals
integer DRAGON_FAVOUR = 0
ResourceOverTime array FavourGen
constant real FAVOUR_INT = 10.
constant integer FAVOUR_AMT = 1
endglobals
struct CustomResource
endstruct
struct ResourceOverTime
private static constant real SPEED = .0355
private static constant real ANGLE = bj_PI/2
private unit mine
private real interval
private timer clock
private playerstate resource
private integer amount
private player play
private Colour clr
private CustomResource custom
private boolean stopped
method destroy takes nothing returns nothing
set .mine = null
call ReleaseTimer(.clock)
set .clock = null
call this.deallocate()
endmethod
private static method callback takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local texttag tt
if not this.stopped then
if this.resource != null then
call SetPlayerState(this.play, this.resource, GetPlayerState(this.play, this.resource) + this.amount)
else
// Custom Stuff here
if this.custom == DRAGON_FAVOUR then
call AddFavour(this.play, this.amount)
endif
endif
if GetLocalPlayer() == this.play then
set tt = CreateTextTag()
call SetTextTagText(tt, "+" + I2S(this.amount), .023)
call SetTextTagPos(tt, GetUnitX(this.mine), GetUnitY(this.mine), GetUnitFlyHeight(this.mine) + BlzGetUnitCollisionSize(this.mine))
call SetTextTagColor(tt, clr.r, clr.g, clr.b, clr.a)
call SetTextTagVelocity(tt, SPEED * Cos(ANGLE), SPEED * Sin(ANGLE))
call SetTextTagLifespan(tt, 2.)
call SetTextTagFadepoint(tt, 1.)
call SetTextTagPermanent(tt, false)
set tt = null
endif
endif
endmethod
method mute takes boolean flag returns nothing
set this.stopped = flag
endmethod
method setAmount takes integer newAmount returns nothing
set this.amount = newAmount
endmethod
static method create takes unit goldmine, player play, real timeout, playerstate resource, integer amount, Colour clr returns thistype
local thistype this = allocate()
set this.mine = goldmine
set this.interval = timeout
set this.custom = 0
set this.resource = resource
set this.amount = amount
set this.play = play
set this.clr = clr
set this.stopped = false
set this.clock = NewTimerEx(this)
call TimerStart(this.clock, timeout, true, function thistype.callback)
return this
endmethod
static method createCustom takes unit goldmine, player play, real timeout, CustomResource cr, integer amount, Colour clr returns thistype
local thistype this = allocate()
set this.mine = goldmine
set this.interval = timeout
set this.custom = cr
set this.resource = null
set this.amount = amount
set this.play = play
set this.clr = clr
set this.stopped = false
set this.clock = NewTimerEx(this)
call TimerStart(this.clock, timeout, true, function thistype.callback)
return this
endmethod
private static method onInit takes nothing returns nothing
set DRAGON_FAVOUR = CustomResource.create()
endmethod
endstruct
endlibrary
//TESH.scrollpos=186
//TESH.alwaysfold=0
scope StaticFieldA
native UnitAlive takes unit id returns boolean
globals
private constant real FPS = 0.0312500
private constant string MODEL_PATH = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
private constant integer SPELL_ID = 'A07D'
private constant string LIGHTNING_ID = "FORK"
private constant real LIGHTNING_RED = 0.00
private constant real LIGHTNING_GREEN = 0.00
private constant real LIGHTNING_BLUE = 0.00
private constant real LIGHTNING_ALPHA = 1.
private constant real DURATION = 0.50
private constant attacktype A_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype D_TYPE = DAMAGE_TYPE_MAGIC
endglobals
private constant function MaxDamage takes integer level returns real
return 75.*level
endfunction
private constant function MinDamage takes integer level returns real
return 30.*level
endfunction
private constant function Aoe takes integer level returns real
return 300 + 0.*level
endfunction
private function UnitFilter takes player source, unit targ returns boolean
return IsUnitEnemy(targ, source) and UnitAlive(targ) and not IsUnitType(targ, UNIT_TYPE_MAGIC_IMMUNE)
endfunction
//! textmacro_once STATIC_FIELD_ALLOC
if thistype(0).prev == 0 then
set count = count + 1
set this = count
else
set this = thistype(0).prev
set thistype(0).prev = thistype(0).prev.prev
endif
if thistype(0).next == 0 then
call TimerStart(period, FPS, true, function thistype.periodic)
else
set thistype(0).next.prev = this
endif
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
//! endtextmacro
private struct Caster extends array
real x
real y
real temp
thistype prev
thistype next
static integer count
static timer period
method destroy takes nothing returns nothing
if this.next != 0 then
set this.next.prev = this.prev
endif
set this.prev.next = this.next
set this.prev = thistype(0).prev
set thistype(0).prev = this
if thistype(0).next == 0 then
call PauseTimer(period)
endif
endmethod
static method periodic takes nothing returns nothing
local thistype this = thistype(0).next
loop
exitwhen this == 0
set this.temp = this.temp - FPS
if this.temp <= 0 then
call DestroyEffect(AddSpecialEffect(MODEL_PATH, this.x, this.y))
call this.destroy()
endif
set this = this.next
endloop
endmethod
static method add takes real x, real y returns nothing
local thistype this
//! runtextmacro STATIC_FIELD_ALLOC()
set this.x = x
set this.y = y
set this.temp = DURATION
endmethod
static method onInit takes nothing returns nothing
set count = 0
set period = CreateTimer()
endmethod
endstruct
private struct SF extends array
unit targ
unit cast
lightning light
real dmg
real cx
real cy
real cz
real tx
real ty
real x
real y
real z
integer steps
thistype prev
thistype next
static integer count
static timer period
static group g
static location loc
method destroy takes nothing returns nothing
if this.next != 0 then
set this.next.prev = this.prev
endif
set this.prev.next = this.next
set this.prev = thistype(0).prev
set thistype(0).prev = this
if thistype(0).next == 0 then
call PauseTimer(period)
endif
call UnitDamageTarget(this.cast, this.targ, this.dmg, true, false, A_TYPE, D_TYPE, null)
call DestroyLightning(this.light)
call SetUnitPropWindow(this.targ, GetUnitDefaultPropWindow(this.targ)*bj_DEGTORAD)
set this.light = null
set this.cast = null
set this.targ = null
endmethod
static method periodic takes nothing returns nothing
local thistype this = thistype(0).next
loop
exitwhen this == 0
set this.tx = this.tx+this.x
set this.ty = this.ty+this.y
call MoveLocation(loc, this.tx, this.ty)
set this.z = GetLocationZ(loc) + 20 + GetUnitFlyHeight(this.targ)
if IsTerrainWalkable(this.tx, this.ty) then
call MoveLightningEx(this.light, true, this.cx, this.cy, this.cz, this.tx, this.ty, this.z)
call SetUnitX(this.targ, this.tx)
call SetUnitY(this.targ, this.ty)
endif
set this.steps = this.steps - 1
if this.steps == 0 then
call this.destroy()
endif
set this = this.next
endloop
endmethod
static method cond takes nothing returns boolean
local thistype this
local integer lvl
local real angle
local unit u
local unit v
local real x
local real y
local player p
local real dist
if GetSpellAbilityId() == SPELL_ID then
set u = GetTriggerUnit()
set x = GetUnitX(u)
set y = GetUnitY(u)
set p = GetOwningPlayer(u)
set lvl = GetUnitAbilityLevel(u, SPELL_ID)
call GroupEnumUnitsInRange(g, x, y, Aoe(lvl), null)
loop
set v = FirstOfGroup(g)
exitwhen v == null
call GroupRemoveUnit(g,v)
if UnitFilter(p,v) then
//! runtextmacro STATIC_FIELD_ALLOC()
set this.cast = u
set this.targ = v
set this.cx = x
set this.cy = y
set this.tx = GetUnitX(v)
set this.ty = GetUnitY(v)
set angle = Atan2(this.ty-y, this.tx-x)
set dist = SquareRoot((this.tx-x)*(this.tx-x) + (this.ty-y)*(this.ty-y))
set this.dmg = MinDamage(lvl) + (dist/Aoe(lvl))*(MaxDamage(lvl)-MinDamage(lvl))
set this.x = -(dist/DURATION)*FPS*Cos(angle)
set this.y = -(dist/DURATION)*FPS*Sin(angle)
call MoveLocation(loc, x, y)
set this.cz = GetLocationZ(loc) + 20
call MoveLocation(loc, this.tx, this.ty)
set this.z = GetLocationZ(loc) + 20 + GetUnitFlyHeight(v)
set this.light = AddLightningEx(LIGHTNING_ID, true, this.cx, this.cy, this.cz, this.tx, this.ty, this.z)
call SetLightningColor(this.light, LIGHTNING_RED, LIGHTNING_GREEN, LIGHTNING_BLUE, LIGHTNING_ALPHA)
call SetLightningColor(this.light, LIGHTNING_RED, LIGHTNING_GREEN, LIGHTNING_BLUE, LIGHTNING_ALPHA)
set this.steps = R2I(DURATION/FPS)
call SetUnitPropWindow(this.targ, 0)
endif
endloop
call Caster.add(x,y)
set u = null
set p = null
endif
return false
endmethod
static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.cond))
call Preload(MODEL_PATH)
set count = 0
set period = CreateTimer()
set g = CreateGroup()
set loc = Location(0,0)
set t = null
endmethod
endstruct
endscope
//TESH.scrollpos=12
//TESH.alwaysfold=0
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary
library MultidimensionalArray /* v1.2b
*/uses /*
*/Table /* http://www.hiveworkshop.com/threads/snippet-new-table.188084/
[Resource Link] - http://www.hiveworkshop.com/threads/snippet-multidimensional-array.289785/
*///! novjass
/* This snippet allows you to have array storage. Unlike default arrays, you can use an index beyond 8190
since this snippet uses Tables which uses hashtable. Therefore, saving data with a really large index
such as using GetHandleId(handle) as the index would not be a problem.
But you may ask, why would we want to use this when there is already the Table library which can support
any type that we want to store? First, this has a feature which supports multidimensions that allows you
to have up to 5-dimensional array. Table already allows you to create multidimensional storage if you do
proper nesting but this library removes the need for users to do it on their own and this also helps set
a standard instead of having redundant scripts that work for the same puspose. Secondly, unlike Table,
this implements a type specific storage i.e., you can create an array storage that is only exclusive for
a specific type but of course, this also provides a generic storage like Table but with a nicer API.
Furthermore, this includes some safety precautions such as compile time safety which throws an error if
you're using an incorrect number of dimensions, as well as preventing the use of an Array instance which
isn't allocated in DEBUG_MODE. lastly, this gives users a nice and intuitive syntax which resembles that
of the original vanilla Jass arrays (call KillUnit(u[1][3])) without having a need for an ugly keyword
at the end (ex: call KillUnit(u[1].unit[3])). */
|=========|
| Credits |
|=========|
/* AGD : Author
Bribe : For the Table library, and for the algorithm of making n-dimensional storage by nesting Tables */
|-----|
| API |
|-----|
Creating an Array:
/* Creates a new array for a specific type */
local Unit1D u = Array.create()
local Unit3D u3 = Unit3D.create()
local Unit5D u5 = Timer4D.create() //You could actually use any of the dimensional array creator
local Array4D a4 = Array.create()
Storing inside an Array:
/* Stores data inside an array */
set u[GetHandleId(timer)] = GetTriggerUnit()
set u3[0x2000]['AAAA'] = GetTriggerUnit() //Syntax error: number of indexes does not match with the number of dimensions
set u5[1][2][3][4][5] = GetTriggerUnit()
set a4[1][2][3][4].unit = GetTriggerUnit()
Retrieving from an Array:
/* Retrieves data from an array */
call KillUnit(u[1234567])
call KillUnit(u3['A']['B']['C'])
call KillUnit(u5[1][2][3][4]) //Syntax error: number of indexes does not match with the number of dimensions
call KillUnit(a4[1][2][3][4].unit)
Checking storage vacancy:
/* Checks if there is data stored inside an array index */
return u.has(index) //Similar to Table(u).unit.has(index)
return u3[1][2].has(3)
return u5[1].has(2) //Checks if the fourth dimension has index 2
return a4[1][2][3].hasHandle(4)
Removing an Array index:
/* Destroys the table instance of an index and clears all its child nodes if there are any */
call u.remove(1)
call u3[1].remove(2)
call u5[1][2][3][4][5].remove(6) //Syntax error: cannot use remove() on a node which has no children
call a4[1][2][3].removeHandle(4)
Flushing an Array Index:
/* Flushes all child nodes attached to the specific index */
call u.flush() //Flushes all data inside the array, analogous to flushing a parent hashtable
call u3[1][2][3].flush() //Syntax error: cannot clear a node which has no children, use u3[1][2].remove(3) instead
call u5[1][2].flush() //Flushes all child nodes attached to the index "2" of the second dimension
call a4[1][2].flush()
Destroying an Array:
/* Destroys an array instance, flushing all data inside it */
call u.destroy()
call u3.destroy()
call u5[1].destroy() //If destroy() is called upon a node which is not a root node, it will work like clear() instead
call a4.destroy()
//! endnovjass
static if DEBUG_MODE then
private struct S extends array
static key allocated
endstruct
private function Debug takes string msg returns nothing
call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "|CFFFFCC00[MultidimensionalArray] |R" + msg)
endfunction
endif
private function AllocateIndex takes integer this, integer index returns integer
debug if not Table(S.allocated).boolean[this] then
debug return 0
debug endif
debug set Table(S.allocated).boolean[HashTable(this)[index]] = true
return HashTable(this)[index]
endfunction
/*============= For a uniform allocator syntax =) ==============*/
struct Array extends array
static method create takes nothing returns thistype
static if DEBUG_MODE then
local Table t = Table.create()
set Table(S.allocated).boolean[t] = true
return t
else
return Table.create()
endif
endmethod
endstruct
/*==============================================================*/
/*====================== Struct methods ========================*/
private module Methods
static method create takes nothing returns thistype
return Array.create()
endmethod
static if not thistype.remove.exists then
method remove takes integer index returns nothing
call HashTable(this).remove(index)
endmethod
endif
static if not thistype.has.exists then
method has takes integer index returns boolean
return HashTable(this).has(index)
endmethod
endif
method flush takes nothing returns nothing
call Table(this).flush()
endmethod
method destroy takes nothing returns nothing
call Table(this).destroy()
debug set Table(S.allocated).boolean[this] = false
endmethod
endmodule
/*==============================================================*/
/*================= Generic Type Array Storage =================*/
private struct Type extends array
static key index
method operator agent= takes agent value returns nothing
debug if not Table(S.allocated).boolean[this] then
debug call Debug("|CFFFF0000[Operator agent= ERROR] : Attempted to use a non-allocated array instance|R")
debug return
debug endif
set Table(this).agent[Table(this)[index]] = value
endmethod
//! textmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS takes TYPE
method operator $TYPE$ takes nothing returns $TYPE$
return Table(this).$TYPE$[Table(this)[index]]
endmethod
method operator $TYPE$= takes $TYPE$ value returns nothing
debug if not Table(S.allocated).boolean[this] then
debug call Debug("|CFFFF0000[Operator $TYPE$= ERROR] : Attempted to use a non-allocated array instance|R")
debug return
debug endif
set Table(this).$TYPE$[Table(this)[index]] = value
endmethod
//! endtextmacro
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("integer")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("real")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("string")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("boolean")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("player")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("widget")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("destructable")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("item")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("unit")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("ability")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("timer")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("trigger")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("triggercondition")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("triggeraction")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("event")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("force")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("group")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("location")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("rect")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("boolexpr")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("sound")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("effect")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("unitpool")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("itempool")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("quest")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("questitem")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("defeatcondition")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("timerdialog")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("leaderboard")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("multiboard")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("multiboarditem")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("trackable")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("dialog")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("button")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("texttag")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("lightning")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("image")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("ubersplat")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("region")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("fogstate")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("fogmodifier")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_OPERATORS("hashtable")
endstruct
struct Array1D extends array
//! textmacro GENERIC_DIMENSIONAL_ARRAY_METHODS takes NAME, TYPE
method has$NAME$ takes integer index returns boolean
return Table(this).$TYPE$.has(index)
endmethod
method remove$NAME$ takes integer index returns nothing
call Table(this).$TYPE$.remove(index)
endmethod
//! endtextmacro
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Integer", "integer")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Real", "real")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("String", "string")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Boolean", "boolean")
//! runtextmacro GENERIC_DIMENSIONAL_ARRAY_METHODS("Handle", "handle")
method has takes integer index returns boolean
return .hasInteger(index) /*
*/or .hasReal(index) /*
*/or .hasString(index) /*
*/or .hasBoolean(index) /*
*/or .hasHandle(index)
endmethod
method remove takes integer index returns nothing
call .removeInteger(index)
call .removeReal(index)
call .removeString(index)
call .removeBoolean(index)
call .removeHandle(index)
endmethod
implement Methods
method operator [] takes integer index returns Type
debug if not Table(S.allocated).boolean[this] then
debug return 0
debug endif
set Table(this)[Type.index] = index
return this
endmethod
endstruct
//! textmacro NEW_DIMENSIONAL_ARRAY_STRUCT takes DIM, RETURNED
struct Array$DIM$D extends array
implement Methods
method operator [] takes integer index returns Array$RETURNED$D
return AllocateIndex(this, index)
endmethod
endstruct
//! endtextmacro
//! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("2", "1")
//! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("3", "2")
//! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("4", "3")
//! runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("5", "4")
// If you want to increase the maximum number of available
// dimensions, just run the textmacros above once again like:
// runtextmacro NEW_DIMENSIONAL_ARRAY_STRUCT("LAST_MAX_DIM + 1", "LAST_MAX_DIM")
/*==============================================================*/
/*================ Type Specific Array Storage =================*/
//! textmacro NEW_DIMENSIONAL_ARRAY takes NAME, TYPE
struct $NAME$1D extends array
method remove takes integer index returns nothing
call Table(this).$TYPE$.remove(index)
endmethod
method has takes integer index returns boolean
return Table(this).$TYPE$.has(index)
endmethod
implement Methods
method operator [] takes integer index returns $TYPE$
return Table(this).$TYPE$[index]
endmethod
method operator []= takes integer index, $TYPE$ value returns nothing
debug if not Table(S.allocated).boolean[this] then
debug call Debug("|CFFFFCC00[ArrayType: $NAME$]|R |CFFFF0000[Operator []= ERROR] : Attempted to use a non-allocated array instance|R")
debug return
debug endif
set Table(this).$TYPE$[index] = value
endmethod
endstruct
struct $NAME$2D extends array
implement Methods
method operator [] takes integer index returns $NAME$1D
return AllocateIndex(this, index)
endmethod
endstruct
struct $NAME$3D extends array
implement Methods
method operator [] takes integer index returns $NAME$2D
return AllocateIndex(this, index)
endmethod
endstruct
struct $NAME$4D extends array
implement Methods
method operator [] takes integer index returns $NAME$3D
return AllocateIndex(this, index)
endmethod
endstruct
struct $NAME$5D extends array
implement Methods
method operator [] takes integer index returns $NAME$4D
return AllocateIndex(this, index)
endmethod
endstruct
//! endtextmacro
// If you want to increase the maximum number of available
// dimensions, just copy the last struct above and increase the
// number of dimension in the struct name and the returned struct
// of the operator [] by 1.
/*==============================================================*/
/*======== Implement textmacros for every storage type =========*/
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Integer", "integer")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Real", "real")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Str", "string")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Boolean", "boolean")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Player", "player")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Widget", "widget")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Item", "item")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Unit", "unit")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Ability", "ability")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Timer", "timer")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Force", "force")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Group", "group")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Location", "location")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Rect", "rect")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Sound", "sound")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Effect", "effect")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Quest", "quest")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Button", "button")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Image", "image")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Region", "region")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_DIMENSIONAL_ARRAY("Hashtable", "hashtable")
/*==============================================================*/
endlibrary
//TESH.scrollpos=51
//TESH.alwaysfold=0
library UnitIndexerGUI //requires GUI Unit Indexer
globals
private trigger index = null
private trigger deindex = null
private trigger init = null
private trigger tempTrig
endglobals
private function DoTheThings takes trigger t, code c, real r returns trigger
if t == null then
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, r)
endif
call TriggerAddCondition(t, Filter(c))
set tempTrig = t
set t = null
return tempTrig
endfunction
//call RegisterUnitIndexEvent(Filter(function Blah), EVENT_UNIT_INDEXED)
//->
//call OnUnitIndex(function Blah)
function OnUnitIndex takes code c returns nothing
set index = DoTheThings(index, c, 1.)
endfunction
//call RegisterUnitIndexEvent(Filter(function Blah), EVENT_UNIT_DEINDEXED)
//->
//call OnUnitDeindex(function Blah)
function OnUnitDeindex takes code c returns nothing
set deindex = DoTheThings(deindex, c, 2.)
endfunction
private function DestroyInit takes nothing returns boolean
call DestroyTrigger(init) //will still allow consecutive triggerconditions to run.
set init = null
return false
endfunction
//GUI Unit Indexer will initialize after any vJass stuff, so you need to do your
//unit-indexer-requiring stuff after this event instead of a module/struct/library
//initializer.
function OnUnitIndexerInitialized takes code c returns nothing
if init == null then
set init = CreateTrigger()
call TriggerAddCondition(init, Filter(function DestroyInit))
call TriggerRegisterVariableEvent(init, "udg_UnitIndexEvent", EQUAL, 3.00)
endif
call TriggerAddCondition(init, Filter(c))
endfunction
function GetUnitId takes unit u returns integer
return GetUnitUserData(u)
endfunction
function GetUnitById takes integer id returns unit
return udg_UDexUnits[id]
endfunction
function GetIndexedUnit takes nothing returns unit
return udg_UDexUnits[udg_UDex]
endfunction
function GetIndexedUnitId takes nothing returns integer
return udg_UDex
endfunction
function IsUnitIndexed takes unit u returns boolean
return udg_UDexUnits[GetUnitUserData(u)] == u
endfunction
endlibrary
library AIBehaviorController /* v1.41 by Riki
Special credits to Kingz for his Behaviour AI System, which inspired me and from which I
based to create this system.
Find it here: https://www.hiveworkshop.com/threads/behaviour-ai-system-v1-5.248639/
----------------------------
---NECESSARY REQUIREMENTS---
----------------------------
*/ requires /*
*/ MultidimensionalArray, /* by AGD: http://www.hiveworkshop.com/threads/snippet-multidimensional-array.289785/
*/ TimerUtils, /*
Others:
-Unit Indexer by Bribe: https://www.hiveworkshop.com/threads/gui-unit-indexer-1-4-0-0.197329/
-Damage Engine by Bribe: https://www.hiveworkshop.com/threads/damage-engine-5-7-1-2.201016/
-Table by Bribe: http://www.hiveworkshop.com/threads/snippet-new-table.188084/
---------------------------
---OPTIONAL REQUIREMENTS---
---------------------------
*/ optional /*
*/ UnitIndexerGUI, /* by Bribe: https://www.hiveworkshop.com/threads/snippet-gui-unit-indexer-vjass-plugin.268592/
*/ RegisterPlayerUnitEvent /* by Bannar: https://www.hiveworkshop.com/threads/snippet-registerevent-pack.250266/
Others:
-RegisterNativeEvent by Bannar: https://www.hiveworkshop.com/threads/snippet-registerevent-pack.250266/
*/
//! novjass
================================== AI Behavior Controller ==================================
/* A system designed to make it easy for users to create AI by giving them the option to */
/* define custom behaviors for specific units or unit types as required. These behaviors */
/* include following a specified order under certain circumstances, using custom spells */
/* and abilities (including those based on Channel), etc. */
/* */
/* Sometimes it is frustrating to have to deal with an AI that does not cast certain */
/* spells because they are based on Channel or some other ability that the AI would not */
/* use under normal circunstances. */
/* */
/* The goal of this system in principle is to provide a tool that allows AI units to use */
/* any spell that the user wishes to create, and it has been extended to include even */
/* more options. */
/* */
/* Please note that this system is not designed to directly create custom AI, but to */
/* support AI creation. */
/*----------------------------------------------------------------------------------------*/
=================
- HOW TO IMPORT -
=================
/*----------------------------------------------------------------------------------------*/
/* For users who want to use the system in vJass, follow steps from 1 to 3. */
/* Those users who need the GUI version must follow all the steps listed. */
/* */
/* 1. Copy all the Necessary Requirements into your map. If you have newer versions of */
/* one of the listed requirements, you can skip it, but remember that you will need all */
/* of them. */
/* */
/* 2. Copy this library into your map. After this you will be ready to use this system. */
/* */
/* 3. I recommend copying the Optional Requirements as well, but you can skip this step */
/* if you want. */
/* */
/* 4. To use the GUI version, you must first follow all the steps above. After that, you */
/* need to copy all the content within the AIBC GUI category to your map. */
/*----------------------------------------------------------------------------------------*/
=======
- API -
=======
struct Controller
|- static method registerBehavior takes unit u, Behavior b, boolean isUserBehavior returns nothing
| // Adds a custom Behavior to a single unit.
| // If isUserBehavior is false, it will fire only for Computer owned units.
| // If isUserBehavior is true, it will fire only for Player owned units.
|
|- static method registerBehaviorType takes integer uTypeId, Behavior b, boolean isUserBehavior returns nothing
| // Adds a custom Behavior to an unit type.
| // If isUserBehavior is false, it will fire only for Computer owned units.
| // If isUserBehavior is true, it will fire only for Player owned units.
|
|- static method removeBehavior takes unit u, Behavior b returns nothing
| // Removes a custom Behavior from a single unit.
|
|- static method removeBehaviorType takes integer uTypeId, Behavior b returns nothing
| // Removes a custom Behavior from an unit type.
struct Behavior
|- method onPeriod takes unit u returns nothing
| // Fires on every interval. Use u to access the unit.
|
|- method onCast takes unit caster, unit target returns nothing
| // Fires when the unit casts an ability. Use caster to access the unit.
|
|- method onTargeted takes unit target, unit caster returns nothing
| // Fires when the unit is targeted with an ability. Use target to access the unit.
|
|- method onAttack takes unit attacker, unit target returns nothing
| // Fires when the unit attacks. Use attacker to access the unit.
|
|- method onAttacked takes unit target, unit attacker returns nothing
| // Fires when the unit is attacked. Use target to access the unit.
|
|- method onDamageDealt takes unit source, unit target returns nothing
| // Fires when the unit deals damage. Use source to access the unit.
|
|- method onDamageTaken takes unit target, unit source returns nothing
| // Fires when the unit receives damage. Use target to access the unit.
|
|- method onKill takes unit killer, unit victim returns nothing
| // Fires when the unit kills another. Use killer to access the unit.
|
|- method onAllyCasts takes unit u, unit ally, unit target returns nothing
|- method onAllyTargeted takes unit u, unit ally, unit caster returns nothing
|- method onAllyAttacks takes unit u, unit ally, unit target returns nothing
|- method onAllyAttacked takes unit u, unit ally, unit attacker returns nothing
|- method onAllyDmgDealt takes unit u, unit ally, unit target returns nothing
|- method onAllyDmgTaken takes unit u, unit ally, unit source returns nothing
|- method onAllyKills takes unit u, unit ally, unit victim returns nothing
|- method onAllyDeath takes unit u, unit ally, unit killer returns nothing
| // Events that will fire when a nearby friendly unit performs a certain action.
| // These events will only activate if OTHER_UNITS_EVENTS is set to true.
| // Use u to access the unit with custom behavior.
| // Use ally to access the allied unit that fires the event.
|
|- method onEnemyCasts takes unit u, unit enemy, unit target returns nothing
|- method onEnemyTargeted takes unit u, unit enemy, unit caster returns nothing
|- method onEnemyAttacks takes unit u, unit enemy, unit target returns nothing
|- method onEnemyAttacked takes unit u, unit enemy, unit attacker returns nothing
|- method onEnemyDmgDealt takes unit u, unit enemy, unit target returns nothing
|- method onEnemyDmgTaken takes unit u, unit enemy, unit source returns nothing
|- method onEnemyKills takes unit u, unit enemy, unit victim returns nothing
|- method onEnemyDeath takes unit u, unit enemy, unit killer returns nothing
| // Events that will fire when a nearby enemy unit performs a certain action.
| // These events will only activate if OTHER_UNITS_EVENTS is set to true.
| // Use u to access the unit with custom behavior.
| // Use enemy to access the enemy unit that fires the event.
struct CustomOrder
|- method create takes unit u returns thistype
| // Registers the unit so it can use custom orders given by its Behavior.
|
|- method checkOrder takes string orderStr returns boolean
| // Checks if an orders is already registered.
|
|- method checkOrderById takes integer orderId returns boolean
| // Checks if an orders is already registered using integers for order id.
|
|- method isOrderInCooldown takes string orderStr returns boolean
| // Checks if an orders is in cooldown.
|
|- method isOrderInCooldownById takes integer orderId returns boolean
| // Checks if an orders is in cooldown using integers for order id.
|
|- method registerTargetOrder takes string orderStr, widget target, integer priority, real cooldown, integer manaCost returns nothing
|- method registerPointOrder takes string orderStr, real locX, real locY, integer priority, real cooldown, integer manaCost returns nothing
|- method registerInstantOrder takes string orderStr, integer priority, real cooldown, integer manaCost returns nothing
| // Registers an order using strings.
|
|- method registerTargetOrderById takes integer orderId, widget target, integer priority, real cooldown, integer manaCost returns nothing
|- method registerPointOrderById takes integer orderId, real locX, real locY, integer priority, real cooldown, integer manaCost returns nothing
|- method registerInstantOrderById takes integer orderId, integer priority, real cooldown, integer manaCost returns nothing
| // Registers an order using integers for order id.
//! endnovjass
native UnitAlive takes unit u returns boolean
/*------CONFIGURATION------*/
globals
private constant real PERIODIC_INTERVAL = .5 // Interval for Periodic Events
private constant real COOLDOWN_INTERVAL = .5 // Interval for Cooldown check
private constant integer MAX_ORDERS = 15 // Max number of orders for a unit per event
private constant integer LOWEST_PRIO = 1 // Minimum priority value for orders
private constant integer HIGHEST_PRIO = 100 // Maximum priority value for orders
private constant boolean OTHER_UNITS_EVENTS = true // Set to false if you don't want to fire onAlly / onEnemy events
private constant real UNIT_SEARCH_RANGE = 700. // Max range used to detect onAlly / onEnemy events
private constant real MIN_DMG = 1. // Minimum value required to fire a Damage event. Recommended value: 1.0
// Used for GroupEnumUnitsWithCollision function
private constant real MAX_COLLISION = 64. // Max collision size for units
private real tempX = 0. // Don't touch
private real tempY = 0. // Don't touch
private real tempRange = 0. // Don't touch
// Arrays, don't touch
Boolean2D OrderInCooldown
Boolean1D OrderExecuted
Integer1D RegOrders
Integer2D UnitBehavior
Integer2D UnitTypeBehavior
Boolean2D RequiredController
Boolean2D RequiredControllerType
Boolean1D HasCustomOrders
Integer1D TotalBehaviors
Integer1D TotalBehaviorsType
endglobals
/*------FUNCTIONS------*/
private function FilterInRange takes nothing returns boolean
return IsUnitInRangeXY(GetFilterUnit(), tempX, tempY, tempRange)
endfunction
private function GroupEnumUnitsWithCollision takes group g, real x, real y, real radius returns group
set tempX = x
set tempY = y
set tempRange = radius
call GroupEnumUnitsInRange(g, x, y, radius+MAX_COLLISION, Filter(function FilterInRange))
return g
endfunction
private function BehaviorMapController takes mapcontrol mc returns boolean
if mc == MAP_CONTROL_USER then
return true
else
return false
endif
endfunction
/*------EVENTS------*/
interface Behavior
// Spell Cast Events
method onCast takes unit caster, unit target returns nothing defaults nothing
method onTargeted takes unit target, unit caster returns nothing defaults nothing
// Attack Events
method onAttack takes unit attacker, unit target returns nothing defaults nothing
method onAttacked takes unit target, unit attacker returns nothing defaults nothing
// Damage Events
method onDamageDealt takes unit source, unit target returns nothing defaults nothing
method onDamageTaken takes unit target, unit source returns nothing defaults nothing
// Kill Event
method onKill takes unit killer, unit victim returns nothing defaults nothing
// Periodic Event
method onPeriod takes unit u returns nothing defaults nothing
// OnAlly Events
method onAllyCasts takes unit u, unit ally, unit target returns nothing defaults nothing
method onAllyTargeted takes unit u, unit ally, unit caster returns nothing defaults nothing
method onAllyAttacks takes unit u, unit ally, unit target returns nothing defaults nothing
method onAllyAttacked takes unit u, unit ally, unit attacker returns nothing defaults nothing
method onAllyDmgDealt takes unit u, unit ally, unit target returns nothing defaults nothing
method onAllyDmgTaken takes unit u, unit ally, unit source returns nothing defaults nothing
method onAllyKills takes unit u, unit ally, unit victim returns nothing defaults nothing
method onAllyDeath takes unit u, unit ally, unit killer returns nothing defaults nothing
// OnEnemy Events
method onEnemyCasts takes unit u, unit enemy, unit target returns nothing defaults nothing
method onEnemyTargeted takes unit u, unit enemy, unit caster returns nothing defaults nothing
method onEnemyAttacks takes unit u, unit enemy, unit target returns nothing defaults nothing
method onEnemyAttacked takes unit u, unit enemy, unit attacker returns nothing defaults nothing
method onEnemyDmgDealt takes unit u, unit enemy, unit target returns nothing defaults nothing
method onEnemyDmgTaken takes unit u, unit enemy, unit source returns nothing defaults nothing
method onEnemyKills takes unit u, unit enemy, unit victim returns nothing defaults nothing
method onEnemyDeath takes unit u, unit enemy, unit killer returns nothing defaults nothing
endinterface
/*------MAIN SYSTEM------*/
struct Cooldown
private integer casterId
private integer order
private real duration
private timer loopTimer
private method onDestroy takes nothing returns nothing
call ReleaseTimer(.loopTimer)
set .loopTimer = null
endmethod
private static method check takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local unit caster
static if LIBRARY_UnitIndexerGUI then
set caster = GetUnitById(.casterId)
else
set caster = udg_UDexUnits[.casterId]
endif
if .duration > 0 and UnitAlive(caster) and OrderInCooldown[.casterId][.order] then
set .duration = .duration - COOLDOWN_INTERVAL
else
set OrderInCooldown[.casterId][.order] = false
call .destroy()
endif
set caster = null
endmethod
static method start takes integer unitId, integer orderId, real cooldown returns nothing
local thistype this = thistype.allocate()
set .casterId = unitId
set .order = orderId
set .duration = cooldown
set .loopTimer = NewTimerEx(this)
if not OrderInCooldown[.casterId][.order] then
set OrderInCooldown[.casterId][.order] = true
endif
call TimerStart(.loopTimer, COOLDOWN_INTERVAL, true, function thistype.check)
endmethod
endstruct
struct PreventNewOrders
private integer casterId
private timer loopTimer
private method onDestroy takes nothing returns nothing
call ReleaseTimer(.loopTimer)
set .loopTimer = null
endmethod
private static method check takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
set OrderExecuted[.casterId] = false
call .destroy()
endmethod
static method start takes integer unitId returns nothing
local thistype this = thistype.allocate()
set .casterId = unitId
set .loopTimer = NewTimerEx(this)
if not OrderExecuted[.casterId] then
set OrderExecuted[.casterId] = true
endif
call TimerStart(.loopTimer, 1., false, function thistype.check)
endmethod
endstruct
struct CustomOrder
private integer unitId
private integer totalOrders = 0
private integer array order[MAX_ORDERS]
private integer array priority[MAX_ORDERS]
private real array cooldown[MAX_ORDERS]
private integer array manaCost[MAX_ORDERS]
private widget array target[MAX_ORDERS]
private real array locX[MAX_ORDERS]
private real array locY[MAX_ORDERS]
private boolean array locBased[MAX_ORDERS]
private method onDestroy takes nothing returns nothing
local integer i = 0
set HasCustomOrders[.unitId] = false
loop
exitwhen i >= .totalOrders
set target[i] = null
set i = i + 1
endloop
endmethod
static method create takes unit u returns thistype
local thistype this
local integer id
static if LIBRARY_UnitIndexerGUI then
set id = GetUnitId(u)
else
set id = GetUnitUserData(u)
endif
if not HasCustomOrders[id] then
set HasCustomOrders[id] = true
set this = thistype.allocate()
set .unitId = id
set RegOrders[.unitId] = this
return RegOrders[.unitId]
else
return RegOrders[id]
endif
endmethod
method checkOrder takes string orderStr returns boolean
local integer i = 0
local boolean isRegistered = false
local integer orderId = OrderId(orderStr)
loop
exitwhen i >= .totalOrders or isRegistered
if orderId == .order[i] then
set isRegistered = true
endif
set i = i + 1
endloop
return isRegistered
endmethod
method checkOrderById takes integer orderId returns boolean
local integer i = 0
local boolean isRegistered = false
loop
exitwhen i >= .totalOrders or isRegistered
if orderId == .order[i] then
set isRegistered = true
endif
set i = i + 1
endloop
return isRegistered
endmethod
method isOrderInCooldown takes string orderStr returns boolean
local integer orderId = OrderId(orderStr)
return OrderInCooldown[.unitId][orderId]
endmethod
method isOrderInCooldownById takes integer orderId returns boolean
return OrderInCooldown[.unitId][orderId]
endmethod
method registerOrder takes integer orderId, widget target, real locX, real locY, boolean locBased, integer priority, real cooldown, integer manaCost returns nothing
set .order[.totalOrders] = orderId
if priority < LOWEST_PRIO then
set .priority[.totalOrders] = LOWEST_PRIO
elseif priority > HIGHEST_PRIO then
set .priority[.totalOrders] = HIGHEST_PRIO
else
set .priority[.totalOrders] = priority
endif
set .cooldown[.totalOrders] = cooldown
set .manaCost[.totalOrders] = manaCost
set .target[.totalOrders] = target
set .locX[.totalOrders] = locX
set .locY[.totalOrders] = locY
set .locBased[.totalOrders] = locBased
set .totalOrders = .totalOrders + 1
endmethod
// String Orders
method registerTargetOrder takes string orderStr, widget target, integer priority, real cooldown, integer manaCost returns nothing
local integer orderId = OrderId(orderStr)
call .registerOrder(orderId, target, 0, 0, false, priority, cooldown, manaCost)
endmethod
method registerPointOrder takes string orderStr, real locX, real locY, integer priority, real cooldown, integer manaCost returns nothing
local integer orderId = OrderId(orderStr)
call .registerOrder(orderId, null, locX, locY, true, priority, cooldown, manaCost)
endmethod
method registerInstantOrder takes string orderStr, integer priority, real cooldown, integer manaCost returns nothing
local integer orderId = OrderId(orderStr)
call .registerOrder(orderId, null, 0, 0, false, priority, cooldown, manaCost)
endmethod
// Integer Orders
method registerTargetOrderById takes integer orderId, widget target, integer priority, real cooldown, integer manaCost returns nothing
call .registerOrder(orderId, target, 0, 0, false, priority, cooldown, manaCost)
endmethod
method registerPointOrderById takes integer orderId, real locX, real locY, integer priority, real cooldown, integer manaCost returns nothing
call .registerOrder(orderId, null, locX, locY, true, priority, cooldown, manaCost)
endmethod
method registerInstantOrderById takes integer orderId, integer priority, real cooldown, integer manaCost returns nothing
call .registerOrder(orderId, null, 0, 0, false, priority, cooldown, manaCost)
endmethod
private method orderByPriority takes nothing returns nothing
local integer i = 0
local integer j
local integer tempOrder = 0
local integer tempPriority = 0
local real tempCooldown = 0
local integer tempMana = 0
local widget tempTarget
local real tempX = 0
local real tempY = 0
local boolean tempLocBased = false
local integer tempIndex
loop
exitwhen i > .totalOrders - 1
set j = i
set tempIndex = i
loop
exitwhen j > .totalOrders - 1
if .priority[tempIndex] < .priority[j + 1] then
set tempIndex = j + 1
endif
set j = j + 1
endloop
set tempOrder = .order[i]
set tempPriority = .priority[i]
set tempCooldown = .cooldown[i]
set tempMana = .manaCost[i]
set tempTarget = .target[i]
set tempX = .locX[i]
set tempY = .locY[i]
set tempLocBased = .locBased[i]
set .order[i] = .order[tempIndex]
set .priority[i] = .priority[tempIndex]
set .cooldown[i] = .cooldown[tempIndex]
set .manaCost[i] = .manaCost[tempIndex]
set .target[i] = .target[tempIndex]
set .locX[i] = .locX[tempIndex]
set .locY[i] = .locY[tempIndex]
set .locBased[i] = .locBased[tempIndex]
set .order[tempIndex] = tempOrder
set .priority[tempIndex] = tempPriority
set .cooldown[tempIndex] = tempCooldown
set .manaCost[tempIndex] = tempMana
set .target[tempIndex] = tempTarget
set .locX[tempIndex] = tempX
set .locY[tempIndex] = tempY
set .locBased[tempIndex] = tempLocBased
set i = i + 1
endloop
set tempTarget = null
endmethod
static method runOrders takes CustomOrder o returns nothing
local thistype this = o
local integer i = 0
local boolean hasUsedOrder = false
local unit caster
local real casterMana
local integer tempOrder
static if LIBRARY_UnitIndexerGUI then
set caster = GetUnitById(.unitId)
else
set caster = udg_UDexUnits[.unitId]
endif
set casterMana = GetUnitState(caster, UNIT_STATE_MANA)
if HasCustomOrders[.unitId] then
call .orderByPriority()
loop
exitwhen i >= .totalOrders or OrderExecuted[.unitId]
if not .isOrderInCooldownById(.order[i]) and casterMana >= .manaCost[i] then
if .target[i] != null then
if IssueTargetOrderById(caster, .order[i], .target[i]) then
set hasUsedOrder = true
endif
elseif .locBased[i] then
if IssuePointOrderById(caster, .order[i], .locX[i], .locY[i]) then
set hasUsedOrder = true
endif
elseif IssueImmediateOrderById(caster, .order[i]) then
set hasUsedOrder = true
endif
if hasUsedOrder then
call Cooldown.start(.unitId, .order[i], .cooldown[i])
call PreventNewOrders.start(.unitId)
endif
endif
set i = i + 1
endloop
endif
set caster = null
call .destroy()
endmethod
endstruct
private module Init
private static method onInit takes nothing returns nothing
call thistype.initArrays()
endmethod
endmodule
struct Controller extends array
private static timer loopTimer = CreateTimer()
//! textmacro LOAD_BEHAVIOR takes opName
set id = GetUnitTypeId(u)
set i = 0
loop
exitwhen i == TotalBehaviorsType[id]
if (GetPlayerController(p) == MAP_CONTROL_USER and RequiredControllerType[id][i] == BehaviorMapController(MAP_CONTROL_USER)) or /*
*/ (GetPlayerController(p) != MAP_CONTROL_USER and RequiredControllerType[id][i] != BehaviorMapController(MAP_CONTROL_USER)) then
set b = UnitTypeBehavior[id][i]
call b.$opName$(u, secU)
endif
set i = i + 1
endloop
static if LIBRARY_UnitIndexerGUI then
set id = GetUnitId(u)
else
set id = GetUnitUserData(u)
endif
set i = 0
loop
exitwhen i == TotalBehaviors[id]
if (GetPlayerController(p) == MAP_CONTROL_USER and RequiredController[id][i] == BehaviorMapController(MAP_CONTROL_USER)) or /*
*/ (GetPlayerController(p) != MAP_CONTROL_USER and RequiredController[id][i] != BehaviorMapController(MAP_CONTROL_USER)) then
set b = UnitBehavior[id][i]
call b.$opName$(u, secU)
endif
set i = i + 1
endloop
if HasCustomOrders[id] then
call CustomOrder.runOrders(RegOrders[id])
endif
//! endtextmacro
//! textmacro LOAD_BEHAVIOR_OTHERS takes opName
set id = GetUnitTypeId(u)
set i = 0
loop
exitwhen i == TotalBehaviorsType[id]
if (GetPlayerController(p) == MAP_CONTROL_USER and RequiredControllerType[id][i] == BehaviorMapController(MAP_CONTROL_USER)) or /*
*/ (GetPlayerController(p) != MAP_CONTROL_USER and RequiredControllerType[id][i] != BehaviorMapController(MAP_CONTROL_USER)) then
set b = UnitTypeBehavior[id][i]
call b.$opName$(u, eventU, secU)
endif
set i = i + 1
endloop
static if LIBRARY_UnitIndexerGUI then
set id = GetUnitId(u)
else
set id = GetUnitUserData(u)
endif
set i = 0
loop
exitwhen i == TotalBehaviors[id]
if (GetPlayerController(p) == MAP_CONTROL_USER and RequiredController[id][i] == BehaviorMapController(MAP_CONTROL_USER)) or /*
*/ (GetPlayerController(p) != MAP_CONTROL_USER and RequiredController[id][i] != BehaviorMapController(MAP_CONTROL_USER)) then
set b = UnitBehavior[id][i]
call b.$opName$(u, eventU, secU)
endif
set i = i + 1
endloop
if HasCustomOrders[id] then
call CustomOrder.runOrders(RegOrders[id])
endif
//! endtextmacro
public static method registerBehavior takes unit u, Behavior b, boolean isUserBehavior returns nothing
local integer i
local integer unitId
local mapcontrol mc
if isUserBehavior then
set mc = MAP_CONTROL_USER
else
set mc = MAP_CONTROL_COMPUTER
endif
static if LIBRARY_UnitIndexerGUI then
set unitId = GetUnitId(u)
else
set unitId = GetUnitUserData(u)
endif
set i = TotalBehaviors[unitId]
set UnitBehavior[unitId][i] = b
set RequiredController[unitId][i] = BehaviorMapController(mc)
set TotalBehaviors[unitId] = TotalBehaviors[unitId] + 1
set mc = null
endmethod
public static method registerBehaviorType takes integer uTypeId, Behavior b, boolean isUserBehavior returns nothing
local integer i = TotalBehaviorsType[uTypeId]
local mapcontrol mc
if isUserBehavior then
set mc = MAP_CONTROL_USER
else
set mc = MAP_CONTROL_COMPUTER
endif
set UnitTypeBehavior[uTypeId][i] = b
set RequiredControllerType[uTypeId][i] = BehaviorMapController(mc)
set TotalBehaviorsType[uTypeId] = TotalBehaviorsType[uTypeId] + 1
set mc = null
endmethod
public static method removeBehavior takes unit u, Behavior b returns nothing
local integer i = 0
local integer unitId
static if LIBRARY_UnitIndexerGUI then
set unitId = GetUnitId(u)
else
set unitId = GetUnitUserData(u)
endif
loop
exitwhen i == TotalBehaviors[unitId]
if UnitBehavior[unitId][i] == b then
set UnitBehavior[unitId][i] = 0
endif
set i = i + 1
endloop
endmethod
public static method removeBehaviorType takes integer uTypeId, Behavior b returns nothing
local integer i = 0
loop
exitwhen i == TotalBehaviorsType[uTypeId]
if UnitTypeBehavior[uTypeId][i] == b then
set UnitTypeBehavior[uTypeId][i] = 0
endif
set i = i + 1
endloop
endmethod
private static method registerCast takes nothing returns boolean
local unit u
local player p
local unit secU
local integer id
local Behavior b
local group g1 = CreateGroup()
local group g2 = CreateGroup()
local unit eventU
local integer i
set u = GetSpellAbilityUnit()
set p = GetOwningPlayer(u)
set secU = GetSpellTargetUnit()
//! runtextmacro LOAD_BEHAVIOR("onCast")
set u = GetSpellTargetUnit()
set p = GetOwningPlayer(u)
set secU = GetSpellAbilityUnit()
//! runtextmacro LOAD_BEHAVIOR("onTargeted")
if OTHER_UNITS_EVENTS then
set eventU = GetSpellAbilityUnit()
set secU = GetSpellTargetUnit()
call GroupEnumUnitsWithCollision(g1, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g1)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyCasts")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyCasts")
endif
call GroupRemoveUnit(g1, u)
set u = null
set p = null
endloop
set eventU = GetSpellTargetUnit()
set secU = GetSpellAbilityUnit()
call GroupEnumUnitsWithCollision(g2, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyTargeted")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyTargeted")
endif
call GroupRemoveUnit(g2, u)
set u = null
set p = null
endloop
set eventU = null
endif
call DestroyGroup(g1)
call DestroyGroup(g2)
set g1 = null
set g2 = null
set u = null
set p = null
set secU = null
return false
endmethod
private static method registerAttack takes nothing returns boolean
local unit u
local player p
local unit secU
local integer id
local Behavior b
local group g1 = CreateGroup()
local group g2 = CreateGroup()
local unit eventU
local integer i
set u = GetAttacker()
set p = GetOwningPlayer(u)
set secU = GetTriggerUnit()
//! runtextmacro LOAD_BEHAVIOR("onAttack")
set u = GetTriggerUnit()
set p = GetOwningPlayer(u)
set secU = GetAttacker()
//! runtextmacro LOAD_BEHAVIOR("onAttacked")
if OTHER_UNITS_EVENTS then
set eventU = GetAttacker()
set secU = GetTriggerUnit()
call GroupEnumUnitsWithCollision(g1, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g1)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyAttacks")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyAttacks")
endif
call GroupRemoveUnit(g1, u)
set u = null
set p = null
endloop
set eventU = GetTriggerUnit()
set secU = GetAttacker()
call GroupEnumUnitsWithCollision(g2, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyAttacked")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyAttacked")
endif
call GroupRemoveUnit(g2, u)
set u = null
set p = null
endloop
set eventU = null
endif
call DestroyGroup(g1)
call DestroyGroup(g2)
set g1 = null
set g2 = null
set u = null
set p = null
set secU = null
return false
endmethod
private static method registerDamage takes nothing returns boolean
local unit u
local player p
local unit secU
local integer id
local Behavior b
local group g1 = CreateGroup()
local group g2 = CreateGroup()
local unit eventU
local integer i
if udg_DamageEventAmount >= MIN_DMG then
set u = udg_DamageEventSource
set p = GetOwningPlayer(u)
set secU = udg_DamageEventTarget
//! runtextmacro LOAD_BEHAVIOR("onDamageDealt")
set u = udg_DamageEventTarget
set p = GetOwningPlayer(u)
set secU = udg_DamageEventSource
//! runtextmacro LOAD_BEHAVIOR("onDamageTaken")
if OTHER_UNITS_EVENTS then
set eventU = udg_DamageEventSource
set secU = udg_DamageEventTarget
call GroupEnumUnitsWithCollision(g1, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g1)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyDmgDealt")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyDmgDealt")
endif
call GroupRemoveUnit(g1, u)
set u = null
set p = null
endloop
set eventU = udg_DamageEventTarget
set secU = udg_DamageEventSource
call GroupEnumUnitsWithCollision(g2, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyDmgTaken")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyDmgTaken")
endif
call GroupRemoveUnit(g2, u)
set u = null
set p = null
endloop
set eventU = null
endif
endif
call DestroyGroup(g1)
call DestroyGroup(g2)
set g1 = null
set g2 = null
set u = null
set p = null
set secU = null
return false
endmethod
private static method registerKill takes nothing returns boolean
local unit u
local player p
local unit secU
local integer id
local Behavior b
local group g1 = CreateGroup()
local group g2 = CreateGroup()
local unit eventU
local integer i
set u = GetKillingUnit()
set p = GetOwningPlayer(u)
set secU = GetDyingUnit()
//! runtextmacro LOAD_BEHAVIOR("onKill")
if OTHER_UNITS_EVENTS then
set eventU = GetKillingUnit()
set secU = GetDyingUnit()
call GroupEnumUnitsWithCollision(g1, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g1)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyKills")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyKills")
endif
call GroupRemoveUnit(g1, u)
set u = null
set p = null
endloop
set eventU = GetDyingUnit()
set secU = GetKillingUnit()
call GroupEnumUnitsWithCollision(g2, GetUnitX(eventU), GetUnitY(eventU), UNIT_SEARCH_RANGE)
loop
set u = FirstOfGroup(g2)
exitwhen u == null
set p = GetOwningPlayer(u)
if IsUnitAlly(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onAllyDeath")
elseif IsUnitEnemy(eventU, p) and eventU != u then
//! runtextmacro LOAD_BEHAVIOR_OTHERS("onEnemyDeath")
endif
call GroupRemoveUnit(g2, u)
set u = null
set p = null
endloop
set eventU = null
endif
call DestroyGroup(g1)
call DestroyGroup(g2)
set g1 = null
set g2 = null
set u = null
set p = null
set secU = null
return false
endmethod
private static method registerPeriod takes nothing returns nothing
local group allUnits = CreateGroup()
local unit u
local player p
local integer id
local Behavior b
local integer i
call GroupEnumUnitsInRect(allUnits, bj_mapInitialPlayableArea, null)
loop
set u = FirstOfGroup(allUnits)
exitwhen u == null
set p = GetOwningPlayer(u)
set id = GetUnitTypeId(u)
set i = 0
loop
exitwhen i == TotalBehaviorsType[id]
if (GetPlayerController(p) == MAP_CONTROL_USER and RequiredControllerType[id][i] == BehaviorMapController(MAP_CONTROL_USER)) or /*
*/ (GetPlayerController(p) != MAP_CONTROL_USER and RequiredControllerType[id][i] != BehaviorMapController(MAP_CONTROL_USER)) then
set b = UnitTypeBehavior[id][i]
call b.onPeriod(u)
endif
set i = i + 1
endloop
static if LIBRARY_UnitIndexerGUI then
set id = GetUnitId(u)
else
set id = GetUnitUserData(u)
endif
set i = 0
loop
exitwhen i == TotalBehaviors[id]
if (GetPlayerController(p) == MAP_CONTROL_USER and RequiredController[id][i] == BehaviorMapController(MAP_CONTROL_USER)) or /*
*/ (GetPlayerController(p) != MAP_CONTROL_USER and RequiredController[id][i] != BehaviorMapController(MAP_CONTROL_USER)) then
set b = UnitBehavior[id][i]
call b.onPeriod(u)
endif
set i = i + 1
endloop
if HasCustomOrders[id] then
call CustomOrder.runOrders(RegOrders[id])
endif
call GroupRemoveUnit(allUnits, u)
set u = null
set p = null
endloop
call DestroyGroup(allUnits)
set allUnits = null
endmethod
private static method initArrays takes nothing returns nothing
set OrderInCooldown = Boolean2D.create()
set OrderExecuted = Boolean1D.create()
set RegOrders = Integer1D.create()
set UnitBehavior = Integer2D.create()
set UnitTypeBehavior = Integer2D.create()
set RequiredController = Boolean2D.create()
set RequiredControllerType = Boolean2D.create()
set HasCustomOrders = Boolean1D.create()
set TotalBehaviors = Integer1D.create()
set TotalBehaviorsType = Integer1D.create()
endmethod
implement Init
private static method onInit takes nothing returns nothing
local trigger castEvent = CreateTrigger()
local trigger attackEvent = CreateTrigger()
local trigger damageEvent = CreateTrigger()
local trigger killEvent = CreateTrigger()
static if LIBRARY_RegisterPlayerUnitEvent then
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.registerCast)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED, function thistype.registerAttack)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.registerKill)
call DestroyTrigger(castEvent)
call DestroyTrigger(attackEvent)
call DestroyTrigger(killEvent)
else
call TriggerRegisterAnyUnitEventBJ(castEvent, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(castEvent, function thistype.registerCast)
call TriggerRegisterAnyUnitEventBJ(attackEvent, EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddCondition(attackEvent, function thistype.registerAttack)
call TriggerRegisterAnyUnitEventBJ(killEvent, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(killEvent, function thistype.registerKill)
endif
call TriggerRegisterVariableEvent(damageEvent, "udg_DamageEvent", EQUAL, 1.0)
call TriggerAddCondition(damageEvent, function thistype.registerDamage)
call TimerStart(thistype.loopTimer, PERIODIC_INTERVAL, true, function thistype.registerPeriod)
set castEvent = null
set attackEvent = null
set damageEvent = null
set killEvent = null
endmethod
endstruct
endlibrary
library GetDummy requires TimerUtils, WorldBounds
// Original library by Peppersawce, modified by Spellbound.
/*
API
set u = GetDummy(owner, abilId, level, x, y, duration)
Alternatively, if you need the dummy to be retrieved to face a certain point, you can use
set u = GetDummyAngled(owner, abilId, level, x, y, facing, duration)
*/
globals
private constant integer DummyId = 'n00G'
private integer AvailableDummy = 0
private group Dummies = CreateGroup()
private unit currentdummy = null
private constant player NEURTAL_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
endglobals
private struct AbilRemoval
integer ab
unit dummy
static method create takes unit dumdum, integer index returns AbilRemoval
local AbilRemoval abrem = AbilRemoval.allocate()
set abrem.dummy = dumdum
set abrem.ab = index
return abrem
endmethod
method destroy takes nothing returns nothing
set this.dummy = null
call this.deallocate()
endmethod
endstruct
private function RecycleDummy takes nothing returns nothing
local AbilRemoval abrem = GetTimerData(GetExpiredTimer())
call UnitRemoveAbility(abrem.dummy, abrem.ab)
if GetOwningPlayer(abrem.dummy) != NEURTAL_OWNER then
call SetUnitOwner(abrem.dummy, NEURTAL_OWNER, false)
endif
call GroupAddUnit(Dummies, abrem.dummy)
call SetUnitX(abrem.dummy, WorldBounds.minX)
call SetUnitY(abrem.dummy, WorldBounds.minY)
call PauseUnit(abrem.dummy, true)
call ShowUnit(abrem.dummy, false)
set AvailableDummy = AvailableDummy + 1
call ReleaseTimer(GetExpiredTimer())
call abrem.destroy()
endfunction
function GetDummy takes player owner, integer abilId, integer abillevel, real x, real y, real expiration returns unit
local AbilRemoval abrem
if AvailableDummy > 0 then
set AvailableDummy = AvailableDummy - 1
set currentdummy = BlzGroupUnitAt(Dummies, AvailableDummy)
call GroupRemoveUnit(Dummies, currentdummy)
if owner != NEURTAL_OWNER then
call SetUnitOwner(currentdummy, owner, false)
endif
call SetUnitX(currentdummy, x)
call SetUnitY(currentdummy, y)
call PauseUnit(currentdummy, false)
call ShowUnit(currentdummy, true)
else
set currentdummy = CreateUnit(owner, DummyId, x, y, bj_UNIT_FACING)
endif
call UnitAddAbility(currentdummy, abilId)
if abillevel > 1 then
call SetUnitAbilityLevel(currentdummy, abilId, abillevel)
endif
set abrem = AbilRemoval.create(currentdummy, abilId)
call TimerStart(NewTimerEx(abrem), expiration, false, function RecycleDummy)
return currentdummy
endfunction
function GetDummyAngled takes player owner, integer abilId, integer abillevel, real x, real y, real facing, real expiration returns unit
set currentdummy = GetDummy(owner, abilId, abillevel, x, y, expiration)
call BlzSetUnitFacingEx(currentdummy, facing)
return currentdummy
endfunction
endlibrary
library GetAttackDummy requires TimerUtils, WorldBounds
// Original library by Peppersawce, modified by Spellbound.
/*
API
set u = GetAttackDummy(owner, abilId, level, x, y, duration)
Alternatively, if you need the dummy to be retrieved to face a certain point, you can use
set u = GetAttackDummy(owner, abilId, level, x, y, facing, duration)
*/
globals
private constant integer DummyId = 'n009'
private integer AvailableDummy = 0
private group Dummies = CreateGroup()
private unit currentdummy = null
private constant player NEURTAL_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
endglobals
private struct AbilRemoval
integer ab
unit dummy
static method create takes unit dumdum, integer index returns AbilRemoval
local AbilRemoval abrem = AbilRemoval.allocate()
set abrem.dummy = dumdum
set abrem.ab = index
return abrem
endmethod
method destroy takes nothing returns nothing
set this.dummy = null
call this.deallocate()
endmethod
endstruct
private function RecycleDummy takes nothing returns nothing
local AbilRemoval abrem = GetTimerData(GetExpiredTimer())
call UnitRemoveAbility(abrem.dummy, 'Abun')
call UnitAddAbility(abrem.dummy, 'Abun')
if GetOwningPlayer(abrem.dummy) != NEURTAL_OWNER then
call SetUnitOwner(abrem.dummy, NEURTAL_OWNER, false)
endif
call GroupAddUnit(Dummies, abrem.dummy)
call SetUnitX(abrem.dummy, WorldBounds.minX)
call SetUnitY(abrem.dummy, WorldBounds.minY)
call PauseUnit(abrem.dummy, true)
call ShowUnit(abrem.dummy, false)
set AvailableDummy = AvailableDummy + 1
call ReleaseTimer(GetExpiredTimer())
call abrem.destroy()
endfunction
function GetAttackDummy takes player owner, integer abilId, integer abillevel, real x, real y, real expiration returns unit
local AbilRemoval abrem
if AvailableDummy > 0 then
set AvailableDummy = AvailableDummy - 1
set currentdummy = BlzGroupUnitAt(Dummies, AvailableDummy)
call GroupRemoveUnit(Dummies, currentdummy)
if owner != NEURTAL_OWNER then
call SetUnitOwner(currentdummy, owner, false)
endif
call SetUnitX(currentdummy, x)
call SetUnitY(currentdummy, y)
call PauseUnit(currentdummy, false)
call ShowUnit(currentdummy, true)
else
set currentdummy = CreateUnit(owner, DummyId, x, y, bj_UNIT_FACING)
endif
call UnitRemoveAbility(currentdummy, 'Abun')
call UnitAddAbility(currentdummy, abilId)
if abillevel > 1 then
call SetUnitAbilityLevel(currentdummy, abilId, abillevel)
endif
set abrem = AbilRemoval.create(currentdummy, abilId)
call TimerStart(NewTimerEx(abrem), expiration, false, function RecycleDummy)
return currentdummy
endfunction
function GetAttackDummyAngled takes player owner, integer abilId, integer abillevel, real x, real y, real facing, real expiration returns unit
set currentdummy = GetAttackDummy(owner, abilId, abillevel, x, y, expiration)
call BlzSetUnitFacingEx(currentdummy, facing)
return currentdummy
endfunction
endlibrary
library AIBCAdapterGUI requires AIBehaviorController
// Clear variables to avoid accidentally inserting old values into new Behaviors
private function ClearVariables takes nothing returns nothing
set udg_Event_Caster = null
set udg_Event_Attacker = null
set udg_Event_Source = null
set udg_Event_Target = null
set udg_Event_Killer = null
set udg_Event_Victim = null
set udg_Event_Unit = null
set udg_Event_Ally = null
set udg_Event_Enemy = null
set udg_Behavior_Unit = null
set udg_Behavior_UnitType = 0
set udg_Behavior_IsPlayerBehavior = false
set udg_Behavior_OnPeriod = null
set udg_Behavior_OnCast = null
set udg_Behavior_OnTargeted = null
set udg_Behavior_OnAttack = null
set udg_Behavior_OnAttacked = null
set udg_Behavior_OnDamageDealt = null
set udg_Behavior_OnDamageTaken = null
set udg_Behavior_OnKill = null
set udg_Behavior_OnAllyCasts = null
set udg_Behavior_OnAllyTargeted = null
set udg_Behavior_OnAllyAttacks = null
set udg_Behavior_OnAllyAttacked = null
set udg_Behavior_OnAllyDmgDealt = null
set udg_Behavior_OnAllyDmgTaken = null
set udg_Behavior_OnAllyKills = null
set udg_Behavior_OnAllyDeath = null
set udg_Behavior_OnEnemyCasts = null
set udg_Behavior_OnEnemyTargeted = null
set udg_Behavior_OnEnemyAttacks = null
set udg_Behavior_OnEnemyAttacked = null
set udg_Behavior_OnEnemyDmgDealt = null
set udg_Behavior_OnEnemyDmgTaken = null
set udg_Behavior_OnEnemyKills = null
set udg_Behavior_OnEnemyDeath = null
call RemoveLocation(udg_CustomO_Location)
set udg_CustomO_Unit = null
set udg_CustomO_Target = null
set udg_CustomO_Location = null
set udg_CustomO_Priority = 0
set udg_CustomO_Cooldown = 0
set udg_CustomO_ManaCost = 0
set udg_CustomO_IsInCooldown = false
endfunction
// Behavior Template
private struct NewB extends Behavior
private trigger OnPeriod
private trigger OnCast
private trigger OnTargeted
private trigger OnAttack
private trigger OnAttacked
private trigger OnDamageDealt
private trigger OnDamageTaken
private trigger OnKill
private trigger OnAllyCasts
private trigger OnAllyTargeted
private trigger OnAllyAttacks
private trigger OnAllyAttacked
private trigger OnAllyDmgDealt
private trigger OnAllyDmgTaken
private trigger OnAllyKills
private trigger OnAllyDeath
private trigger OnEnemyCasts
private trigger OnEnemyTargeted
private trigger OnEnemyAttacks
private trigger OnEnemyAttacked
private trigger OnEnemyDmgDealt
private trigger OnEnemyDmgTaken
private trigger OnEnemyKills
private trigger OnEnemyDeath
private method assignVariables takes nothing returns nothing
set .OnPeriod = udg_Behavior_OnPeriod
set .OnCast = udg_Behavior_OnCast
set .OnTargeted = udg_Behavior_OnTargeted
set .OnAttack = udg_Behavior_OnAttack
set .OnAttacked = udg_Behavior_OnAttacked
set .OnDamageDealt = udg_Behavior_OnDamageDealt
set .OnDamageTaken = udg_Behavior_OnDamageTaken
set .OnKill = udg_Behavior_OnKill
set .OnAllyCasts = udg_Behavior_OnAllyCasts
set .OnAllyTargeted = udg_Behavior_OnAllyTargeted
set .OnAllyAttacks = udg_Behavior_OnAllyAttacks
set .OnAllyAttacked = udg_Behavior_OnAllyAttacked
set .OnAllyDmgDealt = udg_Behavior_OnAllyDmgDealt
set .OnAllyDmgTaken = udg_Behavior_OnAllyDmgTaken
set .OnAllyKills = udg_Behavior_OnAllyKills
set .OnAllyDeath = udg_Behavior_OnAllyDeath
set .OnEnemyCasts = udg_Behavior_OnEnemyCasts
set .OnEnemyTargeted = udg_Behavior_OnEnemyTargeted
set .OnEnemyAttacks = udg_Behavior_OnEnemyAttacks
set .OnEnemyAttacked = udg_Behavior_OnEnemyAttacked
set .OnEnemyDmgDealt = udg_Behavior_OnEnemyDmgDealt
set .OnEnemyDmgTaken = udg_Behavior_OnEnemyDmgTaken
set .OnEnemyKills = udg_Behavior_OnEnemyKills
set .OnEnemyDeath = udg_Behavior_OnEnemyDeath
endmethod
method onPeriod takes unit u returns nothing
if .OnPeriod != null then
set udg_Event_Unit = u
if TriggerEvaluate(.OnPeriod) then
call TriggerExecute(.OnPeriod)
endif
endif
endmethod
method onCast takes unit caster, unit target returns nothing
if .OnCast != null then
set udg_Event_Caster = caster
set udg_Event_Target = target
if TriggerEvaluate(.OnCast) then
call TriggerExecute(.OnCast)
endif
endif
endmethod
method onTargeted takes unit target, unit caster returns nothing
if .OnTargeted != null then
set udg_Event_Target = target
set udg_Event_Caster = caster
if TriggerEvaluate(.OnTargeted) then
call TriggerExecute(.OnTargeted)
endif
endif
endmethod
method onAttack takes unit attacker, unit target returns nothing
if .OnAttack != null then
set udg_Event_Attacker = attacker
set udg_Event_Target = target
if TriggerEvaluate(.OnAttack) then
call TriggerExecute(.OnAttack)
endif
endif
endmethod
method onAttacked takes unit target, unit attacker returns nothing
if .OnAttacked != null then
set udg_Event_Target = target
set udg_Event_Attacker = attacker
if TriggerEvaluate(.OnAttacked) then
call TriggerExecute(.OnAttacked)
endif
endif
endmethod
method onDamageDealt takes unit source, unit target returns nothing
if .OnDamageDealt != null then
set udg_Event_Source = source
set udg_Event_Target = target
if TriggerEvaluate(.OnDamageDealt) then
call TriggerExecute(.OnDamageDealt)
endif
endif
endmethod
method onDamageTaken takes unit target, unit source returns nothing
if .OnDamageTaken != null then
set udg_Event_Target = target
set udg_Event_Source = source
if TriggerEvaluate(.OnDamageTaken) then
call TriggerExecute(.OnDamageTaken)
endif
endif
endmethod
method onKill takes unit killer, unit victim returns nothing
if .OnKill != null then
set udg_Event_Killer = killer
set udg_Event_Victim = victim
if TriggerEvaluate(.OnKill) then
call TriggerExecute(.OnKill)
endif
endif
endmethod
method onAllyCasts takes unit u, unit ally, unit target returns nothing
if .OnAllyCasts != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Target = target
if TriggerEvaluate(.OnAllyCasts) then
call TriggerExecute(.OnAllyCasts)
endif
endif
endmethod
method onAllyTargeted takes unit u, unit ally, unit caster returns nothing
if .OnAllyTargeted != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Caster = caster
if TriggerEvaluate(.OnAllyTargeted) then
call TriggerExecute(.OnAllyTargeted)
endif
endif
endmethod
method onAllyAttacks takes unit u, unit ally, unit target returns nothing
if .OnAllyAttacks != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Target = target
if TriggerEvaluate(.OnAllyAttacks) then
call TriggerExecute(.OnAllyAttacks)
endif
endif
endmethod
method onAllyAttacked takes unit u, unit ally, unit attacker returns nothing
if .OnAllyAttacked != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Attacker = attacker
if TriggerEvaluate(.OnAllyAttacked) then
call TriggerExecute(.OnAllyAttacked)
endif
endif
endmethod
method onAllyDmgDealt takes unit u, unit ally, unit target returns nothing
if .OnAllyDmgDealt != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Target = target
if TriggerEvaluate(.OnAllyDmgDealt) then
call TriggerExecute(.OnAllyDmgDealt)
endif
endif
endmethod
method onAllyDmgTaken takes unit u, unit ally, unit source returns nothing
if .OnAllyDmgTaken != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Source = source
if TriggerEvaluate(.OnAllyDmgTaken) then
call TriggerExecute(.OnAllyDmgTaken)
endif
endif
endmethod
method onAllyKills takes unit u, unit ally, unit victim returns nothing
if .OnAllyKills != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Victim = victim
if TriggerEvaluate(.OnAllyKills) then
call TriggerExecute(.OnAllyKills)
endif
endif
endmethod
method onAllyDeath takes unit u, unit ally, unit killer returns nothing
if .OnAllyDeath != null then
set udg_Event_Unit = u
set udg_Event_Ally = ally
set udg_Event_Killer = killer
if TriggerEvaluate(.OnAllyDeath) then
call TriggerExecute(.OnAllyDeath)
endif
endif
endmethod
method onEnemyCasts takes unit u, unit enemy, unit target returns nothing
if .OnEnemyCasts != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Target = target
if TriggerEvaluate(.OnEnemyCasts) then
call TriggerExecute(.OnEnemyCasts)
endif
endif
endmethod
method onEnemyTargeted takes unit u, unit enemy, unit caster returns nothing
if .OnEnemyTargeted != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Caster = caster
if TriggerEvaluate(.OnEnemyTargeted) then
call TriggerExecute(.OnEnemyTargeted)
endif
endif
endmethod
method onEnemyAttacks takes unit u, unit enemy, unit target returns nothing
if .OnEnemyAttacks != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Target = target
if TriggerEvaluate(.OnEnemyAttacks) then
call TriggerExecute(.OnEnemyAttacks)
endif
endif
endmethod
method onEnemyAttacked takes unit u, unit enemy, unit attacker returns nothing
if .OnEnemyAttacked != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Attacker = attacker
if TriggerEvaluate(.OnEnemyAttacked) then
call TriggerExecute(.OnEnemyAttacked)
endif
endif
endmethod
method onEnemyDmgDealt takes unit u, unit enemy, unit target returns nothing
if .OnEnemyDmgDealt != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Target = target
if TriggerEvaluate(.OnEnemyDmgDealt) then
call TriggerExecute(.OnEnemyDmgDealt)
endif
endif
endmethod
method onEnemyDmgTaken takes unit u, unit enemy, unit source returns nothing
if .OnEnemyDmgTaken != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Source = source
if TriggerEvaluate(.OnEnemyDmgTaken) then
call TriggerExecute(.OnEnemyDmgTaken)
endif
endif
endmethod
method onEnemyKills takes unit u, unit enemy, unit victim returns nothing
if .OnEnemyKills != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Victim = victim
if TriggerEvaluate(.OnEnemyKills) then
call TriggerExecute(.OnEnemyKills)
endif
endif
endmethod
method onEnemyDeath takes unit u, unit enemy, unit killer returns nothing
if .OnEnemyDeath != null then
set udg_Event_Unit = u
set udg_Event_Enemy = enemy
set udg_Event_Killer = killer
if TriggerEvaluate(.OnEnemyDeath) then
call TriggerExecute(.OnEnemyDeath)
endif
endif
endmethod
static method attach takes unit u, boolean isUserBehavior returns nothing
local NewB b = NewB.create()
call b.assignVariables()
call Controller.registerBehavior(u, b, isUserBehavior)
endmethod
static method attachType takes integer uTypeId, boolean isUserBehavior returns nothing
local NewB b = NewB.create()
call b.assignVariables()
call Controller.registerBehaviorType(uTypeId, b, isUserBehavior)
endmethod
endstruct
function AIBC_GUI_RegisterBehavior takes boolean isUnitType returns nothing
if isUnitType then
call NewB.attachType(udg_Behavior_UnitType, udg_Behavior_IsPlayerBehavior)
else
call NewB.attach(udg_Behavior_Unit, udg_Behavior_IsPlayerBehavior)
endif
call ClearVariables()
endfunction
endlibrary
library FootmanExample requires AIBehaviorController
// Defining a new Behavior
private struct Footman extends Behavior
// This event will fire when the Footman deals damage
method onDamageDealt takes unit source, unit target returns nothing
local unit u = source
local CustomOrder o = CustomOrder.create(u)
call o.registerTargetOrder("thunderbolt", target, 10, 7, 0)
set u = null
endmethod
// This event will fire when a nearby enemy attacks
method onEnemyAttacks takes unit u, unit enemy, unit target returns nothing
local CustomOrder o = CustomOrder.create(u)
// If the enemy unit is a Necromancer, the order will be registered
if GetUnitTypeId(enemy) == 'unec' then
call o.registerTargetOrder("thunderbolt", enemy, 20, 7, 0)
endif
endmethod
// Creating the behavior and attaching it to all units of this type
private static method onInit takes nothing returns nothing
local Behavior b = Footman.create()
call Controller.registerBehaviorType('hfoo', b)
endmethod
endstruct
endlibrary
library KnightExample requires AIBehaviorController
// Defining a new Behavior
private struct Knight extends Behavior
// This one will fire when the Knight attacks another unit
method onAttack takes unit attacker, unit target returns nothing
local unit u = attacker
local CustomOrder o = CustomOrder.create(u)
call o.registerInstantOrder("berserk", 10, 12, 0)
set u = null
endmethod
// Creating the behavior and attaching it to all units of this type
private static method onInit takes nothing returns nothing
local Behavior b = Knight.create()
call Controller.registerBehaviorType('hkni', b)
endmethod
endstruct
endlibrary
library RiflemanExample requires AIBehaviorController
// Defining a new Behavior
private struct Rifleman extends Behavior
// This event will fire when a Rifleman is attacked
method onAttacked takes unit target, unit attacker returns nothing
local unit u = target
local CustomOrder o = CustomOrder.create(u)
// If the attacker unit is an Abomination or Death Knight, the order will be registered
if GetUnitTypeId(attacker) == 'uabo' or GetUnitTypeId(attacker) == 'Udea' then
call o.registerInstantOrder("bearform", 30, 0, 0)
endif
set u = null
endmethod
// Creating the behavior and attaching it to all units of this type
private static method onInit takes nothing returns nothing
local Behavior b = Rifleman.create()
call Controller.registerBehaviorType('hrif', b)
endmethod
endstruct
endlibrary
library SorceressExample requires AIBehaviorController
// Defining the first Behavior
private struct Sorceress1 extends Behavior
// This one will fire when the Sorceress attacks another unit
method onAttack takes unit attacker, unit target returns nothing
local unit u = attacker
local CustomOrder o = CustomOrder.create(u)
// Registering 2 orders inside the same event. In this case, the order that will be used first will be the one with higher priority if not in cooldown
call o.registerTargetOrderById(852274, attacker, 30, 15, 50)
call o.registerTargetOrder("shockwave", target, 20, 10, 100)
set u = null
endmethod
// Creating the behavior and attaching it to all units of this type
private static method onInit takes nothing returns nothing
local Behavior b = Sorceress1.create()
call Controller.registerBehaviorType('hsor', b)
endmethod
endstruct
// Defining a second Behavior
private struct Sorceress2 extends Behavior
// Using an event fired by a nearby enemy unit. In this case, it will run when an enemy unit uses an ability
method onEnemyCasts takes unit u, unit enemy, unit target returns nothing
local CustomOrder o = CustomOrder.create(u)
// Checking if the enemy unit is a Necromancer
if GetUnitTypeId(enemy) == 'unec' then
call o.registerTargetOrder("frostnova", enemy, 30, 8, 75)
endif
endmethod
// Adding a second event to the Behavior. This one will run when a nearby enemy attacks another unit
method onEnemyAttacks takes unit u, unit enemy, unit attacker returns nothing
local CustomOrder o = CustomOrder.create(u)
// Checking if the enemy unit is a Necromancer
if GetUnitTypeId(enemy) == 'unec' then
call o.registerTargetOrder("frostnova", enemy, 30, 8, 75)
endif
endmethod
// Creating the behavior and attaching it to all units of this type
private static method onInit takes nothing returns nothing
local Behavior b = Sorceress2.create()
call Controller.registerBehaviorType('hsor', b)
endmethod
endstruct
endlibrary
library PaladinExample requires AIBehaviorController
// Defining a new Behavior
private struct Paladin extends Behavior
// Using an event fired by a nearby friendly unit.
method onAllyAttacked takes unit u, unit ally, unit attacker returns nothing
local CustomOrder o = CustomOrder.create(u)
if GetUnitStatePercent(ally, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE) <= 50. then
call o.registerTargetOrder("holybolt", ally, 30, 5, 60)
endif
endmethod
method onAllyAttacks takes unit u, unit ally, unit target returns nothing
local CustomOrder o = CustomOrder.create(u)
if not UnitHasBuffBJ(ally, 'Binf') then
call o.registerTargetOrder("innerfire", ally, 20, 3, 35)
endif
endmethod
method onAttack takes unit attacker, unit target returns nothing
local unit u = attacker
local CustomOrder o = CustomOrder.create(u)
if not UnitHasBuffBJ(attacker, 'Binf') then
call o.registerTargetOrder("innerfire", attacker, 15, 3, 35)
endif
set u = null
endmethod
// Creating the behavior and attaching it to all units of this type
private static method onInit takes nothing returns nothing
local Behavior b = Paladin.create()
call Controller.registerBehaviorType('Hpal', b)
endmethod
endstruct
endlibrary
library PaladinSpc requires AIBehaviorController
// This will be a more complex example. Here I will define 4 custom behaviors for 4 different Paladins
// Each Paladin will only use the Behavior that will be asigned to him
// If combined with the example above, all Paladins will have 2 custom Behaviors (Individual and Unit Type)
// Northwest Paladin
private struct PaladinNW extends Behavior
method onAttack takes unit attacker, unit target returns nothing
local unit u = attacker
local CustomOrder o = CustomOrder.create(u)
call o.registerTargetOrder("acidbomb", target, 25, 12, 75)
set u = null
endmethod
// Creating the behavior and attaching it to an specific Paladin
// Unlike the behaviors assigned to an Unit Type, the behaviors attached to an individual unit
// must be registered after all units have been indexed, so that custom values are available
private static method register takes nothing returns nothing
local Behavior b = PaladinNW.create()
call Controller.registerBehavior(gg_unit_Hpal_0038, b)
endmethod
// Once all the units are indexed, the behavior will be registered
private static method onInit takes nothing returns nothing
call OnUnitIndexerInitialized(function thistype.register)
endmethod
endstruct
// Northeast Paladin
private struct PaladinNE extends Behavior
method onAttacked takes unit target, unit attacker returns nothing
local unit u = target
local CustomOrder o = CustomOrder.create(u)
call o.registerInstantOrder("divineshield", 30, 25, 50)
set u = null
endmethod
private static method register takes nothing returns nothing
local Behavior b = PaladinNE.create()
call Controller.registerBehavior(gg_unit_Hpal_0037, b)
endmethod
private static method onInit takes nothing returns nothing
call OnUnitIndexerInitialized(function thistype.register)
endmethod
endstruct
// Southwest Paladin
private struct PaladinSW extends Behavior
method onEnemyCasts takes unit u, unit enemy, unit target returns nothing
local CustomOrder o = CustomOrder.create(u)
if GetUnitTypeId(enemy) == 'Udea' then
call o.registerTargetOrder("soulburn", enemy, 20, 12, 85)
endif
endmethod
method onEnemyAttacks takes unit u, unit enemy, unit target returns nothing
local CustomOrder o = CustomOrder.create(u)
if GetUnitTypeId(enemy) == 'Udea' then
call o.registerTargetOrder("soulburn", enemy, 20, 12, 85)
endif
endmethod
private static method register takes nothing returns nothing
local Behavior b = PaladinSW.create()
call Controller.registerBehavior(gg_unit_Hpal_0041, b)
endmethod
private static method onInit takes nothing returns nothing
call OnUnitIndexerInitialized(function thistype.register)
endmethod
endstruct
// Southeast Paladin
private struct PaladinSE extends Behavior
method onAllyAttacked takes unit u, unit ally, unit attacker returns nothing
local CustomOrder o = CustomOrder.create(u)
if GetUnitStatePercent(ally, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE) <= 70. then
call o.registerTargetOrder("healingwave", ally, 25, 9, 90)
endif
endmethod
private static method register takes nothing returns nothing
local Behavior b = PaladinSE.create()
call Controller.registerBehavior(gg_unit_Hpal_0046, b)
endmethod
private static method onInit takes nothing returns nothing
call OnUnitIndexerInitialized(function thistype.register)
endmethod
endstruct
endlibrary
globals
framehandle RaceInfoBackdrop = null
trigger TriggerRaceInfoBackdrop = null
framehandle RaceSelectionBackdrop = null
trigger TriggerRaceSelectionBackdrop = null
framehandle PlayerNumber = null
trigger TriggerPlayerNumber = null
framehandle RaceName = null
trigger TriggerRaceName = null
framehandle ButtonConfirm = null
trigger TriggerButtonConfirm = null
framehandle RaceCrestImageBackdrop = null
trigger TriggerRaceCrestImageBackdrop = null
framehandle RaceTextInfo = null
trigger TriggerRaceTextInfo = null
framehandle CrestImage = null
trigger TriggerCrestImage = null
framehandle RacialUniques00 = null
framehandle BackdropRacialUniques00 = null
trigger TriggerRacialUniques00 = null
framehandle RacialUniques01 = null
framehandle BackdropRacialUniques01 = null
trigger TriggerRacialUniques01 = null
framehandle RacialUniques02 = null
framehandle BackdropRacialUniques02 = null
trigger TriggerRacialUniques02 = null
framehandle RacialUniques03 = null
framehandle BackdropRacialUniques03 = null
trigger TriggerRacialUniques03 = null
framehandle RacialUniques04 = null
framehandle BackdropRacialUniques04 = null
trigger TriggerRacialUniques04 = null
framehandle RacialUniques05 = null
framehandle BackdropRacialUniques05 = null
trigger TriggerRacialUniques05 = null
framehandle RacialUniques = null
trigger TriggerRacialUniques = null
framehandle RaceInfoReturn = null
trigger TriggerRaceInfoReturn = null
framehandle array RaceButtonsT
trigger array TriggerRaceButtonsT
framehandle RaceSelectionText = null
trigger TriggerRaceSelectionText = null
framehandle RandomVanilla = null
trigger TriggerRandomVanilla = null
framehandle RandomCustom = null
trigger TriggerRandomCustom = null
framehandle BackdropSemiTrans049 = null
trigger TriggerBackdropSemiTrans049 = null
framehandle BackdropSemiTrans058 = null
trigger TriggerBackdropSemiTrans058 = null
endglobals
library RaceChoice initializer init
function ButtonConfirmFunc takes nothing returns nothing
call BlzFrameSetEnable(ButtonConfirm, false)
call BlzFrameSetEnable(ButtonConfirm, true)
set udg_ConfirmChoice = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RacialUniques00Func takes nothing returns nothing
call BlzFrameSetEnable(RacialUniques00, false)
call BlzFrameSetEnable(RacialUniques00, true)
set udg_RacialUniques00 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RacialUniques01Func takes nothing returns nothing
call BlzFrameSetEnable(RacialUniques01, false)
call BlzFrameSetEnable(RacialUniques01, true)
set udg_RacialUniques01 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RacialUniques02Func takes nothing returns nothing
call BlzFrameSetEnable(RacialUniques02, false)
call BlzFrameSetEnable(RacialUniques02, true)
set udg_RacialUniques02 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RacialUniques03Func takes nothing returns nothing
call BlzFrameSetEnable(RacialUniques03, false)
call BlzFrameSetEnable(RacialUniques03, true)
set udg_RacialUniques03 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RacialUniques04Func takes nothing returns nothing
call BlzFrameSetEnable(RacialUniques04, false)
call BlzFrameSetEnable(RacialUniques04, true)
set udg_RacialUniques04 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RacialUniques05Func takes nothing returns nothing
call BlzFrameSetEnable(RacialUniques05, false)
call BlzFrameSetEnable(RacialUniques05, true)
set udg_RacialUniques05 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceInfoReturnFunc takes nothing returns nothing
call BlzFrameSetEnable(RaceInfoReturn, false)
call BlzFrameSetEnable(RaceInfoReturn, true)
set udg_RaceInfoReturn = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT00Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[0], false)
call BlzFrameSetEnable(RaceButtonsT[0], true)
set udg_RaceHumans = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT01Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[1], false)
call BlzFrameSetEnable(RaceButtonsT[1], true)
set udg_RaceOrcs = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT02Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[2], false)
call BlzFrameSetEnable(RaceButtonsT[2], true)
set udg_RaceNightElves = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT03Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[3], false)
call BlzFrameSetEnable(RaceButtonsT[3], true)
set udg_RaceUndeadScourge = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT04Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[4], false)
call BlzFrameSetEnable(RaceButtonsT[4], true)
set udg_RaceLivingNerubian = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT05Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[5], false)
call BlzFrameSetEnable(RaceButtonsT[5], true)
set udg_RaceUndeadNerubian = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT06Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[6], false)
call BlzFrameSetEnable(RaceButtonsT[6], true)
set udg_RaceFacelessOnes = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT07Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[7], false)
call BlzFrameSetEnable(RaceButtonsT[7], true)
set udg_RaceQiraji = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT08Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[8], false)
call BlzFrameSetEnable(RaceButtonsT[8], true)
set udg_RaceIceTrolls = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT09Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[9], false)
call BlzFrameSetEnable(RaceButtonsT[9], true)
set udg_RaceWildhammerClan = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT10Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[10], false)
call BlzFrameSetEnable(RaceButtonsT[10], true)
set udg_RaceBronzebeardClan = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT11Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[11], false)
call BlzFrameSetEnable(RaceButtonsT[11], true)
set udg_RaceDarkIronClan = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT12Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[12], false)
call BlzFrameSetEnable(RaceButtonsT[12], true)
set udg_RaceFelbloodElves = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT13Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[13], false)
call BlzFrameSetEnable(RaceButtonsT[13], true)
set udg_RaceVoidElves = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT14Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[14], false)
call BlzFrameSetEnable(RaceButtonsT[14], true)
set udg_RaceFelHorde = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT15Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[15], false)
call BlzFrameSetEnable(RaceButtonsT[15], true)
set udg_RaceDarkHorde = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT16Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[16], false)
call BlzFrameSetEnable(RaceButtonsT[16], true)
set udg_RaceExodarDraenei = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT17Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[17], false)
call BlzFrameSetEnable(RaceButtonsT[17], true)
set udg_RaceLightforgedDraenei = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT18Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[18], false)
call BlzFrameSetEnable(RaceButtonsT[18], true)
set udg_RaceNightborne = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT19Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[19], false)
call BlzFrameSetEnable(RaceButtonsT[19], true)
set udg_RaceIllidari = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT20Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[20], false)
call BlzFrameSetEnable(RaceButtonsT[20], true)
set udg_RaceScarletCrusade = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT21Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[21], false)
call BlzFrameSetEnable(RaceButtonsT[21], true)
set udg_RaceForsaken = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT22Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[22], false)
call BlzFrameSetEnable(RaceButtonsT[22], true)
set udg_RaceDalaran = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT23Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[23], false)
call BlzFrameSetEnable(RaceButtonsT[23], true)
set udg_RaceHighElves = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RaceButtonsT24Func takes nothing returns nothing
call BlzFrameSetEnable(RaceButtonsT[24], false)
call BlzFrameSetEnable(RaceButtonsT[24], true)
set udg_RaceLostOnes = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RandomVanillaFunc takes nothing returns nothing
call BlzFrameSetEnable(RandomVanilla, false)
call BlzFrameSetEnable(RandomVanilla, true)
set udg_RandomRaceAll = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function RandomCustomFunc takes nothing returns nothing
call BlzFrameSetEnable(RandomCustom, false)
call BlzFrameSetEnable(RandomCustom, true)
set udg_RandomRaceCustom = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
private function init takes nothing returns nothing
call BlzHideOriginFrames(true)
call BlzFrameSetSize(BlzGetFrameByName("ConsoleUIBackdrop",0), 0, 0.0001)
call BlzLoadTOCFile("WARTOC.toc")
set RaceInfoBackdrop = BlzCreateFrame("CheckListBox", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(RaceInfoBackdrop, FRAMEPOINT_TOPLEFT, 0.362450, 0.549350)
call BlzFrameSetAbsPoint(RaceInfoBackdrop, FRAMEPOINT_BOTTOMRIGHT, 0.797970, 0.153060)
set RaceSelectionBackdrop = BlzCreateFrame("CheckListBox", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(RaceSelectionBackdrop, FRAMEPOINT_TOPLEFT, 0.0105500, 0.549830)
call BlzFrameSetAbsPoint(RaceSelectionBackdrop, FRAMEPOINT_BOTTOMRIGHT, 0.347220, 0.108410)
set PlayerNumber = BlzCreateFrameByType("TEXT", "name", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
call BlzFrameSetAbsPoint(PlayerNumber, FRAMEPOINT_TOPLEFT, 0.625560, 0.145740)
call BlzFrameSetAbsPoint(PlayerNumber, FRAMEPOINT_BOTTOMRIGHT, 0.776920, 0.115700)
call BlzFrameSetText(PlayerNumber, "|cffFFCC00TextFrametesting|r")
call BlzFrameSetEnable(PlayerNumber, false)
call BlzFrameSetScale(PlayerNumber, 1.00)
call BlzFrameSetTextAlignment(PlayerNumber, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set RaceName = BlzCreateFrameByType("TEXT", "name", RaceInfoBackdrop, "", 0)
call BlzFrameSetAbsPoint(RaceName, FRAMEPOINT_TOPLEFT, 0.503590, 0.524300)
call BlzFrameSetAbsPoint(RaceName, FRAMEPOINT_BOTTOMRIGHT, 0.768140, 0.499810)
call BlzFrameSetText(RaceName, "|cfff0efea[Race Name]|r")
call BlzFrameSetEnable(RaceName, false)
call BlzFrameSetScale(RaceName, 1.29)
call BlzFrameSetTextAlignment(RaceName, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set ButtonConfirm = BlzCreateFrame("ScriptDialogButton", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(ButtonConfirm, FRAMEPOINT_TOPLEFT, 0.667890, 0.220910)
call BlzFrameSetAbsPoint(ButtonConfirm, FRAMEPOINT_BOTTOMRIGHT, 0.774820, 0.188070)
call BlzFrameSetText(ButtonConfirm, "|cffFCD20DConfirm Choice|r")
call BlzFrameSetScale(ButtonConfirm, 0.715)
set TriggerButtonConfirm = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerButtonConfirm, ButtonConfirm, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerButtonConfirm, function ButtonConfirmFunc)
set RaceCrestImageBackdrop = BlzCreateFrame("CheckListBox", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceCrestImageBackdrop, FRAMEPOINT_TOPLEFT, 0.389420, 0.525790)
call BlzFrameSetAbsPoint(RaceCrestImageBackdrop, FRAMEPOINT_BOTTOMRIGHT, 0.489420, 0.425790)
set RaceTextInfo = BlzCreateFrameByType("TEXTAREA", "name", RaceInfoBackdrop, "", 0)
call BlzFrameSetAbsPoint(RaceTextInfo, FRAMEPOINT_TOPLEFT, 0.506380, 0.496540)
call BlzFrameSetAbsPoint(RaceTextInfo, FRAMEPOINT_BOTTOMRIGHT, 0.770380, 0.231050)
call BlzFrameSetText(RaceTextInfo, "|cffffffffrace info|r")
set CrestImage = BlzCreateFrameByType("BACKDROP", "BACKDROP", RaceInfoBackdrop, "", 1)
call BlzFrameSetAbsPoint(CrestImage, FRAMEPOINT_TOPLEFT, 0.392370, 0.525070)
call BlzFrameSetAbsPoint(CrestImage, FRAMEPOINT_BOTTOMRIGHT, 0.490920, 0.429030)
call BlzFrameSetTexture(CrestImage, "CustomFrame.png", 0, true)
set RacialUniques00 = BlzCreateFrame("IconButtonTemplate", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RacialUniques00, FRAMEPOINT_TOPLEFT, 0.390350, 0.405650)
call BlzFrameSetAbsPoint(RacialUniques00, FRAMEPOINT_BOTTOMRIGHT, 0.420350, 0.375650)
set BackdropRacialUniques00 = BlzCreateFrameByType("BACKDROP", "BackdropRacialUniques00", RacialUniques00, "", 0)
call BlzFrameSetAllPoints(BackdropRacialUniques00, RacialUniques00)
call BlzFrameSetTexture(BackdropRacialUniques00, "CustomFrame.png", 0, true)
set TriggerRacialUniques00 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRacialUniques00, RacialUniques00, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRacialUniques00, function RacialUniques00Func)
set RacialUniques01 = BlzCreateFrame("IconButtonTemplate", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RacialUniques01, FRAMEPOINT_TOPLEFT, 0.424270, 0.405650)
call BlzFrameSetAbsPoint(RacialUniques01, FRAMEPOINT_BOTTOMRIGHT, 0.454270, 0.375650)
set BackdropRacialUniques01 = BlzCreateFrameByType("BACKDROP", "BackdropRacialUniques01", RacialUniques01, "", 0)
call BlzFrameSetAllPoints(BackdropRacialUniques01, RacialUniques01)
call BlzFrameSetTexture(BackdropRacialUniques01, "CustomFrame.png", 0, true)
set TriggerRacialUniques01 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRacialUniques01, RacialUniques01, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRacialUniques01, function RacialUniques01Func)
set RacialUniques02 = BlzCreateFrame("IconButtonTemplate", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RacialUniques02, FRAMEPOINT_TOPLEFT, 0.458910, 0.405650)
call BlzFrameSetAbsPoint(RacialUniques02, FRAMEPOINT_BOTTOMRIGHT, 0.488910, 0.375650)
set BackdropRacialUniques02 = BlzCreateFrameByType("BACKDROP", "BackdropRacialUniques02", RacialUniques02, "", 0)
call BlzFrameSetAllPoints(BackdropRacialUniques02, RacialUniques02)
call BlzFrameSetTexture(BackdropRacialUniques02, "CustomFrame.png", 0, true)
set TriggerRacialUniques02 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRacialUniques02, RacialUniques02, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRacialUniques02, function RacialUniques02Func)
set RacialUniques03 = BlzCreateFrame("IconButtonTemplate", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RacialUniques03, FRAMEPOINT_TOPLEFT, 0.390350, 0.371470)
call BlzFrameSetAbsPoint(RacialUniques03, FRAMEPOINT_BOTTOMRIGHT, 0.420350, 0.341470)
set BackdropRacialUniques03 = BlzCreateFrameByType("BACKDROP", "BackdropRacialUniques03", RacialUniques03, "", 0)
call BlzFrameSetAllPoints(BackdropRacialUniques03, RacialUniques03)
call BlzFrameSetTexture(BackdropRacialUniques03, "CustomFrame.png", 0, true)
set TriggerRacialUniques03 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRacialUniques03, RacialUniques03, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRacialUniques03, function RacialUniques03Func)
set RacialUniques04 = BlzCreateFrame("IconButtonTemplate", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RacialUniques04, FRAMEPOINT_TOPLEFT, 0.424480, 0.371470)
call BlzFrameSetAbsPoint(RacialUniques04, FRAMEPOINT_BOTTOMRIGHT, 0.454480, 0.341470)
set BackdropRacialUniques04 = BlzCreateFrameByType("BACKDROP", "BackdropRacialUniques04", RacialUniques04, "", 0)
call BlzFrameSetAllPoints(BackdropRacialUniques04, RacialUniques04)
call BlzFrameSetTexture(BackdropRacialUniques04, "CustomFrame.png", 0, true)
set TriggerRacialUniques04 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRacialUniques04, RacialUniques04, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRacialUniques04, function RacialUniques04Func)
set RacialUniques05 = BlzCreateFrame("IconButtonTemplate", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RacialUniques05, FRAMEPOINT_TOPLEFT, 0.458700, 0.371470)
call BlzFrameSetAbsPoint(RacialUniques05, FRAMEPOINT_BOTTOMRIGHT, 0.488700, 0.341470)
set BackdropRacialUniques05 = BlzCreateFrameByType("BACKDROP", "BackdropRacialUniques05", RacialUniques05, "", 0)
call BlzFrameSetAllPoints(BackdropRacialUniques05, RacialUniques05)
call BlzFrameSetTexture(BackdropRacialUniques05, "CustomFrame.png", 0, true)
set TriggerRacialUniques05 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRacialUniques05, RacialUniques05, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRacialUniques05, function RacialUniques05Func)
set RacialUniques = BlzCreateFrameByType("TEXT", "name", RaceInfoBackdrop, "", 0)
call BlzFrameSetAbsPoint(RacialUniques, FRAMEPOINT_TOPLEFT, 0.391420, 0.422200)
call BlzFrameSetAbsPoint(RacialUniques, FRAMEPOINT_BOTTOMRIGHT, 0.489440, 0.408110)
call BlzFrameSetText(RacialUniques, "|cffFFCC00Racial Uniques|r")
call BlzFrameSetEnable(RacialUniques, false)
call BlzFrameSetScale(RacialUniques, 1.00)
call BlzFrameSetTextAlignment(RacialUniques, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set RaceInfoReturn = BlzCreateFrame("ScriptDialogButton", RaceInfoBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceInfoReturn, FRAMEPOINT_TOPLEFT, 0.397220, 0.337180)
call BlzFrameSetAbsPoint(RaceInfoReturn, FRAMEPOINT_BOTTOMRIGHT, 0.482990, 0.318110)
call BlzFrameSetText(RaceInfoReturn, "|cffFCD20DRace Info|r")
call BlzFrameSetScale(RaceInfoReturn, 0.715)
set TriggerRaceInfoReturn = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceInfoReturn, RaceInfoReturn, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceInfoReturn, function RaceInfoReturnFunc)
set RaceButtonsT[0] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[0], FRAMEPOINT_TOPLEFT, 0.0230000, 0.508120)
call BlzFrameSetAbsPoint(RaceButtonsT[0], FRAMEPOINT_BOTTOMRIGHT, 0.126590, 0.479180)
call BlzFrameSetText(RaceButtonsT[0], "|cffFCD20DHuman Alliance|r")
call BlzFrameSetScale(RaceButtonsT[0], 0.572)
set TriggerRaceButtonsT[0] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[0], RaceButtonsT[0], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[0], function RaceButtonsT00Func)
set RaceButtonsT[1] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[1], FRAMEPOINT_TOPLEFT, 0.126590, 0.508120)
call BlzFrameSetAbsPoint(RaceButtonsT[1], FRAMEPOINT_BOTTOMRIGHT, 0.230180, 0.479180)
call BlzFrameSetText(RaceButtonsT[1], "|cffFCD20DOrcish Horde|r")
call BlzFrameSetScale(RaceButtonsT[1], 0.572)
set TriggerRaceButtonsT[1] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[1], RaceButtonsT[1], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[1], function RaceButtonsT01Func)
set RaceButtonsT[2] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[2], FRAMEPOINT_TOPLEFT, 0.230180, 0.508120)
call BlzFrameSetAbsPoint(RaceButtonsT[2], FRAMEPOINT_BOTTOMRIGHT, 0.333770, 0.479180)
call BlzFrameSetText(RaceButtonsT[2], "|cffFCD20DNight Elves|r")
call BlzFrameSetScale(RaceButtonsT[2], 0.572)
set TriggerRaceButtonsT[2] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[2], RaceButtonsT[2], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[2], function RaceButtonsT02Func)
set RaceButtonsT[3] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[3], FRAMEPOINT_TOPLEFT, 0.0235000, 0.469710)
call BlzFrameSetAbsPoint(RaceButtonsT[3], FRAMEPOINT_BOTTOMRIGHT, 0.127090, 0.440770)
call BlzFrameSetText(RaceButtonsT[3], "|cffFCD20DUndead Scourge|r")
call BlzFrameSetScale(RaceButtonsT[3], 0.572)
set TriggerRaceButtonsT[3] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[3], RaceButtonsT[3], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[3], function RaceButtonsT03Func)
set RaceButtonsT[4] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[4], FRAMEPOINT_TOPLEFT, 0.127090, 0.469710)
call BlzFrameSetAbsPoint(RaceButtonsT[4], FRAMEPOINT_BOTTOMRIGHT, 0.230680, 0.440770)
call BlzFrameSetText(RaceButtonsT[4], "|cffFCD20DLiving Nerubian|r")
call BlzFrameSetScale(RaceButtonsT[4], 0.572)
set TriggerRaceButtonsT[4] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[4], RaceButtonsT[4], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[4], function RaceButtonsT04Func)
set RaceButtonsT[5] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[5], FRAMEPOINT_TOPLEFT, 0.231800, 0.469710)
call BlzFrameSetAbsPoint(RaceButtonsT[5], FRAMEPOINT_BOTTOMRIGHT, 0.335390, 0.440770)
call BlzFrameSetText(RaceButtonsT[5], "|cffFCD20DUndead Nerubian|r")
call BlzFrameSetScale(RaceButtonsT[5], 0.572)
set TriggerRaceButtonsT[5] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[5], RaceButtonsT[5], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[5], function RaceButtonsT05Func)
set RaceButtonsT[6] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[6], FRAMEPOINT_TOPLEFT, 0.0230000, 0.430240)
call BlzFrameSetAbsPoint(RaceButtonsT[6], FRAMEPOINT_BOTTOMRIGHT, 0.126590, 0.401300)
call BlzFrameSetText(RaceButtonsT[6], "|cffFCD20DFaceless Ones|r")
call BlzFrameSetScale(RaceButtonsT[6], 0.572)
set TriggerRaceButtonsT[6] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[6], RaceButtonsT[6], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[6], function RaceButtonsT06Func)
set RaceButtonsT[7] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[7], FRAMEPOINT_TOPLEFT, 0.126590, 0.430240)
call BlzFrameSetAbsPoint(RaceButtonsT[7], FRAMEPOINT_BOTTOMRIGHT, 0.230180, 0.401300)
call BlzFrameSetText(RaceButtonsT[7], "|cffFCD20DQiraji|r")
call BlzFrameSetScale(RaceButtonsT[7], 0.572)
set TriggerRaceButtonsT[7] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[7], RaceButtonsT[7], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[7], function RaceButtonsT07Func)
set RaceButtonsT[8] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[8], FRAMEPOINT_TOPLEFT, 0.230180, 0.430240)
call BlzFrameSetAbsPoint(RaceButtonsT[8], FRAMEPOINT_BOTTOMRIGHT, 0.333770, 0.401300)
call BlzFrameSetText(RaceButtonsT[8], "|cffFCD20DIce Trolls|r")
call BlzFrameSetScale(RaceButtonsT[8], 0.572)
set TriggerRaceButtonsT[8] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[8], RaceButtonsT[8], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[8], function RaceButtonsT08Func)
set RaceButtonsT[9] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[9], FRAMEPOINT_TOPLEFT, 0.0229400, 0.391790)
call BlzFrameSetAbsPoint(RaceButtonsT[9], FRAMEPOINT_BOTTOMRIGHT, 0.126530, 0.362850)
call BlzFrameSetText(RaceButtonsT[9], "|cffFCD20DWildhammer Clan|r")
call BlzFrameSetScale(RaceButtonsT[9], 0.572)
set TriggerRaceButtonsT[9] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[9], RaceButtonsT[9], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[9], function RaceButtonsT09Func)
set RaceButtonsT[10] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[10], FRAMEPOINT_TOPLEFT, 0.126590, 0.391300)
call BlzFrameSetAbsPoint(RaceButtonsT[10], FRAMEPOINT_BOTTOMRIGHT, 0.230180, 0.362360)
call BlzFrameSetText(RaceButtonsT[10], "|cffFCD20DBronzebeard Clan|r")
call BlzFrameSetScale(RaceButtonsT[10], 0.572)
set TriggerRaceButtonsT[10] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[10], RaceButtonsT[10], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[10], function RaceButtonsT10Func)
set RaceButtonsT[11] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[11], FRAMEPOINT_TOPLEFT, 0.230180, 0.391300)
call BlzFrameSetAbsPoint(RaceButtonsT[11], FRAMEPOINT_BOTTOMRIGHT, 0.333770, 0.362360)
call BlzFrameSetText(RaceButtonsT[11], "|cffFCD20DDark Iron Clan|r")
call BlzFrameSetScale(RaceButtonsT[11], 0.572)
set TriggerRaceButtonsT[11] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[11], RaceButtonsT[11], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[11], function RaceButtonsT11Func)
set RaceButtonsT[12] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[12], FRAMEPOINT_TOPLEFT, 0.0229400, 0.352830)
call BlzFrameSetAbsPoint(RaceButtonsT[12], FRAMEPOINT_BOTTOMRIGHT, 0.126530, 0.323890)
call BlzFrameSetText(RaceButtonsT[12], "|cffFCD20DFelblood Elves|r")
call BlzFrameSetScale(RaceButtonsT[12], 0.572)
set TriggerRaceButtonsT[12] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[12], RaceButtonsT[12], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[12], function RaceButtonsT12Func)
set RaceButtonsT[13] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[13], FRAMEPOINT_TOPLEFT, 0.126590, 0.352360)
call BlzFrameSetAbsPoint(RaceButtonsT[13], FRAMEPOINT_BOTTOMRIGHT, 0.230180, 0.323420)
call BlzFrameSetText(RaceButtonsT[13], "|cffFCD20DVoid Elves|r")
call BlzFrameSetScale(RaceButtonsT[13], 0.572)
set TriggerRaceButtonsT[13] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[13], RaceButtonsT[13], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[13], function RaceButtonsT13Func)
set RaceButtonsT[14] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[14], FRAMEPOINT_TOPLEFT, 0.230690, 0.352830)
call BlzFrameSetAbsPoint(RaceButtonsT[14], FRAMEPOINT_BOTTOMRIGHT, 0.334280, 0.323890)
call BlzFrameSetText(RaceButtonsT[14], "|cffFCD20DFel Horde|r")
call BlzFrameSetScale(RaceButtonsT[14], 0.572)
set TriggerRaceButtonsT[14] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[14], RaceButtonsT[14], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[14], function RaceButtonsT14Func)
set RaceButtonsT[15] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[15], FRAMEPOINT_TOPLEFT, 0.0229400, 0.313870)
call BlzFrameSetAbsPoint(RaceButtonsT[15], FRAMEPOINT_BOTTOMRIGHT, 0.126530, 0.284930)
call BlzFrameSetText(RaceButtonsT[15], "|cffFCD20DDark Horde|r")
call BlzFrameSetScale(RaceButtonsT[15], 0.572)
set TriggerRaceButtonsT[15] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[15], RaceButtonsT[15], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[15], function RaceButtonsT15Func)
set RaceButtonsT[16] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[16], FRAMEPOINT_TOPLEFT, 0.126540, 0.313870)
call BlzFrameSetAbsPoint(RaceButtonsT[16], FRAMEPOINT_BOTTOMRIGHT, 0.230130, 0.284930)
call BlzFrameSetText(RaceButtonsT[16], "|cffFCD20DExodar Draenei|r")
call BlzFrameSetScale(RaceButtonsT[16], 0.572)
set TriggerRaceButtonsT[16] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[16], RaceButtonsT[16], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[16], function RaceButtonsT16Func)
set RaceButtonsT[17] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[17], FRAMEPOINT_TOPLEFT, 0.231240, 0.314430)
call BlzFrameSetAbsPoint(RaceButtonsT[17], FRAMEPOINT_BOTTOMRIGHT, 0.334830, 0.285490)
call BlzFrameSetText(RaceButtonsT[17], "|cffFCD20DLightforged Draenei|r")
call BlzFrameSetScale(RaceButtonsT[17], 0.572)
set TriggerRaceButtonsT[17] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[17], RaceButtonsT[17], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[17], function RaceButtonsT17Func)
set RaceButtonsT[18] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[18], FRAMEPOINT_TOPLEFT, 0.0229400, 0.275460)
call BlzFrameSetAbsPoint(RaceButtonsT[18], FRAMEPOINT_BOTTOMRIGHT, 0.126530, 0.246520)
call BlzFrameSetText(RaceButtonsT[18], "|cffFCD20DNightborne|r")
call BlzFrameSetScale(RaceButtonsT[18], 0.572)
set TriggerRaceButtonsT[18] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[18], RaceButtonsT[18], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[18], function RaceButtonsT18Func)
set RaceButtonsT[19] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[19], FRAMEPOINT_TOPLEFT, 0.126590, 0.275460)
call BlzFrameSetAbsPoint(RaceButtonsT[19], FRAMEPOINT_BOTTOMRIGHT, 0.230180, 0.246520)
call BlzFrameSetText(RaceButtonsT[19], "|cffFCD20DIllidari|r")
call BlzFrameSetScale(RaceButtonsT[19], 0.572)
set TriggerRaceButtonsT[19] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[19], RaceButtonsT[19], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[19], function RaceButtonsT19Func)
set RaceButtonsT[20] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[20], FRAMEPOINT_TOPLEFT, 0.230180, 0.275460)
call BlzFrameSetAbsPoint(RaceButtonsT[20], FRAMEPOINT_BOTTOMRIGHT, 0.333770, 0.246520)
call BlzFrameSetText(RaceButtonsT[20], "|cffFCD20DScarlet Crusade|r")
call BlzFrameSetScale(RaceButtonsT[20], 0.572)
set TriggerRaceButtonsT[20] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[20], RaceButtonsT[20], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[20], function RaceButtonsT20Func)
set RaceButtonsT[21] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[21], FRAMEPOINT_TOPLEFT, 0.0229400, 0.236500)
call BlzFrameSetAbsPoint(RaceButtonsT[21], FRAMEPOINT_BOTTOMRIGHT, 0.126530, 0.207560)
call BlzFrameSetText(RaceButtonsT[21], "|cffFCD20DForsaken|r")
call BlzFrameSetScale(RaceButtonsT[21], 0.572)
set TriggerRaceButtonsT[21] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[21], RaceButtonsT[21], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[21], function RaceButtonsT21Func)
set RaceButtonsT[22] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[22], FRAMEPOINT_TOPLEFT, 0.126540, 0.236500)
call BlzFrameSetAbsPoint(RaceButtonsT[22], FRAMEPOINT_BOTTOMRIGHT, 0.230130, 0.207560)
call BlzFrameSetText(RaceButtonsT[22], "|cffFCD20DKirin Tor|r")
call BlzFrameSetScale(RaceButtonsT[22], 0.572)
set TriggerRaceButtonsT[22] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[22], RaceButtonsT[22], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[22], function RaceButtonsT22Func)
set RaceButtonsT[23] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[23], FRAMEPOINT_TOPLEFT, 0.230180, 0.236500)
call BlzFrameSetAbsPoint(RaceButtonsT[23], FRAMEPOINT_BOTTOMRIGHT, 0.333770, 0.207560)
call BlzFrameSetText(RaceButtonsT[23], "|cffFCD20DHigh Elves|r")
call BlzFrameSetScale(RaceButtonsT[23], 0.572)
set TriggerRaceButtonsT[23] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[23], RaceButtonsT[23], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[23], function RaceButtonsT23Func)
set RaceButtonsT[24] = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RaceButtonsT[24], FRAMEPOINT_TOPLEFT, 0.0229500, 0.198280)
call BlzFrameSetAbsPoint(RaceButtonsT[24], FRAMEPOINT_BOTTOMRIGHT, 0.126540, 0.169340)
call BlzFrameSetText(RaceButtonsT[24], "|cffFCD20DLost Ones|r")
call BlzFrameSetScale(RaceButtonsT[24], 0.572)
set TriggerRaceButtonsT[24] = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRaceButtonsT[24], RaceButtonsT[24], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRaceButtonsT[24], function RaceButtonsT24Func)
set RaceSelectionText = BlzCreateFrameByType("TEXT", "name", RaceSelectionBackdrop, "", 0)
call BlzFrameSetAbsPoint(RaceSelectionText, FRAMEPOINT_TOPLEFT, 0.118420, 0.536960)
call BlzFrameSetAbsPoint(RaceSelectionText, FRAMEPOINT_BOTTOMRIGHT, 0.238990, 0.510260)
call BlzFrameSetText(RaceSelectionText, "|cffFFCC00Select a Race|r")
call BlzFrameSetEnable(RaceSelectionText, false)
call BlzFrameSetScale(RaceSelectionText, 1.43)
call BlzFrameSetTextAlignment(RaceSelectionText, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set RandomVanilla = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RandomVanilla, FRAMEPOINT_TOPLEFT, 0.0719100, 0.159820)
call BlzFrameSetAbsPoint(RandomVanilla, FRAMEPOINT_BOTTOMRIGHT, 0.175500, 0.130880)
call BlzFrameSetText(RandomVanilla, "|cffFCD20DRandom (All)|r")
call BlzFrameSetScale(RandomVanilla, 0.572)
set TriggerRandomVanilla = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRandomVanilla, RandomVanilla, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRandomVanilla, function RandomVanillaFunc)
set RandomCustom = BlzCreateFrame("ScriptDialogButton", RaceSelectionBackdrop, 0, 0)
call BlzFrameSetAbsPoint(RandomCustom, FRAMEPOINT_TOPLEFT, 0.181910, 0.159820)
call BlzFrameSetAbsPoint(RandomCustom, FRAMEPOINT_BOTTOMRIGHT, 0.285500, 0.130880)
call BlzFrameSetText(RandomCustom, "|cffFCD20DRandom (Custom)|r")
call BlzFrameSetScale(RandomCustom, 0.572)
set TriggerRandomCustom = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerRandomCustom, RandomCustom, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerRandomCustom, function RandomCustomFunc)
set BackdropSemiTrans049 = BlzCreateFrame("CheckListBox", RaceName, 0, 0)
call BlzFrameSetAbsPoint(BackdropSemiTrans049, FRAMEPOINT_TOPLEFT, 0.500810, 0.499260)
call BlzFrameSetAbsPoint(BackdropSemiTrans049, FRAMEPOINT_BOTTOMRIGHT, 0.776080, 0.226530)
set BackdropSemiTrans058 = BlzCreateFrame("CheckListBox", RaceTextInfo, 0, 0)
call BlzFrameSetAbsPoint(BackdropSemiTrans058, FRAMEPOINT_TOPLEFT, 0.387600, 0.528810)
call BlzFrameSetAbsPoint(BackdropSemiTrans058, FRAMEPOINT_BOTTOMRIGHT, 0.495190, 0.423940)
endfunction
endlibrary
library GameStatus uses optional PlayerUtils
/***************************************************************
*
* v1.0.0 by TriggerHappy
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Simple API for detecting if the game is online, offline, or a replay.
* _________________________________________________________________________
* 1. Installation
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the script to your map and save it (requires JassHelper *or* JNGP)
* _________________________________________________________________________
* 2. API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* This library provides one function
*
* function GetGameStatus takes nothing returns integer
*
* It returns one of the following constants
*
* - GAME_STATUS_OFFLINE
* - GAME_STATUS_ONLINE
* - GAME_STATUS_REPLAY
*
***************************************************************/
// Configuration:
globals
// The dummy unit is only created once, and removed directly after.
private constant integer DUMMY_UNIT_ID = 'hfoo'
endglobals
// (end)
globals
constant integer GAME_STATUS_OFFLINE = 0
constant integer GAME_STATUS_ONLINE = 1
constant integer GAME_STATUS_REPLAY = 2
private integer status = 0
endglobals
function GetGameStatus takes nothing returns integer
return status
endfunction
private module GameStatusInit
private static method onInit takes nothing returns nothing
local player firstPlayer
local unit u
local boolean selected
// find an actual player
static if not (LIBRARY_PlayerUtils) then
set firstPlayer = Player(0)
loop
exitwhen (GetPlayerController(firstPlayer) == MAP_CONTROL_USER and GetPlayerSlotState(firstPlayer) == PLAYER_SLOT_STATE_PLAYING)
set firstPlayer = Player(GetPlayerId(firstPlayer)+1)
endloop
else
set firstPlayer = User.fromPlaying(0).toPlayer()
endif
// force the player to select a dummy unit
set u = CreateUnit(firstPlayer, DUMMY_UNIT_ID, 0, 0, 0)
call SelectUnit(u, true)
set selected = IsUnitSelected(u, firstPlayer)
call RemoveUnit(u)
set u = null
if (selected) then
// detect if replay or offline game
if (ReloadGameCachesFromDisk()) then
set status = GAME_STATUS_OFFLINE
else
set status = GAME_STATUS_REPLAY
endif
else
// if the unit wasn't selected instantly, the game is online
set status = GAME_STATUS_ONLINE
endif
endmethod
endmodule
private struct GameStatus
implement GameStatusInit
endstruct
endlibrary
library FrameLoader initializer init_function
// in 1.31 and upto 1.32.9 PTR (when I wrote this). Frames are not correctly saved and loaded, breaking the game.
// This library runs all functions added to it with a 0s delay after the game was loaded.
// function FrameLoaderAdd takes code func returns nothing
// func runs when the game is loaded.
globals
private trigger eventTrigger = CreateTrigger()
private trigger actionTrigger = CreateTrigger()
private timer t = CreateTimer()
endglobals
function FrameLoaderAdd takes code func returns nothing
call TriggerAddAction(actionTrigger, func)
endfunction
private function timerAction takes nothing returns nothing
call TriggerExecute(actionTrigger)
endfunction
private function eventAction takes nothing returns nothing
call TimerStart(t, 0, false, function timerAction)
endfunction
private function init_function takes nothing returns nothing
call TriggerRegisterGameEvent(eventTrigger, EVENT_GAME_LOADED)
call TriggerAddAction(eventTrigger, function eventAction)
endfunction
endlibrary
library CustomConsoleUI requires optional FrameLoader, optional GameStatus
// CustomConsoleUI by Tasyen
// CustomConsoleUI allows to change the UI during the game, when setuped correctly. This excludes the mouse cursor and the UI sounds.
// In non reforged it can also not change the Idle worker Button nor the no inventory cover.
// How to setup this: First you have to make the default Console Textures be hidden that is done in Game Interface.
// Set ConsoleTexture01 to ConsoleTexture06 to UI\Widgets\EscMenu\Human\blank-background.blp
// The Day of Time clock has hardcoded textures therefore you need to swap it out. That also should be done in Gameinterface.
// TimeOfDayIndicator to the model included in this system.
// Now export and Import war3mapImported\CustomConsoleUI.toc & war3mapImported\CustomConsoleUI.fdf
// Finally you have to set the used textures into local data
globals
// workerFace = true can only be used when you save the map in 1.32.6+
private constant boolean workerFace = false
private framehandle idleWorkerButton
private framehandle idleWorkerButtonOverlay
private framehandle idleWorkerButtonOverlayParent
private framehandle customInventoryCover
private framehandle customInventoryCoverParent
public string array data
public integer array dataCount
private integer dataPageSize = 11
public real array x
public real array y
endglobals
function AddCustomConsole takes integer index, string texture returns nothing
set dataCount[index] = dataCount[index] + 1
set data[index*dataPageSize + dataCount[index]] = texture
endfunction
function UseCustomConsole takes player p, integer index returns nothing
local integer pageValue
if GetLocalPlayer() != p then
return
endif
if index < 1 then
set index = GetHandleId(GetPlayerRace(p))
endif
set pageValue = index*dataPageSize
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI5T", 0), data[pageValue + 5], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI6T", 0), data[pageValue + 6], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI4T", 0), data[pageValue + 4], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI3T", 0), data[pageValue + 3], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI2TL", 0), data[pageValue + 2], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI2TR", 0), data[pageValue + 2], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI1T", 0), data[pageValue + 1], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI1B", 0), data[pageValue + 1], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI2B", 0), data[pageValue + 2], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI3B", 0), data[pageValue + 3], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI4B", 0), data[pageValue + 4], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI5B", 0), data[pageValue + 5], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUI6B", 0), data[pageValue + 6], 0, false)
call BlzFrameSetTexture(BlzGetFrameByName("CustomConsoleUIClock", 0), data[pageValue + 7] ,0, true)
if GetLocalizedString("REFORGED") != "REFORGED" then
call BlzFrameSetTexture(BlzGetFrameByName("InventoryCoverTexture", 0), data[pageValue + 8] ,0, true)
static if workerFace then
call BlzFrameSetTexture(idleWorkerButtonOverlay, data[pageValue + 9], 0, false)
endif
else
call BlzFrameSetTexture(customInventoryCover, data[pageValue + 8] ,0, true)
endif
call BlzFrameSetPoint(BlzGetFrameByName("CustomConsoleUIClock", 0), FRAMEPOINT_TOP, BlzGetFrameByName("ConsoleUI", 0), FRAMEPOINT_TOP, x[index], y[index])
endfunction
function CreateCustomConsole takes nothing returns nothing
call BlzLoadTOCFile( "war3mapimported\\CustomConsoleUI.toc" )
call BlzCreateSimpleFrame("CustomConsoleUITop", BlzGetFrameByName("ConsoleUI", 0), 0)
call BlzFrameSetLevel(BlzGetFrameByName("CustomConsoleUITop", 0), 0)
if GetHandleId(BlzGetFrameByName("ConsoleBottomBar", 0)) > 0 then
call BlzCreateSimpleFrame( "CustomConsoleUIBottom", BlzGetFrameByName("ConsoleBottomBar", 0), 0)
else
call BlzCreateSimpleFrame( "CustomConsoleUIBottom", BlzGetFrameByName("ConsoleUI", 0), 0)
endif
call BlzFrameSetLevel(BlzGetFrameByName("CustomConsoleUIBottom", 0), 0)
if GetLocalizedString("REFORGED") != "REFORGED" then
// Requires a native existing only in Reforged
static if workerFace then
set idleWorkerButton = BlzFrameGetChild(BlzGetFrameByName("ConsoleBottomBar", 0), 3)
set idleWorkerButtonOverlayParent = BlzCreateSimpleFrame( "SimpleTextureFrame", idleWorkerButton, 0 )
set idleWorkerButtonOverlay = BlzGetFrameByName("SimpleTextureFrameValue", 0)
call BlzFrameSetAllPoints(idleWorkerButtonOverlay, idleWorkerButton)
call BlzFrameSetLevel(idleWorkerButtonOverlayParent, 4)
static if LIBRARY_GameStatus then
if GetGameStatus() == GAME_STATUS_REPLAY then
// call BlzFrameSetVisible(idleWorkerButtonOverlayParent, false)
endif
endif
endif
else
set customInventoryCoverParent = BlzCreateSimpleFrame( "SimpleTextureFrame", BlzGetFrameByName("ConsoleUI", 0), 0)
call BlzFrameSetLevel(customInventoryCoverParent, 4)
set customInventoryCover = BlzGetFrameByName("SimpleTextureFrameValue", 0)
call BlzFrameSetAbsPoint(customInventoryCover, FRAMEPOINT_BOTTOMRIGHT, 0.6, 0)
call BlzFrameSetAbsPoint(customInventoryCover, FRAMEPOINT_TOPLEFT, 0.6 - 0.128, 0.2558)
endif
// Preload
call BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON, 0)
call BlzGetFrameByName("InventoryCoverTexture", 0)
call BlzGetFrameByName("CustomConsoleUIClock", 0)
call BlzGetFrameByName("CustomConsoleUI5T", 0)
call BlzGetFrameByName("CustomConsoleUI6T", 0)
call BlzGetFrameByName("CustomConsoleUI4T", 0)
call BlzGetFrameByName("CustomConsoleUI3T", 0)
call BlzGetFrameByName("CustomConsoleUI2TL", 0)
call BlzGetFrameByName("CustomConsoleUI2TR", 0)
call BlzGetFrameByName("CustomConsoleUI1T", 0)
call BlzGetFrameByName("CustomConsoleUI1B", 0)
call BlzGetFrameByName("CustomConsoleUI2B", 0)
call BlzGetFrameByName("CustomConsoleUI3B", 0)
call BlzGetFrameByName("CustomConsoleUI4B", 0)
call BlzGetFrameByName("CustomConsoleUI5B", 0)
call BlzGetFrameByName("CustomConsoleUI6B", 0)
endfunction
private function Init takes nothing returns nothing
call CreateCustomConsole()
call UseCustomConsole(GetLocalPlayer(), 0)
endfunction
private function at0s takes nothing returns nothing
call Init()
call DestroyTimer(GetExpiredTimer())
endfunction
private function update takes nothing returns nothing
call BlzFrameSetVisible(customInventoryCoverParent, not BlzFrameIsVisible(BlzGetOriginFrame(ORIGIN_FRAME_ITEM_BUTTON, 0)))
endfunction
function CustomConsoleInit takes nothing returns nothing
local integer index = 0
set index = udg_LookAt_HUMAN
call AddCustomConsole(index, "ui\\console\\human\\humanuitile01")
call AddCustomConsole(index, "ui\\console\\human\\humanuitile02")
call AddCustomConsole(index, "ui\\console\\human\\humanuitile03")
call AddCustomConsole(index, "ui\\console\\human\\humanuitile04")
call AddCustomConsole(index, "ui\\console\\human\\humanuitile05")
call AddCustomConsole(index, "ui\\console\\human\\humanuitile06")
call AddCustomConsole(index, "ui\\console\\human\\humanuitile-timeindicatorframe")
call AddCustomConsole(index, "ui\\console\\human\\humanuitile-inventorycover")
call AddCustomConsole(index, "ReplaceableTextures\\CommandButtons\\BTNPeasant")
// offset this mostly is used to fit to the glowing orbs showing the houers
set x[index] = 0.0009
set y[index] = 0.0
set index = udg_LookAt_ORC
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile01")
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile02")
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile03")
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile04")
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile05")
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile06")
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile-timeindicatorframe")
call AddCustomConsole(index, "ui\\console\\orc\\orcuitile-inventorycover")
call AddCustomConsole(index, "ReplaceableTextures\\CommandButtons\\BTNPeon")
set x[index] = 0.0004
set y[index] = 0.0
set index = udg_LookAt_UNDEAD
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile01")
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile02")
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile03")
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile04")
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile05")
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile06")
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile-timeindicatorframe")
call AddCustomConsole(index, "ui\\console\\undead\\undeaduitile-inventorycover")
call AddCustomConsole(index, "ReplaceableTextures\\CommandButtons\\BTNAcolyte")
set x[index] = 0.0009
set y[index] = 0.0
set index = udg_LookAt_NELF
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile01")
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile02")
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile03")
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile04")
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile05")
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile06")
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile-timeindicatorframe")
call AddCustomConsole(index, "ui\\console\\nightelf\\nightelfuitile-inventorycover")
call AddCustomConsole(index, "ReplaceableTextures\\CommandButtons\\BTNWisp")
set x[index] = 0.0009
set y[index] = 0.0
set index = udg_LookAt_LIVING_NERUB
call AddCustomConsole(index, "CustomUI/LivingNerubTile01.blp")
call AddCustomConsole(index, "CustomUI/LivingNerubTile02.blp")
call AddCustomConsole(index, "CustomUI/LivingNerubTile03.blp")
call AddCustomConsole(index, "CustomUI/LivingNerubTile04.blp")
call AddCustomConsole(index, "CustomUI/LivingNerubTile05.blp")
call AddCustomConsole(index, "CustomUI/LivingNerubTile06.blp")
call AddCustomConsole(index, "CustomUI/LivingNerubUITile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/LivingNerubUITile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_UNDEAD_NERUB
call AddCustomConsole(index, "CustomUI/UndeadNerubTile01.blp")
call AddCustomConsole(index, "CustomUI/UndeadNerubTile02.blp")
call AddCustomConsole(index, "CustomUI/UndeadNerubTile03.blp")
call AddCustomConsole(index, "CustomUI/UndeadNerubTile04.blp")
call AddCustomConsole(index, "CustomUI/UndeadNerubTile05.blp")
call AddCustomConsole(index, "CustomUI/UndeadNerubTile06.blp")
call AddCustomConsole(index, "CustomUI/UndeadNerubTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/UndeadNerubTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_FACELESS
call AddCustomConsole(index, "CustomUI/FacelessTile01.blp")
call AddCustomConsole(index, "CustomUI/FacelessTile02.blp")
call AddCustomConsole(index, "CustomUI/FacelessTile03.blp")
call AddCustomConsole(index, "CustomUI/FacelessTile04.blp")
call AddCustomConsole(index, "CustomUI/FacelessTile05.blp")
call AddCustomConsole(index, "CustomUI/FacelessTile06.blp")
call AddCustomConsole(index, "CustomUI/FacelessTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/FacelessTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_QIRAJI
call AddCustomConsole(index, "CustomUI/QirajiTile01.blp")
call AddCustomConsole(index, "CustomUI/QirajiTile02.blp")
call AddCustomConsole(index, "CustomUI/QirajiTile03.blp")
call AddCustomConsole(index, "CustomUI/QirajiTile04.blp")
call AddCustomConsole(index, "CustomUI/QirajiTile05.blp")
call AddCustomConsole(index, "CustomUI/QirajiTile06.blp")
call AddCustomConsole(index, "CustomUI/QirajiTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/QirajiTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_ICE_TROLLS
call AddCustomConsole(index, "CustomUI/IceTrollTile01.blp")
call AddCustomConsole(index, "CustomUI/IceTrollTile02.blp")
call AddCustomConsole(index, "CustomUI/IceTrollTile03.blp")
call AddCustomConsole(index, "CustomUI/IceTrollTile04.blp")
call AddCustomConsole(index, "CustomUI/IceTrollTile05.blp")
call AddCustomConsole(index, "CustomUI/IceTrollTile06.blp")
call AddCustomConsole(index, "CustomUI/IceTrollTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/IceTrollTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_BRONZEBEARD
call AddCustomConsole(index, "CustomUI/BronzebeardTile01.blp")
call AddCustomConsole(index, "CustomUI/BronzebeardTile02.blp")
call AddCustomConsole(index, "CustomUI/BronzebeardTile03.blp")
call AddCustomConsole(index, "CustomUI/BronzebeardTile04.blp")
call AddCustomConsole(index, "CustomUI/BronzebeardTile05.blp")
call AddCustomConsole(index, "CustomUI/BronzebeardTile06.blp")
call AddCustomConsole(index, "CustomUI/BronzebeardTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/BronzebeardTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_WILDHAMMER
call AddCustomConsole(index, "CustomUI/WildhammerTile01.blp")
call AddCustomConsole(index, "CustomUI/WildhammerTile02.blp")
call AddCustomConsole(index, "CustomUI/WildhammerTile03.blp")
call AddCustomConsole(index, "CustomUI/WildhammerTile04.blp")
call AddCustomConsole(index, "CustomUI/WildhammerTile05.blp")
call AddCustomConsole(index, "CustomUI/WildhammerTile06.blp")
call AddCustomConsole(index, "CustomUI/WildhammerTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/WildhammerTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_DARKIRON
call AddCustomConsole(index, "CustomUI/DarkIronTile01.blp")
call AddCustomConsole(index, "CustomUI/DarkIronTile02.blp")
call AddCustomConsole(index, "CustomUI/DarkIronTile03.blp")
call AddCustomConsole(index, "CustomUI/DarkIronTile04.blp")
call AddCustomConsole(index, "CustomUI/DarkIronTile05.blp")
call AddCustomConsole(index, "CustomUI/DarkIronTile06.blp")
call AddCustomConsole(index, "CustomUI/DarkIronTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/DarkIronTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_FELBLOOD
call AddCustomConsole(index, "CustomUI/FelbloodTile01.blp")
call AddCustomConsole(index, "CustomUI/FelbloodTile02.blp")
call AddCustomConsole(index, "CustomUI/FelbloodTile03.blp")
call AddCustomConsole(index, "CustomUI/FelbloodTile04.blp")
call AddCustomConsole(index, "CustomUI/FelbloodTile05.blp")
call AddCustomConsole(index, "CustomUI/FelbloodTile06.blp")
call AddCustomConsole(index, "CustomUI/FelbloodTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/FelbloodTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_VOIDELVES
call AddCustomConsole(index, "CustomUI/VoidElvesTile01.blp")
call AddCustomConsole(index, "CustomUI/VoidElvesTile02.blp")
call AddCustomConsole(index, "CustomUI/VoidElvesTile03.blp")
call AddCustomConsole(index, "CustomUI/VoidElvesTile04.blp")
call AddCustomConsole(index, "CustomUI/VoidElvesTile05.blp")
call AddCustomConsole(index, "CustomUI/VoidElvesTile06.blp")
call AddCustomConsole(index, "CustomUI/VoidElvesTile-timeindicatorframe.blp")
call AddCustomConsole(index, "CustomUI/VoidElvesTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_FELHORDE
call AddCustomConsole(index, "CustomUI/FelOrcTile01.blp")
call AddCustomConsole(index, "CustomUI/FelOrcTile02.blp")
call AddCustomConsole(index, "CustomUI/FelOrcTile03.blp")
call AddCustomConsole(index, "CustomUI/FelOrcTile04.blp")
call AddCustomConsole(index, "CustomUI/FelOrcTile05.blp")
call AddCustomConsole(index, "CustomUI/FelOrcTile06.blp")
call AddCustomConsole(index, "CustomUI/FelOrcTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/FelOrcTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_DARKHORDE
call AddCustomConsole(index, "CustomUI/DarkHordeTile01.blp")
call AddCustomConsole(index, "CustomUI/DarkHordeTile02.blp")
call AddCustomConsole(index, "CustomUI/DarkHordeTile03.blp")
call AddCustomConsole(index, "CustomUI/DarkHordeTile04.blp")
call AddCustomConsole(index, "CustomUI/DarkHordeTile05.blp")
call AddCustomConsole(index, "CustomUI/DarkHordeTile06.blp")
call AddCustomConsole(index, "CustomUI/DarkHordeTile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/DarkHordeTile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_EXODAR_DRAENEI
call AddCustomConsole(index, "CustomUI/ExodarUITile01.blp")
call AddCustomConsole(index, "CustomUI/ExodarUITile02.blp")
call AddCustomConsole(index, "CustomUI/ExodarUITile03.blp")
call AddCustomConsole(index, "CustomUI/ExodarUITile04.blp")
call AddCustomConsole(index, "CustomUI/ExodarUITile05.blp")
call AddCustomConsole(index, "CustomUI/ExodarUITile06.blp")
call AddCustomConsole(index, "CustomUI/ExodarUITile-TimeIndicatorFrame.blp")
call AddCustomConsole(index, "CustomUI/ExodarUITile-InventoryCover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_LIGHTFORGED
call AddCustomConsole(index, "CustomUI/LightforgedTile01.blp")
call AddCustomConsole(index, "CustomUI/LightforgedTile02.blp")
call AddCustomConsole(index, "CustomUI/LightforgedTile03.blp")
call AddCustomConsole(index, "CustomUI/LightforgedTile04.blp")
call AddCustomConsole(index, "CustomUI/LightforgedTile05.blp")
call AddCustomConsole(index, "CustomUI/LightforgedTile06.blp")
call AddCustomConsole(index, "CustomUI/LightforgedTile-timeindicatorframe.blp")
call AddCustomConsole(index, "CustomUI/LightforgedTile-inventorycover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_ILLIDARI
call AddCustomConsole(index, "CustomUI/IllidariTile01.blp")
call AddCustomConsole(index, "CustomUI/IllidariTile02.blp")
call AddCustomConsole(index, "CustomUI/IllidariTile03.blp")
call AddCustomConsole(index, "CustomUI/IllidariTile04.blp")
call AddCustomConsole(index, "CustomUI/IllidariTile05.blp")
call AddCustomConsole(index, "CustomUI/IllidariTile06.blp")
call AddCustomConsole(index, "CustomUI/IllidariTile-timeindicatorframe.blp")
call AddCustomConsole(index, "CustomUI/IllidariTile-inventorycover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
set index = udg_LookAt_DALARAN
call AddCustomConsole(index, "CustomUI/KirinTorTile01.blp")
call AddCustomConsole(index, "CustomUI/KirinTorTile02.blp")
call AddCustomConsole(index, "CustomUI/KirinTorTile03.blp")
call AddCustomConsole(index, "CustomUI/KirinTorTile04.blp")
call AddCustomConsole(index, "CustomUI/KirinTorTile05.blp")
call AddCustomConsole(index, "CustomUI/KirinTorTile06.blp")
call AddCustomConsole(index, "CustomUI/KirinTorTile-timeindicatorframe.blp")
call AddCustomConsole(index, "CustomUI/KirinTorTile-inventorycover.blp")
call AddCustomConsole(index, "BTNLiving Nerubian - Drone.blp")
set x[index] = 0.000
set y[index] = 0.0
if GetLocalizedString("REFORGED") == "REFORGED" then
call TimerStart(CreateTimer(), 1/32.0, true, function update)
endif
call TimerStart(CreateTimer(), 0, false, function at0s)
static if LIBRARY_FrameLoader then
call FrameLoaderAdd(function Init)
endif
endfunction
endlibrary
library InitRaceIndex
module InitModule
private static method onInit takes nothing returns nothing
// CONFIG RACE INDEX HERE
set udg_LookAt_HUMAN = 1
set udg_LookAt_ORC = 2
set udg_LookAt_NELF = 3
set udg_LookAt_UNDEAD = 4
set udg_LookAt_LIVING_NERUB = 5
set udg_LookAt_UNDEAD_NERUB = 6
set udg_LookAt_FACELESS = 7
set udg_LookAt_QIRAJI = 8
set udg_LookAt_ICE_TROLLS = 9
set udg_LookAt_WILDHAMMER = 10
set udg_LookAt_BRONZEBEARD = 11
set udg_LookAt_DARKIRON = 12
set udg_LookAt_FELBLOOD = 13
set udg_LookAt_VOIDELVES = 14
set udg_LookAt_FELHORDE = 15
set udg_LookAt_DARKHORDE = 16
set udg_LookAt_EXODAR_DRAENEI = 17
set udg_LookAt_LIGHTFORGED = 18
set udg_LookAt_NIGHTBORNE = 19
set udg_LookAt_ILLIDARI = 20
set udg_LookAt_SCARLETCRUSADE = 21
set udg_LookAt_FORSAKEN = 23
set udg_LookAt_DALARAN = 22
set udg_LookAt_HIGHELVES = 24
set udg_LookAt_LOSTONES = 25
endmethod
endmodule
struct InitRaceIndex
implement InitModule
endstruct
endlibrary
library CustomTierSystem requires MultidimensionalArray, WorldBounds, RegisterPlayerUnitEvent
//----------------------------------------------------------------------------------
//GLOBALS
//----------------------------------------------------------------------------------
globals
// Dummy units
private constant integer TIER_1_ID = 'n02J'
private constant integer TIER_2_ID = 'n02K'
private constant integer TIER_3_ID = 'n02L'
private constant integer ALTAR_ID = 'n00C'
private constant integer HERO_LIMIT = 'n02M'
private constant boolean HIDE_ON_MAP_CORNER = true
// PlayerTier Variable ---> [tier id][player id]
// TIER IDs:
// -Tier 1: 1
// -Tier 2: 2
// -Tier 3: 3
private Unit2D PlayerTier
// PlayerAltar Variable ---> [player id]
private Unit1D PlayerAltar
// PlayerHeroLimit Variable ---> [player id]
private Unit1D PlayerHeroLimit
private boolean array HeroDuringTrain
private boolean array HeroDuringRevive
private unit array WorkingAltar
private integer array HeroCount
private integer array AltarCount
private integer array Tier1Count
private integer array Tier2Count
private integer array Tier3Count
endglobals
private module CreateRegister
private static method onInit takes nothing returns nothing
call thistype.registryArray()
endmethod
endmodule
private module TotalTierTypesInit
private static method onInit takes nothing returns nothing
call thistype.totalTierTypesArray()
endmethod
endmodule
private module PlayerTierInit
private static method onInit takes nothing returns nothing
call thistype.playerTierArray()
endmethod
endmodule
private module PlayerAltarInit
private static method onInit takes nothing returns nothing
call thistype.playerAltarArray()
endmethod
endmodule
private module PlayerHeroLimitInit
private static method onInit takes nothing returns nothing
call thistype.playerHeroLimitArray()
endmethod
endmodule
static if HIDE_ON_MAP_CORNER and not LIBRARY_WorldBounds then
private module BoundsInit
readonly static real x
readonly static real y
private static method onInit takes nothing returns nothing
local rect map = GetWorldBounds()
set thistype.x = GetRectMaxX(map)
set thistype.y = GetRectMaxY(map)
call RemoveRect(map)
set map = null
endmethod
endmodule
private struct Bounds extends array
implement BoundsInit
endstruct
endif
//----------------------------------------------------------------------------------
//FILTERS
//----------------------------------------------------------------------------------
private function IsHero takes unit u returns boolean
return IsUnitType(u, UNIT_TYPE_HERO)
endfunction
private function DetectComputerSlot takes player p returns boolean
return GetPlayerController(p) == MAP_CONTROL_COMPUTER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING
endfunction
private function DetectHumanSlot takes player p returns boolean
return GetPlayerController(p) == MAP_CONTROL_USER and GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING
endfunction
//----------------------------------------------------------------------------------
//TIER AND HERO LIMIT SYSTEM
//----------------------------------------------------------------------------------
struct CustomTiers
// Registry Variable ---> [tier id][i+1]
// TIER IDs:
// -Altar: 0
// -Tier 1: 1
// -Tier 2: 2
// -Tier 3: 3
// -Tiered Upgrade: 9 ---> Tiered upgrades, each level is a new tier
static Integer2D REGISTRY
static Integer1D totalTierTypes
private static method registryArray takes nothing returns nothing
set .REGISTRY = Integer2D.create()
endmethod
private static method totalTierTypesArray takes nothing returns nothing
set .totalTierTypes = Integer1D.create()
endmethod
private static method playerTierArray takes nothing returns nothing
set PlayerTier = Unit2D.create()
endmethod
private static method playerAltarArray takes nothing returns nothing
set PlayerAltar = Unit1D.create()
endmethod
private static method playerHeroLimitArray takes nothing returns nothing
set PlayerHeroLimit = Unit1D.create()
endmethod
implement CreateRegister
implement TotalTierTypesInit
implement PlayerTierInit
implement PlayerAltarInit
implement PlayerHeroLimitInit
static method isTier takes integer buildingId, integer tierId returns boolean
local integer i = 0
local boolean b = false
loop
exitwhen i == totalTierTypes[tierId] or b == true
if .REGISTRY[tierId][i] == buildingId then
set b = true
endif
set i = i + 1
endloop
return b
endmethod
static method isAltar takes integer buildingId returns boolean
local integer i = 0
local boolean b = false
loop
exitwhen i == totalTierTypes[0] or b == true
if .REGISTRY[0][i] == buildingId then
set b = true
endif
set i = i + 1
endloop
return b
endmethod
static method isTieredUpgrade takes integer upgradeId returns boolean
local integer i = 0
local boolean b = false
loop
exitwhen i == totalTierTypes[9] or b == true
if .REGISTRY[9][i] == upgradeId then
set b = true
endif
set i = i + 1
endloop
return b
endmethod
method register takes integer buildingId, integer tierId returns boolean
if CustomTiers.isTier(buildingId, tierId) then
return false
endif
set .REGISTRY[tierId][.totalTierTypes[tierId]] = buildingId
set .totalTierTypes[tierId] = .totalTierTypes[tierId] + 1
return true
endmethod
static method create takes integer buildingId, integer tierId returns CustomTiers
local CustomTiers c = CustomTiers.allocate()
if not c.register(buildingId, tierId) then
call c.destroy()
return 0
endif
return c
endmethod
static method createUpg takes integer upgradeId, boolean isMultiTier, integer tierId returns CustomTiers
local CustomTiers c = CustomTiers.allocate()
if isMultiTier then
if not c.register(upgradeId, 9) then
call c.destroy()
return 0
endif
else
if not c.register(upgradeId, tierId) then
call c.destroy()
return 0
endif
endif
return c
endmethod
static method createAltar takes integer buildingId returns CustomTiers
local CustomTiers c = CustomTiers.allocate()
if not c.register(buildingId, 0) then
call c.destroy()
return 0
endif
return c
endmethod
endstruct
//----------------------------------------------------------------------------------
//CUSTOM INIT FUNCTIONS
//----------------------------------------------------------------------------------
struct CustomTierFuncs
// heroTrainingState:
// -Don't check: 0
// -Is Training: 1
// -Is not Training: 2
private static method setHeroAvailability takes integer playerId returns nothing
if (HeroCount[playerId] == 1 and Tier2Count[playerId] == 0 and Tier3Count[playerId] == 0) or /*
*/ (HeroCount[playerId] == 2 and Tier3Count[playerId] == 0) or /*
*/ HeroCount[playerId] >= 3 or /*
*/ HeroDuringTrain[playerId] or HeroDuringRevive[playerId] then
call SetUnitOwner(PlayerHeroLimit[playerId], Player(PLAYER_NEUTRAL_PASSIVE), false)
else
if HeroCount[playerId] < 0 then
set HeroCount[playerId] = 0
endif
call SetUnitOwner(PlayerHeroLimit[playerId], Player(playerId), false)
endif
endmethod
private static method setAltarAvailability takes integer playerId returns nothing
if AltarCount[playerId] >= 1 then
call SetUnitOwner(PlayerAltar[playerId], Player(playerId), false)
else
if AltarCount[playerId] < 0 then
set AltarCount[playerId] = 0
endif
call SetUnitOwner(PlayerAltar[playerId], Player(PLAYER_NEUTRAL_PASSIVE), false)
endif
call thistype.setHeroAvailability(playerId)
endmethod
private static method setTierAvailability takes integer playerId, integer tierId returns nothing
if tierId == 1 then
if Tier1Count[playerId] >= 1 then
call SetUnitOwner(PlayerTier[1][playerId], Player(playerId), false)
else
if Tier1Count[playerId] < 0 then
set Tier1Count[playerId] = 0
endif
call SetUnitOwner(PlayerTier[1][playerId], Player(PLAYER_NEUTRAL_PASSIVE), false)
endif
elseif tierId == 2 then
if Tier2Count[playerId] >= 1 then
call SetUnitOwner(PlayerTier[2][playerId], Player(playerId), false)
else
if Tier2Count[playerId] < 0 then
set Tier2Count[playerId] = 0
endif
call SetUnitOwner(PlayerTier[2][playerId], Player(PLAYER_NEUTRAL_PASSIVE), false)
endif
elseif tierId == 3 then
if Tier3Count[playerId] >= 1 then
call SetUnitOwner(PlayerTier[3][playerId], Player(playerId), false)
else
if Tier3Count[playerId] < 0 then
set Tier3Count[playerId] = 0
endif
call SetUnitOwner(PlayerTier[3][playerId], Player(PLAYER_NEUTRAL_PASSIVE), false)
endif
endif
call thistype.setHeroAvailability(playerId)
endmethod
private static method registerActions takes nothing returns nothing
local integer action = GetHandleId(GetTriggerEventId())
local integer playerId
local integer researchId
local integer researchLvl
local unit u
// UNIT_TRAIN_START
if action == 32 then
set u = GetTriggerUnit()
set playerId = GetPlayerId(GetOwningPlayer(u))
// if IsHero(u) then
if IsUnitIdType(GetTrainedUnitType(), UNIT_TYPE_HERO) then
set HeroDuringTrain[playerId] = true
set WorkingAltar[playerId] = u
call thistype.setHeroAvailability(playerId)
endif
// UNIT_TRAIN_CANCEL
elseif action == 33 then
set u = GetTriggerUnit()
set playerId = GetPlayerId(GetOwningPlayer(u))
if IsUnitIdType(GetTrainedUnitType(), UNIT_TYPE_HERO) then
set HeroDuringTrain[playerId] = false
set WorkingAltar[playerId] = null
call thistype.setHeroAvailability(playerId)
endif
// UNIT_TRAIN_FINISH
elseif action == 34 then
set u = GetTrainedUnit()
set playerId = GetPlayerId(GetOwningPlayer(u))
if IsHero(u) then
set HeroCount[playerId] = HeroCount[playerId] + 1
set HeroDuringTrain[playerId] = false
set WorkingAltar[playerId] = null
call thistype.setHeroAvailability(playerId)
endif
// UNIT_SELL --> Tabern Hero
elseif action == 269 then
set u = GetSoldUnit()
set playerId = GetPlayerId(GetOwningPlayer(u))
if IsHero(u) then
set HeroCount[playerId] = HeroCount[playerId] + 1
call thistype.setHeroAvailability(playerId)
endif
// UNIT_DEATH
elseif action == 20 then
set u = GetDyingUnit()
set playerId = GetPlayerId(GetOwningPlayer(u))
if CustomTiers.isAltar(GetUnitTypeId(u)) then
set AltarCount[playerId] = AltarCount[playerId] - 1
if u == WorkingAltar[playerId] then
set HeroDuringTrain[playerId] = false
set HeroDuringRevive[playerId] = false
set WorkingAltar[playerId] = null
endif
call thistype.setAltarAvailability(playerId)
elseif CustomTiers.isTier(GetUnitTypeId(u), 1) then
set Tier1Count[playerId] = Tier1Count[playerId] - 1
call thistype.setTierAvailability(playerId, 1)
elseif CustomTiers.isTier(GetUnitTypeId(u), 2) then
set Tier1Count[playerId] = Tier1Count[playerId] - 1
set Tier2Count[playerId] = Tier2Count[playerId] - 1
call thistype.setTierAvailability(playerId, 2)
elseif CustomTiers.isTier(GetUnitTypeId(u), 3) then
set Tier1Count[playerId] = Tier1Count[playerId] - 1
set Tier2Count[playerId] = Tier2Count[playerId] - 1
set Tier3Count[playerId] = Tier3Count[playerId] - 1
call thistype.setTierAvailability(playerId, 3)
endif
// UNIT_CONSTRUCT_FINISH / UNIT_UPGRADE_FINISH
elseif action == 28 or action == 31 then
if action == 28 then
set u = GetConstructedStructure()
elseif action == 31 then
set u = GetTriggerUnit()
endif
set playerId = GetPlayerId(GetOwningPlayer(u))
if CustomTiers.isAltar(GetUnitTypeId(u)) then
set AltarCount[playerId] = AltarCount[playerId] + 1
call thistype.setAltarAvailability(playerId)
elseif CustomTiers.isTier(GetUnitTypeId(u), 1) then
set Tier1Count[playerId] = Tier1Count[playerId] + 1
call thistype.setTierAvailability(playerId, 1)
elseif CustomTiers.isTier(GetUnitTypeId(u), 2) then
set Tier2Count[playerId] = Tier2Count[playerId] + 1
call thistype.setTierAvailability(playerId, 2)
elseif CustomTiers.isTier(GetUnitTypeId(u), 3) then
set Tier3Count[playerId] = Tier3Count[playerId] + 1
call thistype.setTierAvailability(playerId, 3)
endif
// UNIT_RESEARCH_FINISH
elseif action == 37 then
set u = GetResearchingUnit()
set researchId = GetResearched()
set researchLvl = GetPlayerTechCount(GetOwningPlayer(u), researchId, true)
set playerId = GetPlayerId(GetOwningPlayer(u))
if CustomTiers.isTier(researchId, 2) or (CustomTiers.isTieredUpgrade(researchId) and researchLvl == 1) then
set Tier2Count[playerId] = Tier2Count[playerId] + 1
call thistype.setTierAvailability(playerId, 2)
elseif CustomTiers.isTier(researchId, 3) or (CustomTiers.isTieredUpgrade(researchId) and researchLvl == 2) then
set Tier3Count[playerId] = Tier3Count[playerId] + 1
call thistype.setTierAvailability(playerId, 3)
endif
endif
set u = null
endmethod
private static method onInit takes nothing returns nothing
local integer i = 0
local unit dummy
loop
exitwhen i == bj_MAX_PLAYERS
if DetectComputerSlot(Player(i)) or DetectHumanSlot(Player(i)) then
set Tier1Count[i] = 1
set Tier2Count[i] = 0
set Tier3Count[i] = 0
set AltarCount[i] = 0
set HeroDuringTrain[i] = false
set HeroDuringRevive[i] = false
set WorkingAltar[i] = null
if IsMapFlagSet(MAP_RANDOM_HERO) then
set HeroCount[i] = 1
else
set HeroCount[i] = 0
endif
static if HIDE_ON_MAP_CORNER then
static if LIBRARY_WorldBounds then
set PlayerTier[1][i] = CreateUnit(Player(i), TIER_1_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
set PlayerTier[2][i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), TIER_2_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
set PlayerTier[3][i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), TIER_3_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
set PlayerAltar[i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), ALTAR_ID, WorldBounds.maxX, WorldBounds.maxY, 0)
set PlayerHeroLimit[i] = CreateUnit(Player(i), HERO_LIMIT, WorldBounds.maxX, WorldBounds.maxY, 0)
else
set PlayerTier[1][i] = CreateUnit(Player(i), TIER_1_ID, Bounds.x, Bounds.y, 0)
set PlayerTier[2][i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), TIER_2_ID, Bounds.x, Bounds.y, 0)
set PlayerTier[3][i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), TIER_3_ID, Bounds.x, Bounds.y, 0)
set PlayerAltar[i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), ALTAR_ID, Bounds.x, Bounds.y, 0)
set PlayerHeroLimit[i] = CreateUnit(Player(i), HERO_LIMIT, Bounds.x, Bounds.y, 0)
endif
else
set PlayerTier[1][i] = CreateUnit(Player(i), TIER_1_ID, 0, 0, 0)
set PlayerTier[2][i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), TIER_2_ID, 0, 0, 0)
set PlayerTier[3][i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), TIER_3_ID, 0, 0, 0)
set PlayerAltar[i] = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), ALTAR_ID, 0, 0, 0)
set PlayerHeroLimit[i] = CreateUnit(Player(i), HERO_LIMIT, 0, 0, 0)
endif
endif
set i = i + 1
endloop
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_TRAIN_START, function thistype.registerActions)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_TRAIN_CANCEL, function thistype.registerActions)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_TRAIN_FINISH, function thistype.registerActions)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_SELL, function thistype.registerActions)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.registerActions)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, function thistype.registerActions)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_UPGRADE_FINISH, function thistype.registerActions)
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_RESEARCH_FINISH, function thistype.registerActions)
endmethod
endstruct
endlibrary
library CustomTiersSetup initializer Init requires CustomTierSystem
globals
// Altars
private constant integer ALTAR_OF_KINGS = 'halt'
private constant integer ALTAR_OF_STORMS = 'oalt'
private constant integer ALTAR_OF_DARKNESS = 'uaod'
private constant integer ALTAR_OF_ELDERS = 'eate'
// TIER 1
private constant integer TOWN_HALL = 'htow'
private constant integer GREAT_HALL = 'ogre'
private constant integer NECROPOLIS = 'unpl'
private constant integer TREE_OF_LIFE = 'etol'
// TIER 2
private constant integer KEEP = 'hkee'
private constant integer STRONGHOLD = 'ostr'
private constant integer HALLS_OF_DEAD = 'unp1'
private constant integer TREE_OF_AGES = 'etoa'
// TIER 3
private constant integer CASTLE = 'hcas'
private constant integer FORTRESS = 'ofrt'
private constant integer BLACK_CITADEL = 'unp2'
private constant integer TREE_OF_ETERNITY = 'etoe'
endglobals
private function Init takes nothing returns nothing
local CustomTiers c
// Altars
set c = CustomTiers.createAltar(ALTAR_OF_KINGS)
set c = CustomTiers.createAltar(ALTAR_OF_STORMS)
set c = CustomTiers.createAltar(ALTAR_OF_DARKNESS)
set c = CustomTiers.createAltar(ALTAR_OF_ELDERS)
set c = CustomTiers.createAltar('e00W') //Faceless
set c = CustomTiers.createAltar('u005') //Undead Nerubians
set c = CustomTiers.createAltar('h004') //Living Nerubians
set c = CustomTiers.createAltar('h020') //Bronzebeard
set c = CustomTiers.createAltar('h03J') //Felblood
set c = CustomTiers.createAltar('h02Y') //Dark Iron
set c = CustomTiers.createAltar('o039') //Fel Horde
set c = CustomTiers.createAltar('o03A') //Dark Horde
set c = CustomTiers.createAltar('o002') //Ice Trolls
set c = CustomTiers.createAltar('o02I') //Wildhammer
set c = CustomTiers.createAltar('o016') //Qiraji
set c = CustomTiers.createAltar('h04A') //Void Elves
set c = CustomTiers.createAltar('h053') //Exodar
set c = CustomTiers.createAltar('h05X') //Lightforged
set c = CustomTiers.createAltar('h06L') //Illidari
set c = CustomTiers.createAltar('h07F') //Kirin Tor
// Tier 1
set c = CustomTiers.create(TOWN_HALL, 1)
set c = CustomTiers.create(GREAT_HALL, 1)
set c = CustomTiers.create(NECROPOLIS, 1)
set c = CustomTiers.create(TREE_OF_LIFE, 1)
set c = CustomTiers.create('h029', 1) //Bronzebeard
set c = CustomTiers.create('e00O', 1) //Faceless
set c = CustomTiers.create('o011', 1) //Qiraji
set c = CustomTiers.create('h04D', 1) //Void Elves
set c = CustomTiers.create('h000', 1) //Living Nerub
set c = CustomTiers.create('h03R', 1) //Felblood
set c = CustomTiers.create('o03F', 1) //Dark Horde
set c = CustomTiers.create('o02O', 1) //Wildhammer
set c = CustomTiers.create('o003', 1) //Ice Troll
set c = CustomTiers.create('h038', 1) //Dark Iron
set c = CustomTiers.create('u000', 1) //Undead Nerub
set c = CustomTiers.create('o03Q', 1) //Fel Horde
set c = CustomTiers.create('h05A', 1) //Exodar
set c = CustomTiers.create('h061', 1) //Lightforged
set c = CustomTiers.create('h06Y', 1) //Illidari
set c = CustomTiers.create('h07M', 1) //Kirin Tor
// Tier 2
set c = CustomTiers.create(KEEP, 2)
set c = CustomTiers.create(STRONGHOLD, 2)
set c = CustomTiers.create(HALLS_OF_DEAD, 2)
set c = CustomTiers.create(TREE_OF_AGES, 2)
set c = CustomTiers.create('h026', 2) //Bronzebeard
set c = CustomTiers.createUpg('R01B', false, 2) //Faceless
set c = CustomTiers.create('o012', 2) //Qiraji
set c = CustomTiers.create('h04H', 2) //Void Elves
set c = CustomTiers.create('h001', 2) //Living Nerub
set c = CustomTiers.create('h03N', 2) //Felblood
set c = CustomTiers.create('o03L', 2) //Dark Horde
set c = CustomTiers.create('o02R', 2) //Wildhammer
set c = CustomTiers.create('o004', 2) //Ice Troll
set c = CustomTiers.create('h032', 2) //Dark Iron
set c = CustomTiers.create('u001', 2) //Undead Nerub
set c = CustomTiers.create('o03C', 2) //Fel Horde
set c = CustomTiers.create('h059', 2) //Exodar
set c = CustomTiers.create('h05Z', 2) //Lightforged
set c = CustomTiers.create('h06U', 2) //Illidari
set c = CustomTiers.create('h07G', 2) //Kirin Tor
// Tier 3
set c = CustomTiers.create(CASTLE, 3)
set c = CustomTiers.create(FORTRESS, 3)
set c = CustomTiers.create(BLACK_CITADEL, 3)
set c = CustomTiers.create(TREE_OF_ETERNITY, 3)
set c = CustomTiers.create('h025', 3) //Bronzebeard
set c = CustomTiers.createUpg('R01B', false, 2) //Faceless
set c = CustomTiers.createUpg('R01C', false, 3) //Faceless
set c = CustomTiers.create('o013', 3) //Qiraji
set c = CustomTiers.create('h04J', 3) //Void Elves
set c = CustomTiers.create('h002', 3) //Living Nerub
set c = CustomTiers.create('h03Q', 3) //Felblood
set c = CustomTiers.create('o038', 3) //Dark Horde
set c = CustomTiers.create('o02S', 3) //Wildhammer
set c = CustomTiers.create('o008', 3) //Ice Troll
set c = CustomTiers.create('h030', 3) //Dark Iron
set c = CustomTiers.create('u002', 3) //Undead Nerub
set c = CustomTiers.create('o03E', 3) //Fel Horde
set c = CustomTiers.create('h056', 3) //Exodar
set c = CustomTiers.create('h060', 3) //Lightforged
set c = CustomTiers.create('h06V', 3) //Illidari
set c = CustomTiers.create('h07I', 3) //Kirin Tor
endfunction
endlibrary
library OsKeyMeta
struct OSKEY_META
static integer NONE = 0 // 0
static integer SHIFT = 1 // 1
static integer CTRL = 2 // 2
static integer CTRLSHIFT = 3 // 3 = 2 + 1
static integer ALT = 4 // 4
static integer ALTSHIFT = 5 // 5 = 4 + 1
static integer ALTCTRL = 6 // 6 = 4 + 2
static integer CTRLALTSHIT = 7 // 7 = 4 + 2 + 1
static integer META = 8 // 8
static integer METASHIFT = 9 // 9 = 8 + 1
static integer METACTRL = 10 // 10 = 8 + 2
static integer METACTRLSHIFT = 11 // 11 = 8 + 2 + 1
static integer METAALT = 12 // 12 = 8 + 4
static integer METAALTSHIFT = 13 // 13 = 8 + 4 + 1
static integer METAALTCTRL = 14 // 14 = 8 + 4 + 2
static integer ALL = 15 // 15 = 8 + 4 + 2 + 1
endstruct
endlibrary
scope FavourLoop initializer init
globals
private constant integer FAVOUR_ABIL = 'A0RX' //Black Dragon Favor
private constant real INTERVAL = .1
private group SELECT_GROUP = CreateGroup()
endglobals
private function callback takes nothing returns boolean
return GetUnitAbilityLevel(GetFilterUnit(), FAVOUR_ABIL) > 0
endfunction
private function onPeriod takes nothing returns nothing
local integer level
local integer i = -1
local integer cVal
local player play
local string path
local unit u
loop
set i = i + 1
exitwhen i > bj_MAX_PLAYER_SLOTS
set play = Player(i)
if GetPlayerController(play) == MAP_CONTROL_USER and GetPlayerSlotState(play) == PLAYER_SLOT_STATE_PLAYING then
// display/hide favour gathered
if udg_FavourGathered[i+1] == 0 then
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, false)
endif
else
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, true)
call BlzFrameSetText(DFavorText, I2S(udg_FavourGathered[i+1]))
endif
endif
call GroupEnumUnitsSelected(SELECT_GROUP, play, Filter(function callback))
if BlzGroupGetSize(SELECT_GROUP) == 1 then
set u = FirstOfGroup(SELECT_GROUP)
if GetOwningPlayer(u) != play then // cannot buff other player's units
if isUIVisible[i] then
call hideFavourUI(play)
endif
else
if not isUIVisible[i] then
call showFavourUI(play)
endif
set selectedUnit[i] = u
// Dragon's Commendation
set level = GetUnitAbilityLevel(u, 'A0RY')
if level > 0 then
set path = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNDragonCommendation.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton1, path, 0, true)
call BlzFrameSetEnable(DFavorButton1, false)
call SetFavourStackTextLocal(DFStackCount1, level, true, true)
endif
else
set path = "BTNDragonCommendation.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton1, path, 0, true)
call BlzFrameSetEnable(DFavorButton1, true)
call SetFavourStackTextLocal(DFStackCount1, level, false, true)
endif
endif
set cVal = GetUnitUserData(u)
// Dragon's Guile
set level = (udg_DF_DragonGuile[cVal] / udg_CONSTANT_FavourCostLow)
if level >= 4 then
set path = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNDragonGuile.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton2, path, 0, true)
call BlzFrameSetEnable(DFavorButton2, false)
call SetFavourStackTextLocal(DFStackCount2, level, true, true)
endif
else
set path = "BTNDragonGuile.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton2, path, 0, true)
call BlzFrameSetEnable(DFavorButton2, true)
call SetFavourStackTextLocal(DFStackCount2, level, false, true)
endif
endif
// Dragon's Heart
set level = (udg_DF_DragonHeart[cVal] / udg_CONSTANT_FavourCostLow)
if level >= 4 then
set path = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNDragonHeart.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton3, path, 0, true)
call BlzFrameSetEnable(DFavorButton3, false)
call SetFavourStackTextLocal(DFStackCount3, level, true, true)
endif
else
set path = "BTNDragonHeart.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton3, path, 0, true)
call BlzFrameSetEnable(DFavorButton3, true)
call SetFavourStackTextLocal(DFStackCount3, level, false, true)
endif
endif
// Dragon's Rage
set level = (udg_DF_DragonRage[cVal] / udg_CONSTANT_FavourCostLow)
if level >= 4 then
set path = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNDragonRage.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton4, path, 0, true)
call BlzFrameSetEnable(DFavorButton4, false)
call SetFavourStackTextLocal(DFStackCount4, level, true, true)
endif
else
set path = "BTNDragonRage.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton4, path, 0, true)
call BlzFrameSetEnable(DFavorButton4, true)
call SetFavourStackTextLocal(DFStackCount4, level, false, true)
endif
endif
// Dragon's Wisdom
if BlzGetUnitMaxMana(u) <= 0 then
set path = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNDragonMana.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton5, path, 0, true)
call BlzFrameSetEnable(DFavorButton5, false)
call SetFavourStackTextLocal(DFStackCount5, 0, true, false)
endif
else
set level = (udg_DF_DragonWisdom[cVal] / udg_CONSTANT_FavourCostLow)
if level >= 4 then
set path = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTNDragonMana.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton5, path, 0, true)
call BlzFrameSetEnable(DFavorButton5, false)
call SetFavourStackTextLocal(DFStackCount5, level, true, true)
endif
else
set path = "BTNDragonMana.blp"
if GetLocalPlayer() == play then
call BlzFrameSetTexture(BackdropDFavorButton5, path, 0, true)
call BlzFrameSetEnable(DFavorButton5, true)
call SetFavourStackTextLocal(DFStackCount5, level, false, true)
endif
endif
endif
endif
else
if isUIVisible[i] then
call hideFavourUI(play)
endif
endif
call GroupClear(SELECT_GROUP)
endif
endloop
endfunction
private function init takes nothing returns nothing
call TimerStart(CreateTimer(), INTERVAL, true, function onPeriod)
endfunction
endscope
library DFavour initializer init uses OsKeyMeta, SimError, InitTOCFiles
globals
framehandle ButtonBackdrop = null
framehandle ButtonContainer = null
framehandle DFavorButton1 = null
framehandle DFTooltip1 = null
framehandle DFStackCount1 = null
framehandle BackdropDFavorButton1 = null
trigger TriggerDFavorButton1 = null
framehandle DFavorButton2 = null
framehandle DFTooltip2 = null
framehandle DFStackCount2 = null
framehandle BackdropDFavorButton2 = null
trigger TriggerDFavorButton2 = null
framehandle DFavorButton3 = null
framehandle DFTooltip3 = null
framehandle DFStackCount3 = null
framehandle BackdropDFavorButton3 = null
trigger TriggerDFavorButton3 = null
framehandle DFavorButton4 = null
framehandle DFTooltip4 = null
framehandle DFStackCount4 = null
framehandle BackdropDFavorButton4 = null
trigger TriggerDFavorButton4 = null
framehandle DFavorButton5 = null
framehandle DFTooltip5 = null
framehandle DFStackCount5 = null
framehandle BackdropDFavorButton5 = null
trigger TriggerDFavorButton5 = null
framehandle DFavorBackdrop = null
framehandle DFavorText = null
trigger TriggerDFavorBackdrop = null
trigger TriggerDFavorText = null
trigger array HotkeyListener
boolean array isUIVisible
unit array selectedUnit
constant string FAVOUR_ICON_PATH = "UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon.blp"
constant real STACK_SIZE_X = .008
constant real STACK_SIZE_Y = .008
constant real STACK_OFFSET_X = .007
constant real STACK_OFFSET_Y = -.003
constant real BUTTON_SIZE = .017
constant real BUTTON_GUTTER = .004
endglobals
private function processFavourCost takes player play, integer cost returns boolean
local integer id = GetPlayerId(play) + 1
if udg_FavourGathered[id] >= cost then
set udg_FavourGathered[id] = udg_FavourGathered[id] - cost
if GetLocalPlayer() == play then
call BlzFrameSetText(DFavorText, I2S(udg_FavourGathered[id]))
endif
return true
endif
return false
endfunction
function DFavorButton1Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
call BlzFrameSetEnable(DFavorButton1, false)
call BlzFrameSetEnable(DFavorButton1, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostHigh) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl", selectedUnit[id], "origin"))
if GetUnitTypeId(selectedUnit[id]) == 'n01P' then //Enforcer☑
call UnitRemoveAbility(selectedUnit[id], 'A0SF') //[Dark Horde] - Dragon's Blood research☑
call UnitAddAbility(selectedUnit[id], 'A0SA') //Dragon Blood☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0SA', false, false ) //Dragon Blood☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0SG', true, false ) //Dragon's Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01Z' then //Wanderer☑
call UnitRemoveAbility(selectedUnit[id], 'S00L') //Dragons Aggression Req☑
call UnitAddAbility(selectedUnit[id], 'S00K') //Dragon Aggression☑
call UnitAddAbility(selectedUnit[id], 'A0SE') //Dragon Agg Slow☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0SE', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0SG', true, false ) //Dragon's Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'o033' then //Dread Treader☑
call UnitRemoveAbility(selectedUnit[id], 'A0TG') //Sabellian's Ore Req☑
call UnitAddAbility(selectedUnit[id], 'A0TF') //Sabellian Ore☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0TF', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01N' then //Demoniac☑
call UnitRemoveAbility(selectedUnit[id], 'A0S3') //Deathwing Will Req☑
call UnitAddAbility(selectedUnit[id], 'A0S2') //Deathwing Will☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0S2', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'o034' then //Lama☑
call UnitRemoveAbility(selectedUnit[id], 'A0TU') //Visions of N req☑
call UnitAddAbility(selectedUnit[id], 'A0TT') //Visions of N☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0TT', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01S' then //Magi☑
call UnitRemoveAbility(selectedUnit[id], 'A0SZ') //Magma Skin req☑
call UnitAddAbility(selectedUnit[id], 'A0SY') //Magma Skin☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0SY', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'o036' then //Assassin☑
call UnitRemoveAbility(selectedUnit[id], 'A0T6') //Pride of S req☑
call UnitAddAbility(selectedUnit[id], 'A0T5') //Pride of S☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0T5', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0T5', false, false )
call UnitAddAbility(selectedUnit[id], 'A0S0') //Crit + Evad☑
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01R' then //Goliath☑
call UnitRemoveAbility(selectedUnit[id], 'A0RV') //Anarchist req☑
call UnitAddAbility(selectedUnit[id], 'A0RU') //Anarchist☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0RU', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0RU', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01J' then //Black Rider☑
call UnitRemoveAbility(selectedUnit[id], 'A0TH') //Sacifice of N req☑
call UnitAddAbility(selectedUnit[id], 'A0TI') //Sacrifice of N☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0TI', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0TI', false, false )
call BlzSetUnitMaxHP(selectedUnit[id], BlzGetUnitMaxHP(selectedUnit[id]) + 100)
call SetWidgetLife(selectedUnit[id], GetWidgetLife(selectedUnit[id]) + 100.00)
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
endif
set cVal = GetUnitUserData(selectedUnit[id])
set udg_FavoursLearned[cVal] = ( udg_FavoursLearned[cVal] + 1 )
endif
endif
// set udg_DButton1 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton1Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton1) and BlzFrameGetEnable(DFavorButton1) then
call BlzFrameClick(DFavorButton1)
endif
endif
endfunction
function DFavorButton2Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer abil
call BlzFrameSetEnable(DFavorButton2, false)
call BlzFrameSetEnable(DFavorButton2, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonGuile[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIam\\AIamTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonGuile[cVal] = udg_DF_DragonGuile[cVal] + udg_CONSTANT_FavourCostLow
set abil = 'A0WD'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
set abil = 'A0WI'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
endif
endif
endif
// set udg_DButton2 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton2Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton2) and BlzFrameGetEnable(DFavorButton2) then
call BlzFrameClick(DFavorButton2)
endif
endif
endfunction
// Dragon's Heart
function DFavorButton3Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer value
call BlzFrameSetEnable(DFavorButton3, false)
call BlzFrameSetEnable(DFavorButton3, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonHeart[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIim\\AIimTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonHeart[cVal] = udg_DF_DragonHeart[cVal] + udg_CONSTANT_FavourCostLow
set value = 20 * udg_CONSTANT_FavourCostLow
call BlzSetUnitMaxHP(selectedUnit[id], BlzGetUnitMaxHP(selectedUnit[id]) + value)
call SetWidgetLife(selectedUnit[id], GetWidgetLife(selectedUnit[id]) + value)
endif
endif
endif
// set udg_DButton3 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton3Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton3) and BlzFrameGetEnable(DFavorButton3) then
call BlzFrameClick(DFavorButton3)
endif
endif
endfunction
// Dragon's Rage
function DFavorButton4Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer abil
call BlzFrameSetEnable(DFavorButton4, false)
call BlzFrameSetEnable(DFavorButton4, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonRage[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonRage[cVal] = udg_DF_DragonRage[cVal] + udg_CONSTANT_FavourCostLow
set abil = 'A0WJ'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
endif
endif
endif
// set udg_DButton4 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton4Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton4) and BlzFrameGetEnable(DFavorButton4) then
call BlzFrameClick(DFavorButton4)
endif
endif
endfunction
// Dragon's Wisdom
function DFavorButton5Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer value
call BlzFrameSetEnable(DFavorButton5, false)
call BlzFrameSetEnable(DFavorButton5, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonWisdom[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonWisdom[cVal] = udg_DF_DragonWisdom[cVal] + udg_CONSTANT_FavourCostLow
set value = (10 * udg_CONSTANT_FavourCostLow)
call BlzSetUnitMaxMana(selectedUnit[id], BlzGetUnitMaxMana(selectedUnit[id]) + value)
call SetUnitState(selectedUnit[id], UNIT_STATE_MANA, GetUnitState(selectedUnit[id], UNIT_STATE_MANA) + value)
endif
endif
endif
// set udg_DButton5 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton5Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton5) and BlzFrameGetEnable(DFavorButton5) then
call BlzFrameClick(DFavorButton5)
endif
endif
endfunction
function AddFavour takes player play, integer amount returns nothing
local integer id = GetPlayerId(play) + 1
set udg_FavourGathered[id] = udg_FavourGathered[id] + amount
if udg_FavourGathered[id] == 0 then
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, false)
endif
else
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, true)
call BlzFrameSetText(DFavorText, I2S(udg_FavourGathered[id]))
endif
endif
endfunction
function hideFavourUI takes player play returns nothing
local integer id = GetPlayerId(play)
if GetLocalPlayer() == play then
call BlzFrameSetVisible(ButtonBackdrop, false)
endif
set isUIVisible[id] = false
set selectedUnit[id] = null
endfunction
function showFavourUI takes player play returns nothing
if GetLocalPlayer() == play then
call BlzFrameSetVisible(ButtonBackdrop, true)
endif
set isUIVisible[GetPlayerId(play)] = true
endfunction
function SetFavourStackText takes player play, framehandle whichFrame, integer level, boolean maxed, boolean active returns nothing
local string s = ""
if not active then
set s = "|cff777777"
else
if maxed then
set s = "|cff2bff00"
endif
endif
if GetLocalPlayer() == play then
call BlzFrameSetText(whichFrame, s + I2S(level))
endif
endfunction
// to use inside GetLocalPlayer()
function SetFavourStackTextLocal takes framehandle whichFrame, integer level, boolean maxed, boolean active returns nothing
local string s = ""
if not active then
set s = "|cff777777"
else
if maxed then
set s = "|cff2bff00"
endif
endif
call BlzFrameSetText(whichFrame, s + I2S(level))
endfunction
private function setTooltip takes framehandle btn, framehandle tooltipMaster, string title, string cost, string body returns nothing
local framehandle toolTitle
local framehandle toolText
set tooltipMaster = BlzCreateFrame("TooltipTextEx", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
set toolTitle = BlzGetFrameByName("TooltipTextExTitle", 0)
set toolText = BlzGetFrameByName("TooltipTextExValue", 0)
call BlzFrameSetText(toolTitle, title)
call BlzFrameSetText(toolText, body)
call BlzFrameSetText(BlzGetFrameByName("TooltipTextExGoldAmount", 0), cost)
call BlzFrameSetTexture(BlzGetFrameByName("TooltipTextExGoldIcon", 0), FAVOUR_ICON_PATH, 0, true)
call BlzFrameSetVisible(BlzGetFrameByName("TooltipTextExLumberIcon", 0), false) // hide lumber icon
call BlzFrameSetVisible(BlzGetFrameByName("TooltipTextExFoodIcon", 0), false) // hide food icon
call BlzFrameSetTooltip(btn, tooltipMaster)
call BlzFrameSetPoint(tooltipMaster, FRAMEPOINT_TOPLEFT, toolTitle, FRAMEPOINT_TOPLEFT, -.005, .0055)
call BlzFrameSetPoint(tooltipMaster, FRAMEPOINT_BOTTOMRIGHT, toolText, FRAMEPOINT_BOTTOMRIGHT, .005, -.0055)
call BlzFrameSetAbsPoint(toolText, FRAMEPOINT_BOTTOMRIGHT, 0.8 -.005, 0.1625 + .0055)
set toolTitle = null
set toolText = null
endfunction
private function init takes nothing returns nothing
local integer i = 0
local framehandle fh
// call BlzLoadTOCFile("UI\\CustomUI.toc")
// Button container backdrop
set ButtonBackdrop = BlzCreateFrameByType("BACKDROP", "ButtonBackdrop", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
// set ButtonContainer = BlzCreateFrameByType("FRAME", "ButtonBackdrop", BlzGetFrameByName("SimpleInfoPanelUnitDetail",0), "", 0)
// call BlzFrameSetSize(ButtonBackdrop, (BUTTON_SIZE * 5) + (BUTTON_GUTTER * 4), BUTTON_SIZE)
call BlzFrameSetSize(ButtonBackdrop, BUTTON_GUTTER * 8 + BUTTON_SIZE * 5, BUTTON_SIZE + BUTTON_GUTTER * 4)
call BlzFrameSetAbsPoint(ButtonBackdrop, FRAMEPOINT_CENTER, 0.4, 0.155) // y of 0.0925 sets this right below the unit name
call BlzFrameSetTexture(ButtonBackdrop, "DarkHordeCounter.blp", 0, true)
set ButtonContainer = BlzCreateFrameByType("FRAME", "ButtonContainer", ButtonBackdrop, "", 0)
call BlzFrameSetSize(ButtonContainer, BUTTON_GUTTER * 4 + BUTTON_SIZE * 5, BUTTON_SIZE)
call BlzFrameSetPoint(ButtonContainer, FRAMEPOINT_CENTER, ButtonBackdrop, FRAMEPOINT_CENTER, 0., 0.)
// Dragon's Commendation
set DFavorButton1 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton1, FRAMEPOINT_TOPLEFT, 0.355000, 0.102690)
// call BlzFrameSetAbsPoint(DFavorButton1, FRAMEPOINT_BOTTOMRIGHT, 0.372700, 0.0850000)
call BlzFrameSetSize(DFavorButton1, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton1, FRAMEPOINT_LEFT, ButtonContainer, FRAMEPOINT_LEFT, 0., 0.)
set BackdropDFavorButton1 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton1", DFavorButton1, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton1, DFavorButton1)
call BlzFrameSetTexture(BackdropDFavorButton1, "BTNDragonCommendation.blp", 0, true)
set TriggerDFavorButton1 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton1, DFavorButton1, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton1, function DFavorButton1Func)
call setTooltip(DFavorButton1, DFTooltip1, "Dragon's Commendation " + " (|cffffcc00" + "Ctrl + Q" + "|r)", "40", /*
*/ "Unlocks the unit's special ability")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton1, 0, 0)
set DFStackCount1 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount1, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton1, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Guile
set DFavorButton2 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton2, FRAMEPOINT_TOPLEFT, 0.375000, 0.102870)
// call BlzFrameSetAbsPoint(DFavorButton2, FRAMEPOINT_BOTTOMRIGHT, 0.392700, 0.0851800)
call BlzFrameSetSize(DFavorButton2, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton2, FRAMEPOINT_LEFT, DFavorButton1, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton2 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton2", DFavorButton2, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton2, DFavorButton2)
call BlzFrameSetTexture(BackdropDFavorButton2, "BTNDragonGuile.blp", 0, true)
set TriggerDFavorButton2 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton2, DFavorButton2, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton2, function DFavorButton2Func)
call setTooltip(DFavorButton2, DFTooltip2, "Dragon's Guile " + " (|cffffcc00" + "Ctrl + W" + "|r)", "5", /*
*/ "Increases attack rate by 5%% and movement speed by 10 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton2, 0, 0)
set DFStackCount2 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount2, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton2, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Heart
set DFavorButton3 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton3, FRAMEPOINT_TOPLEFT, 0.395000, 0.103060)
// call BlzFrameSetAbsPoint(DFavorButton3, FRAMEPOINT_BOTTOMRIGHT, 0.412700, 0.0853700)
call BlzFrameSetSize(DFavorButton3, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton3, FRAMEPOINT_LEFT, DFavorButton2, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton3 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton3", DFavorButton3, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton3, DFavorButton3)
call BlzFrameSetTexture(BackdropDFavorButton3, "BTNDragonHeart.blp", 0, true)
set TriggerDFavorButton3 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton3, DFavorButton3, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton3, function DFavorButton3Func)
call setTooltip(DFavorButton3, DFTooltip3, "Dragon's Heart " + " (|cffffcc00" + "Ctrl + E" + "|r)", "5", /*
*/ "Increases hit points by 100 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton3, 0, 0)
set DFStackCount3 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount3, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton3, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Rage
set DFavorButton4 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton4, FRAMEPOINT_TOPLEFT, 0.415000, 0.103040)
// call BlzFrameSetAbsPoint(DFavorButton4, FRAMEPOINT_BOTTOMRIGHT, 0.432700, 0.0853500)
call BlzFrameSetSize(DFavorButton4, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton4, FRAMEPOINT_LEFT, DFavorButton3, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton4 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton4", DFavorButton4, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton4, DFavorButton4)
call BlzFrameSetTexture(BackdropDFavorButton4, "BTNDragonRage.blp", 0, true)
set TriggerDFavorButton4 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton4, DFavorButton4, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton4, function DFavorButton4Func)
call setTooltip(DFavorButton4, DFTooltip4, "Dragon's Rage " + " (|cffffcc00" + "Ctrl + R" + "|r)", "5", /*
*/ "Increases attack damage by 5 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton4, 0, 0)
set DFStackCount4 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount4, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton4, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Wisdom
set DFavorButton5 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton5, FRAMEPOINT_TOPLEFT, 0.435000, 0.103040)
// call BlzFrameSetAbsPoint(DFavorButton5, FRAMEPOINT_BOTTOMRIGHT, 0.452700, 0.0853500)
call BlzFrameSetSize(DFavorButton5, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton5, FRAMEPOINT_LEFT, DFavorButton4, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton5 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton5", DFavorButton5, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton5, DFavorButton5)
call BlzFrameSetTexture(BackdropDFavorButton5, "BTNDragonMana.blp", 0, true)
set TriggerDFavorButton5 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton5, DFavorButton5, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton5, function DFavorButton5Func)
call setTooltip(DFavorButton5, DFTooltip5, "Dragon's Wisdom " + " (|cffffcc00" + "Ctrl + T" + "|r)", "5", /*
*/ "Increases mana by 50 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton5, 0, 0)
set DFStackCount5 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount5, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton5, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Hotkeys
loop
set i = i + 1
exitwhen i > 5
set HotkeyListener[i] = CreateTrigger()
endloop
set i = -1
loop
set i = i + 1
exitwhen i > bj_MAX_PLAYER_SLOTS
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[1], Player(i), OSKEY_Q, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[2], Player(i), OSKEY_W, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[3], Player(i), OSKEY_E, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[4], Player(i), OSKEY_R, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[5], Player(i), OSKEY_T, OSKEY_META.CTRL, true)
endloop
call TriggerAddAction(HotkeyListener[1], function DFavorButton1Hotkey)
call TriggerAddAction(HotkeyListener[2], function DFavorButton2Hotkey)
call TriggerAddAction(HotkeyListener[3], function DFavorButton3Hotkey)
call TriggerAddAction(HotkeyListener[4], function DFavorButton4Hotkey)
call TriggerAddAction(HotkeyListener[5], function DFavorButton5Hotkey)
// Favour counter backdrop
set DFavorBackdrop = BlzCreateFrameByType("BACKDROP", "DFavorBackdrop", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 1)
// call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_TOPLEFT, 0.360000, 0.139950)
// call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_BOTTOMRIGHT, 0.448480, 0.113800)
call BlzFrameSetSize(DFavorBackdrop, .06, .025)
call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_CENTER, 0.4, 0.13) // y of 0.0925 sets this right below the unit name
call BlzFrameSetTexture(DFavorBackdrop, "DarkHordeCounter.blp", 0, true)
// Favour amount text
set DFavorText = BlzCreateFrameByType("TEXT", "name", DFavorBackdrop, "", 0)
call BlzFrameSetPoint(DFavorText, FRAMEPOINT_CENTER, DFavorBackdrop, FRAMEPOINT_CENTER, 0., -.001)
call BlzFrameSetText(DFavorText, "|cffFFFFFF40|r")
call BlzFrameSetEnable(DFavorText, false)
call BlzFrameSetScale(DFavorText, 1.29)
call BlzFrameSetTextAlignment(DFavorText, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
call BlzFrameSetVisible(ButtonBackdrop, false)
endfunction
endlibrary
library DFavour initializer init uses OsKeyMeta, SimError//, InitTOCFiles
globals
framehandle ButtonBackdrop = null
framehandle ButtonContainer = null
framehandle DFavorButton1 = null
framehandle DFTooltip1 = null
framehandle DFStackCount1 = null
framehandle BackdropDFavorButton1 = null
trigger TriggerDFavorButton1 = null
framehandle DFavorButton2 = null
framehandle DFTooltip2 = null
framehandle DFStackCount2 = null
framehandle BackdropDFavorButton2 = null
trigger TriggerDFavorButton2 = null
framehandle DFavorButton3 = null
framehandle DFTooltip3 = null
framehandle DFStackCount3 = null
framehandle BackdropDFavorButton3 = null
trigger TriggerDFavorButton3 = null
framehandle DFavorButton4 = null
framehandle DFTooltip4 = null
framehandle DFStackCount4 = null
framehandle BackdropDFavorButton4 = null
trigger TriggerDFavorButton4 = null
framehandle DFavorButton5 = null
framehandle DFTooltip5 = null
framehandle DFStackCount5 = null
framehandle BackdropDFavorButton5 = null
trigger TriggerDFavorButton5 = null
framehandle DFavorBackdrop = null
framehandle DFavorText = null
trigger TriggerDFavorBackdrop = null
trigger TriggerDFavorText = null
trigger array HotkeyListener
boolean array isUIVisible
unit array selectedUnit
constant string FAVOUR_ICON_PATH = "UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon.blp"
constant real STACK_SIZE_X = .008
constant real STACK_SIZE_Y = .008
constant real STACK_OFFSET_X = .007
constant real STACK_OFFSET_Y = -.003
constant real BUTTON_SIZE = .017
constant real BUTTON_GUTTER = .004
endglobals
private function processFavourCost takes player play, integer cost returns boolean
local integer id = GetPlayerId(play) + 1
if udg_FavourGathered[id] >= cost then
set udg_FavourGathered[id] = udg_FavourGathered[id] - cost
if GetLocalPlayer() == play then
call BlzFrameSetText(DFavorText, I2S(udg_FavourGathered[id]))
endif
return true
endif
return false
endfunction
function DFavorButton1Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
call BlzFrameSetEnable(DFavorButton1, false)
call BlzFrameSetEnable(DFavorButton1, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostHigh) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl", selectedUnit[id], "origin"))
if GetUnitTypeId(selectedUnit[id]) == 'n00Q' then
call UnitRemoveAbility(selectedUnit[id], 'A061')
call UnitAddAbility(selectedUnit[id], 'A02A')
call BlzUnitDisableAbility( selectedUnit[id], 'A02A', false, false )
call BlzUnitDisableAbility( selectedUnit[id], 'A02D', true, false )
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'n00R' then
call UnitRemoveAbility(selectedUnit[id], 'S004')
call UnitAddAbility(selectedUnit[id], 'S002')
call UnitAddAbility(selectedUnit[id], 'A02C')
call SetUnitAbilityLevel(selectedUnit[id], 'A02C', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A02D', true, false )
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'o00M' then
call UnitRemoveAbility(selectedUnit[id], 'A062')
call UnitAddAbility(selectedUnit[id], 'A02J')
call BlzUnitDisableAbility( selectedUnit[id], 'A02J', false, false )
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'n00U' then
call UnitRemoveAbility(selectedUnit[id], 'A064')
call UnitAddAbility(selectedUnit[id], 'A02Q')
call BlzUnitDisableAbility( selectedUnit[id], 'A02Q', false, false )
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'o00N' then
call UnitRemoveAbility(selectedUnit[id], 'A063')
call UnitAddAbility(selectedUnit[id], 'A02Y')
call BlzUnitDisableAbility( selectedUnit[id], 'A02Y', false, false )
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'n00T' then
call UnitRemoveAbility(selectedUnit[id], 'A065')
call UnitAddAbility(selectedUnit[id], 'A03B')
call BlzUnitDisableAbility( selectedUnit[id], 'A03B', false, false )
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'o00O' then
call UnitRemoveAbility(selectedUnit[id], 'A066')
call UnitAddAbility(selectedUnit[id], 'A03D')
call SetUnitAbilityLevel(selectedUnit[id], 'A03D', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A03D', false, false )
call UnitAddAbility(selectedUnit[id], 'A03F')
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'n00V' then
call UnitRemoveAbility(selectedUnit[id], 'A067')
call UnitAddAbility(selectedUnit[id], 'A03E')
call SetUnitAbilityLevel(selectedUnit[id], 'A03E', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A03E', false, false )
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
elseif GetUnitTypeId(selectedUnit[id]) == 'n00W' then
call UnitRemoveAbility(selectedUnit[id], 'A068')
call UnitAddAbility(selectedUnit[id], 'A03J')
call SetUnitAbilityLevel(selectedUnit[id], 'A03J', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A03J', false, false )
call BlzSetUnitMaxHP(selectedUnit[id], BlzGetUnitMaxHP(selectedUnit[id]) + 100)
call SetWidgetLife(selectedUnit[id], GetWidgetLife(selectedUnit[id]) + 100.00)
call UnitAddAbility(selectedUnit[id], 'A05P')
call UnitAddAbility(selectedUnit[id], 'A060')
endif
set cVal = GetUnitUserData(selectedUnit[id])
set udg_FavoursLearned[cVal] = ( udg_FavoursLearned[cVal] + 1 )
endif
endif
// set udg_DButton1 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton1Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton1) and BlzFrameGetEnable(DFavorButton1) then
call BlzFrameClick(DFavorButton1)
endif
endif
endfunction
function DFavorButton2Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer abil
call BlzFrameSetEnable(DFavorButton2, false)
call BlzFrameSetEnable(DFavorButton2, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonGuile[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIam\\AIamTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonGuile[cVal] = udg_DF_DragonGuile[cVal] + udg_CONSTANT_FavourCostLow
set abil = 'A05X'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
set abil = 'A05Y'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
endif
endif
endif
// set udg_DButton2 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton2Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton2) and BlzFrameGetEnable(DFavorButton2) then
call BlzFrameClick(DFavorButton2)
endif
endif
endfunction
// Dragon's Heart
function DFavorButton3Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer value
call BlzFrameSetEnable(DFavorButton3, false)
call BlzFrameSetEnable(DFavorButton3, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonHeart[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIim\\AIimTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonHeart[cVal] = udg_DF_DragonHeart[cVal] + udg_CONSTANT_FavourCostLow
set value = 20 * udg_CONSTANT_FavourCostLow
call BlzSetUnitMaxHP(selectedUnit[id], BlzGetUnitMaxHP(selectedUnit[id]) + value)
call SetWidgetLife(selectedUnit[id], GetWidgetLife(selectedUnit[id]) + value)
endif
endif
endif
// set udg_DButton3 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton3Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton3) and BlzFrameGetEnable(DFavorButton3) then
call BlzFrameClick(DFavorButton3)
endif
endif
endfunction
// Dragon's Rage
function DFavorButton4Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer abil
call BlzFrameSetEnable(DFavorButton4, false)
call BlzFrameSetEnable(DFavorButton4, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonRage[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonRage[cVal] = udg_DF_DragonRage[cVal] + udg_CONSTANT_FavourCostLow
set abil = 'A05W'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
endif
endif
endif
// set udg_DButton4 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton4Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton4) and BlzFrameGetEnable(DFavorButton4) then
call BlzFrameClick(DFavorButton4)
endif
endif
endfunction
// Dragon's Wisdom
function DFavorButton5Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer value
call BlzFrameSetEnable(DFavorButton5, false)
call BlzFrameSetEnable(DFavorButton5, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonWisdom[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonWisdom[cVal] = udg_DF_DragonWisdom[cVal] + udg_CONSTANT_FavourCostLow
set value = (10 * udg_CONSTANT_FavourCostLow)
call BlzSetUnitMaxMana(selectedUnit[id], BlzGetUnitMaxMana(selectedUnit[id]) + value)
call SetUnitState(selectedUnit[id], UNIT_STATE_MANA, GetUnitState(selectedUnit[id], UNIT_STATE_MANA) + value)
endif
endif
endif
// set udg_DButton5 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton5Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton5) and BlzFrameGetEnable(DFavorButton5) then
call BlzFrameClick(DFavorButton5)
endif
endif
endfunction
function AddFavour takes player play, integer amount returns nothing
local integer id = GetPlayerId(play) + 1
set udg_FavourGathered[id] = udg_FavourGathered[id] + amount
if udg_FavourGathered[id] == 0 then
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, false)
endif
else
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, true)
call BlzFrameSetText(DFavorText, I2S(udg_FavourGathered[id]))
endif
endif
endfunction
function hideFavourUI takes player play returns nothing
local integer id = GetPlayerId(play)
if GetLocalPlayer() == play then
call BlzFrameSetVisible(ButtonBackdrop, false)
endif
set isUIVisible[id] = false
set selectedUnit[id] = null
endfunction
function showFavourUI takes player play returns nothing
if GetLocalPlayer() == play then
call BlzFrameSetVisible(ButtonBackdrop, true)
endif
set isUIVisible[GetPlayerId(play)] = true
endfunction
function SetFavourStackText takes player play, framehandle whichFrame, integer level, boolean maxed, boolean active returns nothing
local string s = ""
if not active then
set s = "|cff777777"
else
if maxed then
set s = "|cff2bff00"
endif
endif
if GetLocalPlayer() == play then
call BlzFrameSetText(whichFrame, s + I2S(level))
endif
endfunction
// to use inside GetLocalPlayer()
function SetFavourStackTextLocal takes framehandle whichFrame, integer level, boolean maxed, boolean active returns nothing
local string s = ""
if not active then
set s = "|cff777777"
else
if maxed then
set s = "|cff2bff00"
endif
endif
call BlzFrameSetText(whichFrame, s + I2S(level))
endfunction
private function setTooltip takes framehandle btn, framehandle tooltipMaster, string title, string cost, string body returns nothing
local framehandle toolTitle
local framehandle toolText
set tooltipMaster = BlzCreateFrame("TooltipTextEx", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
set toolTitle = BlzGetFrameByName("TooltipTextExTitle", 0)
set toolText = BlzGetFrameByName("TooltipTextExValue", 0)
call BlzFrameSetText(toolTitle, title)
call BlzFrameSetText(toolText, body)
call BlzFrameSetText(BlzGetFrameByName("TooltipTextExGoldAmount", 0), cost)
call BlzFrameSetTexture(BlzGetFrameByName("TooltipTextExGoldIcon", 0), FAVOUR_ICON_PATH, 0, true)
call BlzFrameSetVisible(BlzGetFrameByName("TooltipTextExLumberIcon", 0), false) // hide lumber icon
call BlzFrameSetVisible(BlzGetFrameByName("TooltipTextExFoodIcon", 0), false) // hide food icon
call BlzFrameSetTooltip(btn, tooltipMaster)
call BlzFrameSetPoint(tooltipMaster, FRAMEPOINT_TOPLEFT, toolTitle, FRAMEPOINT_TOPLEFT, -.005, .0055)
call BlzFrameSetPoint(tooltipMaster, FRAMEPOINT_BOTTOMRIGHT, toolText, FRAMEPOINT_BOTTOMRIGHT, .005, -.0055)
call BlzFrameSetAbsPoint(toolText, FRAMEPOINT_BOTTOMRIGHT, 0.8 -.005, 0.1625 + .0055)
set toolTitle = null
set toolText = null
endfunction
private function init takes nothing returns nothing
local integer i = 0
local framehandle fh
call BlzLoadTOCFile("UI\\CustomUI.toc")
// Button container backdrop
set ButtonBackdrop = BlzCreateFrameByType("BACKDROP", "ButtonBackdrop", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
// set ButtonContainer = BlzCreateFrameByType("FRAME", "ButtonBackdrop", BlzGetFrameByName("SimpleInfoPanelUnitDetail",0), "", 0)
// call BlzFrameSetSize(ButtonBackdrop, (BUTTON_SIZE * 5) + (BUTTON_GUTTER * 4), BUTTON_SIZE)
call BlzFrameSetSize(ButtonBackdrop, BUTTON_GUTTER * 8 + BUTTON_SIZE * 5, BUTTON_SIZE + BUTTON_GUTTER * 4)
call BlzFrameSetAbsPoint(ButtonBackdrop, FRAMEPOINT_CENTER, 0.4, 0.155) // y of 0.0925 sets this right below the unit name
call BlzFrameSetTexture(ButtonBackdrop, "DarkHordeCounter.blp", 0, true)
set ButtonContainer = BlzCreateFrameByType("FRAME", "ButtonContainer", ButtonBackdrop, "", 0)
call BlzFrameSetSize(ButtonContainer, BUTTON_GUTTER * 4 + BUTTON_SIZE * 5, BUTTON_SIZE)
call BlzFrameSetPoint(ButtonContainer, FRAMEPOINT_CENTER, ButtonBackdrop, FRAMEPOINT_CENTER, 0., 0.)
// Dragon's Commendation
set DFavorButton1 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton1, FRAMEPOINT_TOPLEFT, 0.355000, 0.102690)
// call BlzFrameSetAbsPoint(DFavorButton1, FRAMEPOINT_BOTTOMRIGHT, 0.372700, 0.0850000)
call BlzFrameSetSize(DFavorButton1, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton1, FRAMEPOINT_LEFT, ButtonContainer, FRAMEPOINT_LEFT, 0., 0.)
set BackdropDFavorButton1 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton1", DFavorButton1, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton1, DFavorButton1)
call BlzFrameSetTexture(BackdropDFavorButton1, "BTNDragonCommendation.blp", 0, true)
set TriggerDFavorButton1 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton1, DFavorButton1, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton1, function DFavorButton1Func)
call setTooltip(DFavorButton1, DFTooltip1, "Dragon's Commendation" + " (|cffffcc00" + "Ctrl + Q" + "|r)", "40", /*
*/ "Unlocks the unit's special ability")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton1, 0, 0)
set DFStackCount1 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount1, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton1, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Guile
set DFavorButton2 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton2, FRAMEPOINT_TOPLEFT, 0.375000, 0.102870)
// call BlzFrameSetAbsPoint(DFavorButton2, FRAMEPOINT_BOTTOMRIGHT, 0.392700, 0.0851800)
call BlzFrameSetSize(DFavorButton2, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton2, FRAMEPOINT_LEFT, DFavorButton1, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton2 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton2", DFavorButton2, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton2, DFavorButton2)
call BlzFrameSetTexture(BackdropDFavorButton2, "BTNDragonGuile.blp", 0, true)
set TriggerDFavorButton2 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton2, DFavorButton2, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton2, function DFavorButton2Func)
call setTooltip(DFavorButton2, DFTooltip2, "Dragon's Guile" + " (|cffffcc00" + "Ctrl + W" + "|r)", "5", /*
*/ "Increases attack rate by 5%% and movement speed by 10 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton2, 0, 0)
set DFStackCount2 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount2, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton2, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Heart
set DFavorButton3 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton3, FRAMEPOINT_TOPLEFT, 0.395000, 0.103060)
// call BlzFrameSetAbsPoint(DFavorButton3, FRAMEPOINT_BOTTOMRIGHT, 0.412700, 0.0853700)
call BlzFrameSetSize(DFavorButton3, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton3, FRAMEPOINT_LEFT, DFavorButton2, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton3 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton3", DFavorButton3, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton3, DFavorButton3)
call BlzFrameSetTexture(BackdropDFavorButton3, "BTNDragonHeart.blp", 0, true)
set TriggerDFavorButton3 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton3, DFavorButton3, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton3, function DFavorButton3Func)
call setTooltip(DFavorButton3, DFTooltip3, "Dragon's Heart" + " (|cffffcc00" + "Ctrl + E" + "|r)", "5", /*
*/ "Increases hit points by 100 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton3, 0, 0)
set DFStackCount3 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount3, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton3, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Rage
set DFavorButton4 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton4, FRAMEPOINT_TOPLEFT, 0.415000, 0.103040)
// call BlzFrameSetAbsPoint(DFavorButton4, FRAMEPOINT_BOTTOMRIGHT, 0.432700, 0.0853500)
call BlzFrameSetSize(DFavorButton4, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton4, FRAMEPOINT_LEFT, DFavorButton3, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton4 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton4", DFavorButton4, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton4, DFavorButton4)
call BlzFrameSetTexture(BackdropDFavorButton4, "BTNDragonRage.blp", 0, true)
set TriggerDFavorButton4 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton4, DFavorButton4, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton4, function DFavorButton4Func)
call setTooltip(DFavorButton4, DFTooltip4, "Dragon's Rage" + " (|cffffcc00" + "Ctrl + R" + "|r)", "5", /*
*/ "Increases attack damage by 5 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton4, 0, 0)
set DFStackCount4 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount4, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton4, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Wisdom
set DFavorButton5 = BlzCreateFrame("ScriptDialogButton", ButtonContainer, 0, 0)
// call BlzFrameSetAbsPoint(DFavorButton5, FRAMEPOINT_TOPLEFT, 0.435000, 0.103040)
// call BlzFrameSetAbsPoint(DFavorButton5, FRAMEPOINT_BOTTOMRIGHT, 0.452700, 0.0853500)
call BlzFrameSetSize(DFavorButton5, BUTTON_SIZE, BUTTON_SIZE)
call BlzFrameSetPoint(DFavorButton5, FRAMEPOINT_LEFT, DFavorButton4, FRAMEPOINT_RIGHT, BUTTON_GUTTER, 0.)
set BackdropDFavorButton5 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton5", DFavorButton5, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton5, DFavorButton5)
call BlzFrameSetTexture(BackdropDFavorButton5, "BTNDragonMana.blp", 0, true)
set TriggerDFavorButton5 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton5, DFavorButton5, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton5, function DFavorButton5Func)
call setTooltip(DFavorButton5, DFTooltip5, "Dragon's Wisdom" + " (|cffffcc00" + "Ctrl + T" + "|r)", "5", /*
*/ "Increases mana by 50 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton5, 0, 0)
set DFStackCount5 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount5, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton5, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Hotkeys
loop
set i = i + 1
exitwhen i > 5
set HotkeyListener[i] = CreateTrigger()
endloop
set i = -1
loop
set i = i + 1
exitwhen i > bj_MAX_PLAYER_SLOTS
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[1], Player(i), OSKEY_Q, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[2], Player(i), OSKEY_W, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[3], Player(i), OSKEY_E, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[4], Player(i), OSKEY_R, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[5], Player(i), OSKEY_T, OSKEY_META.CTRL, true)
endloop
call TriggerAddAction(HotkeyListener[1], function DFavorButton1Hotkey)
call TriggerAddAction(HotkeyListener[2], function DFavorButton2Hotkey)
call TriggerAddAction(HotkeyListener[3], function DFavorButton3Hotkey)
call TriggerAddAction(HotkeyListener[4], function DFavorButton4Hotkey)
call TriggerAddAction(HotkeyListener[5], function DFavorButton5Hotkey)
// Favour counter backdrop
set DFavorBackdrop = BlzCreateFrameByType("BACKDROP", "DFavorBackdrop", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 1)
// call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_TOPLEFT, 0.360000, 0.139950)
// call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_BOTTOMRIGHT, 0.448480, 0.113800)
call BlzFrameSetSize(DFavorBackdrop, .06, .025)
call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_CENTER, 0.4, 0.13) // y of 0.0925 sets this right below the unit name
call BlzFrameSetTexture(DFavorBackdrop, "DarkHordeCounter.blp", 0, true)
// Favour amount text
set DFavorText = BlzCreateFrameByType("TEXT", "name", DFavorBackdrop, "", 0)
call BlzFrameSetPoint(DFavorText, FRAMEPOINT_CENTER, DFavorBackdrop, FRAMEPOINT_CENTER, 0., -.001)
call BlzFrameSetText(DFavorText, "|cffFFFFFF40|r")
call BlzFrameSetEnable(DFavorText, false)
call BlzFrameSetScale(DFavorText, 1.29)
call BlzFrameSetTextAlignment(DFavorText, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
call BlzFrameSetVisible(ButtonBackdrop, false)
endfunction
endlibrary
library DFavour initializer init uses OsKeyMeta, SimError//, InitTOCFiles
globals
framehandle ButtonBackdrop = null
framehandle ButtonContainer = null
framehandle DFavorButton1 = null
framehandle DFTooltip1 = null
framehandle DFStackCount1 = null
framehandle BackdropDFavorButton1 = null
trigger TriggerDFavorButton1 = null
framehandle DFavorButton2 = null
framehandle DFTooltip2 = null
framehandle DFStackCount2 = null
framehandle BackdropDFavorButton2 = null
trigger TriggerDFavorButton2 = null
framehandle DFavorButton3 = null
framehandle DFTooltip3 = null
framehandle DFStackCount3 = null
framehandle BackdropDFavorButton3 = null
trigger TriggerDFavorButton3 = null
framehandle DFavorButton4 = null
framehandle DFTooltip4 = null
framehandle DFStackCount4 = null
framehandle BackdropDFavorButton4 = null
trigger TriggerDFavorButton4 = null
framehandle DFavorButton5 = null
framehandle DFTooltip5 = null
framehandle DFStackCount5 = null
framehandle BackdropDFavorButton5 = null
trigger TriggerDFavorButton5 = null
framehandle DFavorBackdrop = null
framehandle DFavorText = null
trigger TriggerDFavorBackdrop = null
trigger TriggerDFavorText = null
trigger array HotkeyListener
boolean array isUIVisible
unit array selectedUnit
constant string FAVOUR_ICON_PATH = "UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon.blp"
constant real STACK_SIZE_X = .008
constant real STACK_SIZE_Y = .008
constant real STACK_OFFSET_X = .007
constant real STACK_OFFSET_Y = -.003
constant real BUTTON_SIZE = .017
constant real BUTTON_GUTTER = .004
endglobals
private function processFavourCost takes player play, integer cost returns boolean
local integer id = GetPlayerId(play) + 1
if udg_FavourGathered[id] >= cost then
set udg_FavourGathered[id] = udg_FavourGathered[id] - cost
if GetLocalPlayer() == play then
call BlzFrameSetText(DFavorText, I2S(udg_FavourGathered[id]))
endif
return true
endif
return false
endfunction
function DFavorButton1Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
call BlzFrameSetEnable(DFavorButton1, false)
call BlzFrameSetEnable(DFavorButton1, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostHigh) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl", selectedUnit[id], "origin"))
if GetUnitTypeId(selectedUnit[id]) == 'n01P' then //Enforcer☑
call UnitRemoveAbility(selectedUnit[id], 'A0SF') //[Dark Horde] - Dragon's Blood research☑
call UnitAddAbility(selectedUnit[id], 'A0SA') //Dragon Blood☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0SA', false, false ) //Dragon Blood☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0SG', true, false ) //Dragon's Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01Z' then //Wanderer☑
call UnitRemoveAbility(selectedUnit[id], 'S00L') //Dragons Aggression Req☑
call UnitAddAbility(selectedUnit[id], 'S00K') //Dragon Aggression☑
call UnitAddAbility(selectedUnit[id], 'A0SE') //Dragon Agg Slow☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0SE', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0SG', true, false ) //Dragon's Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'o033' then //Dread Treader☑
call UnitRemoveAbility(selectedUnit[id], 'A0TG') //Sabellian's Ore Req☑
call UnitAddAbility(selectedUnit[id], 'A0TF') //Sabellian Ore☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0TF', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01N' then //Demoniac☑
call UnitRemoveAbility(selectedUnit[id], 'A0S3') //Deathwing Will Req☑
call UnitAddAbility(selectedUnit[id], 'A0S2') //Deathwing Will☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0S2', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'o034' then //Lama☑
call UnitRemoveAbility(selectedUnit[id], 'A0TU') //Visions of N req☑
call UnitAddAbility(selectedUnit[id], 'A0TT') //Visions of N☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0TT', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01S' then //Magi☑
call UnitRemoveAbility(selectedUnit[id], 'A0SZ') //Magma Skin req☑
call UnitAddAbility(selectedUnit[id], 'A0SY') //Magma Skin☑
call BlzUnitDisableAbility( selectedUnit[id], 'A0SY', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'o036' then //Assassin☑
call UnitRemoveAbility(selectedUnit[id], 'A0T6') //Pride of S req☑
call UnitAddAbility(selectedUnit[id], 'A0T5') //Pride of S☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0T5', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0T5', false, false )
call UnitAddAbility(selectedUnit[id], 'A0S0') //Crit + Evad☑
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01R' then //Goliath☑
call UnitRemoveAbility(selectedUnit[id], 'A0RV') //Anarchist req☑
call UnitAddAbility(selectedUnit[id], 'A0RU') //Anarchist☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0RU', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0RU', false, false )
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
elseif GetUnitTypeId(selectedUnit[id]) == 'n01J' then //Black Rider☑
call UnitRemoveAbility(selectedUnit[id], 'A0TH') //Sacifice of N req☑
call UnitAddAbility(selectedUnit[id], 'A0TI') //Sacrifice of N☑
call SetUnitAbilityLevel(selectedUnit[id], 'A0TI', 2)
call BlzUnitDisableAbility( selectedUnit[id], 'A0TI', false, false )
call BlzSetUnitMaxHP(selectedUnit[id], BlzGetUnitMaxHP(selectedUnit[id]) + 100)
call SetWidgetLife(selectedUnit[id], GetWidgetLife(selectedUnit[id]) + 100.00)
call UnitAddAbility(selectedUnit[id], 'A0SL') //Effect Commendation☑
call UnitAddAbility(selectedUnit[id], 'A0RY') //Black Dragon Favor (Commendation Requirement)☑
endif
set cVal = GetUnitUserData(selectedUnit[id])
set udg_FavoursLearned[cVal] = ( udg_FavoursLearned[cVal] + 1 )
endif
endif
// set udg_DButton1 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton1Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton1) and BlzFrameGetEnable(DFavorButton1) then
call BlzFrameClick(DFavorButton1)
endif
endif
endfunction
function DFavorButton2Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer abil
call BlzFrameSetEnable(DFavorButton2, false)
call BlzFrameSetEnable(DFavorButton2, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonGuile[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIam\\AIamTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonGuile[cVal] = udg_DF_DragonGuile[cVal] + udg_CONSTANT_FavourCostLow
set abil = 'A0WD'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
set abil = 'A0WI'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
endif
endif
endif
// set udg_DButton2 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton2Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton2) and BlzFrameGetEnable(DFavorButton2) then
call BlzFrameClick(DFavorButton2)
endif
endif
endfunction
// Dragon's Heart
function DFavorButton3Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer value
call BlzFrameSetEnable(DFavorButton3, false)
call BlzFrameSetEnable(DFavorButton3, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonHeart[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIim\\AIimTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonHeart[cVal] = udg_DF_DragonHeart[cVal] + udg_CONSTANT_FavourCostLow
set value = 20 * udg_CONSTANT_FavourCostLow
call BlzSetUnitMaxHP(selectedUnit[id], BlzGetUnitMaxHP(selectedUnit[id]) + value)
call SetWidgetLife(selectedUnit[id], GetWidgetLife(selectedUnit[id]) + value)
endif
endif
endif
// set udg_DButton3 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton3Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton3) and BlzFrameGetEnable(DFavorButton3) then
call BlzFrameClick(DFavorButton3)
endif
endif
endfunction
// Dragon's Rage
function DFavorButton4Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer abil
call BlzFrameSetEnable(DFavorButton4, false)
call BlzFrameSetEnable(DFavorButton4, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonRage[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIsm\\AIsmTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonRage[cVal] = udg_DF_DragonRage[cVal] + udg_CONSTANT_FavourCostLow
set abil = 'A0WJ'
call UnitAddAbility(selectedUnit[id], abil)
call SetUnitAbilityLevel(selectedUnit[id], abil, GetUnitAbilityLevel(selectedUnit[id], abil) + udg_CONSTANT_FavourCostLow)
endif
endif
endif
// set udg_DButton4 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton4Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton4) and BlzFrameGetEnable(DFavorButton4) then
call BlzFrameClick(DFavorButton4)
endif
endif
endfunction
// Dragon's Wisdom
function DFavorButton5Func takes nothing returns nothing
local player play = GetTriggerPlayer()
local integer id = GetPlayerId(play)
local integer cVal
local integer value
call BlzFrameSetEnable(DFavorButton5, false)
call BlzFrameSetEnable(DFavorButton5, true)
if selectedUnit[id] != null then
if not processFavourCost(play, udg_CONSTANT_FavourCostLow) then
call SimError(play, udg_CONSTANT_NotEnoughFavour)
else
set cVal = GetUnitUserData(selectedUnit[id])
if udg_DF_DragonWisdom[cVal] < 20 then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl", selectedUnit[id], "origin"))
set udg_DF_DragonWisdom[cVal] = udg_DF_DragonWisdom[cVal] + udg_CONSTANT_FavourCostLow
set value = (10 * udg_CONSTANT_FavourCostLow)
call BlzSetUnitMaxMana(selectedUnit[id], BlzGetUnitMaxMana(selectedUnit[id]) + value)
call SetUnitState(selectedUnit[id], UNIT_STATE_MANA, GetUnitState(selectedUnit[id], UNIT_STATE_MANA) + value)
endif
endif
endif
// set udg_DButton5 = GetConvertedPlayerId(GetTriggerPlayer())
endfunction
function DFavorButton5Hotkey takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
if BlzFrameIsVisible(DFavorButton5) and BlzFrameGetEnable(DFavorButton5) then
call BlzFrameClick(DFavorButton5)
endif
endif
endfunction
function AddFavour takes player play, integer amount returns nothing
local integer id = GetPlayerId(play) + 1
set udg_FavourGathered[id] = udg_FavourGathered[id] + amount
if udg_FavourGathered[id] == 0 then
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, false)
endif
else
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorBackdrop, true)
call BlzFrameSetText(DFavorText, I2S(udg_FavourGathered[id]))
endif
endif
endfunction
function hideFavourUI takes player play returns nothing
local integer id = GetPlayerId(play)
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorButton1, false)
call BlzFrameSetVisible(DFavorButton2, false)
call BlzFrameSetVisible(DFavorButton3, false)
call BlzFrameSetVisible(DFavorButton4, false)
call BlzFrameSetVisible(DFavorButton5, false)
endif
set isUIVisible[id] = false
set selectedUnit[id] = null
endfunction
function showFavourUI takes player play returns nothing
if GetLocalPlayer() == play then
call BlzFrameSetVisible(DFavorButton1, true)
call BlzFrameSetVisible(DFavorButton2, true)
call BlzFrameSetVisible(DFavorButton3, true)
call BlzFrameSetVisible(DFavorButton4, true)
call BlzFrameSetVisible(DFavorButton5, true)
endif
set isUIVisible[GetPlayerId(play)] = true
endfunction
function SetFavourStackText takes player play, framehandle whichFrame, integer level, boolean maxed, boolean active returns nothing
local string s = ""
if not active then
set s = "|cff777777"
else
if maxed then
set s = "|cff2bff00"
endif
endif
if GetLocalPlayer() == play then
call BlzFrameSetText(whichFrame, s + I2S(level))
endif
endfunction
// to use inside GetLocalPlayer()
function SetFavourStackTextLocal takes framehandle whichFrame, integer level, boolean maxed, boolean active returns nothing
local string s = ""
if not active then
set s = "|cff777777"
else
if maxed then
set s = "|cff2bff00"
endif
endif
call BlzFrameSetText(whichFrame, s + I2S(level))
endfunction
private function setTooltip takes framehandle btn, framehandle tooltipMaster, string title, string cost, string body returns nothing
local framehandle toolTitle
local framehandle toolText
set tooltipMaster = BlzCreateFrame("TooltipTextEx", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
set toolTitle = BlzGetFrameByName("TooltipTextExTitle", 0)
set toolText = BlzGetFrameByName("TooltipTextExValue", 0)
call BlzFrameSetText(toolTitle, title)
call BlzFrameSetText(toolText, body)
call BlzFrameSetText(BlzGetFrameByName("TooltipTextExGoldAmount", 0), cost)
call BlzFrameSetTexture(BlzGetFrameByName("TooltipTextExGoldIcon", 0), FAVOUR_ICON_PATH, 0, true)
call BlzFrameSetVisible(BlzGetFrameByName("TooltipTextExLumberIcon", 0), false) // hide lumber icon
call BlzFrameSetVisible(BlzGetFrameByName("TooltipTextExFoodIcon", 0), false) // hide food icon
call BlzFrameSetTooltip(btn, tooltipMaster)
call BlzFrameSetPoint(tooltipMaster, FRAMEPOINT_TOPLEFT, toolTitle, FRAMEPOINT_TOPLEFT, -.005, .0055)
call BlzFrameSetPoint(tooltipMaster, FRAMEPOINT_BOTTOMRIGHT, toolText, FRAMEPOINT_BOTTOMRIGHT, .005, -.0055)
call BlzFrameSetAbsPoint(toolText, FRAMEPOINT_BOTTOMRIGHT, 0.8 -.005, 0.1625 + .0055)
set toolTitle = null
set toolText = null
endfunction
private function init takes nothing returns nothing
local integer i = 0
local framehandle fh
//call BlzLoadTOCFile("UI\\CustomUI.toc")//
// Dragon's Commendation
set DFavorButton1 = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(DFavorButton1, FRAMEPOINT_TOPLEFT, 0.355000, 0.102690)
call BlzFrameSetAbsPoint(DFavorButton1, FRAMEPOINT_BOTTOMRIGHT, 0.372700, 0.0850000)
set BackdropDFavorButton1 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton1", DFavorButton1, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton1, DFavorButton1)
call BlzFrameSetTexture(BackdropDFavorButton1, "BTNDragonCommendation.blp", 0, true)
set TriggerDFavorButton1 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton1, DFavorButton1, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton1, function DFavorButton1Func)
call setTooltip(DFavorButton1, DFTooltip1, "Dragon's Commendation" + "[|cffffcc00" + "Ctrl + Q" + "|r]", "40", /*
*/ "Unlocks the unit's special ability")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton1, 0, 0)
set DFStackCount1 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount1, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton1, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Guile
set DFavorButton2 = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(DFavorButton2, FRAMEPOINT_TOPLEFT, 0.375000, 0.102870)
call BlzFrameSetAbsPoint(DFavorButton2, FRAMEPOINT_BOTTOMRIGHT, 0.392700, 0.0851800)
set BackdropDFavorButton2 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton2", DFavorButton2, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton2, DFavorButton2)
call BlzFrameSetTexture(BackdropDFavorButton2, "BTNDragonGuile.blp", 0, true)
set TriggerDFavorButton2 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton2, DFavorButton2, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton2, function DFavorButton2Func)
call setTooltip(DFavorButton2, DFTooltip2, "Dragon's Guile" + "[|cffffcc00" + "Ctrl + W" + "|r]", "5", /*
*/ "Increases attack rate by 5%% and movement speed by 10 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton2, 0, 0)
set DFStackCount2 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount2, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton2, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Heart
set DFavorButton3 = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(DFavorButton3, FRAMEPOINT_TOPLEFT, 0.395000, 0.103060)
call BlzFrameSetAbsPoint(DFavorButton3, FRAMEPOINT_BOTTOMRIGHT, 0.412700, 0.0853700)
set BackdropDFavorButton3 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton3", DFavorButton3, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton3, DFavorButton3)
call BlzFrameSetTexture(BackdropDFavorButton3, "BTNDragonHeart.blp", 0, true)
set TriggerDFavorButton3 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton3, DFavorButton3, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton3, function DFavorButton3Func)
call setTooltip(DFavorButton3, DFTooltip3, "Dragon's Heart" + "[|cffffcc00" + "Ctrl + E" + "|r]", "5", /*
*/ "Increases hit points by 100 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton3, 0, 0)
set DFStackCount3 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount3, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton3, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Rage
set DFavorButton4 = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(DFavorButton4, FRAMEPOINT_TOPLEFT, 0.415000, 0.103040)
call BlzFrameSetAbsPoint(DFavorButton4, FRAMEPOINT_BOTTOMRIGHT, 0.432700, 0.0853500)
set BackdropDFavorButton4 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton4", DFavorButton4, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton4, DFavorButton4)
call BlzFrameSetTexture(BackdropDFavorButton4, "BTNDragonRage.blp", 0, true)
set TriggerDFavorButton4 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton4, DFavorButton4, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton4, function DFavorButton4Func)
call setTooltip(DFavorButton4, DFTooltip4, "Dragon's Rage" + "[|cffffcc00" + "Ctrl + R" + "|r]", "5", /*
*/ "Increases attack damage by 5 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton4, 0, 0)
set DFStackCount4 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount4, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton4, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Dragon's Wisdom
set DFavorButton5 = BlzCreateFrame("ScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
call BlzFrameSetAbsPoint(DFavorButton5, FRAMEPOINT_TOPLEFT, 0.435000, 0.103040)
call BlzFrameSetAbsPoint(DFavorButton5, FRAMEPOINT_BOTTOMRIGHT, 0.452700, 0.0853500)
set BackdropDFavorButton5 = BlzCreateFrameByType("BACKDROP", "BackdropDFavorButton5", DFavorButton5, "", 1)
call BlzFrameSetAllPoints(BackdropDFavorButton5, DFavorButton5)
call BlzFrameSetTexture(BackdropDFavorButton5, "BTNDragonMana.blp", 0, true)
set TriggerDFavorButton5 = CreateTrigger()
call BlzTriggerRegisterFrameEvent(TriggerDFavorButton5, DFavorButton5, FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(TriggerDFavorButton5, function DFavorButton5Func)
call setTooltip(DFavorButton5, DFTooltip5, "Dragon's Wisdom" + "[|cffffcc00" + "Ctrl + T" + "|r]", "5", /*
*/ "Increases mana by 50 per stack. Stacks up to 4 times.")
// stack count
set fh = BlzCreateFrame("SimpleTextSlimFrame", DFavorButton5, 0, 0)
set DFStackCount5 = BlzGetFrameByName("SimpleTextSlimFrameValue", 0)
call BlzFrameSetText(DFStackCount5, "0")
call BlzFrameSetSize(fh, STACK_SIZE_X, STACK_SIZE_Y)
call BlzFrameSetPoint(fh, FRAMEPOINT_BOTTOM, DFavorButton5, FRAMEPOINT_BOTTOM, STACK_OFFSET_X, STACK_OFFSET_Y)
// Hotkeys
loop
set i = i + 1
exitwhen i > 5
set HotkeyListener[i] = CreateTrigger()
endloop
set i = -1
loop
set i = i + 1
exitwhen i > bj_MAX_PLAYER_SLOTS
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[1], Player(i), OSKEY_Q, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[2], Player(i), OSKEY_W, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[3], Player(i), OSKEY_E, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[4], Player(i), OSKEY_R, OSKEY_META.CTRL, true)
call BlzTriggerRegisterPlayerKeyEvent(HotkeyListener[5], Player(i), OSKEY_T, OSKEY_META.CTRL, true)
endloop
call TriggerAddAction(HotkeyListener[1], function DFavorButton1Hotkey)
call TriggerAddAction(HotkeyListener[2], function DFavorButton2Hotkey)
call TriggerAddAction(HotkeyListener[3], function DFavorButton3Hotkey)
call TriggerAddAction(HotkeyListener[4], function DFavorButton4Hotkey)
call TriggerAddAction(HotkeyListener[5], function DFavorButton5Hotkey)
set DFavorBackdrop = BlzCreateFrameByType("BACKDROP", "DFavorBackdrop", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 1)
call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_TOPLEFT, 0.360000, 0.139950)
call BlzFrameSetAbsPoint(DFavorBackdrop, FRAMEPOINT_BOTTOMRIGHT, 0.448480, 0.113800)
call BlzFrameSetTexture(DFavorBackdrop, "DarkHordeCounter.blp", 0, true)
set DFavorText = BlzCreateFrameByType("TEXT", "name", DFavorBackdrop, "", 0)
call BlzFrameSetAbsPoint(DFavorText, FRAMEPOINT_TOPLEFT, 0.366800, 0.133080)
call BlzFrameSetAbsPoint(DFavorText, FRAMEPOINT_BOTTOMRIGHT, 0.442800, 0.120000)
call BlzFrameSetText(DFavorText, "|cffFFFFFF40|r")
call BlzFrameSetEnable(DFavorText, false)
call BlzFrameSetScale(DFavorText, 1.29)
call BlzFrameSetTextAlignment(DFavorText, TEXT_JUSTIFY_TOP, TEXT_JUSTIFY_MIDDLE)
call BlzFrameSetVisible(DFavorButton1, false)
call BlzFrameSetVisible(DFavorButton2, false)
call BlzFrameSetVisible(DFavorButton3, false)
call BlzFrameSetVisible(DFavorButton4, false)
call BlzFrameSetVisible(DFavorButton5, false)
endfunction
endlibrary
scope MarchOftheSavages initializer init
globals
private constant integer SPELL_ID = 'A0VS'
private constant integer SAVAGE_ID = 'o049'
private constant integer COUNT = 4
private constant real OFFSET = 110.
private constant real DIST = 200.
private constant real DURATION = 60.
private constant string SPAWN_FX = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
endglobals
private function Conditions takes nothing returns boolean
if GetSpellAbilityId() == SPELL_ID then
return true
endif
return false
endfunction
private function Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local player owner = GetOwningPlayer(caster)
local real facing = GetUnitFacing(caster)
local real a = (facing * bj_DEGTORAD) + bj_PI
local real x = GetUnitX(caster) + Cos(a) * DIST
local real y = GetUnitY(caster) + Sin(a) * DIST
local real offset = ((OFFSET * COUNT) * .5) - (OFFSET * .5)
local integer i = 0
local unit u
set a = a - (bj_PI * .5)
set x = x + Cos(a) * (offset)
set y = y + Sin(a) * (offset)
set a = a + bj_PI
loop
set i = i + 1
exitwhen i > COUNT
set u = CreateUnit(owner, SAVAGE_ID, x, y, facing)
call DestroyEffect(AddSpecialEffect(SPAWN_FX, x, y))
call UnitApplyTimedLife(u, 'BTLF', DURATION)
set x = x + Cos(a) * OFFSET
set y = y + Sin(a) * OFFSET
endloop
set u = null
set caster = null
endfunction
//===========================================================================
private function init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition(trig, Condition( function Conditions ) )
call TriggerAddAction(trig, function Actions )
set trig = null
endfunction
endscope
//TESH.scrollpos=0
//TESH.alwaysfold=0
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// PORTAL SYSTEM v2.5 by Spellbound
//
// The Portal System allows you to teleport your units from one portal to another. Use the Connect Portal skill to link two Portals - this means Portals are buildable.
// A Portal that is already connected can connect to one that is not active, thus disconnecting from it's current counterpart to connect to the new one. You can make teleportation
// work via missiles (that can be configured to be killable) or have delays before teleporting. Check out the Demo Portal folder for templates to use. Conncet Portal 1 has
// detailed explanation on each variable.
//
// Also, reciever Portals will make your units move to their rally points if they have one.
//
//
// REQUIRED:
// Unit Indexer, by Bribe http://www.hiveworkshop.com/forums/spells-569/gui-unit-indexer-1-2-0-2-a-197329/
//
//
// INSTALLATION:
// - Make sure that in File > Preferences > General, the box next to 'Automatically create unknown variables while pasting trigger data' is ticked.
// Then copy the Variable Creator trigger to your map so that the variables are automatically generated. You may then delete it.
// - Copy the Requirements folder to your map.
// - Copy the Sever Connection ability to you map.
// - Unless you already have a dummy unit, import the dummy.mdx model by Vexorian and copy one or all of the Portal Carrier (Dummy Unit - [type]) from this map to yours.
// - Your dummies must have storm crow form if you do not use GUI Auto Fly or Auto Fly
// - Copy the Portals folder to your map.
// - In Portal Connect, set Portal_SeverAbility to Sever Connection (Required) or any non-target spell you want your portals to use to disconnect from a sister portal.
// - Copy any of the four templates (recommended) alongside their corresponding abilities in the Object Editor (always copy units/abilities before triggers).
// For example, Connect Portal 1 uses delayFX - Connect Portal 1 and FX - Blue Energy in it's setup. It also uses a flying dummy unit, so copy that as well if
// you don't have a dummy unit.
// - Save your map.
// You're all done!
//
//
// CUSTOMISATION:
// - All customisation is done in the Connect Portal triggers in the Template folder. In there you may change the various special effects for departure/arrival
// fx, active portal fx, the range at which the portal may catch units to teleport, allowing allies through or not, the use of a missile to carry the units,
// it's height, and what unit will that missile be. The latter means you can chose to have a missile that can be shot down, effectively terminating the
// teleportation prematurely. Keep in mind while I have not put in conditions to prevent flying units from using the Portals, the special effect will display
// at their location, at ground level. If this bothers you, consider using flying dummy units to which you attach a special effect. You'll have to modify
// Portal Periodic for that.
// - Connect Portal 1 - 4 are template triggers. Consider copy/pasting them to your map, and then modifying their configurables.
//
//
// SPECIAL THANKS:
// Bribe, for his wonderful Unit Indexer and letting me know that detecting pathing would be very annoying to deal with in-game :P
//
//
// VARIABLES:
// Portal_activeFX - this is the special effect that will attach to your active Portals. The effect can be changed in Connect Portal.
// Portal_departureFX - this is the special effect that plays when a unit uses a Portal. The effect can be changed in Connect Portal.
// Portal_arrivalFX - this is the special effect that plays when a unit exits a Portal. The effect can be changed in Connect Portal.
// Portal_range - that's the range at which the Portals will pick unit for teleportation.
// Portal_delay - whether you Portals have a delay before they teleport units. Units that move outside their reach (like through knockback)
// will automatically reingage the Portal. If set to 0, the teleportation is instantaneous.
// Portal_delayFXAbil - this is an ability that carries the special effects to apply on your units when there is a delay, to indicate teleportation
// has started. I use an ability here instead of a special effect because abilities can have up to 6 effects, each with their own attachment
// points if you so desire.
// Portal_missileSpeed - if set to 0 or lower, the teleportation is instantaneous. Otherwise, will shoot a missile that will teleport
// units when it reaches the sister Portal. If sister Portal is destroyed before it's reached, the missile and unit is carries
// are both killed.
// Portal_missileDummy - this is the dummy unit that will serve as your missile. I made this configurable in case you would want to have missiles
// that can be destroyed or have missiles that have to walk to the sister Portal. Refer to Connect Portal 3 and 4.
// Portal_missileHeight - the height of your missile. If missile speed is 0 or lower, this does nothing.
// Portal_missileFXAbil - this is ability that carries the special effects of your missile. Can be overlooked if your dummy unit has a
// model already.
// Portal_preventAllies - setting this to TRUE will prevent allies from using your Portal.
// Portal_missileTargetable - setting this to TRUE will remove locust from your missile units, making them targetable.
// Portal_missileUseOwnMovement - setting this to TRUE will order the missile to move instead of moving them by triggers. This is useful if you want
// your missile to respect pathing.
//
// The rest of the variables should not be meddled with.
//
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TESH.scrollpos=-1
//TESH.alwaysfold=0
//This part is where you can configure the spell.
scope Dash initializer Init
globals
//Configurables
integer Rush = 'A05W' //This is the ability id the spell uses. Change it after copying the trigger.
real Speed = 1150 //This is the speed of the caster when he uses the spell.
real Interval = .03 //How often you want the timer to run.
real Range = 175 //How close units should be to be damaged by the spell.
boolean UnitOrSfx = false //This decides if you want to use a dummy unit or sfx as the well...sfx of the spell. False for sfx, true for dummy unit.
integer Transparency = 80 //How transparent you want the dummy to be.
integer RushDummy = 'e00V' // This is the id of the dummy unit created.
real Lifespan = 0.5 // Life span of the dummy.
string Sfx = "Void Elves - Valiant Charge Void.mdx" //The sfx that appears when the caster dashes.
string Animation = "attack 2" //What animation plays when the caster dashes.
real DamageBase = 75 //This is the base damage which will be multiplied by the ability level.
integer R = 255 //This is the red value for the dummy unit.
integer G = 255 //This is the blue value for the dummy unit.
integer B = 255 //This is the green value for the dummy unit.
real AbilDist = 200 //This is the distance that scales per level of ability. Set BonusDist to 0 if you want a pure level based distance.
real BonusDist = 100 // This is the bonus distance. Set AbilDist to 0 if you want constant distant.
attacktype AttackType = ATTACK_TYPE_CHAOS //The attack type.
damagetype DamageType = DAMAGE_TYPE_UNIVERSAL //The damage type. They're both currently set to these configurations to allow easy testing.
//Non-configurables
group RushGroup = CreateGroup() //Don't touch this. Don't null or destroy this.
real Offset = Speed * Interval //How far the caster moves per interval.
endglobals
//------Configurable functions------//
//Configure the conditions for group check here
function UnitCheck takes unit caster, unit u returns boolean
return IsUnitEnemy(u, GetOwningPlayer(caster)) and not (IsUnitType(u, UNIT_TYPE_DEAD) and GetUnitTypeId(u) != 0) and IsUnitType(u, UNIT_TYPE_GROUND) and not IsUnitType(u, UNIT_TYPE_STRUCTURE)
endfunction
//The Damage formula for the ability.
function Damage takes unit caster, integer Rush, real DamageBase returns real
return GetUnitAbilityLevel(caster, 'A05W') * DamageBase
endfunction
//Formula for the maximum distance. If you only want the ability to affect distance, set BonusDist to 0.
function MaximumDistance takes unit caster, integer Rush, real AbilDist, real BonusDist returns real
return GetUnitAbilityLevel(caster, 'A05W') * AbilDist + BonusDist
endfunction
//---End of Configurable functions---//
function Rush_Periodic takes nothing returns nothing
//Local Variable Setup
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit caster = LoadUnitHandle(udg_Rush_Hash, id, 0)
local real facing = LoadReal(udg_Rush_Hash, id, 1)
local real cur_dist = LoadReal(udg_Rush_Hash, id, 2)
local group g = LoadGroupHandle(udg_Rush_Hash, id, 3)
local real x = GetUnitX(caster)
local real y = GetUnitY(caster)
local real x1 = x + Offset * Cos(facing)
local real y1 = y + Offset * Sin(facing)
local player owner = GetOwningPlayer(caster)
local unit dummy
local unit u
local real damage = Damage(caster, Rush, DamageBase) //You can change this to whatever you want.
local real MaxDistance = MaximumDistance(caster, Rush, AbilDist, BonusDist) //This makes the distance you dash scale with the level.
if cur_dist < MaxDistance then
call SetUnitAnimation(caster, Animation)
if not UnitOrSfx then
call DestroyEffect(AddSpecialEffect(Sfx, x, y))
else
set dummy = CreateUnit(owner, RushDummy, x, y, facing)
call SetUnitAnimation(dummy, Animation)
call SetUnitVertexColor(dummy, R, G, B, Transparency)
call UnitApplyTimedLife(dummy, 'BTLF', Lifespan)
set dummy = null
endif
call GroupEnumUnitsInRange(RushGroup, x, y, Range, null)
loop //What we do here is check if the target is in g. If not, then we damage it and add it to g to prevent it from being damaged again.
set u = FirstOfGroup(RushGroup)
exitwhen u == null
if not IsUnitInGroup(u, g) and UnitCheck(caster, u) then
call UnitDamageTarget(caster, u, damage, false, false, AttackType, DamageType, null)
call GroupAddUnit(g, u)
endif
call GroupRemoveUnit(RushGroup, u)
endloop
if IsTerrainWalkable(x1, y1) then //If the terrain is passable the you'll dash, if not then trigger ends.
call SetUnitX(caster, x1)
call SetUnitY(caster, y1)
set cur_dist = cur_dist + Offset //This counts how many times you've moved.
call SaveReal(udg_Rush_Hash, id, 2, cur_dist)
else
call PauseTimer(t)
call DestroyTimer(t)
call DestroyGroup(g)
call SetUnitAnimation(caster, "stand") //Resets the animation.
call FlushChildHashtable(udg_Rush_Hash, id)
endif
else
call PauseTimer(t)
call DestroyTimer(t)
call DestroyGroup(g)
call SetUnitAnimation(caster, "stand") //Resets the animation.
call FlushChildHashtable(udg_Rush_Hash, id)
endif
//Nulling
set t = null
set caster = null
set g = null
endfunction
function Rush_Actions takes nothing returns nothing
//Local Variable Setup
local timer t = CreateTimer()
local integer id = GetHandleId(t)
local unit caster = GetTriggerUnit()
local real dx = GetSpellTargetX() - GetUnitX(caster)
local real dy = GetSpellTargetY() - GetUnitY(caster)
local real dist_check = (dx*dx) + (dy*dy)
local real facing
//A little distance check to avoid bugs when you cast the spell in your current position.
if dist_check <= 100 * 100 then
set facing = GetUnitFacing(caster) * bj_DEGTORAD
else
set facing = (Atan2(dy, dx))
endif
//Hashtable Setup
call SaveUnitHandle(udg_Rush_Hash, id, 0, caster)
call SaveReal(udg_Rush_Hash, id, 1, facing)
call SaveReal(udg_Rush_Hash, id, 2, 0)
call SaveGroupHandle(udg_Rush_Hash, id, 3, CreateGroup())
//End Hashtable Setup
call TimerStart(t, Interval, true, function Rush_Periodic)
//Nulling
set t = null
set caster = null
endfunction
function Rush_Conditions takes nothing returns boolean
if GetSpellAbilityId() == Rush then
call Rush_Actions()
endif
return false
endfunction
//===========================================================================
private function Init takes nothing returns nothing
local trigger t = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function Rush_Conditions) )
set udg_Rush_Hash = InitHashtable()
set t = null
endfunction
endscope
//TESH.scrollpos=24
//TESH.alwaysfold=0
globals
unit array spellCaster
unit array spellTargetUnit
group array spellGroupVictims
integer array spellCounter
real array spellDuration
group array spellGroup
timer array spellTimer
real array spellRadius
integer array spellLevel
group ug=CreateGroup()
constant integer FELDUMMY = 'n00A' //universal dummy for many spells
unit g_tempTarget = null
hashtable g_hash1
endglobals
function Trig_Vars_Actions takes nothing returns nothing
set spellGroup[1] = CreateGroup()
set spellTimer[1] = CreateTimer()
set spellGroup[2] = CreateGroup()
set spellTimer[2] = CreateTimer()
endfunction
//===========================================================================
function InitTrig_Vars takes nothing returns nothing
set g_hash1 = InitHashtable()
// save FelFevor data:
call SaveInteger(g_hash1, 'h03B', 1, 'A0PD') // Initiate unit , ABI_FEL_BARRAGE
call SaveInteger(g_hash1, 'h03I', 1, 'A0PQ') // Vanguard unit , ABI_LINGERING_STRENGTH new
call SaveInteger(g_hash1, 'h03C', 1, 'A0OQ') // Neophyte unit , ABI_BLOOD_CORD
call SaveInteger(g_hash1, 'h03H', 1, 'A0Q9') // Doomguard unit , ABI_UNLEASH_POWER
call SaveInteger(g_hash1, 'h045', 1, 'A0Q9') // Doomguard unit - Demonsight , ABI_UNLEASH_POWER
call SaveInteger(g_hash1, 'h011', 1, 'A0PZ') // Falconeer unit , ABI_SHADOW_PASSERINE
call SaveInteger(g_hash1, 'h03D', 1, 'A0PS') // Oculist unit , ABI_OCULIST_ATTACK_RATE
call SaveInteger(g_hash1, 'h003', 1, 'A0P2') // Bloodwarder unit , ABI_CHAOTIC_ENERGIES
call SaveInteger(g_hash1, 'h003', 2, 'A0ON') // Bloodwarder unit , ABI_ACURSED_AEGIS
call SaveInteger(g_hash1, 'h003', 3, 'A0QB') // Bloodwarder unit , ABI_WRITHE_OF_AGONY
call SaveInteger(g_hash1, 'h00I', 1, 'A0Q1') // Cabalist unit , ABI_STOLEN_POWER
call SaveInteger(g_hash1, 'h00I', 2, 'A0P3') // Cabalist unit , ABI_CURSE_OF_FRAGILITY
call SaveInteger(g_hash1, 'h00I', 3, 'A0P8') // Cabalist unit , ABI_DESTRUCTIVE_FIRES
call SaveInteger(g_hash1, 'h00Z', 1, 'A0PN') // Demonologist unit , ABI_HAND_OF_DOOM
call SaveInteger(g_hash1, 'h00Z', 2, 'A0PJ') // Demonologist unit , ABI_FIENDISH_SHELL
call SaveInteger(g_hash1, 'h00Z', 3, 'A0PB') // Demonologist unit , ABI_ENSLAVE_DEMON
call SaveInteger(g_hash1, 'h03E', 1, 'A0OL') // Reclaimer unit , ABI_ABSOLUTION_CIRCLE
call SaveInteger(g_hash1, 'h03E', 2, 'A0P4') // Reclaimer unit , ABI_DARK_LESSONS
call SaveInteger(g_hash1, 'h03F', 1, 'A0Q0') // Reconnoiteirer unit , ABI_SPAWN_DECREP
call SaveInteger(g_hash1, 'h03F', 2, 'A0Q7') // Reconnoiteirer unit , ABI_UNGODLY_CHAINS
call SaveInteger(g_hash1, 'h03G', 1, 'A0PY') // Siphoner unit , ABI_SLEEPING_MANA
call Trig_Vars_Actions()
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
globals
constant integer ABI_BANEOFHAVOC = 'A0OP' //"bloodlust" based, 30sec
constant integer ABI_FELFERVOR = 'A0PH' //30sec
constant integer ABI_FELFERVOR_ITEM = 'A0QX' //120sec <---
constant integer ABI_FELFERVOR_WREATHING = 'A0PI' //30sec
constant integer BUFF_FELFERVOR = 'B08Y'
endglobals
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
function Trig_FelFevor_Conditions takes nothing returns boolean
local integer s=GetSpellAbilityId()
return s==ABI_BANEOFHAVOC or s==ABI_FELFERVOR or s==ABI_FELFERVOR_ITEM or s==ABI_FELFERVOR_WREATHING
endfunction
//----------------------------------------------------------------------------------
function FelFevor_LoopEnum takes nothing returns nothing
local unit d = GetEnumUnit()
local integer id = GetUnitUserData(d)
local integer unitId
if (spellCounter[id]>1) and GetUnitAbilityLevel(spellTargetUnit[id], BUFF_FELFERVOR)==0 then
set spellDuration[id] = 0.00
endif
//---
set spellCounter[id] = spellCounter[id] + 1
set spellDuration[id] = spellDuration[id] - 1.00
if spellDuration[id] <= 0.00 then // Clean up any data attached to this spell
//set bonuses to level 1
set unitId=GetUnitTypeId(spellTargetUnit[id])
call SetUnitAbilityLevel(spellTargetUnit[id], LoadInteger(g_hash1, unitId, 1), 1)
call SetUnitAbilityLevel(spellTargetUnit[id], LoadInteger(g_hash1, unitId, 2), 1)
call SetUnitAbilityLevel(spellTargetUnit[id], LoadInteger(g_hash1, unitId, 3), 1)
set spellTargetUnit[id]=null
call GroupRemoveUnit(spellGroup[1], d)
call RemoveUnit(d)
if FirstOfGroup(spellGroup[1]) == null then
call PauseTimer(spellTimer[1])
endif
endif
set d=null
endfunction
//---
function FelFevor_Loop takes nothing returns nothing
call ForGroup(spellGroup[1], function FelFevor_LoopEnum)
endfunction
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
function FelFevor_UpdateDuration takes nothing returns nothing
local integer id = GetUnitUserData(GetEnumUnit())
if spellTargetUnit[id]==g_tempTarget then
set spellDuration[id] = 120.00 //longest duration possible
endif
endfunction
//----------------------------------------------------------------------------------
function FelFevor_OnCast takes nothing returns nothing
local unit target=GetSpellTargetUnit()
local integer id
local integer unitId
set g_tempTarget = target
if GetUnitAbilityLevel(g_tempTarget, BUFF_FELFERVOR)>0 then
call ForGroup(spellGroup[1], function FelFevor_UpdateDuration)
else //start new instance:
set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(GetTriggerUnit()), FELDUMMY, GetUnitX(target), GetUnitY(target), 0.00)
set id = GetUnitUserData(bj_lastCreatedUnit)
set spellCounter[id] = 0
set spellDuration[id] = 120.00 //longest possible duration
set spellTargetUnit[id] = target
//set bonuses to level 2
set unitId=GetUnitTypeId(spellTargetUnit[id])
call SetUnitAbilityLevel(spellTargetUnit[id], LoadInteger(g_hash1, unitId, 1), 2)
call SetUnitAbilityLevel(spellTargetUnit[id], LoadInteger(g_hash1, unitId, 2), 2)
call SetUnitAbilityLevel(spellTargetUnit[id], LoadInteger(g_hash1, unitId, 3), 2)
//---
if FirstOfGroup(spellGroup[1]) == null then
call TimerStart(spellTimer[1], 1.00, true, function FelFevor_Loop)
endif
call GroupAddUnit(spellGroup[1], bj_lastCreatedUnit)
endif
set target=null
endfunction
//===========================================================================
function InitTrig_FelFevor takes nothing returns nothing
set gg_trg_FelFevor = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_FelFevor, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_FelFevor, Condition( function Trig_FelFevor_Conditions ) )
call TriggerAddAction( gg_trg_FelFevor, function FelFevor_OnCast)
endfunction
scope Protect
globals
private constant integer PROTECT__ABIL_ID = 'A0EK' // The Protect ability itself
private constant integer PROTECT_CASTER__ABIL_ID = 'A0EN' // Caster buff carrier
private constant integer PROTECT_TARGET__ABIL_ID = 'A0EO' // Caster buff
private constant integer PROTECT_CASTER__BUFF_ID = 'B05B' // Target buff carrier
private constant integer PROTECT_TARGET__BUFF_ID = 'B05A' // Target buff
private constant real HP_PERCENTAGE_THRESHOLD_LIMIT = .2 // .2 == 20%. A Protector below 20% hit points will not share damage anymore.
private constant real DAMAGE_REDUCTION_RATE = .5 // .5 == 50%. That's the percentage damage that will be shared with the Protector.
private constant real RANGE_LIMIT = 1000. // If Protector and Protectee move beyond that range, Protect ends.
private constant real CHECK_INTERVAL = .5 // The interval at which Protect checks if all buffs are accounted for, everybody's alive and within acceptable distance.
private constant string CASTER_ANIMATION_TAG = "Defend"
private constant integer DAMAGE_TRIGGER = DamageEngine_FILTER_OTHER
private constant string EVENT_TYPE = "Mod"
private constant real DAMAGE_ORDER = 4. // 4. and above will run after armour
// NB: duration is determined by the ability itself. If the buff goes away, Protect stops.
endglobals
struct Protect
unit source
unit target
integer index
private static thistype array ProtectList
private static integer ProtectCount = 0
private static Table instance // this is specifically for the target to track
private static timer clock = null
private method destroy takes nothing returns nothing
local thistype replacement = ProtectList[ProtectCount]
set ProtectList[this.index] = replacement
set replacement.index = this.index
set ProtectList[ProtectCount] = 0
set ProtectCount = ProtectCount - 1
call instance.remove(GetHandleId(this.source))
call instance.remove(GetHandleId(this.target))
if CASTER_ANIMATION_TAG != "" then
call AddUnitAnimationProperties(this.source, CASTER_ANIMATION_TAG, false)
endif
call UnitRemoveAbility(this.source, PROTECT_CASTER__ABIL_ID)
call UnitRemoveAbility(this.source, PROTECT_CASTER__BUFF_ID)
call UnitRemoveAbility(this.target, PROTECT_TARGET__ABIL_ID)
call UnitRemoveAbility(this.target, PROTECT_TARGET__BUFF_ID)
set this.source = null
set this.target = null
if ProtectCount < 1 then
call ReleaseTimer(clock)
endif
call this.deallocate()
endmethod
private static method onPeriod takes nothing returns nothing
local integer i = 0
local thistype this
loop
set i = i + 1
exitwhen i > ProtectCount
set this = ProtectList[i]
if not (UnitAlive(this.target) and UnitAlive(this.source) and /*
*/ GetUnitAbilityLevel(this.target, PROTECT_TARGET__BUFF_ID) > 0 and GetUnitAbilityLevel(this.source, PROTECT_CASTER__BUFF_ID) > 0 and /*
*/ IsUnitInRange(this.source, this.target, RANGE_LIMIT)) then
call this.destroy()
set i = i - 1
endif
endloop
endmethod
private static method establishLink takes unit caster, integer idCaster, unit mark, integer idMark returns nothing
local thistype this = allocate()
set this.source = caster
set this.target = mark
if CASTER_ANIMATION_TAG != "" then
call AddUnitAnimationProperties(caster, CASTER_ANIMATION_TAG, true)
endif
call UnitAddAbility(caster, PROTECT_CASTER__ABIL_ID)
call UnitAddAbility(mark, PROTECT_TARGET__ABIL_ID)
set ProtectCount = ProtectCount + 1
set ProtectList[ProtectCount] = this
set this.index = ProtectCount
set instance[idCaster] = this
set instance[idMark] = this
if ProtectCount == 1 then
set clock = NewTimer()
call TimerStart(clock, CHECK_INTERVAL, true, function thistype.onPeriod)
endif
endmethod
private static method onCast takes nothing returns nothing
local unit caster = GetTriggerUnit()
local unit mark = GetSpellTargetUnit()
local integer idCaster = GetHandleId(caster)
local integer idMark = GetHandleId(mark)
local thistype this = instance[idCaster]
local thistype instanceMark = instance[idMark]
if this == 0 and instanceMark == 0 then
debug call BJDebugMsg("caster null, target null")
if caster != mark then
debug call BJDebugMsg("caster != target")
call thistype.establishLink(caster, idCaster, mark, idMark)
endif
elseif this != 0 and instanceMark == 0 then
debug call BJDebugMsg("caster has val " + I2S(this) + ", target null")
call this.destroy()
call thistype.establishLink(caster, idCaster, mark, idMark)
elseif this == 0 and instanceMark != 0 then
debug call BJDebugMsg("caster null, target has val " + I2S(instanceMark))
call instanceMark.destroy()
call thistype.establishLink(caster, idCaster, mark, idMark)
elseif this != 0 and instanceMark != 0 then
debug call BJDebugMsg("caster has val " + I2S(this) + ", target has val " + I2S(instanceMark))
if this == instanceMark then
debug call BJDebugMsg("caster val " + I2S(this) + " == target val " + I2S(instanceMark))
if caster == mark then
debug call BJDebugMsg("caster == target")
call this.destroy()
else
debug call BJDebugMsg("caster != target")
debug call BJDebugMsg("swapping link")
call this.destroy()
call thistype.establishLink(caster, idCaster, mark, idMark)
endif
else
debug call BJDebugMsg("caster val " + I2S(this) + " != target val " + I2S(instanceMark))
call this.destroy()
call instanceMark.destroy()
call thistype.establishLink(caster, idCaster, mark, idMark)
endif
endif
set caster = null
set mark = null
endmethod
private static method onDamage takes nothing returns nothing
local unit target = Damage.target
local integer id = GetHandleId(target)
local thistype this = instance[id]
local real hpMax = BlzGetUnitMaxHP(this.source)
local real hp = GetWidgetLife(this.source)
local real hpBuffer = 0.
local real hpPercentage = 0.
local real dmg = Damage.amount
local real transferableDmg = dmg * DAMAGE_REDUCTION_RATE
local trigger trig = GetTriggeringTrigger()
if hp > 0. then
set hpPercentage = hp / hpMax
if hpPercentage > HP_PERCENTAGE_THRESHOLD_LIMIT then
set hpBuffer = hpMax * (hpPercentage - HP_PERCENTAGE_THRESHOLD_LIMIT)
if hpBuffer >= transferableDmg then
set Damage.amount = transferableDmg // this reduces the damage taken by the target by DAMAGE_REDUCTION_RATE
call DisableTrigger(trig)
call Damage.apply(Damage.source, this.source, transferableDmg, false, false, Damage.index.attackType, Damage.index.damageType, null)
// call Damage.applySpell(Damage.source, this.source, transferableDmg, DAMAGE_TYPE_UNIVERSAL)
call EnableTrigger(trig)
else
set Damage.amount = dmg - hpBuffer
call DisableTrigger(trig)
call Damage.apply(Damage.source, this.source, hpBuffer, false, false, Damage.index.attackType, Damage.index.damageType, null)
// call Damage.applySpell(Damage.source, this.source, hpBuffer, DAMAGE_TYPE_UNIVERSAL)
call EnableTrigger(trig)
endif
endif
endif
set target = null
set trig = null
endmethod
private static method onInit takes nothing returns nothing
local DamageTrigger dt = RegisterDamageEngineEx(function thistype.onDamage, EVENT_TYPE, DAMAGE_ORDER, DAMAGE_TRIGGER)
set dt.targetBuff = PROTECT_TARGET__BUFF_ID
set dt.configured = true
set instance = Table.create()
call RegisterSpellEffectEvent(PROTECT__ABIL_ID, function thistype.onCast)
endmethod
endstruct
endscope
scope HealingVow
globals
private constant integer HEALING_VOW__ABIL_ID = 'A0E9'
private constant integer HEALING_VOW__BUFF_ID = 'B056'
private constant real PRIMARY_HEAL_VAL = 10.
private constant real SECONDARY_HEAL_VAL = 5.
private constant real AREA_OF_EFFECT = 200.
private constant real PULSE_INTERVAL = 3.
private constant string PULSE_EFFECT_PATH = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
private constant string PULSE_EFFECT_ATTACH = "overhead"
private constant string HEAL_EFFECT_PATH = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl"
private constant string HEAL_EFFECT_ATTACH = "origin"
private constant real INTERVAL = .33
// NB: Healing Vow will persist on a target as long as it has the buff. Spell Steal will act as a dispel since triggered effects cannot be transferred.
endglobals
struct HealingVow
unit source
unit target
real timeout = PULSE_INTERVAL
private static thistype array healingVowList
private static integer healingVowCount = 0
private static Table structTable
private method destroy takes nothing returns nothing
call structTable.remove(GetHandleId(this.target))
set this.source = null
set this.target = null
call this.deallocate()
endmethod
private method pulseHeal takes nothing returns nothing
local player owner = GetOwningPlayer(this.target)
local real x = GetUnitX(this.target)
local real y = GetUnitY(this.target)
local unit u = null
local real life
call GroupEnumUnitsInRange(ENUM_GROUP, x, y, AREA_OF_EFFECT + MAX_COLLISION_SIZE, null)
loop
set u = FirstOfGroup(ENUM_GROUP)
call GroupRemoveUnit(ENUM_GROUP, u)
exitwhen u == null
set life = GetWidgetLife(u)
if u != this.target and UnitAlive(u) and IsUnitAlly(u, owner) and not IsUnitType(u, UNIT_TYPE_MECHANICAL) and IsUnitInRangeXY(u, x, y, AREA_OF_EFFECT) and life < BlzGetUnitMaxHP(u) then
call SetWidgetLife(u, life + SECONDARY_HEAL_VAL)
call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT_PATH, u, HEAL_EFFECT_ATTACH))
endif
endloop
call DestroyEffect(AddSpecialEffectTarget(PULSE_EFFECT_PATH, this.target, PULSE_EFFECT_ATTACH))
call SetWidgetLife(this.target, GetWidgetLife(this.target) + PRIMARY_HEAL_VAL)
call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT_PATH, u, HEAL_EFFECT_ATTACH))
endmethod
private static method onPeriod takes nothing returns nothing
local integer i = 0
local thistype this
loop
set i = i + 1
exitwhen i > healingVowCount
set this = healingVowList[i]
if GetUnitAbilityLevel(this.target, HEALING_VOW__BUFF_ID) == 0 then
set healingVowList[i] = healingVowList[healingVowCount]
set healingVowList[healingVowCount] = 0
set healingVowCount = healingVowCount - 1
set i = i - 1
call this.destroy()
else
set this.timeout = this.timeout - INTERVAL
if this.timeout <= 0. then
set this.timeout = PULSE_INTERVAL
call this.pulseHeal()
endif
endif
endloop
if healingVowCount < 1 then
call ReleaseTimer(GetExpiredTimer())
endif
endmethod
static method new takes unit caster, unit mark returns thistype
local integer id = GetHandleId(mark)
local thistype this = structTable[id]
if this != 0 then // if the unit already has HealingVow...
set this.source = caster // update it's source, in case a different unit cast HealingVow... in case a Healing library eventually gets implememented lol.
else
set this = allocate()
set this.source = caster
set this.target = mark
set structTable[id] = this
set healingVowCount = healingVowCount + 1
set healingVowList[healingVowCount] = this
if healingVowCount == 1 then
call TimerStart(NewTimer(), INTERVAL, true, function thistype.onPeriod)
endif
call this.pulseHeal()
endif
return this
endmethod
private static method onCast takes nothing returns nothing
call thistype.new(GetTriggerUnit(), GetSpellTargetUnit())
endmethod
private static method onInit takes nothing returns nothing
set structTable = Table.create()
call RegisterSpellEffectEvent(HEALING_VOW__ABIL_ID, function thistype.onCast)
endmethod
endstruct
endscope
library RuneBuffCheck
function checkRuneBuffs takes unit u, real manaAmount returns boolean
if (GetUnitAbilityLevel(u, 'B05G') == 0 and GetUnitAbilityLevel(u, 'B05H') == 0 and GetUnitAbilityLevel(u, 'B05I') == 0) then
call GroupRemoveUnit(udg_BB_RuneGroup, u)
if BlzGroupGetSize(udg_BB_RuneGroup) == 0 then
return true
endif
else
if GetUnitAbilityLevel(u, 'B05G') > 0 and GetUnitAbilityLevel(u, 'B05H') > 0 and GetUnitAbilityLevel(u, 'B05I') > 0 then
call UnitAddAbility(u, 'A0F9')
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) + .3)
else
call UnitRemoveAbility(u, 'A0F9')
endif
endif
return false
endfunction
endlibrary
//TESH.scrollpos=139
//TESH.alwaysfold=0
scope DistantFieldE
//native UnitAlive takes unit id returns boolean
globals
private constant real FPS = 0.0312500
private constant string MODEL_PATH = "none.mdl"
private constant integer SPELL_ID = 'A0G2'
private constant string LIGHTNING_ID = "FORK"
private constant real LIGHTNING_RED = 0.00
private constant real LIGHTNING_GREEN = 0.00
private constant real LIGHTNING_BLUE = 0.00
private constant real LIGHTNING_ALPHA = 1.
private constant real DURATION = 0.75
private constant attacktype A_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype D_TYPE = DAMAGE_TYPE_MAGIC
private constant real SPEED = 300.
endglobals
private constant function MaxDamage takes integer level returns real
return 0.*level
endfunction
private constant function MinDamage takes integer level returns real
return 0.*level
endfunction
private constant function Aoe takes integer level returns real
return 250 + 0.*level
endfunction
private function UnitFilter takes player source, unit targ returns boolean
return IsUnitEnemy(targ, source) and UnitAlive(targ) and not IsUnitType(targ, UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(targ, UNIT_TYPE_STRUCTURE)
endfunction
//! textmacro_once STATIC_FIELD_ALLOC
if thistype(0).prev == 0 then
set count = count + 1
set this = count
else
set this = thistype(0).prev
set thistype(0).prev = thistype(0).prev.prev
endif
if thistype(0).next == 0 then
call TimerStart(period, FPS, true, function thistype.periodic)
else
set thistype(0).next.prev = this
endif
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
//! endtextmacro
private struct SF extends array
unit targ
unit cast
lightning light
real dmg
real cx
real cy
real cz
real tx
real ty
real x
real y
real z
integer steps
thistype prev
thistype next
static integer count
static timer period
static group g
static location loc
method destroy takes nothing returns nothing
if this.next != 0 then
set this.next.prev = this.prev
endif
set this.prev.next = this.next
set this.prev = thistype(0).prev
set thistype(0).prev = this
if thistype(0).next == 0 then
call PauseTimer(period)
endif
call UnitDamageTarget(this.cast, this.targ, this.dmg, true, false, A_TYPE, D_TYPE, null)
call DestroyLightning(this.light)
call SetUnitPropWindow(this.targ, GetUnitDefaultPropWindow(this.targ)*bj_DEGTORAD)
set this.light = null
set this.cast = null
set this.targ = null
endmethod
static method periodic takes nothing returns nothing
local thistype this = thistype(0).next
loop
exitwhen this == 0
set this.tx = this.tx+this.x
set this.ty = this.ty+this.y
call MoveLocation(loc, this.tx, this.ty)
set this.z = GetLocationZ(loc) + 20 + GetUnitFlyHeight(this.targ)
if IsTerrainWalkable(this.tx, this.ty) then
call MoveLightningEx(this.light, true, this.cx, this.cy, this.cz, this.tx, this.ty, this.z)
call SetUnitX(this.targ, this.tx)
call SetUnitY(this.targ, this.ty)
endif
set this.steps = this.steps - 1
if this.steps == 0 then
call this.destroy()
endif
set this = this.next
endloop
endmethod
static method cond takes nothing returns boolean
local thistype this
local integer lvl
local real angle
local unit u
local unit v
local real x
local real y
local player p
local real dist
if GetSpellAbilityId() == SPELL_ID then
set u = GetTriggerUnit()
set x = GetSpellTargetX()
set y = GetSpellTargetY()
set p = GetOwningPlayer(u)
set lvl = GetUnitAbilityLevel(u, SPELL_ID)
call GroupEnumUnitsInRange(g, x, y, Aoe(lvl), null)
call DestroyEffect(AddSpecialEffect(MODEL_PATH, x, y))
loop
set v = FirstOfGroup(g)
exitwhen v == null
call GroupRemoveUnit(g,v)
if UnitFilter(p,v) then
//! runtextmacro STATIC_FIELD_ALLOC()
set this.cast = u
set this.targ = v
set this.cx = x
set this.cy = y
set this.tx = GetUnitX(v)
set this.ty = GetUnitY(v)
set angle = Atan2(this.ty-y, this.tx-x)
set dist = SquareRoot((this.tx-x)*(this.tx-x) + (this.ty-y)*(this.ty-y))
set this.dmg = MinDamage(lvl) + (1-(dist/Aoe(lvl)))*(MaxDamage(lvl)-MinDamage(lvl))
set this.x = SPEED*FPS*Cos(angle)
set this.y = SPEED*FPS*Sin(angle)
call MoveLocation(loc, x, y)
set this.cz = GetLocationZ(loc) + 20
call MoveLocation(loc, this.tx, this.ty)
set this.z = GetLocationZ(loc) + 20 + GetUnitFlyHeight(v)
set this.light = AddLightningEx(LIGHTNING_ID, true, this.cx, this.cy, this.cz, this.tx, this.ty, this.z)
call SetLightningColor(this.light, LIGHTNING_RED, LIGHTNING_GREEN, LIGHTNING_BLUE, LIGHTNING_ALPHA)
set this.steps = R2I(DURATION/FPS)
call SetUnitPropWindow(this.targ, 0)
endif
endloop
set u = null
set p = null
endif
return false
endmethod
static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.cond))
call Preload(MODEL_PATH)
set count = 0
set period = CreateTimer()
set g = CreateGroup()
set loc = Location(0,0)
set t = null
endmethod
endstruct
endscope
//TESH.scrollpos=135
//TESH.alwaysfold=0
scope StaticFieldE
//native UnitAlive takes unit id returns boolean
globals
private constant real FPS = 0.0312500
private constant string MODEL_PATH = "none.mdl"
private constant integer SPELL_ID = 'A0G3'
private constant string LIGHTNING_ID = "FORK"
private constant real LIGHTNING_RED = 0.00
private constant real LIGHTNING_GREEN = 0.00
private constant real LIGHTNING_BLUE = 0.00
private constant real LIGHTNING_ALPHA = 1.
private constant real DURATION = 0.75
private constant attacktype A_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype D_TYPE = DAMAGE_TYPE_MAGIC
private constant real SPEED = 300.
endglobals
private constant function MaxDamage takes integer level returns real
return 0.*level
endfunction
private constant function MinDamage takes integer level returns real
return 0.*level
endfunction
private constant function Aoe takes integer level returns real
return 300 + 0.*level
endfunction
private function UnitFilter takes player source, unit targ returns boolean
return IsUnitEnemy(targ, source) and UnitAlive(targ) and not IsUnitType(targ, UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(targ, UNIT_TYPE_STRUCTURE)
endfunction
//! textmacro_once STATIC_FIELD_ALLOC
if thistype(0).prev == 0 then
set count = count + 1
set this = count
else
set this = thistype(0).prev
set thistype(0).prev = thistype(0).prev.prev
endif
if thistype(0).next == 0 then
call TimerStart(period, FPS, true, function thistype.periodic)
else
set thistype(0).next.prev = this
endif
set this.next = thistype(0).next
set thistype(0).next = this
set this.prev = thistype(0)
//! endtextmacro
private struct SF extends array
unit targ
unit cast
lightning light
real dmg
real cx
real cy
real cz
real tx
real ty
real x
real y
real z
integer steps
thistype prev
thistype next
static integer count
static timer period
static group g
static location loc
method destroy takes nothing returns nothing
if this.next != 0 then
set this.next.prev = this.prev
endif
set this.prev.next = this.next
set this.prev = thistype(0).prev
set thistype(0).prev = this
if thistype(0).next == 0 then
call PauseTimer(period)
endif
call UnitDamageTarget(this.cast, this.targ, this.dmg, true, false, A_TYPE, D_TYPE, null)
call DestroyLightning(this.light)
call SetUnitPropWindow(this.targ, GetUnitDefaultPropWindow(this.targ)*bj_DEGTORAD)
set this.light = null
set this.cast = null
set this.targ = null
endmethod
static method periodic takes nothing returns nothing
local thistype this = thistype(0).next
loop
exitwhen this == 0
set this.tx = this.tx+this.x
set this.ty = this.ty+this.y
call MoveLocation(loc, this.tx, this.ty)
set this.z = GetLocationZ(loc) + 20 + GetUnitFlyHeight(this.targ)
if IsTerrainWalkable(this.tx, this.ty) then
call MoveLightningEx(this.light, true, this.cx, this.cy, this.cz, this.tx, this.ty, this.z)
call SetUnitX(this.targ, this.tx)
call SetUnitY(this.targ, this.ty)
endif
set this.steps = this.steps - 1
if this.steps == 0 then
call this.destroy()
endif
set this = this.next
endloop
endmethod
static method cond takes nothing returns boolean
local thistype this
local integer lvl
local real angle
local unit u
local unit v
local real x
local real y
local player p
local real dist
if GetSpellAbilityId() == SPELL_ID then
set u = GetTriggerUnit()
set x = GetUnitX(u)
set y = GetUnitY(u)
set p = GetOwningPlayer(u)
set lvl = GetUnitAbilityLevel(u, SPELL_ID)
call GroupEnumUnitsInRange(g, x, y, Aoe(lvl), null)
call DestroyEffect(AddSpecialEffect(MODEL_PATH, x, y))
loop
set v = FirstOfGroup(g)
exitwhen v == null
call GroupRemoveUnit(g,v)
if UnitFilter(p,v) then
//! runtextmacro STATIC_FIELD_ALLOC()
set this.cast = u
set this.targ = v
set this.cx = x
set this.cy = y
set this.tx = GetUnitX(v)
set this.ty = GetUnitY(v)
set angle = Atan2(this.ty-y, this.tx-x)
set dist = SquareRoot((this.tx-x)*(this.tx-x) + (this.ty-y)*(this.ty-y))
set this.dmg = MinDamage(lvl) + (1-(dist/Aoe(lvl)))*(MaxDamage(lvl)-MinDamage(lvl))
set this.x = SPEED*FPS*Cos(angle)
set this.y = SPEED*FPS*Sin(angle)
call MoveLocation(loc, x, y)
set this.cz = GetLocationZ(loc)
call MoveLocation(loc, this.tx, this.ty)
set this.z = GetLocationZ(loc) + 20 + GetUnitFlyHeight(v)
set this.light = AddLightningEx(LIGHTNING_ID, true, this.cx, this.cy, this.cz, this.tx, this.ty, this.z)
call SetLightningColor(this.light, LIGHTNING_RED, LIGHTNING_GREEN, LIGHTNING_BLUE, LIGHTNING_ALPHA)
call SetLightningColor(this.light, LIGHTNING_RED, LIGHTNING_GREEN, LIGHTNING_BLUE, LIGHTNING_ALPHA)
set this.steps = R2I(DURATION/FPS)
call SetUnitPropWindow(this.targ, 0)
endif
endloop
set u = null
set p = null
endif
return false
endmethod
static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.cond))
call Preload(MODEL_PATH)
set count = 0
set period = CreateTimer()
set g = CreateGroup()
set loc = Location(0,0)
set t = null
endmethod
endstruct
endscope
scope StrafingRun initializer init
globals
private constant integer SPELL_ID = 'A0GD'
private constant integer SAVAGE_ID = 'h02T'
private constant integer COUNT = 4
private constant real OFFSET = 110.
private constant real DIST = 200.
private constant real DURATION = 15.
private constant string SPAWN_FX = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspiritdone.mdl"
endglobals
private function Conditions takes nothing returns boolean
if GetSpellAbilityId() == SPELL_ID then
return true
endif
return false
endfunction
private function Actions takes nothing returns nothing
local unit caster = GetTriggerUnit()
local player owner = GetOwningPlayer(caster)
local real facing = GetUnitFacing(caster)
local real a = (facing * bj_DEGTORAD) + bj_PI
local real x = GetUnitX(caster) + Cos(a) * DIST
local real y = GetUnitY(caster) + Sin(a) * DIST
local real offset = ((OFFSET * COUNT) * .5) - (OFFSET * .5)
local integer i = 0
local unit u
set a = a - (bj_PI * .5)
set x = x + Cos(a) * (offset)
set y = y + Sin(a) * (offset)
set a = a + bj_PI
loop
set i = i + 1
exitwhen i > COUNT
set u = CreateUnit(owner, SAVAGE_ID, x, y, facing)
call DestroyEffect(AddSpecialEffect(SPAWN_FX, x, y))
call UnitApplyTimedLife(u, 'BTLF', DURATION)
set x = x + Cos(a) * OFFSET
set y = y + Sin(a) * OFFSET
endloop
set u = null
set caster = null
endfunction
//===========================================================================
private function init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition(trig, Condition( function Conditions ) )
call TriggerAddAction(trig, function Actions )
set trig = null
endfunction
endscope
library WinterNativeDeclarations
native UnitAlive takes unit u returns boolean
native GetUnitGoldCost takes integer unitID returns integer
native GetUnitWoodCost takes integer unitID returns integer
native GetUnitBuildTime takes integer id returns integer
native BlzSetHeroPrimaryStattakes unit hero, integer whichVal returns nothing // This is a bonus. If this line is giving you problems just delete it
endlibrary
library ProgressBar uses TimerUtils, Table, GetLocZ
// call ProgressBar.new(u, BlzGetAbilityRealLevelField(BlzGetUnitAbility(u, 'A03Q'), ABILITY_RLF_DURATION_NORMAL, GetUnitAbilityLevel(u, 'A03Q')), 240., false)
struct ProgressBar
private static constant string PROGRESS_BAR_PATH = "war3mapImported\\Progressbar.mdx"
private static constant real ANIMATION_TIME = 1.
private static constant real ANIMATION_PERIOD = 1./32.
private static thistype array allBars
private static integer barCount = 0
private static Table structTab = 0
private static boolean isCinematic = false
unit anchor
effect bar
real timeout
real speed
real progress
real barZ
boolean follow
integer index
timer clock
method destroy takes nothing returns nothing
set this.anchor = null
call BlzSetSpecialEffectZ(this.bar, -5000.)
call DestroyEffect(this.bar)
set this.bar = null
call ReleaseTimer(this.clock)
set allBars[this.index] = allBars[barCount]
set allBars[barCount].index = this.index
set allBars[barCount] = 0
set barCount = barCount - 1
call this.deallocate()
endmethod
private static method onPeriod takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local real x
local real y
if this != 0 then
if not UnitAlive(this.anchor) then
call this.destroy()
else
if not isCinematic and this.follow then
set x = GetUnitX(this.anchor)
set y = GetUnitY(this.anchor)
call BlzSetSpecialEffectPosition(this.bar, x, y, GetLocZ(x, y) + GetUnitFlyHeight(this.anchor) + this.barZ)
endif
set this.progress = this.progress + this.speed
if this.progress >= 1. then
// set this.progress = 0.
// call BlzSetSpecialEffectTime(this.bar, 0.)
call this.destroy()
else
call BlzSetSpecialEffectTime(this.bar, this.progress)
endif
endif
endif
endmethod
static method new takes unit u, real duration, real barHeight, boolean follow returns thistype
local thistype this = structTab[GetHandleId(u)]
if this == 0 then
set this = allocate()
set this.anchor = u
set this.follow = follow
set this.timeout = duration
set this.speed = (ANIMATION_TIME / duration) * ANIMATION_PERIOD
set this.progress = 0.
set this.barZ = barHeight
set this.bar = AddSpecialEffect(PROGRESS_BAR_PATH, GetUnitX(u), GetUnitY(u))
if isCinematic then
call BlzSetSpecialEffectZ(this.bar, -5000.)
else
call BlzSetSpecialEffectZ(this.bar, GetUnitFlyHeight(this.anchor) + GetLocZ(GetUnitX(u), GetUnitY(u)) + this.barZ)
endif
call BlzSetSpecialEffectColorByPlayer(this.bar, GetOwningPlayer(u))
call BlzSetSpecialEffectTimeScale(this.bar, 0.)
call BlzSetSpecialEffectTime(this.bar, 0.)
set barCount = barCount + 1
set allBars[barCount] = this
set this.index = barCount
// Timer
set this.clock = NewTimerEx(this)
call TimerStart(this.clock, ANIMATION_PERIOD, true, function thistype.onPeriod)
endif
return this
endmethod
static method hideAllBars takes nothing returns nothing
local integer i = 0
local thistype this
set isCinematic = true
loop
set i = i + 1
exitwhen i > barCount
set this = allBars[i]
call BlzSetSpecialEffectZ(this.bar, -5000.)
endloop
endmethod
static method unhideAllBars takes nothing returns nothing
local integer i = 0
local thistype this
set isCinematic = false
loop
set i = i + 1
exitwhen i > barCount
set this = allBars[i]
call BlzSetSpecialEffectZ(this.bar, GetLocZ(GetUnitX(this.anchor), GetUnitY(this.anchor)) + GetUnitFlyHeight(this.anchor) + this.barZ)
endloop
endmethod
static method toggleBars takes boolean flag, force pGroup returns nothing
if flag then
call thistype.hideAllBars()
else
call thistype.unhideAllBars()
endif
endmethod
static method toggleBarsEx takes boolean flag, force pGroup, real duration returns nothing
if flag then
call thistype.hideAllBars()
else
call thistype.unhideAllBars()
endif
endmethod
method modifyDuration takes real newTimeout returns nothing
// local real conversionRate = newTimeout / this.timeout
// set this.timeout = newTimeout
set this.speed = (ANIMATION_TIME / newTimeout) * ANIMATION_PERIOD
endmethod
static method modifyDurationUnit takes unit u, real newDuration returns nothing
local thistype this = structTab[GetHandleId(u)]
if this != 0 then
call this.modifyDuration(newDuration)
endif
endmethod
endstruct
hook CinematicModeBJ ProgressBar.toggleBars
hook CinematicModeExBJ ProgressBar.toggleBarsEx
endlibrary
globals
framehandle FaneUIBack = null
framehandle CurrentFanes = null
framehandle MaxCurrentFanes = null
framehandle FaneUIMouseOver = null
framehandle FaneUITooltip = null
framehandle FaneUITooltipTitleText = null
framehandle FaneUITooltipBodyText = null
endglobals
library FaneUISystem initializer init uses InitTOCFiles
private function init takes nothing returns nothing
set FaneUIBack = BlzCreateFrameByType("BACKDROP", "BACKDROP", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 1)
call BlzFrameSetAbsPoint(FaneUIBack, FRAMEPOINT_TOPLEFT, 0.633320, 0.581790)
call BlzFrameSetAbsPoint(FaneUIBack, FRAMEPOINT_BOTTOMRIGHT, 0.711690, 0.564740)
call BlzFrameSetTexture(FaneUIBack, "FaneUITexture.tga", 0, true)
set CurrentFanes = BlzCreateFrameByType("TEXT", "name", FaneUIBack, "", 0)
call BlzFrameSetAbsPoint(CurrentFanes, FRAMEPOINT_TOPLEFT, 0.679180, 0.578460)
call BlzFrameSetAbsPoint(CurrentFanes, FRAMEPOINT_BOTTOMRIGHT, 0.692520, 0.567160)
call BlzFrameSetText(CurrentFanes, "|cffffffff0|r")
call BlzFrameSetEnable(CurrentFanes, false)
call BlzFrameSetScale(CurrentFanes, 1.00)
call BlzFrameSetTextAlignment(CurrentFanes, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set MaxCurrentFanes = BlzCreateFrameByType("TEXT", "name", FaneUIBack, "", 0)
call BlzFrameSetAbsPoint(MaxCurrentFanes, FRAMEPOINT_TOPLEFT, 0.691550, 0.578460)
call BlzFrameSetAbsPoint(MaxCurrentFanes, FRAMEPOINT_BOTTOMRIGHT, 0.707740, 0.567160)
call BlzFrameSetText(MaxCurrentFanes, "|cffffffff/10|r")
call BlzFrameSetEnable(MaxCurrentFanes, false)
call BlzFrameSetScale(MaxCurrentFanes, 1.00)
call BlzFrameSetTextAlignment(MaxCurrentFanes, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_RIGHT)
set FaneUITooltip = BlzCreateFrame("TooltipText", FaneUIBack, 0, 0)
set FaneUITooltipTitleText = BlzGetFrameByName("TooltipTextTitle", 0)
set FaneUITooltipBodyText = BlzGetFrameByName("TooltipTextValue", 0)
call BlzFrameSetText(FaneUITooltipTitleText, "Fanes |cffffffff" + "0/10" + "|r")
call BlzFrameSetText(FaneUITooltipBodyText, "The number of Fanes currently under your control. " + /*
*/ "The more Fanes you have, the faster your units regenerate health and gain increased ability effectiveness.")
call BlzFrameSetPoint(FaneUITooltip, FRAMEPOINT_TOPLEFT, FaneUITooltipTitleText, FRAMEPOINT_TOPLEFT, -.005, .0055)
call BlzFrameSetPoint(FaneUITooltip, FRAMEPOINT_BOTTOMRIGHT, FaneUITooltipBodyText, FRAMEPOINT_BOTTOMRIGHT, .005, -.0055)
call BlzFrameSetAbsPoint(FaneUITooltipBodyText, FRAMEPOINT_BOTTOMRIGHT, 0.8 -.005, 0.1625 + .0055)
set FaneUIMouseOver = BlzCreateFrameByType("FRAME", "FaneMouseOverFrame", FaneUIBack, "", 0)
call BlzFrameSetAllPoints(FaneUIMouseOver, FaneUIBack)
call BlzFrameSetTooltip(FaneUIMouseOver, FaneUITooltip)
endfunction
endlibrary
library DefyingMartyr uses RegisterPlayerUnitEvent, TimerUtils
struct DefyingMartyr
// The spell id.
private static constant integer SPELL_ID = 'A0Z5'
// Base HP gain
private static constant real HP_GAIN_BASE = 10.
// Base HP gain per level
private static constant real HP_GAIN_LVL = 10.
// Base HP cap
private static constant real HP_CAP_BASE = 200.
// Base HP cap per level
private static constant real HP_CAP_LVL = 100.
// The delay after which you start losing bonus HP.
private static constant real TIMEOUT = 3.
// This is the micro-time for checking whether decaying bonus health should be refreshed
private static constant real INTERVAL = .1
// How much HP is lost after not attacking for TIMEOUT seconds.
private static constant real HP_LOSS = -15.
// How the effect that plays to indicate the unit has bonus health
private static constant string BONUS_FX = "Abilities\\Weapons\\ProcMissile\\ProcMissile.mdl"
// How the effect that plays to indicate the unit has bonus health
private static constant string ATTACHMENT_PT = "head"
private static integer array Instance
private real hpBonus
private real countdown
private unit source
private timer clock
private effect fx
private method destroy takes nothing returns nothing
set this.source = null
call DestroyEffect(this.fx)
set this.fx = null
call ReleaseTimer(this.clock)
set this.clock = null
call this.deallocate()
endmethod
private method modHp takes real bonus returns nothing
local real hp = GetUnitState(this.source, UNIT_STATE_LIFE)
local real hpMax = GetUnitState(this.source, UNIT_STATE_MAX_LIFE)
local real percentage = ((100. / hpMax) * hp) * .01
local integer newMaxHp = R2I(hpMax + bonus)
set this.hpBonus = this.hpBonus + bonus
call BlzSetUnitMaxHP(this.source, newMaxHp)
call SetUnitState(this.source, UNIT_STATE_LIFE, newMaxHp * percentage)
endmethod
private static method update takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local real loss
set this.countdown = this.countdown - INTERVAL
if this.countdown <= 0. then
set this.countdown = TIMEOUT
if this.hpBonus < -HP_LOSS then
set loss = -this.hpBonus
else
set loss = HP_LOSS
endif
call this.modHp(loss)
endif
if this.hpBonus <= 0. then
set Instance[GetUnitUserData(this.source)] = 0
call this.destroy()
endif
set t = null
endmethod
private static method make takes nothing returns nothing
local unit caster = GetAttacker()
local integer spellLvl = GetUnitAbilityLevel(caster, SPELL_ID)
local integer id = GetUnitUserData(caster)
local thistype this = Instance[id]
local real cap
local real bonus
if spellLvl > 0 then
if this == 0 then
set this = allocate()
set this.source = caster
set this.hpBonus = 0.
set this.countdown = TIMEOUT
set this.clock = NewTimerEx(this)
set this.fx = AddSpecialEffectTarget(BONUS_FX, caster, ATTACHMENT_PT)
set Instance[id] = this
call TimerStart(this.clock, INTERVAL, true, function thistype.update)
endif
set this.countdown = TIMEOUT
set cap = HP_CAP_BASE + HP_CAP_LVL * spellLvl
if this.hpBonus < cap then
set bonus = HP_GAIN_BASE + HP_GAIN_LVL * spellLvl
if bonus + this.hpBonus > cap then
set bonus = cap - this.hpBonus
endif
call this.modHp(bonus)
endif
endif
set caster = null
endmethod
private static method onInit takes nothing returns nothing
call RegisterAnyPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED, function thistype.make)
endmethod
endstruct
endlibrary
globals
framehandle IllidarRaceBar = null
trigger TriggerIllidarRaceBar = null
framehandle IllidariDemonTooltip = null
trigger TriggerIllidariDemonTooltip = null
framehandle IllidariBloodElfTooltip = null
trigger TriggerIllidariBloodElfTooltip = null
framehandle IllidariNagaTooltip = null
trigger TriggerIllidariNagaTooltip = null
framehandle IllidariUIBack = null
framehandle CurrentIllidari = null
framehandle MaxCurrentIllidari = null
framehandle IllidariUIMouseOver = null
framehandle IllidariUITooltip = null
framehandle IllidariUITooltipTitleText = null
framehandle IllidariUITooltipBodyText = null
endglobals
library IllidariUISystem initializer init uses InitTOCFiles
private function init takes nothing returns nothing
set IllidarRaceBar = BlzCreateFrameByType("BACKDROP", "BACKDROP", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 1)
call BlzFrameSetAbsPoint(IllidarRaceBar, FRAMEPOINT_TOPLEFT, 0.632460, 0.579620)
call BlzFrameSetAbsPoint(IllidarRaceBar, FRAMEPOINT_BOTTOMRIGHT, 0.776250, 0.558770)
call BlzFrameSetTexture(IllidarRaceBar, "IllidarBar.tga", 0, true)
set IllidariDemonTooltip = BlzCreateFrameByType("TEXT", "name", IllidarRaceBar, "", 0)
call BlzFrameSetAbsPoint(IllidariDemonTooltip, FRAMEPOINT_TOPLEFT, 0.696760, 0.574690)
call BlzFrameSetAbsPoint(IllidariDemonTooltip, FRAMEPOINT_BOTTOMRIGHT, 0.715660, 0.563670)
call BlzFrameSetText(IllidariDemonTooltip, "|cffffffffDemon|r")
call BlzFrameSetEnable(IllidariDemonTooltip, false)
call BlzFrameSetScale(IllidariDemonTooltip, 0.9)
call BlzFrameSetTextAlignment(IllidariDemonTooltip, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set IllidariBloodElfTooltip = BlzCreateFrameByType("TEXT", "name", IllidarRaceBar, "", 0)
call BlzFrameSetAbsPoint(IllidariBloodElfTooltip, FRAMEPOINT_TOPLEFT, 0.653370, 0.574690)
call BlzFrameSetAbsPoint(IllidariBloodElfTooltip, FRAMEPOINT_BOTTOMRIGHT, 0.672270, 0.563670)
call BlzFrameSetText(IllidariBloodElfTooltip, "|cffffffffBlood|r")
call BlzFrameSetEnable(IllidariBloodElfTooltip, false)
call BlzFrameSetScale(IllidariBloodElfTooltip, 0.9)
call BlzFrameSetTextAlignment(IllidariBloodElfTooltip, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set IllidariNagaTooltip = BlzCreateFrameByType("TEXT", "name", IllidarRaceBar, "", 0)
call BlzFrameSetAbsPoint(IllidariNagaTooltip, FRAMEPOINT_TOPLEFT, 0.748210, 0.574690)
call BlzFrameSetAbsPoint(IllidariNagaTooltip, FRAMEPOINT_BOTTOMRIGHT, 0.767110, 0.563670)
call BlzFrameSetText(IllidariNagaTooltip, "|cffffffffNaga|r")
call BlzFrameSetEnable(IllidariNagaTooltip, false)
call BlzFrameSetScale(IllidariNagaTooltip, 0.9)
call BlzFrameSetTextAlignment(IllidariNagaTooltip, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
set IllidariUITooltip = BlzCreateFrame("TooltipText", IllidarRaceBar, 0, 0)
set IllidariUITooltipTitleText = BlzGetFrameByName("TooltipTextTitle", 0)
set IllidariUITooltipBodyText = BlzGetFrameByName("TooltipTextValue", 0)
call BlzFrameSetText(IllidariUITooltipTitleText, "Illidari Coalition")
call BlzFrameSetText(IllidariUITooltipBodyText, "The numbers represent the level of the racial bonus. " + /*
*/ "Every 2 food used (3 for Naga) from a respective unit's race increases the effectiveness of a racial passive bonus. |n|nBlood Elves increase maximum mana and mana regeneration by 1%; Naga increase attack speed by 1%; Demons increase life regeneration by 0.05.
|nUp to 50 levels in each bonus. ")
call BlzFrameSetPoint(IllidariUITooltip, FRAMEPOINT_TOPLEFT, IllidariUITooltipTitleText, FRAMEPOINT_TOPLEFT, -.005, .0055)
call BlzFrameSetPoint(IllidariUITooltip, FRAMEPOINT_BOTTOMRIGHT, IllidariUITooltipBodyText, FRAMEPOINT_BOTTOMRIGHT, .005, -.0055)
call BlzFrameSetAbsPoint(IllidariUITooltipBodyText, FRAMEPOINT_BOTTOMRIGHT, 0.8 -.005, 0.1625 + .0055)
set IllidariUIMouseOver = BlzCreateFrameByType("FRAME", "IllidariMouseOverFrame", IllidarRaceBar, "", 0)
call BlzFrameSetAllPoints(IllidariUIMouseOver, IllidarRaceBar)
call BlzFrameSetTooltip(IllidariUIMouseOver, IllidariUITooltip)
endfunction
endlibrary