Name | Type | is_array | initial_value |
A_AnimSpeed | real | No | |
A_Apus | unit | Yes | |
A_ApusAcc | real | Yes | |
A_ApusColor | real | Yes | |
A_ApusShadow | unit | Yes | |
A_ApusSize | real | Yes | |
A_ApusSpeed | real | Yes | |
A_ApusXVelo | real | Yes | |
A_ApusYVelo | real | Yes | |
A_Area | real | Yes | |
A_Area2 | real | Yes | |
A_Area3 | real | Yes | |
A_Caster | unit | Yes | |
A_Cooldown | real | Yes | |
A_Cooldown2 | real | Yes | |
A_Cooldown2R | real | Yes | |
A_CooldownR | real | Yes | |
A_DestTreesBool | boolean | No | |
A_DestTreesRange | real | Yes | |
A_Directions3 | integer | Yes | |
A_Dmg | real | Yes | |
A_Dmg2 | real | Yes | |
A_Dmg3 | real | Yes | |
A_Dummy | unit | Yes | |
A_DummyType | unitcode | No | |
A_ExecCount | real | Yes | |
A_FlameStrikeAttackType | attacktype | No | |
A_FlameStrikeDamageType | damagetype | No | |
A_FlameStrikeEffectString | string | No | |
A_FreezeAttackType | attacktype | No | |
A_FreezeDamageType | damagetype | No | |
A_FreezePos | location | Yes | |
A_Group | group | Yes | |
A_IceEffectString | string | No | |
A_Index | integer | No | |
A_Last | real | Yes | |
A_Last2 | real | Yes | |
A_Level | integer | Yes | |
A_Limit | boolean | No | |
A_LoopIndex | integervar | No | |
A_LoopTime | real | No | |
A_LoopTime2 | real | No | |
A_LoopTime3 | real | No | |
A_MaxDist3 | real | Yes | |
A_MaxDist3_2 | real | Yes | |
A_Peasant | unit | No | |
A_ShadowIndexAnim | integer | No | |
A_SpawnArea | real | Yes | |
A_Spell | abilcode | No | |
A_StompAttackType | attacktype | No | |
A_StompDamageType | damagetype | No | |
A_StompEffectString | string | No | |
A_TargetUnit | unit | Yes | |
A_TempC | integervar | No | |
A_TempDest | destructable | No | |
A_TempGroup | group | No | |
A_TempPoint | location | No | |
A_TempPoint2 | location | No | |
A_TempPoint3 | location | No | |
A_TempPoint4 | location | No | |
A_TempUnit | unit | No | |
A_TempUnit2 | unit | No | |
A_UnitType | unitcode | No | |
A_Velocity | real | No | |
AB_Damage | integer | No | |
AB_Damage_Per_Level | integer | No | |
AB_Duration | integer | No | |
AB_Duration_Per_Level | integer | No | |
AB_Hash | hashtable | No | |
AB_Key | integer | No | |
AB_Level | integer | No | |
AB_On | group | No | |
AB_Percent_chance | integer | No | |
AB_Remainingtime | integer | No | |
AB_Unitgroup | group | No | |
Addinunitsinthedmgdetect | group | No | |
Agile_AoE | real | No | |
AgileAbility | abilcode | No | |
AgileAmount | integer | Yes | |
AgileCasters | unit | Yes | |
AgileCasterSE | effect | Yes | |
AgileDamage | integer | No | |
AgileDamageArea | location | No | |
AgileDamageEnemy | group | No | |
AgileDamagePercent | real | No | |
AgileDamageSize | integer | No | |
AgileEnemies | unit | No | |
Agileindex | integer | Yes | |
Agileindex_max_size | integer | No | |
Agileindex_size | integer | No | |
AgileInteger | integer | No | |
AgileLevel | integer | No | |
AgileLoop | integervar | No | |
AgileRAmount | integer | No | |
AgileRTime | integer | No | |
AgileSFX1 | string | No | |
AgileSFX1_AP | string | No | |
AgileSFX2 | string | No | |
AgileSFX2_AP | string | No | |
AgileSFX3 | string | No | |
AgileSFX3_Ap | string | No | |
AgileTime | integer | Yes | |
BB_Point1 | location | No | |
BB_Point2 | location | No | |
BB_Unit | unit | No | |
BE_damages | integer | No | |
BE_level | integer | No | |
Beast_Attack_Ability_Level | integer | No | |
Beast_Attack_Atribute | integer | No | |
Beast_Attack_Base_Offset | real | No | |
Beast_Attack_Base_Radius | real | No | |
Beast_Attack_Bonus_Offset | real | No | |
Beast_Attack_Bonus_Radius | real | No | |
Beast_Attack_Caster | unit | No | |
Beast_Attack_Damage_Group | group | No | |
Beast_Attack_Damage_Location | location | No | |
Beast_Attack_Damage_Multiplier | real | No | |
Beast_Attack_Destroy_Trees | boolean | No | |
Beast_Attack_Destroy_Trees_SE | string | No | |
Beast_Attack_Destruct_Kill_AoE | real | No | |
Beast_Attack_Direction | real | No | |
Beast_Attack_KB_Angle | real | No | |
Beast_Attack_KB_Base_Distance | real | No | |
Beast_Attack_KB_Bonus_Distance | real | No | |
Beast_Attack_KB_Group | group | No | |
Beast_Attack_KB_LocI | location | No | |
Beast_Attack_KB_LocII | location | No | |
Beast_Attack_KB_LocIII | location | No | |
Beast_Attack_KB_Minim_Distance | real | No | |
Beast_Attack_KB_Special_Effect | string | No | |
Beast_Attack_KB_Speed | real | No | |
Beast_Attack_KB_Total_Distance | real | No | |
Beast_Attack_Knock_Back_on | boolean | No | |
Beast_Attack_Location | location | No | |
Beast_Attack_LocationII | location | No | |
Beast_Attack_Random_Distance | boolean | No | |
Beast_Attack_Table | hashtable | No | |
Beast_Attack_Total_Damage | real | No | |
Beast_Attack_Total_Offset | real | No | |
Beast_Attack_Total_Radius | real | No | |
BH_Caster | unit | No | |
BH_Target | unit | No | |
BladeMaster | unit | No | |
BladeMasterOwner | player | No | |
BladeMasterPotition | location | No | |
BladeMasterTarget | unit | No | |
BUS_Loc | location | No | |
BUS_MapMaxX | real | No | |
BUS_MapMaxY | real | No | |
BUS_MapMinX | real | No | |
BUS_MapMinY | real | No | |
BUS_Rect | rect | No | |
BUS_Stunner | unit | No | |
BUS_Target | unit | No | |
BUS_TreeChecker | unit | No | |
BUS_Unit | unit | No | |
BUS_X | real | No | |
BUS_Y | real | No | |
BUSC_Ability | real | Yes | |
BUSC_Cancel | boolean | Yes | |
BUSC_CChangeHueDelay | real | Yes | |
BUSC_CDelay | real | Yes | |
BUSC_CDuration | real | Yes | |
BUSC_ChangeHueDelay | real | Yes | |
BUSC_ChannelId | integer | Yes | |
BUSC_CHueAlpha | integer | Yes | |
BUSC_CHueBlue | integer | Yes | |
BUSC_CHueGreen | integer | Yes | |
BUSC_CHueRed | integer | Yes | |
BUSC_Delay | real | Yes | |
BUSC_Event | real | No | |
BUSC_HueChange | boolean | Yes | |
BUSC_HueChangeAlpha | integer | Yes | |
BUSC_HueChangeBlue | integer | Yes | |
BUSC_HueChangeGreen | integer | Yes | |
BUSC_HueChangeRed | integer | Yes | |
BUSC_NextNode | integer | Yes | |
BUSC_NodeNumber | integer | No | |
BUSC_Order | ordercode | Yes | |
BUSC_PCaster | unit | Yes | |
BUSC_PCurrentEffect | effect | Yes | |
BUSC_PCurrentZ | real | Yes | |
BUSC_PNextNode | integer | Yes | |
BUSC_PNodeNumber | integer | No | |
BUSC_PPrevNode | integer | Yes | |
BUSC_PRecyclableNodes | integer | No | |
BUSC_PRecycleNodes | integer | Yes | |
BUSC_PrevNode | integer | Yes | |
BUSC_PUnit | unit | Yes | |
BUSC_PXVelocity | real | Yes | |
BUSC_PYVelocity | real | Yes | |
BUSC_PZVelocity | real | Yes | |
BUSC_RecyclableNodes | integer | No | |
BUSC_RecycleNodes | integer | Yes | |
BUSC_Running | boolean | Yes | |
BUSC_Target | unit | Yes | |
BUSC_TargetX | real | Yes | |
BUSC_TargetY | real | Yes | |
BUSC_Timer | timer | No | |
BUSC_Unit | unit | Yes | |
BUSCR_AbsorbAOE | real | Yes | |
BUSCR_Counter | integer | No | |
BUSCR_Effect | string | Yes | |
BUSCR_HueAlpha | real | Yes | |
BUSCR_HueBlue | real | Yes | |
BUSCR_HueGreen | real | Yes | |
BUSCR_HueRed | real | Yes | |
BUSCR_HueSpeed | real | Yes | |
BUSCR_MaxAOE | real | Yes | |
BUSCR_MaxSize | real | Yes | |
BUSCR_MinAOE | real | Yes | |
BUSCR_MinSize | real | Yes | |
BUSCR_Name | string | Yes | |
BUSCR_Power | real | Yes | |
BUSCR_SpawnCount | integer | Yes | |
BUSCR_SpawnRate | real | Yes | |
BUSE_Cancel | boolean | Yes | |
BUSE_NextNode | integer | Yes | |
BUSE_NodeNumber | integer | No | |
BUSE_PAOE | real | Yes | |
BUSE_PCaster | unit | Yes | |
BUSE_PCurrentEffect | effect | Yes | |
BUSE_PCurrentSize | real | Yes | |
BUSE_PDoesPan | boolean | Yes | |
BUSE_PDX | real | Yes | |
BUSE_PDY | real | Yes | |
BUSE_PDZ | real | Yes | |
BUSE_PGrowing | boolean | Yes | |
BUSE_PGrowthTime | real | Yes | |
BUSE_PHealthDamage | real | Yes | |
BUSE_PManaDamage | real | Yes | |
BUSE_PNextNode | integer | Yes | |
BUSE_PNodeNumber | integer | No | |
BUSE_POwner | player | Yes | |
BUSE_PPan | real | Yes | |
BUSE_PPanningTime | real | Yes | |
BUSE_PPrevNode | integer | Yes | |
BUSE_PRange | real | Yes | |
BUSE_PRecyclableNodes | integer | No | |
BUSE_PRecycleNodes | integer | Yes | |
BUSE_PRemove | boolean | Yes | |
BUSE_PrevNode | integer | Yes | |
BUSE_PScaleSpeed | real | Yes | |
BUSE_PTimer | real | Yes | |
BUSE_PUnit | unit | Yes | |
BUSE_RecyclableNodes | integer | No | |
BUSE_RecycleNodes | integer | Yes | |
BUSE_Timer | timer | No | |
BUSE_Unit | unit | Yes | |
BUSE_UnitGroup | group | No | |
BUSF_CurrentEffect | effect | Yes | |
BUSF_CurrentSize | real | Yes | |
BUSF_GrowthTime | real | Yes | |
BUSF_NextNode | integer | Yes | |
BUSF_NodeNumber | integer | No | |
BUSF_PrevNode | integer | Yes | |
BUSF_RecyclableNodes | integer | No | |
BUSF_RecycleNodes | integer | Yes | |
BUSF_Remove | boolean | Yes | |
BUSF_RemoveTimer | real | Yes | |
BUSF_ScaleSpeed | real | Yes | |
BUSF_Timer | timer | No | |
BUSF_Unit | unit | Yes | |
BUSF_UnitGroup | group | No | |
BUSK_CurrentEffect | effect | Yes | |
BUSK_CurrentHeight | real | Yes | |
BUSK_KnockbackX | real | Yes | |
BUSK_KnockbackY | real | Yes | |
BUSK_KnockbackZ | real | Yes | |
BUSK_NextNode | integer | Yes | |
BUSK_NodeNumber | integer | No | |
BUSK_PrevNode | integer | Yes | |
BUSK_RecyclableNodes | integer | No | |
BUSK_RecycleNodes | integer | Yes | |
BUSK_ReturnHeight | real | Yes | |
BUSK_Timer | timer | No | |
BUSK_TreeCounter | integer | No | |
BUSK_Unit | unit | Yes | |
BUSK_UnitType | boolean | Yes | |
BUSR_NextNode | integer | Yes | |
BUSR_NodeNumber | integer | No | |
BUSR_PAlphaReduction | integer | Yes | |
BUSR_PCurrentAlpha | integer | Yes | |
BUSR_PNextNode | integer | Yes | |
BUSR_PNodeNumber | integer | No | |
BUSR_PPrevNode | integer | Yes | |
BUSR_PRecyclableNodes | integer | No | |
BUSR_PRecycleNodes | integer | Yes | |
BUSR_PrevNode | integer | Yes | |
BUSR_PSpeed | real | Yes | |
BUSR_PUnit | unit | Yes | |
BUSR_RecyclableNodes | integer | No | |
BUSR_RecycleNodes | integer | Yes | |
BUSR_Time | real | Yes | |
BUSR_Timer | timer | No | |
BUSR_Unit | unit | Yes | |
BUSR_UnitGroup | group | No | |
BUSS_Activate | boolean | Yes | |
BUSS_Angle | real | Yes | |
BUSS_AOE | real | Yes | |
BUSS_Cancel | boolean | Yes | |
BUSS_DX | real | Yes | |
BUSS_DY | real | Yes | |
BUSS_DZ | real | Yes | |
BUSS_EffectMade | boolean | Yes | |
BUSS_EndChannelTime | real | Yes | |
BUSS_EndDelay | real | Yes | |
BUSS_Force | real | Yes | |
BUSS_HealthDamage | real | Yes | |
BUSS_LaserScale | real | Yes | |
BUSS_ManaDamage | real | Yes | |
BUSS_NextNode | integer | Yes | |
BUSS_NodeNumber | integer | No | |
BUSS_Owner | player | Yes | |
BUSS_PAnimationIndex | integer | Yes | |
BUSS_PCaster | unit | Yes | |
BUSS_PCurrentEffect | effect | Yes | |
BUSS_PNextNode | integer | Yes | |
BUSS_PNodeNumber | integer | No | |
BUSS_PPrevNode | integer | Yes | |
BUSS_PRecyclableNodes | integer | No | |
BUSS_PRecycleNodes | integer | Yes | |
BUSS_PRemove | boolean | Yes | |
BUSS_PrevNode | integer | Yes | |
BUSS_PScale | real | Yes | |
BUSS_PTimer | real | Yes | |
BUSS_PUnit | unit | Yes | |
BUSS_PX | real | Yes | |
BUSS_PY | real | Yes | |
BUSS_PZ | real | Yes | |
BUSS_Range | real | Yes | |
BUSS_RecyclableNodes | integer | No | |
BUSS_RecycleNodes | integer | Yes | |
BUSS_Timer | timer | No | |
BUSS_Unit | unit | Yes | |
BUSS_UnitGroup | group | No | |
BW_Caster | unit | No | |
BW_Dummy | unit | No | |
BW_Point | location | No | |
Caster | unit | No | |
Caster_J | unit | No | |
CB_angle | real | No | |
CB_attacked_loc | location | No | |
CB_attacker | unit | No | |
CB_attacking_loc | location | No | |
CB_BOOOM | boolean | No | |
CB_chance_to_knockback | integer | Yes | |
CB_defender | unit | No | |
CB_distance | real | No | |
CB_distance_setup | real | Yes | |
CB_effectOnCast | string | No | |
CB_effectOnLoop | string | No | |
CB_group | group | No | |
CB_hash | hashtable | No | |
CB_temp_unit | unit | No | |
CB_temploc | location | No | |
CB_temploc_2 | location | No | |
CB_time | real | No | |
CC_Caster | unit | No | |
CC_Level | integer | No | |
CC_Point | location | No | |
CC_Target | unit | No | |
CI_Dummies | group | No | |
CI_Frozen | group | No | |
CI_Group | group | No | |
CI_Hash | hashtable | No | |
CI_Reals | real | Yes | |
CI_SFX_Group | group | No | |
CI_Terrain_Types | terraintype | Yes | |
CJ_PointX | real | No | |
CJ_PointY | real | No | |
CodeHeroLVL | integer | No | |
CodeString | string | No | |
CreepSpawn_Count | integer | No | |
CreepSpawn_RespawnPoint | location | No | |
CreepSpawn_SpawnPoints | location | Yes | |
CreepSpawn_UnitCounts | integer | Yes | |
CreepSpawn_UnitTypes | unitcode | Yes | |
Damage | integer | No | |
Damage_Group | group | No | |
Damage_GroupJ | group | No | |
Damage_Rock | integer | No | |
DamageBonus_Unit | unit | No | |
DamageBonus_Value | integer | No | |
DamageBonus_ValueFake | integer | No | |
DC_Point | location | No | |
DEBounty | integer | No | |
DEEventRunning | boolean | No | |
DEHeroCount | integer | Yes | |
DETempPoint | location | Yes | |
DETempUnit | unit | Yes | |
DETimer | timer | No | |
DR_Dummy_Group | group | No | |
DR_Group | group | No | |
DR_Hash | hashtable | No | |
DR_Reals | real | Yes | |
Dummy | unitcode | No | |
Dummy_Unit | unit | No | |
Earth_Group | group | No | |
Empower_Caster | unit | No | |
Empower_Group | group | No | |
Empower_Integer | integer | No | |
Empower_Point | location | No | |
Empower_Timer | timer | No | |
FF | integervar | No | |
FF_AOE | integer | Yes | |
FF_Boolean | boolean | Yes | |
FF_Damage | group | Yes | |
FF_Damage2 | group | Yes | |
FF_Distance | real | Yes | |
FF_Dummy | unit | Yes | |
FF_FF_Time | integer | Yes | |
FF_FLY | real | Yes | |
FF_Foff | real | Yes | |
FF_Formula | real | Yes | |
FF_Group | group | No | |
FF_Hero | unit | Yes | |
FF_Max_Height | real | Yes | |
FF_Point | location | Yes | |
FF_REAL | real | Yes | |
FF_Skip | integer | Yes | |
FF_Speed | real | Yes | |
FF_Target | location | Yes | |
FF_Times | integer | No | |
FH_Charge_Group | group | No | |
FH_Group | group | No | |
FH_Hash | hashtable | No | |
FH_Knockback_Group | group | No | |
FH_Loop_Group_1 | group | No | |
FH_Loop_Group_2 | group | No | |
FH_Reals | real | Yes | |
FH_Unit_Type | unitcode | No | |
Float | texttag | Yes | |
FrenziedReg_Group | group | No | |
GI_Caster | unit | No | |
GI_Casterpoint | location | No | |
GI_Group | group | No | |
GI_Point | location | No | |
Hashtable | hashtable | No | |
HK_Ability | abilcode | No | |
HK_Ability_Stun | abilcode | No | |
HK_Attribute_Agiity | integer | No | |
HK_Attribute_Force | integer | No | |
HK_Caster | unit | No | |
HK_Chance | integer | Yes | |
HK_Damage_Critical | real | Yes | |
HK_Damage_Max | real | Yes | |
HK_Damage_Min | real | Yes | |
HK_Damage_Total | real | No | |
HK_Dummy | unit | No | |
HK_Heal_Max | real | Yes | |
HK_Heal_Total | real | No | |
HK_Level | integer | No | |
HK_Loc | location | No | |
HK_Model_Name | string | Yes | |
HK_Model_Target | string | Yes | |
HK_Target | unit | No | |
HK_Text_Angle | real | No | |
HK_Text_Color | string | Yes | |
HK_Text_Display | string | Yes | |
HK_Text_FadingAge | real | No | |
HK_Text_LifeSpan | real | No | |
HK_Text_On | boolean | No | |
HK_Text_Player | force | No | |
HK_Text_Size | real | No | |
HK_Type_Attack | attacktype | No | |
HK_Type_Damage | damagetype | No | |
HK_Type_Dummy | unitcode | No | |
HookAbility | abilcode | No | |
HookAllowAllyMagicImmune | boolean | No | |
HookAllowEnemyMagicImmune | boolean | No | |
HookAttackType | attacktype | No | |
HookChainBreakDistance | real | No | |
HookDamage | real | Yes | |
HookDamageType | damagetype | No | |
HookDisableWhileInUse | boolean | No | |
HookDummy | unitcode | No | |
HookGrabRadius | real | No | |
HookLightningEffect | lightningtype | No | |
HookLightningEffectEx | string | No | |
HookSoundEffect | sound | No | |
HookSpecialEffect | string | No | |
HookTravelDistance | real | Yes | |
HookTravelDuration | real | No | |
HookTravelSpeed | real | No | |
HookUseLightningEx | boolean | No | |
HookUseSpeed | boolean | No | |
HuskarLB_ABILITY | abilcode | No | |
HuskarLB_AnimationIndex | integer | No | |
HuskarLB_AnimationSpeed | real | No | |
HuskarLB_AttackType | attacktype | No | |
HuskarLB_BreakDistance | real | No | |
HuskarLB_CastersAlive | integer | No | |
HuskarLB_Damage | real | Yes | |
HuskarLB_DamageType | damagetype | No | |
HuskarLB_Delay | real | No | |
HuskarLB_Effect | string | No | |
HuskarLB_EffectHand | string | No | |
HuskarLB_EffectHandAttachment | string | No | |
HuskarLB_EffectHandAttachment2 | string | No | |
HuskarLB_Group | group | No | |
HuskarLB_Identifier | integer | No | |
HuskarLB_Speed | real | No | |
HuskarLB_Table | hashtable | No | |
HuskarLB_TempInteger | integer | No | |
HuskarLB_TempPoint | location | No | |
HuskarLB_TempPoint2 | location | No | |
HuskarLB_TempReal | real | No | |
HuskarLB_TempUnit | unit | No | |
HuskarLB_TempUnit2 | unit | No | |
InnerWisdom_Unit | unit | No | |
KB_Angle | real | Yes | |
KB_Casters | unit | Yes | |
KB_CountBuffs | integer | No | |
KB_DestroyTrees | boolean | Yes | |
KB_EffectCounter | integer | Yes | |
KB_EffectCounter2 | integer | Yes | |
KB_Effects_1 | string | Yes | |
KB_Effects_2 | string | Yes | |
KB_GeneralIntegers | integervar | Yes | |
KB_KnockbackedUnits | group | No | |
KB_Levels | integer | Yes | |
KB_MaxDistance | real | Yes | |
KB_ReachedDistance | real | Yes | |
KB_ReducedReal | real | No | |
KB_ReduceSpeedReal | real | Yes | |
KB_SpecificSpeed | real | Yes | |
KB_StartPositions | location | Yes | |
KB_TempPoint | location | Yes | |
KB_TempReal | real | No | |
KB_TotalKnockUnits | integer | No | |
KB_Units | unit | Yes | |
KBA_Caster | unit | No | |
KBA_DestroyTrees | boolean | No | |
KBA_DistancePerLevel | real | No | |
KBA_Level | integer | No | |
KBA_SpecialEffects | string | Yes | |
KBA_Speed | real | No | |
KBA_StartingPosition | location | No | |
KBA_TargetUnit | unit | No | |
Key | integer | No | |
LavaBolt_Caster | unit | No | |
LavaBolt_Point | location | No | |
Leapers | group | No | |
LifeLeaks | group | No | |
Lightning | lightning | No | |
loopA | integervar | No | |
LoopInterval | real | No | |
Map_Point | location | No | |
MH_Ability | abilcode | Yes | |
MH_Angle | real | Yes | |
MH_Animation_Indexes | integer | Yes | |
MH_ApplyDamage | boolean | Yes | |
MH_Attach_Point | string | No | |
MH_Booleans | boolean | Yes | |
MH_Caster_Execute | group | No | |
MH_Caster_Stop | group | No | |
MH_Dest | real | No | |
MH_DestPoint | location | No | |
MH_Detector | group | No | |
MH_Distance | real | Yes | |
MH_DistCounter | real | Yes | |
MH_Dummy_Type | unitcode | No | |
MH_Effect | string | Yes | |
MH_EndPoint | location | No | |
MH_Hash | hashtable | No | |
MH_Hook | unit | Yes | |
MH_HookChain | lightning | Yes | |
MH_HookedUnit | unit | Yes | |
MH_Hooker | unit | Yes | |
MH_HookerPos | location | Yes | |
MH_HookOn | boolean | Yes | |
MH_HookPos | location | Yes | |
MH_i1 | integer | No | |
MH_i2 | integer | No | |
MH_Images | group | No | |
MH_Index1 | integer | No | |
MH_Index2 | integer | No | |
MH_Level | integer | Yes | |
MH_OffsetConstant | real | No | |
MH_r1 | real | No | |
MH_r2 | real | No | |
MH_r3 | real | No | |
MH_r4 | real | No | |
MH_r5 | real | No | |
MH_Reals | real | Yes | |
MH_StartPoint | location | No | |
MH_u1 | unit | No | |
MH_u2 | unit | No | |
MH_u3 | unit | No | |
MI_Group | group | No | |
MI_Hash | hashtable | No | |
MI_Lightning | string | No | |
MI_Reals | real | Yes | |
MI_Unit_Type | unitcode | No | |
MMDamage | real | No | |
MobINT | integer | No | |
Overpower | integer | No | |
Overpowermax | integer | No | |
PCJ_XY | location | No | |
Picked_Unit | unit | No | |
Plus | integer | No | |
point | location | Yes | |
Point_Caster | location | No | |
Point_CasterJ | location | No | |
Point_X | real | No | |
Point_Y | real | No | |
Points | location | Yes | |
Real | real | Yes | |
RespawningUnits | group | No | |
RespawningUnits2 | group | No | |
RNG | integer | No | |
Rock_Dummy | unit | Yes | |
SaveHeroLVL | integer | No | |
SD_AbsoluteDamage | real | Yes | |
SD_ActionId | integer | Yes | |
SD_AgilityDamage | real | Yes | |
SD_Angle | real | Yes | |
SD_AngleAdjustment | real | No | |
SD_AreaEffect | effect | Yes | |
SD_AttackType | attacktype | No | |
SD_Blue | real | No | |
SD_Caster | unit | Yes | |
SD_CasterAbility | abilcode | No | |
SD_CrowAoE | real | Yes | |
SD_CrowCount | integer | Yes | |
SD_CrowCounter | integer | No | |
SD_CrowDistance | real | Yes | |
SD_CrowMaximum | real | No | |
SD_CrowMinimum | real | No | |
SD_CrowModel | string | No | |
SD_CrowModelSize | real | Yes | |
SD_CrowUnit | unit | Yes | |
SD_CurrentDistance | real | Yes | |
SD_CurrentHeight | real | Yes | |
SD_DaggerEffect | effect | Yes | |
SD_DaggerModel | string | No | |
SD_DaggerSpeed | real | Yes | |
SD_DaggerUnit | unit | Yes | |
SD_Damage | real | Yes | |
SD_DamageDelay | real | Yes | |
SD_DamageGroup | group | No | |
SD_DamageType | damagetype | No | |
SD_DefaultOutward | boolean | No | |
SD_Dummy | unit | No | |
SD_DummyType | unitcode | No | |
SD_ExplosionModel | string | No | |
SD_Flag | boolean | Yes | |
SD_Green | real | No | |
SD_HoldAbility | abilcode | No | |
SD_Index | integer | No | |
SD_IntelligenceDamage | real | Yes | |
SD_InwardAbility | abilcode | No | |
SD_IsOutward | boolean | Yes | |
SD_Level | integer | Yes | |
SD_Looper | integervar | No | |
SD_MaxDistance | real | Yes | |
SD_MaxHeight | real | Yes | |
SD_OutwardAbility | abilcode | No | |
SD_PickedUnit | unit | No | |
SD_PlaceHolder | unit | No | |
SD_Player | player | Yes | |
SD_Point1 | location | No | |
SD_Point2 | location | No | |
SD_Red | real | No | |
SD_SafeAoE | real | Yes | |
SD_SafeAreaModel1 | string | No | |
SD_SafeAreaModel2 | string | No | |
SD_SafeGroup | group | No | |
SD_ShadowModel | string | No | |
SD_SlowAbility | abilcode | No | |
SD_SlowBuff | buffcode | No | |
SD_StrengthDamage | real | Yes | |
SD_TargetModelSize | real | Yes | |
SD_TempAgiDamage | real | No | |
SD_TempAngle | real | No | |
SD_TempCaster | unit | No | |
SD_TempDistance | real | No | |
SD_TempIntDamage | real | No | |
SD_TempLevel | integer | No | |
SD_TempPlayer | player | No | |
SD_TempStrDamage | real | No | |
SD_TimeLeft | real | Yes | |
SD_TurnRate | real | Yes | |
SD_UnitAttach | string | No | |
SD_UnlearnList | abilcode | Yes | |
SD_UnlearnTotal | integer | No | |
Shared_Dummy | unit | No | |
Shared_Integer | integer | No | |
Shared_Integer_2 | integer | No | |
Shared_Point | location | No | |
Shared_Unit | unit | No | |
Shared_Unit_2 | unit | No | |
SM_Ability | abilcode | No | |
SM_Angle | real | Yes | |
SM_Caster | unit | Yes | |
SM_Damage | real | Yes | |
SM_DamagePer20DBonus | real | No | |
SM_DistanceTraveled | real | No | |
SM_HealAmount | real | Yes | |
SM_HealFactor | real | No | |
SM_Index | integer | No | |
SM_InitialDamage | real | Yes | |
SM_Level | integer | Yes | |
SM_OwnerofUnit | player | No | |
SM_SM | unit | Yes | |
SM_SM_Type | unitcode | No | |
SM_Target | unit | Yes | |
SOC_Angle | real | Yes | |
SOC_AngleInteger | integer | Yes | |
SOC_AOE | real | No | |
SOC_Caster | unit | Yes | |
SOC_CasterPoint | location | Yes | |
SOC_Damage | real | Yes | |
SOC_ECSP | string | No | |
SOC_Hit | group | Yes | |
SOC_Index | integer | Yes | |
SOC_Integer | integer | Yes | |
SOC_IntegerEnd | integer | No | |
SOC_KBCasterPoint | location | Yes | |
SOC_Range | real | No | |
SOC_SP | string | No | |
SOC_WantSP | boolean | No | |
SP_Ability | abilcode | No | |
SP_AbilityLvl | integer | Yes | |
SP_AbilityMSFactor | abilcode | No | |
SP_AttackType | attacktype | No | |
SP_Blue | real | No | |
SP_Caster | unit | Yes | |
SP_ChangeColor | boolean | No | |
SP_CounterDuration | real | Yes | |
SP_CounterInfect | real | Yes | |
SP_Damage | real | Yes | |
SP_DamageType | damagetype | No | |
SP_DeathAoE | real | No | |
SP_Duration | real | Yes | |
SP_ExplosionDamage | real | Yes | |
SP_Green | real | No | |
SP_GroupCheck | group | No | |
SP_GroupCount | integer | Yes | |
SP_GroupInfected | group | Yes | |
SP_IndexMax | integer | No | |
SP_InfectChance | real | Yes | |
SP_InfectionLimit | boolean | No | |
SP_InfectRange | real | No | |
SP_InfectTime | real | No | |
SP_LoopInt | integervar | No | |
SP_MaxInfect | integer | Yes | |
SP_MaxLevel | integer | No | |
SP_Node | integer | Yes | |
SP_NodeNext | integer | Yes | |
SP_NodePrev | integer | Yes | |
SP_Order_ID | string | No | |
SP_Owner | player | Yes | |
SP_PeriodicTimer | real | No | |
SP_RecycledSize | integer | No | |
SP_RecycledStack | integer | Yes | |
SP_Red | real | No | |
SP_SFXDamage | string | No | |
SP_SFXDamage_AP | string | No | |
SP_SFXExplode | string | No | |
SP_SFXInfect | string | No | |
SP_SFXInfect_AP | string | No | |
SP_SpawnZombie | boolean | No | |
SP_Spell_ID | integer | No | |
SP_SpellCount | integer | No | |
SP_TempInt | integervar | No | |
SP_TempLoc | location | No | |
SP_TempReal | real | No | |
SP_TempUnit | unit | No | |
SP_UnitID | integer | No | |
SP_UnitType | unitcode | Yes | |
SP_WillExplode | boolean | Yes | |
SP_ZombieDuration | real | Yes | |
SP_ZombieExpire | boolean | No | |
Special_Effect | effect | Yes | |
Stomp | integer | No | |
Swipe_AttScaling | real | No | |
Swipe_Base | real | No | |
SwipeAOE_AttScaling | real | No | |
SwipeAOE_Base | real | No | |
Sword_Expert_Attacker | unit | No | |
Sword_Expert_Group | group | No | |
Sword_Expert_Hash | hashtable | No | |
Sword_Expert_Max_Dur | real | No | |
Sword_Expert_Max_Stat | integer | No | |
Sword_Expert_Stat_Bonus | integer | No | |
Sword_Expert_Stat_Level | integer | No | |
Target | unit | No | |
TargetFacing | real | No | |
Temp_Group_1 | group | No | |
Temp_Integer_1 | integer | No | |
Temp_Integer_2 | integer | No | |
Temp_Integer_3 | integer | No | |
Temp_Integer_4 | integer | No | |
Temp_Integer_5 | integer | No | |
Temp_Lightning_1 | lightning | No | |
Temp_Loc | location | No | |
Temp_Loc_1 | location | No | |
Temp_Loc_2 | location | No | |
Temp_Loc_3 | location | No | |
Temp_Loc_4 | location | No | |
Temp_Loc_5 | location | No | |
Temp_Locations | location | No | |
Temp_Real_1 | real | No | |
Temp_Real_2 | real | No | |
Temp_Real_3 | real | No | |
Temp_Real_4 | real | No | |
Temp_Real_5 | real | No | |
Temp_Real_6 | real | No | |
Temp_Unit_1 | unit | No | |
Temp_Unit_2 | unit | No | |
Temp_Unit_3 | unit | No | |
TempGroup | group | No | |
TempInt | integer | No | |
tempInt | integervar | No | |
TempLevel | integer | No | |
TempLoc | location | No | |
TempPoint | location | No | |
tempPoints | location | Yes | |
tempReal | real | No | |
TempUnit | unit | No | |
tempUnit | unit | No | |
Terrain_Hash | hashtable | No | |
Thrash_AttScaling | real | No | |
Thrash_AttScalingCons | real | No | |
Thrash_AttStacking1st | real | No | |
Thrash_Base | real | No | |
Thrash_MaxStacks | real | No | |
ThrashBld_AttScaling | real | No | |
ThrashBld_Base | real | No | |
ThrashBld_Duration | real | No | |
ThrashBleed_Group | group | No | |
ThrashHeal_Group | group | No | |
TookUrsolDamage | group | No | |
TRdummyh | unit | No | |
TRhash | hashtable | No | |
TRindexD | integer | No | |
TRindexN | integer | No | |
TRisEnabled | boolean | No | |
TRtimers | timer | Yes | |
TRtrig | trigger | No | |
unitarray | unit | Yes | |
UnitTypeArray | unitcode | Yes | |
Ursols_Group | group | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
//************************************************************************************************
//* ____ ___ ___ *
//* /_ _| _ \/ __/ Tree Revival System *
//* | || /\__ \ by Spinnaker *
//* |_||_|\_\___/ v1.2.3.1 *
//* *
//************************************************************************************************
//*********************************************************
//* Globals required
//*********************************************************
//* udg_TRtrig Trigger for handling the revive actions
//* udg_TRhash Hashtable for timer issues
//* udg_TRindexD Stores revival instances
//* udg_TRindexN Parameter for timers manipulation
//* udg_TRtimers Timer array variable for recycle issues
//* udg_TRdummyh Dummy harvester for IsDestructibleTree function
//* udg_TRisEnabled Boolean parameter for enabling/disabling the system
//*********************************************************
//* Important
//*********************************************************
// Note: Units which step on position of tree which is currently
// being resurrected may get stuck between trees in that area
//*********************************************************
//* Constant configurable functions
//*********************************************************
//* Rawdata of undead locust unit type
constant function TR_dummyhId takes nothing returns integer
return 'uloc'
endfunction
//* Rawdata of dummy ghoul harvest ability
constant function TR_harvestId takes nothing returns integer
return 'Ahrl'
endfunction
//* Harvest order ID
constant function TR_orderId takes nothing returns integer
return 852018
endfunction
//* Delay before tree gets resurrected
constant function TR_ReviveDelay takes nothing returns real
return 5.
endfunction
//* Tells if birth animation should be shown while resurrecting a tree
constant function TR_ShowAnimation takes nothing returns boolean
return true
endfunction
//*********************************************************
//* System itself
//*********************************************************
function TR_recycleTimer takes timer t returns nothing
debug if t == null then
debug call BJDebugMsg("Attempt to release a null timer")
else
call PauseTimer(t)
set udg_TRtimers[udg_TRindexN] = t
set udg_TRindexN = udg_TRindexN + 1
endif
endfunction
function TR_getTimer takes nothing returns timer
if 0 == udg_TRindexN then
return CreateTimer()
endif
set udg_TRindexN = udg_TRindexN - 1
return udg_TRtimers[udg_TRindexN]
endfunction
function TR_Callback takes nothing returns nothing
local destructable d = LoadDestructableHandle(udg_TRhash, 0, GetHandleId(GetExpiredTimer()))
call DestructableRestoreLife(d, GetDestructableMaxLife(d), TR_ShowAnimation())
call TR_recycleTimer(GetExpiredTimer())
set udg_TRindexD = udg_TRindexD - 1
if udg_TRindexD == 0 then
call FlushChildHashtable(udg_TRhash, 0)
endif
set d = null
endfunction
function TR_CallRevive takes nothing returns boolean
local timer t
if udg_TRisEnabled then
set t = TR_getTimer()
set udg_TRindexD = udg_TRindexD + 1
call SaveDestructableHandle(udg_TRhash, 0, GetHandleId(t), GetTriggerDestructable())
call TimerStart(t, TR_ReviveDelay(), false, function TR_Callback)
set t = null
endif
return false
endfunction
function TR_IsDestructableTree takes destructable dest returns boolean
return IssueTargetOrderById(udg_TRdummyh, TR_orderId(), dest)
endfunction
function TR_AddTree takes nothing returns nothing
if TR_IsDestructableTree(GetEnumDestructable()) then
call TriggerRegisterDeathEvent(udg_TRtrig, GetEnumDestructable())
endif
endfunction
//***************************************************************************
function InitTrig_TreeRevival takes nothing returns nothing
set udg_TRtrig = CreateTrigger()
set udg_TRhash = InitHashtable()
//* By default enabled
set udg_TRisEnabled = true
//* Actions required for IsDestructibleTree function
set udg_TRdummyh = CreateUnit(Player(15), TR_dummyhId(), 0., 0., 0.)
call ShowUnit(udg_TRdummyh, false)
call UnitAddAbility(udg_TRdummyh, TR_harvestId())
call UnitRemoveAbility(udg_TRdummyh, 'Amov')
//* Revival setup
call EnumDestructablesInRect(bj_mapInitialPlayableArea, null, function TR_AddTree)
call TriggerAddCondition(udg_TRtrig, Condition(function TR_CallRevive))
endfunction
////////////////////////////////////////////////////////////////////
// Boss Ultimate Spellpack Channel V1.02 //
// Author: Tank-Commander //
// Purpose: Handles spell channelling within the spellpack //
// Used for: Soul Release, Scathe, Sheer Force, Energy Spike //
// //
// Notes: //
// - Read the readme before you try modifying the config //
// - Use the "Helpful files" to help you import the system //
// //
// Credits: //
// - (Dummy.mdl) Vexorian //
// //
// If you have used this spellpack in your map, you are required //
// to give credits to Tank-Commander for the creation of it //
// If you would like to use snippets of code from this for //
// whatever, getting permission and crediting the source/linking //
// would be much appreciated. //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// README: //
// Before modifying this spell a few things need to be //
// understood and read, this is one of those things, while //
// most modification can be considered intuitive, it still //
// helps to read through these intstructions, as they will //
// inform you about how to configure this spell to your //
// desire. //
//----------------------------------------------------------------//
// Initial importing: The variable creator trigger can be //
// imported first and if you have the correct settings (file, //
// preferences, General, automatically create unknown variables //
// checked, then when you paste in the variable creator it //
// will automatically give you all the variables you need for //
// this spell //
// //
// While the remaining object editor based data is not required //
// to function (provided they're replaced with equivelents) //
// it's recommended that they are also imported, if their data //
// value are not the same as listed in the configuration, those //
// configurables will need to be changed to work correctly //
//----------------------------------------------------------------//
// CONFIGURABLE INFORMATION/HELP: //
// //
// - Viewing data values: To see data values in the editor you //
// need to press Ctrl + D, to shift back to normal viewing //
// press it again //
// //
// - Effects: Pathnames for effects used in the spells should //
// have two "\"s throughout or the effect will not work (the //
// WE progress bar will not go away when saving, however if //
// fixed afterwards the save will still work, but the progress //
// bar will still remain until the WE is closed) //
// e.g. "units\\human\\Footman\\Footman" //
// //
// - Effect Scaling: Some effects have scale values below them //
// the scale determines the size of the effect and is expressed //
// as a real percentage (1.00 = 100%) //
// //
// - Removing Effects: to remove an effect you don't want from //
// the ability, set the model path to that of Dummy.mdl //
// //
// - Timer: Some configurables have PerSecond values, the code //
// automatically accounts for changes to the timer as to //
// maintain consistency with what the user has chosen //
// All times in the system are expressions of seconds //
// //
//----------------------------------------------------------------//
// TimerSpeed: This is the amount of time in seconds between //
// each iteration of the channel loop function //
constant function BUSCR_TimerSpeed takes nothing returns real
return 0.031250000
endfunction
//----------------------------------------------------------------//
// DummyId: This is the raw data value of the dummy unit used //
// for creating the channeling effects it's advised this unit //
// uses Dummy.mdl for optimal usage, have death type set to //
// "can't raise does not decay" and a death time long enough //
// to play all effects (about 5.00 should be long enough) for //
// all effects) //
constant function BUSCR_DummyId takes nothing returns integer
return 'u00A'
endfunction
//----------------------------------------------------------------//
// AttachmentPoint: This is the location on the dummy unit where //
// effects will be placed //
constant function BUSCR_AttachmentPoint takes nothing returns string
return "origin"
endfunction
//----------------------------------------------------------------//
// GroundMinAngle: This is the minimum angle off the floor that //
// all effects are made when the caster is a ground unit //
constant function BUSCR_GroundMinAngle takes nothing returns real
return 0.1
endfunction
//----------------------------------------------------------------//
// DummyPlayer: This is the player that is given ownership of //
// all the dummy units used by the system //
constant function BUSCR_DummyPlayer takes nothing returns player
return Player(14)
endfunction
//----------------------------------------------------------------//
// END OF CONFIGURATION //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// RegisterChannel: This is the function used to register a new //
// type of channel (calling this function after setting up the //
// new channel will register it and allowit to be used) //
////////////////////////////////////////////////////////////////////
function BUS_RegisterChannel takes integer target returns nothing
local integer Id
if (target == 0) then
set udg_BUSCR_Counter = udg_BUSCR_Counter + 1
set Id = udg_BUSCR_Counter
else
set Id = target
endif
set udg_BUSCR_Name[Id] = StringCase(udg_BUSCR_Name[0], true)
set udg_BUSCR_Effect[Id] = udg_BUSCR_Effect[0]
set udg_BUSCR_MinAOE[Id] = udg_BUSCR_MinAOE[0]
set udg_BUSCR_MaxAOE[Id] = udg_BUSCR_MaxAOE[0]
set udg_BUSCR_AbsorbAOE[Id] = udg_BUSCR_AbsorbAOE[0]
set udg_BUSCR_MinSize[Id] = udg_BUSCR_MinSize[0]
set udg_BUSCR_MaxSize[Id] = udg_BUSCR_MaxSize[0]
set udg_BUSCR_SpawnRate[Id] = udg_BUSCR_SpawnRate[0]
set udg_BUSCR_SpawnCount[Id] = udg_BUSCR_SpawnCount[0]
set udg_BUSCR_Power[Id] = udg_BUSCR_Power[0]
set udg_BUSCR_HueRed[Id] = udg_BUSCR_HueRed[0]
set udg_BUSCR_HueGreen[Id] = udg_BUSCR_HueGreen[0]
set udg_BUSCR_HueBlue[Id] = udg_BUSCR_HueBlue[0]
set udg_BUSCR_HueAlpha[Id] = udg_BUSCR_HueAlpha[0]
set udg_BUSCR_HueSpeed[Id] = udg_BUSCR_HueSpeed[0]
endfunction
////////////////////////////////////////////////////////////////////
// GetChannelByName: This returns the Id number of the channel //
// which shares the name with the passed parameter, it can be //
// used to consistently refer to a channel without knowing the //
// order by which it was declared (allowing dynamic introduction //
// of channels //
////////////////////////////////////////////////////////////////////
function BUS_GetChannelByName takes string name returns integer
local integer iLoop = 0
set name = StringCase(name, true)
loop
set iLoop = iLoop + 1
exitwhen iLoop > udg_BUSCR_Counter
if (name == udg_BUSCR_Name[iLoop]) then
return iLoop
endif
endloop
return 0
endfunction
////////////////////////////////////////////////////////////////////
// GetZ: Used to get the Z height of a given location, used to //
// make sure that entities going over cliffs aren't incorrectly //
// moved/placed on the z plane //
////////////////////////////////////////////////////////////////////
function BUS_GetZ takes real x, real y returns real
call MoveLocation(udg_BUS_Loc, x, y)
return GetLocationZ(udg_BUS_Loc)
endfunction
////////////////////////////////////////////////////////////////////
// Function used to prevent two casts of the same channel being //
// done simultaneously //
////////////////////////////////////////////////////////////////////
function BUS_CheckChannel takes unit u returns integer
local integer Node = 0
loop
set Node = udg_BUSC_NextNode[Node]
exitwhen (udg_BUSC_Unit[Node] == u) or (Node == 0)
endloop
return Node
endfunction
////////////////////////////////////////////////////////////////////
// ChannelLoop: The function used to control the channel this //
// includes creating entities and moving them toward the caster //
// checking if they are still casting the channel and activating //
// the channel effects when it is completed //
////////////////////////////////////////////////////////////////////
function BUS_ChannelLoop takes nothing returns nothing
local integer Node = 0
local integer TempNode = 0
local integer iLoop = 0
local integer EffectCount = 0
local real x
local real x2
local real x3
local real y
local real y2
local real y3
local real z
local real z2
local real dy
local real dx
local real Angle
local real Angle2
local real Distance
local real TempReal
loop
exitwhen TempNode == 0
set TempNode = udg_BUSC_PNextNode[TempNode]
endloop
loop
set Node = udg_BUSC_NextNode[Node]
exitwhen Node == 0
set x = GetUnitX(udg_BUSC_Unit[Node])
set y = GetUnitY(udg_BUSC_Unit[Node])
set z = BUS_GetZ(x, y) + GetUnitFlyHeight(udg_BUSC_Unit[Node])
set TempNode = 0
if (udg_BUSC_CDuration[Node] > 0) then
set udg_BUSC_CDuration[Node] = udg_BUSC_CDuration[Node] - BUSCR_TimerSpeed()
if (udg_BUSC_CDelay[Node] <= BUSCR_TimerSpeed()) then
set udg_BUSC_CDelay[Node] = udg_BUSC_Delay[Node]
set iLoop = 0
loop
set iLoop = iLoop + 1
exitwhen iLoop > udg_BUSCR_SpawnCount[udg_BUSC_ChannelId[Node]]
if (udg_BUSC_PRecyclableNodes == 0) then
set udg_BUSC_PNodeNumber = udg_BUSC_PNodeNumber + 1
set TempNode = udg_BUSC_PNodeNumber
else
set udg_BUSC_PRecyclableNodes = udg_BUSC_PRecyclableNodes - 1
set TempNode = udg_BUSC_PRecycleNodes[udg_BUSC_PRecyclableNodes]
endif
set udg_BUSC_PNextNode[TempNode] = 0
set udg_BUSC_PNextNode[udg_BUSC_PPrevNode[0]] = TempNode
set udg_BUSC_PPrevNode[TempNode] = udg_BUSC_PPrevNode[0]
set udg_BUSC_PPrevNode[0] = TempNode
set Angle = GetRandomReal(0, bj_PI * 2)
if (IsUnitType(udg_BUSC_Unit[Node], UNIT_TYPE_GROUND)) then
set Angle2 = GetRandomReal(BUSCR_GroundMinAngle(), bj_PI - BUSCR_GroundMinAngle())
else
set Angle2 = GetRandomReal(-bj_PI, bj_PI)
endif
set TempReal = GetRandomReal(udg_BUSCR_MinAOE[udg_BUSC_ChannelId[Node]], udg_BUSCR_MaxAOE[udg_BUSC_ChannelId[Node]])
set Distance = Cos(Angle2) * TempReal
if Distance < 0 then
set Distance = Distance * -1
endif
set x2 = x + Distance * Cos(Angle)
set y2 = y + Distance * Sin(Angle)
set z2 = Sin(Angle2) * TempReal + z
set TempReal = GetRandomReal(udg_BUSCR_MinSize[udg_BUSC_ChannelId[Node]], udg_BUSCR_MaxSize[udg_BUSC_ChannelId[Node]])
set udg_BUSC_PCaster[TempNode] = udg_BUSC_Unit[Node]
set udg_BUSC_PXVelocity[TempNode] = 0
set udg_BUSC_PYVelocity[TempNode] = 0
set udg_BUSC_PZVelocity[TempNode] = 0
set udg_BUSC_PCurrentZ[TempNode] = z2
set udg_BUSC_PUnit[TempNode] = CreateUnit(BUSCR_DummyPlayer(), BUSCR_DummyId(), x2, y2, Angle * bj_RADTODEG + 180)
if UnitAddAbility(udg_BUSC_PUnit[TempNode], 'Amrf') and UnitRemoveAbility(udg_BUSC_PUnit[TempNode], 'Amrf') then
endif
set udg_BUSC_PCurrentEffect[TempNode] = AddSpecialEffectTarget(udg_BUSCR_Effect[udg_BUSC_ChannelId[Node]], udg_BUSC_PUnit[TempNode], BUSCR_AttachmentPoint())
call SetUnitScale(udg_BUSC_PUnit[TempNode], TempReal, 0.00, 0.00)
call SetUnitFlyHeight(udg_BUSC_PUnit[TempNode], udg_BUSC_PCurrentZ[TempNode] - BUS_GetZ(x2,y2), 0.00)
endloop
else
set udg_BUSC_CDelay[Node] = udg_BUSC_CDelay[Node] - BUSCR_TimerSpeed()
endif
if (udg_BUSC_HueChange[Node]) then
set udg_BUSC_CHueRed[Node] = udg_BUSC_CHueRed[Node] + udg_BUSC_HueChangeRed[Node]
set udg_BUSC_CHueGreen[Node] = udg_BUSC_CHueGreen[Node] + udg_BUSC_HueChangeGreen[Node]
set udg_BUSC_CHueBlue[Node] = udg_BUSC_CHueBlue[Node] + udg_BUSC_HueChangeBlue[Node]
set udg_BUSC_CHueAlpha[Node] = udg_BUSC_CHueAlpha[Node] + udg_BUSC_HueChangeAlpha[Node]
call SetUnitVertexColor(udg_BUSC_Unit[Node], udg_BUSC_CHueRed[Node], udg_BUSC_CHueGreen[Node], udg_BUSC_CHueBlue[Node], udg_BUSC_CHueAlpha[Node])
if (udg_BUSC_CChangeHueDelay[Node] < 0) then
set udg_BUSC_CChangeHueDelay[Node] = udg_BUSCR_HueSpeed[udg_BUSC_ChannelId[Node]]
set udg_BUSC_HueChangeRed[Node] = udg_BUSC_HueChangeRed[Node] * -1
set udg_BUSC_HueChangeGreen[Node] = udg_BUSC_HueChangeGreen[Node] * -1
set udg_BUSC_HueChangeBlue[Node] = udg_BUSC_HueChangeBlue[Node] * -1
set udg_BUSC_HueChangeAlpha[Node] = udg_BUSC_HueChangeAlpha[Node] * - 1
else
set udg_BUSC_CChangeHueDelay[Node] = udg_BUSC_CChangeHueDelay[Node] - BUSCR_TimerSpeed()
endif
endif
elseif (udg_BUSC_Running[Node]) then
set udg_BUS_Unit = udg_BUSC_Unit[Node]
set udg_BUS_Target = udg_BUSC_Target[Node]
set udg_BUS_X = udg_BUSC_TargetX[Node]
set udg_BUS_Y = udg_BUSC_TargetY[Node]
set udg_BUSC_Running[Node] = false
set udg_BUSC_Event = 0
set udg_BUSC_Event = udg_BUSC_Ability[Node]
endif
set TempNode = 0
set EffectCount = 0
loop
set TempNode = udg_BUSC_PNextNode[TempNode]
exitwhen TempNode == 0
if (udg_BUSC_PCaster[TempNode] == udg_BUSC_Unit[Node]) then
set x2 = GetUnitX(udg_BUSC_PUnit[TempNode])
set y2 = GetUnitY(udg_BUSC_PUnit[TempNode])
set z2 = BUS_GetZ(x2, y2) + GetUnitFlyHeight(udg_BUSC_PUnit[TempNode])
set Distance = SquareRoot((x - x2) * (x - x2) + (y - y2) * (y - y2) + (z - z2) * (z - z2))
if ((Distance < udg_BUSCR_AbsorbAOE[udg_BUSC_ChannelId[Node]]) or (not(GetUnitCurrentOrder(udg_BUSC_Unit[Node]) == udg_BUSC_Order[Node]) or udg_BUSC_Cancel[Node])) then
call DestroyEffect(udg_BUSC_PCurrentEffect[TempNode])
call KillUnit(udg_BUSC_PUnit[TempNode])
set udg_BUSC_PRecycleNodes[udg_BUSC_PRecyclableNodes] = TempNode
set udg_BUSC_PRecyclableNodes = udg_BUSC_PRecyclableNodes + 1
set udg_BUSC_PNextNode[udg_BUSC_PPrevNode[TempNode]] = udg_BUSC_PNextNode[TempNode]
set udg_BUSC_PPrevNode[udg_BUSC_PNextNode[TempNode]] = udg_BUSC_PPrevNode[TempNode]
if (udg_BUSC_NextNode[0] + udg_BUSC_NextNode[0] == 0) then
call PauseTimer(udg_BUSC_Timer)
endif
else
set EffectCount = EffectCount + 1
set dy = y - y2
set dx = x - x2
set Angle = Atan2(dy, dx)
set Angle2 = Atan2(z - z2, SquareRoot((dx * dx) + (dy * dy)))
set TempReal = udg_BUSCR_Power[udg_BUSC_ChannelId[Node]] / Distance
set udg_BUSC_PZVelocity[TempNode] = udg_BUSC_PZVelocity[TempNode] + TempReal * Sin(Angle2)
set udg_BUSC_PXVelocity[TempNode] = udg_BUSC_PXVelocity[TempNode] + TempReal * Cos(Angle) * Cos(Angle2)
set udg_BUSC_PYVelocity[TempNode] = udg_BUSC_PYVelocity[TempNode] + TempReal * Sin(Angle) * Cos(Angle2)
set udg_BUSC_PCurrentZ[TempNode] = udg_BUSC_PCurrentZ[TempNode] + udg_BUSC_PZVelocity[TempNode]
set x3 = x2 + udg_BUSC_PXVelocity[TempNode]
set y3 = y2 + udg_BUSC_PYVelocity[TempNode]
if ((udg_BUS_MapMinX <= x3) and (x3 <= udg_BUS_MapMaxX) and (udg_BUS_MapMinY <= y3)and (y3 <= udg_BUS_MapMaxY)) then
call SetUnitX(udg_BUSC_PUnit[TempNode], x3)
call SetUnitY(udg_BUSC_PUnit[TempNode], y3)
endif
call SetUnitFlyHeight(udg_BUSC_PUnit[TempNode], udg_BUSC_PCurrentZ[TempNode] - BUS_GetZ(x3,y3), 0.00)
call SetUnitAnimationByIndex(udg_BUSC_PUnit[TempNode], R2I(Atan2(udg_BUSC_PZVelocity[TempNode], SquareRoot((udg_BUSC_PXVelocity[TempNode] * udg_BUSC_PXVelocity[TempNode]) + (udg_BUSC_PYVelocity[TempNode] * udg_BUSC_PYVelocity[TempNode]))) * bj_RADTODEG + 0.5) + 90)
endif
endif
endloop
if (EffectCount == 0) and ((udg_BUSC_CDuration[Node] <= 0) or not(GetUnitCurrentOrder(udg_BUSC_Unit[Node]) == udg_BUSC_Order[Node] or udg_BUSC_Cancel[Node])) then
if (udg_BUSC_HueChange[Node]) then
call SetUnitVertexColor(udg_BUSC_Unit[Node], 255, 255, 255, 255)
endif
set udg_BUSC_RecycleNodes[udg_BUSC_RecyclableNodes] = Node
set udg_BUSC_RecyclableNodes = udg_BUSC_RecyclableNodes + 1
set udg_BUSC_NextNode[udg_BUSC_PrevNode[Node]] = udg_BUSC_NextNode[Node]
set udg_BUSC_PrevNode[udg_BUSC_NextNode[Node]] = udg_BUSC_PrevNode[Node]
if (udg_BUSC_NextNode[0] + udg_BUSC_NextNode[0] == 0) then
call PauseTimer(udg_BUSC_Timer)
endif
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// StartChannel: Used to start a channeling effect on a spell //
// Calling this function, passing the ability Id, the unit, any //
// target unit or point, the duration of the channel and the //
// duration of the channel (as well as if the channel will //
// include a hue change) //
////////////////////////////////////////////////////////////////////
function BUS_StartChannel takes integer Id, unit u, unit Target, real x, real y, real Duration, real Event, boolean Hue returns nothing
local integer Node = 0
local real TempReal = 0
set udg_BUSC_Cancel[BUS_CheckChannel(u)] = true
if (udg_BUSC_RecyclableNodes == 0) then
set udg_BUSC_NodeNumber = udg_BUSC_NodeNumber + 1
set Node = udg_BUSC_NodeNumber
else
set udg_BUSC_RecyclableNodes = udg_BUSC_RecyclableNodes - 1
set Node = udg_BUSC_RecycleNodes[udg_BUSC_RecyclableNodes]
endif
set udg_BUSC_NextNode[Node] = 0
set udg_BUSC_NextNode[udg_BUSC_PrevNode[0]] = Node
set udg_BUSC_PrevNode[Node] = udg_BUSC_PrevNode[0]
set udg_BUSC_PrevNode[0] = Node
set udg_BUSC_ChannelId[Node] = Id
set udg_BUSC_Ability[Node] = Event
set udg_BUSC_Unit[Node] = u
set udg_BUSC_Target[Node] = Target
set udg_BUSC_TargetX[Node] = x
set udg_BUSC_TargetY[Node] = y
set udg_BUSC_Order[Node] = GetUnitCurrentOrder(u)
set udg_BUSC_Cancel[Node] = false
set udg_BUSC_Running[Node] = true
set udg_BUSC_CDuration[Node] = Duration
set udg_BUSC_Delay[Node] = 1. / udg_BUSCR_SpawnRate[Id]
set udg_BUSC_CDelay[Node] = udg_BUSC_Delay[Node]
set udg_BUSC_HueChange[Node] = Hue
set udg_BUSC_CHueRed[Node] = 255
set udg_BUSC_CHueGreen[Node] = 255
set udg_BUSC_CHueBlue[Node] = 255
set udg_BUSC_CHueAlpha[Node] = 255
set TempReal = (1 / udg_BUSCR_HueSpeed[Id]) * BUSCR_TimerSpeed()
set udg_BUSC_HueChangeRed[Node] = R2I((udg_BUSCR_HueRed[Id] - udg_BUSC_CHueRed[Node]) * TempReal)
set udg_BUSC_HueChangeGreen[Node] = R2I((udg_BUSCR_HueGreen[Id] - udg_BUSC_CHueGreen[Node]) * TempReal)
set udg_BUSC_HueChangeBlue[Node] = R2I((udg_BUSCR_HueBlue[Id] - udg_BUSC_CHueBlue[Node]) * TempReal)
set udg_BUSC_HueChangeAlpha[Node] = R2I((udg_BUSCR_HueAlpha[Id] - udg_BUSC_CHueAlpha[Node]) * TempReal)
set udg_BUSC_CChangeHueDelay[Node] = udg_BUSCR_HueSpeed[Id]
if (udg_BUSC_PrevNode[Node] == 0) then
call TimerStart(udg_BUSC_Timer, BUSCR_TimerSpeed(), true, function BUS_ChannelLoop)
endif
endfunction
////////////////////////////////////////////////////////////////////
// InitTrig BUS Channel: Sets up the map bounds and the location //
// used for getting Z locations and the timer used to run the //
// loop //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Channel takes nothing returns nothing
set udg_BUS_Loc = Location(0,0)
set udg_BUSC_Timer = CreateTimer()
set udg_BUS_MapMaxX = GetRectMaxX(bj_mapInitialPlayableArea)
set udg_BUS_MapMinX = GetRectMinX(bj_mapInitialPlayableArea)
set udg_BUS_MapMaxY = GetRectMaxY(bj_mapInitialPlayableArea)
set udg_BUS_MapMinY = GetRectMinY(bj_mapInitialPlayableArea)
endfunction
////////////////////////////////////////////////////////////////////
// End of the system //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Boss Ultimate Spellpack Knockback V1.01 //
// Author: Tank-Commander //
// Purpose: Handles physics simulation within the spellpack //
// Used for: Scathe, Sheer Force //
// //
// Notes: //
// - Read the readme before you try modifying the config //
// - Use the "Helpful files" to help you import the system //
// //
// Credits: //
// - (Dummy.mdl) Vexorian //
// //
// If you have used this spellpack in your map, you are required //
// to give credits to Tank-Commander for the creation of it //
// If you would like to use snippets of code from this for //
// whatever, getting permission and crediting the source/linking //
// would be much appreciated. //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// README: //
// Before modifying this spell a few things need to be //
// understood and read, this is one of those things, while //
// most modification can be considered intuitive, it still //
// helps to read through these intstructions, as they will //
// inform you about how to configure this spell to your //
// desire. //
//----------------------------------------------------------------//
// Initial importing: The variable creator trigger can be //
// imported first and if you have the correct settings (file, //
// preferences, General, automatically create unknown variables //
// checked, then when you paste in the variable creator it //
// will automatically give you all the variables you need for //
// this spell //
// //
// While the remaining object editor based data is not required //
// to function (provided they're replaced with equivelents) //
// it's recommended that they are also imported, if their data //
// value are not the same as listed in the configuration, those //
// configurables will need to be changed to work correctly //
//----------------------------------------------------------------//
// CONFIGURABLE INFORMATION/HELP: //
// //
// - Viewing data values: To see data values in the editor you //
// need to press Ctrl + D, to shift back to normal viewing //
// press it again //
// //
// - Effects: Pathnames for effects used in the spells should //
// have two "\"s throughout or the effect will not work (the //
// WE progress bar will not go away when saving, however if //
// fixed afterwards the save will still work, but the progress //
// bar will still remain until the WE is closed) //
// e.g. "units\\human\\Footman\\Footman" //
// //
// - Removing Effects: to remove an effect you don't want from //
// the ability, set the model path to that of Dummy.mdl //
// //
// - Timer: Some configurables have PerSecond values, the code //
// automatically accounts for changes to the timer as to //
// maintain consistency with what the user has chosen //
// All times in the system are expressions of seconds //
// //
//----------------------------------------------------------------//
// TimerSpeed: This is the amount of time in seconds between //
// each iteration of the Knockback Loop function //
constant function BUSKR_TimerSpeed takes nothing returns real
return 0.031250000
endfunction
//----------------------------------------------------------------//
// TreeCheckerId: This is the raw data Id of the unit used for //
// locating and potentially killing trees, it is advised this //
// unit uses dummy.mdl for its model for optimal usage and must //
// be able to harvest trees //
constant function BUSKR_TreeCheckerId takes nothing returns integer
return 'u00B'
endfunction
//----------------------------------------------------------------//
// TreeCheckerId: This is the order Id of the ability used to //
// stun units that have been knocked back, by default this is //
// the order ID for storm bolt (use the one in the object editor //
// which has been placed onto the TreeChecker dummy unit there) //
constant function BUSKR_StunOrderId takes nothing returns integer
return 852095
endfunction
//----------------------------------------------------------------//
// AttachmentPoint: This is the point on affected units that the //
// effects will be placed on while they are being knocked back //
constant function BUSKR_AttachmentPoint takes nothing returns string
return "origin"
endfunction
//----------------------------------------------------------------//
// HeightResetRate: This is the speed at which units return to //
// their original heights (both flying units and ground units) //
constant function BUSKR_HeightResetRate takes nothing returns real
return 18.5
endfunction
//----------------------------------------------------------------//
// ForceAirDecay: This is the ratio at which momentum decays //
// while a unit is in the Air (Current Force / ForceDecay ) //
constant function BUSKR_ForceAirDecay takes nothing returns real
return 1.10
endfunction
//----------------------------------------------------------------//
// ForceGroundDecay: This is the ratio at which momentum decays //
// while a unit is on the ground (Current Force / Force Decay) //
constant function BUSKR_ForceGroundDecay takes nothing returns real
return 2.
endfunction
//----------------------------------------------------------------//
// DragLet: This is a "let" value for when units will be reset //
// (if the units current total knockback is less than this value //
// it will be treated as its knockback value is 0, this also //
// applies to fly heights and should not be 0 or less) //
constant function BUSKR_DragLet takes nothing returns real
return 2.
endfunction
//----------------------------------------------------------------//
// Use3DKnockback: This only applies to ground units, the value //
// determines whether or not ground units which are hit by a //
// force will be knocked into the air, this includes "bouncing" //
// off the ground when hit by a force coming from above (this //
// only occurs if the unit is currently on the ground) //
constant function BUSKR_Use3DKnockback takes nothing returns boolean
return true
endfunction
//----------------------------------------------------------------//
// StunGround: This determines whether or not ground units hit //
// into the air will be stunned for that time (so they do not //
// alter the arc) //
constant function BUSKR_StunGround takes nothing returns boolean
return true
endfunction
//----------------------------------------------------------------//
// KnockbackEffect: This is the path of the effect that will be //
// attached to units that are currently being knocked back //
constant function BUSKR_KnockbackEffect takes nothing returns string
return "Abilities\\Spells\\Other\\Tornado\\Tornado_Target.mdl"
endfunction
//----------------------------------------------------------------//
// GroundedEffect: This is the path of the effect that will be //
// created when a flying unit is knocked into the ground (fly //
// height of 0) //
constant function BUSKR_GroundedEffect takes nothing returns string
return "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
endfunction
//----------------------------------------------------------------//
// InstantKillGround: This determines whether or not grounded //
// flyers will be instantly killed upon impact with the ground //
constant function BUSKR_InstantKillGround takes nothing returns boolean
return true
endfunction
//----------------------------------------------------------------//
// KillTrees; This determines whether or not trees will be //
// killed when a unit (on the ground) is pushed through them, if //
// set to false the system will attempt to prevent the unit from //
// moving into trees (but cannot be garunteed as 100% effective //
// due to knockback values potentially "jumping" the unit into //
// a clearing in the trees - TreeKillRadius can supplement this //
// issue //
constant function BUSKR_KillTrees takes nothing returns boolean
return false
endfunction
//----------------------------------------------------------------//
// TreeKillRadius: This determines the size of the area checked //
// when looking for trees to kill, but also functions as the //
// "let" radius for preventing units from being pushed through //
// trees, only applies to grounded units //
constant function BUSKR_TreeKillRadius takes nothing returns real
return 250.00
endfunction
//----------------------------------------------------------------//
// PreventUnpathable: This determines whether or not the system //
// will prevent units being knocked back into positions that //
// units cannot move in (it will assume ground units are not //
// able to move in deep water) //
constant function BUSKR_PreventUnpathable takes nothing returns boolean
return false
endfunction
//----------------------------------------------------------------//
// END OF CONFIGURATION //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// TreeDestroy: Function used to count trees and kill them if //
// the configuration has been set up to do so //
////////////////////////////////////////////////////////////////////
function BUS_TreeDestroy takes nothing returns nothing
local destructable Tree = GetEnumDestructable()
set udg_BUSK_TreeCounter = udg_BUSK_TreeCounter + 1
call IssueTargetOrderById(udg_BUS_TreeChecker, 852018, Tree)
if (GetUnitCurrentOrder(udg_BUS_TreeChecker) == 852018) and (BUSKR_KillTrees()) then
call KillDestructable(Tree)
endif
call IssueImmediateOrderById(udg_BUS_TreeChecker, 851972)
set Tree = null
endfunction
////////////////////////////////////////////////////////////////////
// GetTrees: Part of the system used to locate trees and pass //
// them on to the TreeDestroy function //
////////////////////////////////////////////////////////////////////
function BUS_GetTrees takes real x, real y returns nothing
//Move Rect and find trees
call MoveRectTo(udg_BUS_Rect, x, y)
set udg_BUSK_TreeCounter = 0
call MoveLocation(udg_BUS_Loc, x, y)
set bj_enumDestructableCenter = udg_BUS_Loc
set bj_enumDestructableRadius = BUSKR_TreeKillRadius()
call EnumDestructablesInRect(udg_BUS_Rect, filterEnumDestructablesInCircleBJ, function BUS_TreeDestroy)
endfunction
////////////////////////////////////////////////////////////////////
// KnockbackLoop: function used to handle moving and changing //
// the heights knocked back units as well as slowing down their //
// speeds to 0 //
////////////////////////////////////////////////////////////////////
function BUS_KnockbackLoop takes nothing returns nothing
local integer Node = 0
local real x
local real x2
local real y
local real y2
local real TempReal
loop
set Node = udg_BUSK_NextNode[Node]
exitwhen Node == 0
set x2 = GetUnitX(udg_BUSK_Unit[Node])
set y2 = GetUnitY(udg_BUSK_Unit[Node])
set x = x2 + udg_BUSK_KnockbackX[Node]
set y = y2 + udg_BUSK_KnockbackY[Node]
set TempReal = BUS_GetZ(x, y)
if ((udg_BUS_MapMinX <= x) and (x <= udg_BUS_MapMaxX) and (udg_BUS_MapMinY <= y)and (y <= udg_BUS_MapMaxY)) then
if not((BUSKR_PreventUnpathable()) and not(IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY))) or not(udg_BUSK_UnitType[Node]) then
if (udg_BUSK_UnitType[Node] and udg_BUSK_CurrentHeight[Node] - TempReal <= 0) then
call BUS_GetTrees(x, y)
if (udg_BUSK_TreeCounter == 0) or (BUSKR_KillTrees()) then
call SetUnitX(udg_BUSK_Unit[Node], x)
call SetUnitY(udg_BUSK_Unit[Node], y)
endif
else
call SetUnitX(udg_BUSK_Unit[Node], x)
call SetUnitY(udg_BUSK_Unit[Node], y)
endif
endif
endif
if BUSKR_StunGround() then
call IssueTargetOrderById(udg_BUS_Stunner, BUSKR_StunOrderId(), udg_BUSK_Unit[Node])
endif
set udg_BUSK_CurrentHeight[Node] = udg_BUSK_CurrentHeight[Node] + udg_BUSK_KnockbackZ[Node] + (BUS_GetZ(x2, y2) - TempReal)
if ((udg_BUSK_CurrentHeight[Node] - TempReal) > 0) then
set udg_BUSK_KnockbackX[Node] = udg_BUSK_KnockbackX[Node] / BUSKR_ForceAirDecay()
set udg_BUSK_KnockbackY[Node] = udg_BUSK_KnockbackY[Node] / BUSKR_ForceAirDecay()
set udg_BUSK_KnockbackZ[Node] = udg_BUSK_KnockbackZ[Node] / BUSKR_ForceAirDecay()
else
set udg_BUSK_KnockbackX[Node] = udg_BUSK_KnockbackX[Node] / BUSKR_ForceGroundDecay()
set udg_BUSK_KnockbackY[Node] = udg_BUSK_KnockbackY[Node] / BUSKR_ForceGroundDecay()
set udg_BUSK_KnockbackZ[Node] = 0
if not(udg_BUSK_UnitType[Node]) then
call DestroyEffect(AddSpecialEffectTarget(BUSKR_GroundedEffect(), udg_BUSK_Unit[Node], BUSKR_AttachmentPoint()))
if (BUSKR_InstantKillGround()) then
call KillUnit(udg_BUSK_Unit[Node])
call DestroyEffect(udg_BUSK_CurrentEffect[Node])
set udg_BUSK_RecycleNodes[udg_BUSK_RecyclableNodes] = Node
set udg_BUSK_RecyclableNodes = udg_BUSK_RecyclableNodes + 1
set udg_BUSK_NextNode[udg_BUSK_PrevNode[Node]] = udg_BUSK_NextNode[Node]
set udg_BUSK_PrevNode[udg_BUSK_NextNode[Node]] = udg_BUSK_PrevNode[Node]
if (udg_BUSK_PrevNode[0] == 0) then
call PauseTimer(udg_BUSK_Timer)
endif
endif
endif
endif
call SetUnitFlyHeight(udg_BUSK_Unit[Node], udg_BUSK_CurrentHeight[Node] - TempReal, 0.00)
if (udg_BUSK_UnitType[Node]) then
if(udg_BUSK_KnockbackX[Node] + udg_BUSK_KnockbackY[Node] + udg_BUSK_KnockbackZ[Node] < BUSKR_DragLet()) and (udg_BUSK_CurrentHeight[Node] - TempReal <= 0) then
call SetUnitFlyHeight(udg_BUSK_Unit[Node], 0, 0.00)
call DestroyEffect(udg_BUSK_CurrentEffect[Node])
set udg_BUSK_RecycleNodes[udg_BUSK_RecyclableNodes] = Node
set udg_BUSK_RecyclableNodes = udg_BUSK_RecyclableNodes + 1
set udg_BUSK_NextNode[udg_BUSK_PrevNode[Node]] = udg_BUSK_NextNode[Node]
set udg_BUSK_PrevNode[udg_BUSK_NextNode[Node]] = udg_BUSK_PrevNode[Node]
if (udg_BUSK_PrevNode[0] == 0) then
call PauseTimer(udg_BUSK_Timer)
endif
endif
set udg_BUSK_CurrentHeight[Node] = udg_BUSK_CurrentHeight[Node] - BUSKR_HeightResetRate()
else
set TempReal = udg_BUSK_ReturnHeight[Node] - (udg_BUSK_CurrentHeight[Node] - TempReal)
if (TempReal * TempReal <= BUSKR_HeightResetRate() * BUSKR_HeightResetRate()) and (udg_BUSK_KnockbackZ[Node] < BUSKR_DragLet()) then
call SetUnitFlyHeight(udg_BUSK_Unit[Node], udg_BUSK_ReturnHeight[Node], 0.00)
call DestroyEffect(udg_BUSK_CurrentEffect[Node])
if (udg_BUSK_KnockbackX[Node] + udg_BUSK_KnockbackY[Node] + udg_BUSK_KnockbackZ[Node] < BUSKR_DragLet()) then
set udg_BUSK_RecycleNodes[udg_BUSK_RecyclableNodes] = Node
set udg_BUSK_RecyclableNodes = udg_BUSK_RecyclableNodes + 1
set udg_BUSK_NextNode[udg_BUSK_PrevNode[Node]] = udg_BUSK_NextNode[Node]
set udg_BUSK_PrevNode[udg_BUSK_NextNode[Node]] = udg_BUSK_PrevNode[Node]
if (udg_BUSK_PrevNode[0] == 0) then
call PauseTimer(udg_BUSK_Timer)
endif
endif
elseif (udg_BUSK_ReturnHeight[Node] > (udg_BUSK_CurrentHeight[Node] - TempReal)) then
set udg_BUSK_CurrentHeight[Node] = udg_BUSK_CurrentHeight[Node] + BUSKR_HeightResetRate()
else
set udg_BUSK_CurrentHeight[Node] = udg_BUSK_CurrentHeight[Node] - BUSKR_HeightResetRate()
endif
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// StartKnockback: Function used to start a unit's knockback //
// and adds it into the loop to be knocked back, it also //
// prevents a unit having two iterations within the loop //
////////////////////////////////////////////////////////////////////
function BUS_StartKnockback takes unit u, real Force, real x, real x2, real y, real y2, real z, real z2 returns nothing
local boolean TempBoolean = true
local integer Node = 0
local real dx
local real dy
local real Angle
local real Angle2
loop
set Node = udg_BUSK_NextNode[Node]
if (udg_BUSK_Unit[Node] == u) then
set TempBoolean = false
endif
exitwhen (Node == 0) or (udg_BUSK_Unit[Node] == u)
endloop
if (TempBoolean) then
if (udg_BUSK_RecyclableNodes == 0) then
set udg_BUSK_NodeNumber = udg_BUSK_NodeNumber + 1
set Node = udg_BUSK_NodeNumber
else
set udg_BUSK_RecyclableNodes = udg_BUSK_RecyclableNodes - 1
set Node = udg_BUSK_RecycleNodes[udg_BUSK_RecyclableNodes]
endif
set udg_BUSK_NextNode[Node] = 0
set udg_BUSK_NextNode[udg_BUSK_PrevNode[0]] = Node
set udg_BUSK_PrevNode[Node] = udg_BUSK_PrevNode[0]
set udg_BUSK_PrevNode[0] = Node
set udg_BUSK_Unit[Node] = u
set udg_BUSK_ReturnHeight[Node] = GetUnitFlyHeight(u)
set udg_BUSK_CurrentHeight[Node] = udg_BUSK_ReturnHeight[Node] + BUS_GetZ(x, y)
set udg_BUSK_CurrentEffect[Node] = AddSpecialEffectTarget(BUSKR_KnockbackEffect(), u, BUSKR_AttachmentPoint())
set udg_BUSK_UnitType[Node] = IsUnitType(u, UNIT_TYPE_GROUND)
set udg_BUSK_KnockbackX[Node] = 0.
set udg_BUSK_KnockbackY[Node] = 0.
set udg_BUSK_KnockbackZ[Node] = 0.
if UnitAddAbility(udg_BUSK_Unit[Node], 'Amrf') and UnitRemoveAbility(udg_BUSK_Unit[Node], 'Amrf') then
endif
if (udg_BUSK_PrevNode[Node] == 0) then
call TimerStart(udg_BUSK_Timer, BUSKR_TimerSpeed(), true, function BUS_KnockbackLoop)
endif
endif
set dy = y - y2
set dx = x - x2
if (udg_BUSK_UnitType[Node]) and (udg_BUSK_CurrentHeight[Node] - BUS_GetZ(x, y) <= BUSKR_DragLet()) then
set Angle2 = Atan2((z2 - z), SquareRoot((dy * dy) + (dx * dx)))
if(BUSKR_Use3DKnockback()) then
if ((z2 - z) < 0) then
set Angle2 = Atan2((z - z2), SquareRoot((dy * dy) + (dx * dx)))
endif
set udg_BUSK_KnockbackZ[Node] = udg_BUSK_KnockbackZ[Node] + Sin(Angle2) * Force
endif
else
set Angle2 = Atan2((z - z2), SquareRoot((dy * dy) + (dx * dx)))
set udg_BUSK_KnockbackZ[Node] = udg_BUSK_KnockbackZ[Node] + Sin(Angle2) * Force
endif
set Angle = Atan2(dy, dx)
set udg_BUSK_KnockbackX[Node] = udg_BUSK_KnockbackX[Node] + Cos(Angle) * Cos(Angle2) * Force
set udg_BUSK_KnockbackY[Node] = udg_BUSK_KnockbackY[Node] + Sin(Angle) * Cos(Angle2) * Force
endfunction
////////////////////////////////////////////////////////////////////
// InitTrig BUS Knockback: function used to set up the timer //
// used by the system and the tree checking unit //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Knockback takes nothing returns nothing
set udg_BUSK_Timer = CreateTimer()
set udg_BUS_TreeChecker = CreateUnit(BUSCR_DummyPlayer(), BUSKR_TreeCheckerId(), 0., 0. , 0.)
set udg_BUS_Stunner = CreateUnit(BUSCR_DummyPlayer(), BUSKR_TreeCheckerId(), 0., 0., 0.)
set udg_BUS_Rect = Rect(0, 0, BUSKR_TreeKillRadius(), BUSKR_TreeKillRadius())
endfunction
////////////////////////////////////////////////////////////////////
// End of the system //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Boss Ultimate Spellpack Soul Release V1.00 //
// Author: Tank-Commander //
// Purpose: Boss Ultimate Instant Kill //
// Requires: Dummy.mdl, BUS Channel //
// //
// Notes: //
// - Read the readme before you try modifying the config //
// - Use the "Helpful files" to help you import the system //
// //
// Credits: //
// - (Dummy.mdl) Vexorian //
// - (LightningWrath.mdl) Callahan //
// //
// Optimum User: Any (Large) //
// //
// If you have used this spellpack in your map, you are required //
// to give credits to Tank-Commander for the creation of it //
// If you would like to use snippets of code from this for //
// whatever, getting permission and crediting the source/linking //
// would be much appreciated. //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// README: //
// Before modifying this spell a few things need to be //
// understood and read, this is one of those things, while //
// most modification can be considered intuitive, it still //
// helps to read through these intstructions, as they will //
// inform you about how to configure this spell to your //
// desire. //
//----------------------------------------------------------------//
// Initial importing: The variable creator trigger can be //
// imported first and if you have the correct settings (file, //
// preferences, General, automatically create unknown variables //
// checked, then when you paste in the variable creator it //
// will automatically give you all the variables you need for //
// this spell //
// //
// While the remaining object editor based data is not required //
// to function (provided they're replaced with equivelents) //
// it's recommended that they are also imported, if their data //
// value are not the same as listed in the configuration, those //
// configurables will need to be changed to work correctly //
//----------------------------------------------------------------//
// CONFIGURABLE INFORMATION/HELP: //
// //
// - Viewing data values: To see data values in the editor you //
// need to press Ctrl + D, to shift back to normal viewing //
// press it again //
// //
// - Effects: Pathnames for effects used in the spells should //
// have two "\"s throughout or the effect will not work (the //
// WE progress bar will not go away when saving, however if //
// fixed afterwards the save will still work, but the progress //
// bar will still remain until the WE is closed) //
// e.g. "units\\human\\Footman\\Footman" //
// //
// - Effect Scaling: Some effects have scale values below them //
// the scale determines the size of the effect and is expressed //
// as a real percentage (1.00 = 100%) //
// //
// - Removing Effects: to remove an effect you don't want from //
// the ability, set the model path to that of Dummy.mdl //
// //
// - Base and Per Values: Most configurables have a base and per //
// value, Base values are what a value is set to regardless of //
// other factors. Per values are what a value is set to based on //
// what the per value is the formula for calculating the result //
// is as follows: //
// - BaseValue + (Factor * PerValue) //
// //
// - Timer: Some configurables have PerSecond values, the code //
// automatically accounts for changes to the timer as to //
// maintain consistency with what the user has chosen //
// All times in the system are expressions of seconds //
// //
// - AttackTypes: This should match the Damage Type of the //
// ability, though it can be something else if you wish //
// //
// - DamageTypes: This changes the damage multiplyer vs. enemy //
// armour types, note that by default the damage filters //
// exclude magic immune units so changing this from MAGIC //
// damage will not make them take damage //
// //
// - WeaponTypes: Generally don't need to be used, should only //
// not be null if you particularly wish or need to use them //
// //
//----------------------------------------------------------------//
// TimerSpeed: This is the amount of time in seconds between //
// each iteration of the Soul Release Loop function //
constant function BUSRR_TimerSpeed takes nothing returns real
return 0.031250000
endfunction
//----------------------------------------------------------------//
// Ability: This is the AbilityId that is used as the dummy //
// ability used for the soul release spell //
constant function BUSRR_Ability takes nothing returns integer
return 'A06P'
endfunction
//----------------------------------------------------------------//
// InvulAbility: This is the AbilityId that is used to make the //
// spirits immune, this should be the ability "invulnerability" //
// (which one it is doesn't matter) //
constant function BUSRR_InvulAbility takes nothing returns integer
return 'Avul'
endfunction
//----------------------------------------------------------------//
// DummyId: This is the UnitId that is used to create effects //
// It is recommended this unit use Dummy.mdl for its model for //
// optimal usage //
constant function BUSRR_DummyId takes nothing returns integer
return 'u00A'
endfunction
//----------------------------------------------------------------//
// Event: This is the value of BUS_Event that it will be set to //
// when the channeling ends, this should be unique to each //
// ability which uses the channel system //
constant function BUSRR_Event takes nothing returns integer
return 1
endfunction
//----------------------------------------------------------------//
// AttachmentPoint: This is the point on units that effects will //
// be attached to //
constant function BUSRR_AttachmentPoint takes nothing returns string
return "origin"
endfunction
//----------------------------------------------------------------//
// HaveHue: This determines whether or not a unit will have its //
// hue altered during the channeling stage //
constant function BUSRR_HaveHue takes nothing returns boolean
return true
endfunction
//----------------------------------------------------------------//
// ChannelType: This determines the type of channel that is used //
// This should match the name of channel type used //
constant function BUSRR_ChannelType takes nothing returns string
return "Holy Storm"
endfunction
//----------------------------------------------------------------//
// ChannelDurationBase: This determines how long the ability //
// will use the channel system before starting its next stage //
constant function BUSRR_ChannelDurationBase takes nothing returns real
return 6.
endfunction
//----------------------------------------------------------------//
// ChannelDurationPerLevel: The per level counterpart of //
// ChannelDurationBase //
constant function BUSRR_ChannelDurationPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// HitDistanceBase: This is the range used to check if units //
// are valid targets for the ability once the channeling is //
// completed //
constant function BUSRR_HitDistanceBase takes nothing returns real
return 700.
endfunction
//----------------------------------------------------------------//
// HitDistancePerLevel: The per level counterpart of //
// HitDistanceBase //
constant function BUSRR_HitDistancePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// MainAOEBase: This is the AOE of the central bolt of the //
// ability which will turn units into spirits //
constant function BUSRR_MainAOEBase takes nothing returns real
return 150.
endfunction
//----------------------------------------------------------------//
// MainAoePerLevel: This is the per level counterpart of //
// MainAOEBase //
constant function BUSRR_MainAOEPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// MiniAOEBase: This is the AOE of the smaller bolts of the //
// ability which appear around the central bolt //
constant function BUSRR_MiniAOEBase takes nothing returns real
return 75.
endfunction
//----------------------------------------------------------------//
// MiniAOEPerLevel: This is the per level counterpart of //
// MiniAOEBase //
constant function BUSRR_MiniAOEPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// MiniCountBase: This is the amount of smaller bolts that //
// appear around the central bolt //
constant function BUSRR_MiniCountBase takes nothing returns integer
return 8
endfunction
//----------------------------------------------------------------//
// MiniCountPerLevel: This is the per level counterpart of //
// MiniCountBase //
constant function BUSRR_MiniCountPerLevel takes nothing returns integer
return 0
endfunction
//----------------------------------------------------------------//
// MainScaleBase: This is the scaling size of the main bolt //
constant function BUSRR_MainScaleBase takes nothing returns real
return 3.
endfunction
//----------------------------------------------------------------//
// MainScalePerLevel: This is the per level counterpart of //
// MainScaleBase //
constant function BUSRR_MainScalePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// MiniScaleBase: This is the scaling size of the smaller bolts //
// that appear around the central bolt //
constant function BUSRR_MiniScaleBase takes nothing returns real
return 0.5
endfunction
//----------------------------------------------------------------//
// MiniScalePerLevel: This is the per level counterpart of //
// MiniScaleBase //
constant function BUSRR_MiniScalePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// MainEffect: This is the pathname of the model used for the //
// central bolt //
constant function BUSRR_MainEffect takes nothing returns string
return "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
endfunction
//----------------------------------------------------------------//
// MiniEffect: This is the pathname of the model used for the //
// smaller bolts //
constant function BUSRR_MiniEffect takes nothing returns string
return "war3mapImported\\LightningWrath.mdx"
endfunction
//----------------------------------------------------------------//
// FailEffect: This is the pathname of the model used when the //
// Ability fails (target moved too far away) //
constant function BUSRR_FailEffect takes nothing returns string
return "Abilities\\Spells\\Human\\Invisibility\\InvisibilityTarget.mdl"
endfunction
//----------------------------------------------------------------//
// SpiritRed: This is the red hue of spirits created by the //
// ability //
constant function BUSRR_SpiritRed takes nothing returns integer
return 255
endfunction
//----------------------------------------------------------------//
// SpiritGreen: This is the green hue of spirits created by the //
// ability //
constant function BUSRR_SpiritGreen takes nothing returns integer
return 255
endfunction
//----------------------------------------------------------------//
// SpiritBlue: This is the blue hue of spirits created by the //
// ability //
constant function BUSRR_SpiritBlue takes nothing returns integer
return 125
endfunction
//----------------------------------------------------------------//
// SpiritAlpha: This is the alpha of spirits created by the //
// ability //
constant function BUSRR_SpiritAlpha takes nothing returns integer
return 125
endfunction
//----------------------------------------------------------------//
// AscentionBase: This is the speed at which spirits travel //
// upwards //
constant function BUSRR_AscentionBase takes nothing returns real
return 5.
endfunction
//----------------------------------------------------------------//
// AscentionPerLevel: This is the per level counterpart of //
// AscentionBase //
constant function BUSRR_AscentionPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// AscentionStart: This is the starting height of spirits when //
// they are created //
constant function BUSRR_AscentionStart takes nothing returns real
return 200.
endfunction
//----------------------------------------------------------------//
// AscentionTimeBase: This is how long a spirit ascends //
constant function BUSRR_AscentionTimeBase takes nothing returns real
return 1.
endfunction
//----------------------------------------------------------------//
// AscentionTimePerLevel: This is the per level counterpart of //
// AscentionTimeBase //
constant function BUSRR_AscentionTimePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// EffectTime: This is how long after the effects are completed //
// that they are completely removed from the lists //
constant function BUSRR_EffectTime takes nothing returns real
return 4.0
endfunction
//----------------------------------------------------------------//
// TargetFilter: This is the target filter for units that can //
// be turned into spirits, configure this as desired (requires //
// some coding knowledge, u is the target unit, pl is the player //
// who owns the caster) //
function BUS_RTargetFilter takes unit u, player pl returns boolean
return (not(IsUnitType(u, UNIT_TYPE_DEAD)) and not(IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (IsPlayerEnemy(GetOwningPlayer(u), pl)))
endfunction
//----------------------------------------------------------------//
// END OF CONFIGURATION //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// SoulReleaseLoop: Function used to move and handle spirits and //
// effects that are no longer in use //
////////////////////////////////////////////////////////////////////
function BUS_SoulReleaseLoop takes nothing returns nothing
local integer Node = 0
loop
set Node = udg_BUSR_PNextNode[Node]
exitwhen Node == 0
if (udg_BUSR_PCurrentAlpha[Node] <= 0) then
call RemoveUnit(udg_BUSR_PUnit[Node])
set udg_BUSR_PRecycleNodes[udg_BUSR_PRecyclableNodes] = Node
set udg_BUSR_PRecyclableNodes = udg_BUSR_PRecyclableNodes + 1
set udg_BUSR_PNextNode[udg_BUSR_PPrevNode[Node]] = udg_BUSR_PNextNode[Node]
set udg_BUSR_PPrevNode[udg_BUSR_PNextNode[Node]] = udg_BUSR_PPrevNode[Node]
if (udg_BUSR_NextNode[0] + udg_BUSR_PNextNode[0] == 0) then
call PauseTimer(udg_BUSR_Timer)
endif
else
set udg_BUSR_PCurrentAlpha[Node] = udg_BUSR_PCurrentAlpha[Node] - udg_BUSR_PAlphaReduction[Node]
call SetUnitVertexColor(udg_BUSR_PUnit[Node], BUSRR_SpiritRed(), BUSRR_SpiritGreen(), BUSRR_SpiritBlue(), udg_BUSR_PCurrentAlpha[Node])
call SetUnitFlyHeight(udg_BUSR_PUnit[Node], GetUnitFlyHeight(udg_BUSR_PUnit[Node]) + udg_BUSR_PSpeed[Node], 0.)
endif
endloop
set Node = 0
loop
set Node = udg_BUSR_NextNode[Node]
exitwhen Node == 0
if (udg_BUSR_Time[Node] < 0) then
call RemoveUnit(udg_BUSR_Unit[Node])
set udg_BUSR_RecycleNodes[udg_BUSR_RecyclableNodes] = Node
set udg_BUSR_RecyclableNodes = udg_BUSR_RecyclableNodes + 1
set udg_BUSR_NextNode[udg_BUSR_PrevNode[Node]] = udg_BUSR_NextNode[Node]
set udg_BUSR_PrevNode[udg_BUSR_NextNode[Node]] = udg_BUSR_PrevNode[Node]
if (udg_BUSR_NextNode[0] + udg_BUSR_PNextNode[0] == 0) then
call PauseTimer(udg_BUSR_Timer)
endif
else
set udg_BUSR_Time[Node] = udg_BUSR_Time[Node] - BUSRR_TimerSpeed()
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// SoulReleaseSpawn: The main function, used to kill units, //
// create spirits and effects and set up the loop //
////////////////////////////////////////////////////////////////////
function BUS_SoulReleaseSpawn takes real x, real y, real AOE, real Scale, real Speed, real Time, player pl, string m returns nothing
local integer Node
local unit u
if (udg_BUSR_RecyclableNodes == 0) then
set udg_BUSR_NodeNumber = udg_BUSR_NodeNumber + 1
set Node = udg_BUSR_NodeNumber
else
set udg_BUSR_RecyclableNodes = udg_BUSR_RecyclableNodes - 1
set Node = udg_BUSR_RecycleNodes[udg_BUSR_RecyclableNodes]
endif
set udg_BUSR_NextNode[Node] = 0
set udg_BUSR_NextNode[udg_BUSR_PrevNode[0]] = Node
set udg_BUSR_PrevNode[Node] = udg_BUSR_PrevNode[0]
set udg_BUSR_PrevNode[0] = Node
if (udg_BUSR_PrevNode[Node] + udg_BUSR_PPrevNode[0] == 0) then
call TimerStart(udg_BUSR_Timer, BUSRR_TimerSpeed(), true, function BUS_SoulReleaseLoop)
endif
set udg_BUSR_Unit[Node] = CreateUnit(BUSCR_DummyPlayer(), BUSRR_DummyId(), x, y, 0.)
call SetUnitScale(udg_BUSR_Unit[Node], Scale, 0., 0.)
call DestroyEffect(AddSpecialEffectTarget(m, udg_BUSR_Unit[Node], BUSRR_AttachmentPoint()))
set udg_BUSR_Time[Node] = BUSRR_EffectTime()
call GroupEnumUnitsInRange(udg_BUSR_UnitGroup, x, y, AOE, null)
loop
set u = FirstOfGroup(udg_BUSR_UnitGroup)
exitwhen u == null
call GroupRemoveUnit(udg_BUSR_UnitGroup, u)
if (BUS_RTargetFilter(u, pl)) then
if (udg_BUSR_PRecyclableNodes == 0) then
set udg_BUSR_PNodeNumber = udg_BUSR_PNodeNumber + 1
set Node = udg_BUSR_PNodeNumber
else
set udg_BUSR_PRecyclableNodes = udg_BUSR_PRecyclableNodes - 1
set Node = udg_BUSR_PRecycleNodes[udg_BUSR_PRecyclableNodes]
endif
set udg_BUSR_PNextNode[Node] = 0
set udg_BUSR_PNextNode[udg_BUSR_PPrevNode[0]] = Node
set udg_BUSR_PPrevNode[Node] = udg_BUSR_PPrevNode[0]
set udg_BUSR_PPrevNode[0] = Node
call KillUnit(u)
set x = GetUnitX(u)
set y = GetUnitY(u)
set udg_BUSR_PUnit[Node] = CreateUnit(Player(15), GetUnitTypeId(u), x, y, GetUnitFacing(u))
call SetUnitColor(udg_BUSR_PUnit[Node], GetPlayerColor(GetOwningPlayer(u)))
call SetUnitVertexColor(udg_BUSR_PUnit[Node], BUSRR_SpiritRed(), BUSRR_SpiritGreen(), BUSRR_SpiritBlue(), BUSRR_SpiritAlpha())
call SetUnitPathing(udg_BUSR_PUnit[Node], false)
if UnitAddAbility(udg_BUSR_PUnit[Node], 'Amrf') and UnitRemoveAbility(udg_BUSR_PUnit[Node], 'Amrf') then
endif
call PauseUnit(udg_BUSR_PUnit[Node], true)
call UnitAddAbility(udg_BUSR_PUnit[Node], BUSRR_InvulAbility())
call SetUnitFlyHeight(udg_BUSR_PUnit[Node], BUSRR_AscentionStart(), 0.)
set udg_BUSR_PSpeed[Node] = Speed
set udg_BUSR_PCurrentAlpha[Node] = BUSRR_SpiritAlpha()
set udg_BUSR_PAlphaReduction[Node] = R2I((I2R(BUSRR_SpiritAlpha()) / Time) * BUSRR_TimerSpeed())
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// SoulReleaseEvent: Function used to determine the points of //
// impact. Runs when the channeling is finished and handles //
// all calculations //
////////////////////////////////////////////////////////////////////
function BUS_SoulReleaseEvent takes nothing returns boolean
local real rLevel = GetUnitAbilityLevel(udg_BUS_Unit, BUSRR_Ability())
local real x = GetUnitX(udg_BUS_Unit)
local real y = GetUnitY(udg_BUS_Unit)
local real x2 = GetUnitX(udg_BUS_Target)
local real y2 = GetUnitY(udg_BUS_Target)
local real TempReal
local real TempReal2
local real TempReal3
local real TempReal4
local real TempReal5
local real TempReal6
local real Angle
local integer iLoop
local integer TempInt
local player pl
if (SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)) <= BUSRR_HitDistanceBase() + (rLevel * BUSRR_HitDistancePerLevel())) then
set pl = GetOwningPlayer(udg_BUS_Unit)
set TempReal = BUSRR_MainAOEBase() + (rLevel * BUSRR_MainAOEPerLevel())
set TempReal2 = BUSRR_MainScaleBase() + (rLevel * BUSRR_MainScalePerLevel())
set TempReal3 = BUSRR_AscentionBase() + (rLevel * BUSRR_AscentionPerLevel())
set TempReal4 = BUSRR_AscentionTimeBase() + (rLevel * BUSRR_AscentionTimePerLevel())
call BUS_SoulReleaseSpawn(x2, y2, TempReal, TempReal2, TempReal3, TempReal4, pl, BUSRR_MainEffect())
set TempReal2 = BUSRR_MiniAOEBase() + (rLevel * BUSRR_MiniAOEPerLevel())
set TempReal6 = TempReal + TempReal2
set TempReal = BUSRR_MiniScaleBase() + (rLevel *BUSRR_MiniScalePerLevel())
set TempInt = BUSRR_MiniCountBase() + (R2I(rLevel) * BUSRR_MiniCountPerLevel())
set TempReal5 = 360 / I2R(TempInt)
set Angle = 0
set iLoop = 0
loop
set iLoop = iLoop + 1
exitwhen iLoop > TempInt
set Angle = Angle + TempReal5
set x = x2 + TempReal6 * Cos(Angle * bj_DEGTORAD)
set y = y2 + TempReal6 * Sin(Angle * bj_DEGTORAD)
call BUS_SoulReleaseSpawn(x, y, TempReal2, TempReal, TempReal3, TempReal4, pl, BUSRR_MiniEffect())
endloop
set pl = null
else
call DestroyEffect(AddSpecialEffectTarget(BUSRR_FailEffect(), udg_BUS_Unit, BUSRR_AttachmentPoint()))
endif
return false
endfunction
////////////////////////////////////////////////////////////////////
// SoulReleaseStart: Function used to set up the channeling //
// for the ability //
////////////////////////////////////////////////////////////////////
function BUS_SoulReleaseStart takes nothing returns boolean
local unit u
if (GetSpellAbilityId() == BUSRR_Ability()) then
set u = GetTriggerUnit()
call BUS_StartChannel(BUS_GetChannelByName(BUSRR_ChannelType()), u, GetSpellTargetUnit(), 0., 0., BUSRR_ChannelDurationBase() + (GetUnitAbilityLevel(u, BUSRR_Ability()) * BUSRR_ChannelDurationPerLevel()), BUSRR_Event(), BUSRR_HaveHue())
set u = null
endif
return false
endfunction
////////////////////////////////////////////////////////////////////
// InitTrig BUS Soul Release: Function used to set up the //
// event and starting functions of the ability as well as the //
// timer for the loop //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Soul_Release takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index >= bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t, Condition(function BUS_SoulReleaseStart))
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_BUSC_Event", EQUAL, BUSRR_Event())
call TriggerAddCondition(t, Condition(function BUS_SoulReleaseEvent))
set udg_BUSS_Timer = CreateTimer()
endfunction
////////////////////////////////////////////////////////////////////
// End of the spell //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Boss Ultimate Spellpack Scathe V1.00 //
// Author: Tank-Commander //
// Purpose: Boss Strong Knockback/High Damage Laser //
// Requires: Dummy.mdl, BUS Channel, BUS Knockback //
// //
// Notes: //
// - Read the readme before you try modifying the config //
// - Use the "Helpful files" to help you import the system //
// //
// Credits: //
// - (Dummy.mdl) Vexorian //
// - (OrbitalRay.mdl) Callahan //
// //
// Optimum User: Any //
// //
// If you have used this spellpack in your map, you are required //
// to give credits to Tank-Commander for the creation of it //
// If you would like to use snippets of code from this for //
// whatever, getting permission and crediting the source/linking //
// would be much appreciated. //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// README: //
// Before modifying this spell a few things need to be //
// understood and read, this is one of those things, while //
// most modification can be considered intuitive, it still //
// helps to read through these intstructions, as they will //
// inform you about how to configure this spell to your //
// desire. //
//----------------------------------------------------------------//
// Initial importing: The variable creator trigger can be //
// imported first and if you have the correct settings (file, //
// preferences, General, automatically create unknown variables //
// checked, then when you paste in the variable creator it //
// will automatically give you all the variables you need for //
// this spell //
// //
// While the remaining object editor based data is not required //
// to function (provided they're replaced with equivelents) //
// it's recommended that they are also imported, if their data //
// value are not the same as listed in the configuration, those //
// configurables will need to be changed to work correctly //
//----------------------------------------------------------------//
// CONFIGURABLE INFORMATION/HELP: //
// //
// - Viewing data values: To see data values in the editor you //
// need to press Ctrl + D, to shift back to normal viewing //
// press it again //
// //
// - Effects: Pathnames for effects used in the spells should //
// have two "\"s throughout or the effect will not work (the //
// WE progress bar will not go away when saving, however if //
// fixed afterwards the save will still work, but the progress //
// bar will still remain until the WE is closed) //
// e.g. "units\\human\\Footman\\Footman" //
// //
// - Effect Scaling: Some effects have scale values below them //
// the scale determines the size of the effect and is expressed //
// as a real percentage (1.00 = 100%) //
// //
// - Removing Effects: to remove an effect you don't want from //
// the ability, set the model path to that of Dummy.mdl //
// //
// - Base and Per Values: Most configurables have a base and per //
// value, Base values are what a value is set to regardless of //
// other factors. Per values are what a value is set to based on //
// what the per value is the formula for calculating the result //
// is as follows: //
// - BaseValue + (Factor * PerValue) //
// //
// - Timer: Some configurables have PerSecond values, the code //
// automatically accounts for changes to the timer as to //
// maintain consistency with what the user has chosen //
// All times in the system are expressions of seconds //
// //
// - AttackTypes: This should match the Damage Type of the //
// ability, though it can be something else if you wish //
// //
// - DamageTypes: This changes the damage multiplyer vs. enemy //
// armour types, note that by default the damage filters //
// exclude magic immune units so changing this from MAGIC //
// damage will not make them take damage //
// //
// - WeaponTypes: Generally don't need to be used, should only //
// not be null if you particularly wish or need to use them //
// //
//----------------------------------------------------------------//
// TimerSpeed: This is the amount of time in seconds between //
// each iteration of the Scathe Loop function //
constant function BUSSR_TimerSpeed takes nothing returns real
return 0.031250000
endfunction
//----------------------------------------------------------------//
// Ability: This is the AbilityId that is used as the dummy //
// ability used for the scathe spell //
constant function BUSSR_Ability takes nothing returns integer
return 'A06N'
endfunction
//----------------------------------------------------------------//
// DummyId: This is the UnitId that is used to create effects //
// It is recommended this unit use Dummy.mdl for its model for //
// optimal usage //
constant function BUSSR_DummyId takes nothing returns integer
return 'u00A'
endfunction
//----------------------------------------------------------------//
// Event: This is the value of BUS_Event that it will be set to //
// when the channeling ends, this should be unique to each //
// ability which uses the channel system //
constant function BUSSR_Event takes nothing returns integer
return 2
endfunction
//----------------------------------------------------------------//
// Order: This is the order ID of the ability used to make sure //
// that the unit is still channeling the ability //
constant function BUSSR_Order takes nothing returns integer
return 852187
endfunction
//----------------------------------------------------------------//
// AttachmentPoint: This is the point that effects are attached //
// to on units and dummy units //
constant function BUSSR_AttachmentPoint takes nothing returns string
return "origin"
endfunction
//----------------------------------------------------------------//
// HaveHue; This determines whether or not during channeling //
// the hue of the caster changes throughout //
constant function BUSSR_HaveHue takes nothing returns boolean
return true
endfunction
//----------------------------------------------------------------//
// ChannelType: This is the name of the channel type used by //
// this ability (it should match the name of the channel type) //
constant function BUSSR_ChannelType takes nothing returns string
return "Arcane charge"
endfunction
//----------------------------------------------------------------//
// HealthDamageBase: This is the damage dealt by the laser to //
// enemy units //
constant function BUSSR_HealthDamageBase takes nothing returns real
return 10000.0
endfunction
//----------------------------------------------------------------//
// HealthDamagePerLevel: This is the per level counterpart of //
// HealthDamageBase //
constant function BUSSR_HealthDamagePerLevel takes nothing returns real
return 10000.00
endfunction
//----------------------------------------------------------------//
// ManaDamageBase: This is the mana damage dealt by the laser //
// to enemy units //
constant function BUSSR_ManaDamageBase takes nothing returns real
return 10000.
endfunction
//----------------------------------------------------------------//
// ManaDamagePerLevel: This is the per level counterpart of //
// ManaDamageBase //
constant function BUSSR_ManaDamagePerLevel takes nothing returns real
return 10000.
endfunction
//----------------------------------------------------------------//
// ChannelDurationBase: This is the duration of the channeling //
// used by the spell //
constant function BUSSR_ChannelDurationBase takes nothing returns real
return 2.5
endfunction
//----------------------------------------------------------------//
// ChannelDurationPerLevel: This is the per level counterpart of //
// ChannelDurationBase //
constant function BUSSR_ChannelDurationPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// AOEBase: This is the AOE of the laser (width of the laser) //
constant function BUSSR_AOEBase takes nothing returns real
return 100.
endfunction
//----------------------------------------------------------------//
// AOEPerLevel: This is the per level counterpart of AOEBASE //
constant function BUSSR_AOEPerLevel takes nothing returns real
return 100.
endfunction
//----------------------------------------------------------------//
// RangeBase: This is the maximum distance of the laser //
constant function BUSSR_RangeBase takes nothing returns real
return 100.
endfunction
//----------------------------------------------------------------//
// RangePerLevel: This is the per level counterpart of RangeBase //
constant function BUSSR_RangePerLevel takes nothing returns real
return 100.
endfunction
//----------------------------------------------------------------//
// ForceBase: This is the amount of force the laser exerts on //
// units which are hit by it //
constant function BUSSR_ForceBase takes nothing returns real
return 90.
endfunction
//----------------------------------------------------------------//
// ForcePerLevel: This is the per level counterpart of ForceBase //
constant function BUSSR_ForcePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// EndChannelTimeBase: This is the time after channeling is //
// completed that the laser is created (this value + the Angle //
// delay == how long after channeling the laser fires) //
constant function BUSSR_EndChannelTimeBase takes nothing returns real
return 0.75
endfunction
//----------------------------------------------------------------//
// EndChannelTimePerLevel: This is the per level counterpart //
// EndChannelTimeBase //
constant function BUSSR_EndChannelTimePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// EndChannelAngleDelay: This is the time after being created //
// that the laser fires //
constant function BUSSR_EndChannelAngleDelay takes nothing returns real
return 0.50
endfunction
//----------------------------------------------------------------//
// EffectRemove: This is how long after an effect has been //
// completed that it is removed //
constant function BUSSR_EffectRemove takes nothing returns real
return 4.00
endfunction
//----------------------------------------------------------------//
// PointerScaleBase: This is the scale of the effect which //
// denotes the angle of fire of the laser //
constant function BUSSR_PointerScaleBase takes nothing returns real
return 3.
endfunction
//----------------------------------------------------------------//
// PointerScalePerLevel: This is the per level counterpart //
// PointerScaleBase //
constant function BUSSR_PointerScalePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// LaserScaleBase: This is the scaling size of the laser //
constant function BUSSR_LaserScaleBase takes nothing returns real
return 2.25
endfunction
//----------------------------------------------------------------//
// LaserScalePerLevel: This is the per level counterpart of //
// LaserScaleBase //
constant function BUSSR_LaserScalePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OffsetBase: This is the offset from the casting unit that all //
// laser effects are created at //
constant function BUSSR_OffsetBase takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OffsetPerLevel: This is the per level counterpart of //
// OffsetBase //
constant function BUSSR_OffsetPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// GroundHeightOffset: This is the z offset lasers are created //
// at when the spell is cast by a ground unit //
constant function BUSSR_GroundHeightOffset takes nothing returns real
return 200.
endfunction
//----------------------------------------------------------------//
// PointerEffect: This is the pathname of the effect used to //
// denote the direction of the laser //
constant function BUSSR_PointerEffect takes nothing returns string
return "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldTarget.mdl"
endfunction
//----------------------------------------------------------------//
// LaserEffect: This is the pathname of the effect used to //
// denote the laser //
constant function BUSSR_LaserEffect takes nothing returns string
return "OrbitalRay.mdx"
endfunction
//----------------------------------------------------------------//
// UnitDamageEffect: This is the pathname of the effect used to //
// denote a unit being damaged //
constant function BUSSR_UnitDamageEffect takes nothing returns string
return "Objects\\Spawnmodels\\NightElf\\NEDeathSmall\\NEDeathSmall.mdl"
endfunction
//----------------------------------------------------------------//
// GroundDamageEffect: This is the pathname of the effect used //
// to mark where the laser hits the ground //
constant function BUSSR_GroundDamageEffect takes nothing returns string
return "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
endfunction
//----------------------------------------------------------------//
// AttackType: This is the attacktype used by the spell //
constant function BUSSR_AttackType takes nothing returns attacktype
return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
// DamageType: This is the damagetype used by the spell //
constant function BUSSR_DamageType takes nothing returns damagetype
return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
// WeaponType: This is the weapontype used by the spell //
constant function BUSSR_WeaponType takes nothing returns weapontype
return null
endfunction
//----------------------------------------------------------------//
// TargetFilter: This is the target filter for units that can //
// be turned into spirits, configure this as desired (requires //
// some coding knowledge, u is the target unit, Node is the //
// index of the casting unit //
function BUS_STargetFilter takes unit u, integer Node returns boolean
return (not(IsUnitType(u, UNIT_TYPE_DEAD)) and not(IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (IsPlayerEnemy(GetOwningPlayer(u), udg_BUSS_Owner[Node])))
endfunction
//----------------------------------------------------------------//
// END OF CONFIGURATION //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function used to prevent two casts of the same channel being //
// done simultaneously //
////////////////////////////////////////////////////////////////////
function BUS_CheckScathe takes unit u returns integer
local integer Node = 0
loop
set Node = udg_BUSS_NextNode[Node]
exitwhen (udg_BUSS_Unit[Node] == u) or (Node == 0)
endloop
return Node
endfunction
////////////////////////////////////////////////////////////////////
// ScatheLoop: The main function used to make sure the caster is //
// still channeling the ability, fire the laser and handle all //
// effects used by the ability //
////////////////////////////////////////////////////////////////////
function BUS_ScatheLoop takes nothing returns nothing
local integer Node = 0
local integer TempNode = 0
local real TempRealX
local real TempRealY
local real TempRealZ
local real TempRealMax
local real x
local real y
local real z
local real dx
local real dy
local real Angle
local real Angle2
local unit TempUnit
local boolean TempBoolean
loop
set Node = udg_BUSS_NextNode[Node]
exitwhen Node == 0
if (GetUnitCurrentOrder(udg_BUSS_Unit[Node]) == BUSSR_Order()) and not(udg_BUSS_Cancel[Node]) then
if (udg_BUSS_EndChannelTime[Node] < 0) and (udg_BUSS_Activate[Node]) then
set udg_BUSS_Activate[Node] = false
set udg_BUSS_EndDelay[Node] = BUSSR_EndChannelAngleDelay()
set udg_BUSS_EffectMade[Node] = true
if (udg_BUSS_PRecyclableNodes == 0) then
set udg_BUSS_PNodeNumber = udg_BUSS_PNodeNumber + 1
set TempNode = udg_BUSS_PNodeNumber
else
set udg_BUSS_PRecyclableNodes = udg_BUSS_PRecyclableNodes - 1
set TempNode = udg_BUSS_PRecycleNodes[udg_BUSS_PRecyclableNodes]
endif
set udg_BUSS_PNextNode[TempNode] = 0
set udg_BUSS_PNextNode[udg_BUSS_PPrevNode[0]] = TempNode
set udg_BUSS_PPrevNode[TempNode] = udg_BUSS_PPrevNode[0]
set udg_BUSS_PPrevNode[0] = TempNode
set udg_BUSS_PRemove[TempNode] = false
set udg_BUSS_PCaster[TempNode] = udg_BUSS_Unit[Node]
set udg_BUSS_PUnit[TempNode] = CreateUnit(BUSCR_DummyPlayer(), BUSSR_DummyId(),udg_BUSS_PX[Node],udg_BUSS_PY[Node], udg_BUSS_Angle[Node])
if UnitAddAbility(udg_BUSS_PUnit[TempNode], 'Amrf') and UnitRemoveAbility(udg_BUSS_PUnit[TempNode], 'Amrf') then
endif
call SetUnitScale(udg_BUSS_PUnit[TempNode], udg_BUSS_LaserScale[Node], 0.00, 0.00)
call SetUnitAnimationByIndex(udg_BUSS_PUnit[TempNode], udg_BUSS_PAnimationIndex[Node])
set udg_BUSS_PCurrentEffect[TempNode] = null
call SetUnitFlyHeight(udg_BUSS_PUnit[TempNode], udg_BUSS_PZ[Node] - BUS_GetZ(udg_BUSS_PX[Node], udg_BUSS_PY[Node]), 0.00)
else
set udg_BUSS_EndChannelTime[Node] = udg_BUSS_EndChannelTime[Node] - BUSSR_TimerSpeed()
endif
if (udg_BUSS_EndDelay[Node] < 0) and (not(udg_BUSS_Activate[Node])) and (udg_BUSS_EffectMade[Node]) then
set TempNode = 0
loop
set TempNode = udg_BUSS_PNextNode[TempNode]
exitwhen TempNode == 0
if (udg_BUSS_PCurrentEffect[TempNode] == null) and (udg_BUSS_PCaster[TempNode] == udg_BUSS_Unit[Node]) then
set udg_BUSS_PCurrentEffect[TempNode] = AddSpecialEffectTarget(BUSSR_LaserEffect(), udg_BUSS_PUnit[TempNode], BUSSR_AttachmentPoint())
set udg_BUSS_EffectMade[Node] = false
endif
endloop
set TempRealX = udg_BUSS_PX[Node]
set TempRealY = udg_BUSS_PY[Node]
set TempRealZ = udg_BUSS_PZ[Node]
set TempRealMax = 0.
loop
call GroupEnumUnitsInRange(udg_BUSS_UnitGroup, TempRealX, TempRealY, udg_BUSS_AOE[Node], null)
loop
set TempUnit = FirstOfGroup(udg_BUSS_UnitGroup)
exitwhen TempUnit == null
set x = GetUnitX(TempUnit)
set y = GetUnitY(TempUnit)
set z = GetUnitFlyHeight(TempUnit) + BUS_GetZ(x,y)
if (BUS_STargetFilter(TempUnit, Node)) and (SquareRoot((TempRealX - x) * (TempRealX - x) + (TempRealY - y) * (TempRealY - y) + (TempRealZ - z) * (TempRealZ - z)) < udg_BUSS_AOE[Node]) then
call UnitDamageTarget(udg_BUSS_Unit[Node], TempUnit, udg_BUSS_HealthDamage[Node], false, false, BUSSR_AttackType(), BUSSR_DamageType(), BUSSR_WeaponType())
call SetUnitState(TempUnit, UNIT_STATE_MANA, GetUnitState(TempUnit, UNIT_STATE_MANA) - udg_BUSS_ManaDamage[Node])
call DestroyEffect(AddSpecialEffectTarget(BUSSR_UnitDamageEffect(), TempUnit, BUSSR_AttachmentPoint()))
call BUS_StartKnockback(TempUnit, udg_BUSS_Force[Node], x, udg_BUSS_PX[Node], y, udg_BUSS_PY[Node], z, udg_BUSS_PZ[Node])
endif
call GroupRemoveUnit(udg_BUSS_UnitGroup, TempUnit)
endloop
exitwhen ((TempRealMax > udg_BUSS_Range[Node]) or (TempRealZ < BUS_GetZ(TempRealX, TempRealY)))
set TempRealX = TempRealX + (udg_BUSS_DX[Node])
set TempRealY = TempRealY + (udg_BUSS_DY[Node])
set TempRealZ = TempRealZ + (udg_BUSS_DZ[Node])
set TempRealMax = TempRealMax + udg_BUSS_AOE[Node]
endloop
if (TempRealZ < BUS_GetZ(TempRealX, TempRealY)) then
call DestroyEffect(AddSpecialEffect(BUSSR_GroundDamageEffect(), TempRealX, TempRealY))
endif
else
set udg_BUSS_EndDelay[Node] = udg_BUSS_EndDelay[Node] - BUSSR_TimerSpeed()
endif
else
set TempNode = 0
loop
set TempNode = udg_BUSS_PNextNode[TempNode]
exitwhen TempNode == 0
if (udg_BUSS_PCaster[TempNode] == udg_BUSS_Unit[Node]) then
if not(udg_BUSS_PCurrentEffect[TempNode] == null) then
call DestroyEffect(udg_BUSS_PCurrentEffect[TempNode])
endif
set udg_BUSS_PRemove[TempNode] = true
set udg_BUSS_PTimer[TempNode] = BUSSR_EffectRemove()
endif
endloop
set udg_BUSS_RecycleNodes[udg_BUSS_RecyclableNodes] = Node
set udg_BUSS_RecyclableNodes = udg_BUSS_RecyclableNodes + 1
set udg_BUSS_NextNode[udg_BUSS_PrevNode[Node]] = udg_BUSS_NextNode[Node]
set udg_BUSS_PrevNode[udg_BUSS_NextNode[Node]] = udg_BUSS_PrevNode[Node]
if (udg_BUSS_NextNode[0] + udg_BUSS_PNextNode[0] == 0) then
call PauseTimer(udg_BUSS_Timer)
endif
endif
endloop
set TempNode = 0
loop
set TempNode = udg_BUSS_PNextNode[TempNode]
exitwhen TempNode == 0
if (udg_BUSS_PRemove[TempNode]) then
if (udg_BUSS_PTimer[TempNode] < 0) then
call RemoveUnit(udg_BUSS_PUnit[TempNode])
set udg_BUSS_PRecycleNodes[udg_BUSS_PRecyclableNodes] = TempNode
set udg_BUSS_PRecyclableNodes = udg_BUSS_PRecyclableNodes + 1
set udg_BUSS_PNextNode[udg_BUSS_PPrevNode[TempNode]] = udg_BUSS_PNextNode[TempNode]
set udg_BUSS_PPrevNode[udg_BUSS_PNextNode[TempNode]] = udg_BUSS_PPrevNode[TempNode]
if (udg_BUSS_NextNode[0] + udg_BUSS_PNextNode[0] == 0) then
call PauseTimer(udg_BUSS_Timer)
endif
else
set udg_BUSS_PTimer[TempNode] = udg_BUSS_PTimer[TempNode] - BUSSR_TimerSpeed()
endif
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// ScatheEvent: Function used to set up all the data and effects //
// that are used in the loop. Activates when the channeling is //
// completed //
////////////////////////////////////////////////////////////////////
function BUS_ScatheEvent takes nothing returns boolean
local real rLevel = GetUnitAbilityLevel(udg_BUS_Unit, BUSSR_Ability())
local integer Node
local integer TempNode
local real x = GetUnitX(udg_BUS_Unit)
local real y = GetUnitY(udg_BUS_Unit)
local real x2 = GetUnitX(udg_BUS_Target)
local real y2 = GetUnitY(udg_BUS_Target)
local real z = BUS_GetZ(x,y) + GetUnitFlyHeight(udg_BUS_Unit)
local real z2 = BUS_GetZ(x2, y2) + GetUnitFlyHeight(udg_BUS_Target)
local real Angle
local real TempReal = BUSSR_OffsetBase() + (rLevel * BUSSR_OffsetPerLevel())
if (IsUnitType(udg_BUS_Unit, UNIT_TYPE_GROUND)) then
set z = z + BUSSR_GroundHeightOffset()
endif
if (udg_BUSS_RecyclableNodes == 0) then
set udg_BUSS_NodeNumber = udg_BUSS_NodeNumber + 1
set Node = udg_BUSS_NodeNumber
else
set udg_BUSS_RecyclableNodes = udg_BUSS_RecyclableNodes - 1
set Node = udg_BUSS_RecycleNodes[udg_BUSS_RecyclableNodes]
endif
set udg_BUSS_NextNode[Node] = 0
set udg_BUSS_NextNode[udg_BUSS_PrevNode[0]] = Node
set udg_BUSS_PrevNode[Node] = udg_BUSS_PrevNode[0]
set udg_BUSS_PrevNode[0] = Node
set udg_BUSS_Unit[Node] = udg_BUS_Unit
set udg_BUSS_Owner[Node] = GetOwningPlayer(udg_BUSS_Unit[Node])
set udg_BUSS_HealthDamage[Node] = BUSSR_HealthDamageBase() + (rLevel * BUSSR_HealthDamagePerLevel())
set udg_BUSS_ManaDamage[Node] = BUSSR_ManaDamageBase() + (rLevel * BUSSR_ManaDamagePerLevel())
set udg_BUSS_AOE[Node] = BUSSR_AOEBase() + (rLevel * BUSSR_AOEPerLevel())
set udg_BUSS_Range[Node] = BUSSR_RangeBase() + (rLevel * BUSSR_RangePerLevel())
set udg_BUSS_Force[Node] = BUSSR_ForceBase() + (rLevel * BUSSR_ForcePerLevel())
set udg_BUSS_EndChannelTime[Node] = BUSSR_EndChannelTimeBase() + (rLevel * BUSSR_EndChannelTimePerLevel())
set udg_BUSS_Activate[Node] = true
set udg_BUSS_Cancel[Node] = false
set udg_BUSS_DY[Node] = y2 - y
set udg_BUSS_DX[Node] = x2 - x
set Angle = Atan2(udg_BUSS_DY[Node], udg_BUSS_DX[Node])
set udg_BUSS_DZ[Node] = Atan2(z2 - z, SquareRoot((udg_BUSS_DX[Node] * udg_BUSS_DX[Node]) + (udg_BUSS_DY[Node] * udg_BUSS_DY[Node])))
set udg_BUSS_PZ[Node] = z + (TempReal * Sin(udg_BUSS_DZ[Node]))
set udg_BUSS_PX[Node] = x + (TempReal * Cos(Angle) * Cos(udg_BUSS_DZ[Node]))
set udg_BUSS_PY[Node] = y + (TempReal * Sin(Angle) * Cos(udg_BUSS_DZ[Node]))
if (udg_BUSS_PrevNode[Node] + udg_BUSS_PPrevNode[0] == 0) then
call TimerStart(udg_BUSS_Timer, BUSSR_TimerSpeed(), true, function BUS_ScatheLoop)
endif
if (udg_BUSS_PRecyclableNodes == 0) then
set udg_BUSS_PNodeNumber = udg_BUSS_PNodeNumber + 1
set TempNode = udg_BUSS_PNodeNumber
else
set udg_BUSS_PRecyclableNodes = udg_BUSS_PRecyclableNodes - 1
set TempNode = udg_BUSS_PRecycleNodes[udg_BUSS_PRecyclableNodes]
endif
set udg_BUSS_PNextNode[TempNode] = 0
set udg_BUSS_PNextNode[udg_BUSS_PPrevNode[0]] = TempNode
set udg_BUSS_PPrevNode[TempNode] = udg_BUSS_PPrevNode[0]
set udg_BUSS_PPrevNode[0] = TempNode
set udg_BUSS_Angle[Node] = Angle * bj_RADTODEG
set udg_BUSS_PRemove[TempNode] = false
set udg_BUSS_PCaster[TempNode] = udg_BUS_Unit
set udg_BUSS_PUnit[TempNode] = CreateUnit(BUSCR_DummyPlayer(), BUSSR_DummyId(),udg_BUSS_PX[Node],udg_BUSS_PY[Node], udg_BUSS_Angle[Node])
if UnitAddAbility(udg_BUSS_PUnit[TempNode], 'Amrf') and UnitRemoveAbility(udg_BUSS_PUnit[TempNode], 'Amrf') then
endif
set TempReal = z2 - z
if (TempReal < 0) then
set udg_BUSS_PScale[Node] = -1 * (BUSSR_PointerScaleBase() + (rLevel * BUSSR_PointerScalePerLevel()))
set udg_BUSS_LaserScale[Node] = -1 * (BUSSR_LaserScaleBase() + (rLevel * BUSSR_LaserScalePerLevel()))
set udg_BUSS_PAnimationIndex[Node] = R2I(Atan2((TempReal), SquareRoot((udg_BUSS_DX[Node] * udg_BUSS_DX[Node]) + (udg_BUSS_DY[Node] * udg_BUSS_DY[Node]))) * bj_RADTODEG + 0.5) + 180
else
set udg_BUSS_PScale[Node] = (BUSSR_PointerScaleBase() + (rLevel * BUSSR_PointerScalePerLevel()))
set udg_BUSS_LaserScale[Node] = (BUSSR_LaserScaleBase() + (rLevel * BUSSR_LaserScalePerLevel()))
set udg_BUSS_PAnimationIndex[Node] = R2I(Atan2((TempReal), SquareRoot((udg_BUSS_DX[Node] * udg_BUSS_DX[Node]) + (udg_BUSS_DY[Node] * udg_BUSS_DY[Node]))) * bj_RADTODEG + 0.5)
endif
call SetUnitScale(udg_BUSS_PUnit[TempNode], udg_BUSS_PScale[Node], 0.00, 0.00)
call SetUnitAnimationByIndex(udg_BUSS_PUnit[TempNode], udg_BUSS_PAnimationIndex[Node])
set udg_BUSS_PCurrentEffect[TempNode] = AddSpecialEffectTarget(BUSSR_PointerEffect(), udg_BUSS_PUnit[TempNode], BUSSR_AttachmentPoint())
call SetUnitFlyHeight(udg_BUSS_PUnit[TempNode], udg_BUSS_PZ[Node] - BUS_GetZ(udg_BUSS_PX[Node], udg_BUSS_PY[Node]), 0.00)
set udg_BUSS_DX[Node] = Cos(Angle) * Cos(udg_BUSS_DZ[Node]) * udg_BUSS_AOE[Node]
set udg_BUSS_DY[Node] = Sin(Angle) * Cos(udg_BUSS_DZ[Node]) * udg_BUSS_AOE[Node]
set udg_BUSS_DZ[Node] = Sin(udg_BUSS_DZ[Node]) * udg_BUSS_AOE[Node]
return false
endfunction
////////////////////////////////////////////////////////////////////
// ScatheStart: Function used to set up the channeling for the //
// ability //
////////////////////////////////////////////////////////////////////
function BUS_ScatheStart takes nothing returns boolean
local unit u
if (GetSpellAbilityId() == BUSSR_Ability()) then
set u = GetTriggerUnit()
set udg_BUSS_Cancel[BUS_CheckScathe(u)] = true
call BUS_StartChannel(BUS_GetChannelByName(BUSSR_ChannelType()), u, GetSpellTargetUnit(), 0., 0., BUSSR_ChannelDurationBase() + (GetUnitAbilityLevel(u, BUSSR_Ability()) * BUSSR_ChannelDurationPerLevel()), BUSSR_Event(), BUSSR_HaveHue())
set u = null
endif
return false
endfunction
////////////////////////////////////////////////////////////////////
// InitTrig BUS Scathe: Function used to set up the event and //
// starting functions of the ability as well as the timer for //
// the loop //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Scathe takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index >= bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t, Condition(function BUS_ScatheStart))
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_BUSC_Event", EQUAL, BUSSR_Event())
call TriggerAddCondition(t, Condition(function BUS_ScatheEvent))
set udg_BUSS_Timer = CreateTimer()
endfunction
////////////////////////////////////////////////////////////////////
// End of the spell //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Boss Ultimate Spellpack Sheer Force V1.00 //
// Author: Tank-Commander //
// Purpose: Boss Strong Knockback (ring out) //
// Requires: Dummy.mdl, BUS Channel, BUS Knockback //
// //
// Notes: //
// - Read the readme before you try modifying the config //
// - Use the "Helpful files" to help you import the system //
// //
// Credits: //
// - (Dummy.mdl) Vexorian //
// - (ForceField.mdl) Fingolfin //
// //
// Optimum User: Flyer (any) //
// //
// If you have used this spellpack in your map, you are required //
// to give credits to Tank-Commander for the creation of it //
// If you would like to use snippets of code from this for //
// whatever, getting permission and crediting the source/linking //
// would be much appreciated. //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// README: //
// Before modifying this spell a few things need to be //
// understood and read, this is one of those things, while //
// most modification can be considered intuitive, it still //
// helps to read through these intstructions, as they will //
// inform you about how to configure this spell to your //
// desire. //
//----------------------------------------------------------------//
// Initial importing: The variable creator trigger can be //
// imported first and if you have the correct settings (file, //
// preferences, General, automatically create unknown variables //
// checked, then when you paste in the variable creator it //
// will automatically give you all the variables you need for //
// this spell //
// //
// While the remaining object editor based data is not required //
// to function (provided they're replaced with equivelents) //
// it's recommended that they are also imported, if their data //
// value are not the same as listed in the configuration, those //
// configurables will need to be changed to work correctly //
//----------------------------------------------------------------//
// CONFIGURABLE INFORMATION/HELP: //
// //
// - Viewing data values: To see data values in the editor you //
// need to press Ctrl + D, to shift back to normal viewing //
// press it again //
// //
// - Effects: Pathnames for effects used in the spells should //
// have two "\"s throughout or the effect will not work (the //
// WE progress bar will not go away when saving, however if //
// fixed afterwards the save will still work, but the progress //
// bar will still remain until the WE is closed) //
// e.g. "units\\human\\Footman\\Footman" //
// //
// - Effect Scaling: Some effects have scale values below them //
// the scale determines the size of the effect and is expressed //
// as a real percentage (1.00 = 100%) //
// //
// - Removing Effects: to remove an effect you don't want from //
// the ability, set the model path to that of Dummy.mdl //
// //
// - Base and Per Values: Most configurables have a base and per //
// value, Base values are what a value is set to regardless of //
// other factors. Per values are what a value is set to based on //
// what the per value is the formula for calculating the result //
// is as follows: //
// - BaseValue + (Factor * PerValue) //
// //
// - Timer: Some configurables have PerSecond values, the code //
// automatically accounts for changes to the timer as to //
// maintain consistency with what the user has chosen //
// All times in the system are expressions of seconds //
// //
// - AttackTypes: This should match the Damage Type of the //
// ability, though it can be something else if you wish //
// //
// - DamageTypes: This changes the damage multiplyer vs. enemy //
// armour types, note that by default the damage filters //
// exclude magic immune units so changing this from MAGIC //
// damage will not make them take damage //
// //
// - WeaponTypes: Generally don't need to be used, should only //
// not be null if you particularly wish or need to use them //
// //
//----------------------------------------------------------------//
// TimerSpeed: This is the amount of time in seconds between //
// each iteration of the Sheer Force Loop function //
constant function BUSFR_TimerSpeed takes nothing returns real
return 0.031250000
endfunction
//----------------------------------------------------------------//
// Ability: This is the AbilityId that is used as the dummy //
// ability used for the Sheer Force spell //
constant function BUSFR_Ability takes nothing returns integer
return 'A06O'
endfunction
//----------------------------------------------------------------//
// DummyId: This is the UnitId that is used to create effects //
// It is recommended this unit use Dummy.mdl for its model for //
// optimal usage //
constant function BUSFR_DummyId takes nothing returns integer
return 'u00A'
endfunction
//----------------------------------------------------------------//
// Event: This is the value of BUS_Event that it will be set to //
// when the channeling ends, this should be unique to each //
// ability which uses the channel system //
constant function BUSFR_Event takes nothing returns integer
return 3
endfunction
//----------------------------------------------------------------//
// AttachmentPoint: This is the point that effects are attached //
// to on units and dummy units //
constant function BUSFR_AttachmentPoint takes nothing returns string
return "origin"
endfunction
//----------------------------------------------------------------//
// HaveHue; This determines whether or not during channeling //
// the hue of the caster changes throughout //
constant function BUSFR_HaveHue takes nothing returns boolean
return true
endfunction
//----------------------------------------------------------------//
// ChannelType: This is the name of the channel type used by //
// this ability (it should match the name of the channel type) //
constant function BUSFR_ChannelType takes nothing returns string
return "gravity"
endfunction
//----------------------------------------------------------------//
// ChannelDurationBase: This is the duration of the channeling //
// used by the spell //
constant function BUSFR_ChannelDurationBase takes nothing returns real
return 2.
endfunction
//----------------------------------------------------------------//
// ChannelDurationPerLevel: This is the per level counterpart of //
// ChannelDurationBase //
constant function BUSFR_ChannelDurationPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// AOEBase: This is the AOE of the ability //
constant function BUSFR_AOEBase takes nothing returns real
return 800.
endfunction
//----------------------------------------------------------------//
// AOEPerLevel: This is the per level counterpart of AOEBase //
constant function BUSFR_AOEPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// ForceBase: This is the amount of force this ability exerts //
// on the units that are affected //
constant function BUSFR_ForceBase takes nothing returns real
return 4000.
endfunction
//----------------------------------------------------------------//
// ForcePerLevel: This is the per level counterpart of ForceBase //
constant function BUSFR_ForcePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// ForceDegradeBase: This is the change of force over distance //
// the lower the value the faster the force degrades //
constant function BUSFR_ForceDegradeBase takes nothing returns real
return 10.
endfunction
//----------------------------------------------------------------//
// ForceDegradePerLevel: This is the per level counterpart of //
// ForceDegradeBase //
constant function BUSFR_ForceDegradePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// ForceDamageMultiplyerBase: This is the multiplyer of damage //
// in terms of Force, Force * Multiplyer = Damage //
constant function BUSFR_ForceDamageMultiplyerBase takes nothing returns real
return .33
endfunction
//----------------------------------------------------------------//
// ForceDamageMultiplyerPerLevel: This is the per level //
// counterpart of ForceDamageMultiplyerBase //
constant function BUSFR_ForceDamageMultiplyerPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// DamageMana: This determines whether or not the same damage //
// is dealt to the units mana //
constant function BUSFR_DamageMana takes nothing returns boolean
return false
endfunction
//----------------------------------------------------------------//
// OrbStartSizeBase: This determines the start size of the orb //
// effect which marks the boundaries of the effect //
constant function BUSFR_OrbStartSizeBase takes nothing returns real
return 0.01
endfunction
//----------------------------------------------------------------//
// OrbStartSizePerLevel: This is the per level counterpart of //
// OrbStartSizeBase //
constant function BUSFR_OrbStartSizePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OrbEndSizeBase: This is the final size of the Orb effect //
constant function BUSFR_OrbEndSizeBase takes nothing returns real
return 1.
endfunction
//----------------------------------------------------------------//
// OrbEndSizePerLevel: This is the per level counterpart of //
// OrbEndSizeBase //
constant function BUSFR_OrbEndSizePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OrbTimeBase: This is how long it takes for the Orb to reach //
// its maximum size //
constant function BUSFR_OrbTimeBase takes nothing returns real
return 0.25
endfunction
//----------------------------------------------------------------//
// OrbTimePerLevel: This is the per level counterpart of //
// OrbTimeBase //
constant function BUSFR_OrbTimePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OrbEffect: This is the pathname of the effect used to denote //
// the boarder of the ability //
constant function BUSFR_OrbEffect takes nothing returns string
return "ForceField.mdx"
endfunction
//----------------------------------------------------------------//
// AttackType: This is the attacktype used by the spell //
constant function BUSFR_AttackType takes nothing returns attacktype
return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
// DamageType: This is the damagetype used by the spell //
constant function BUSFR_DamageType takes nothing returns damagetype
return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
// WeaponType: This is the weapontype used by the spell //
constant function BUSFR_WeaponType takes nothing returns weapontype
return null
endfunction
//----------------------------------------------------------------//
// EffectRemove: This is how long after an effect has been //
// completed that it is removed //
constant function BUSFR_EffectRemove takes nothing returns real
return 2.00
endfunction
//----------------------------------------------------------------//
// TargetFilter: This is the target filter for units that can //
// be turned into spirits, configure this as desired (requires //
// some coding knowledge, u is the target unit, Node is the //
// index of the casting unit //
function BUS_FTargetFilter takes unit u, player pl returns boolean
return (not(IsUnitType(u, UNIT_TYPE_DEAD)) and not(IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (IsPlayerEnemy(GetOwningPlayer(u), pl)))
endfunction
//----------------------------------------------------------------//
// END OF CONFIGURATION //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// SheerForceLoop: Function used to handle the effects of the //
// ability and recycle the ones that have been completed //
////////////////////////////////////////////////////////////////////
function BUS_SheerForceLoop takes nothing returns nothing
local integer Node = 0
loop
set Node = udg_BUSF_NextNode[Node]
exitwhen Node == 0
if (udg_BUSF_Remove[Node]) then
if (udg_BUSF_RemoveTimer[Node] <= 0) then
call RemoveUnit(udg_BUSF_Unit[Node])
set udg_BUSF_RecycleNodes[udg_BUSF_RecyclableNodes] = Node
set udg_BUSF_RecyclableNodes = udg_BUSF_RecyclableNodes + 1
set udg_BUSF_NextNode[udg_BUSF_PrevNode[Node]] = udg_BUSF_NextNode[Node]
set udg_BUSF_PrevNode[udg_BUSF_NextNode[Node]] = udg_BUSF_PrevNode[Node]
if (udg_BUSF_PrevNode[0] == 0) then
call PauseTimer(udg_BUSF_Timer)
endif
else
set udg_BUSF_RemoveTimer[Node] = udg_BUSF_RemoveTimer[Node] - BUSFR_TimerSpeed()
endif
else
set udg_BUSF_CurrentSize[Node] = udg_BUSF_CurrentSize[Node] + udg_BUSF_ScaleSpeed[Node]
set udg_BUSF_GrowthTime[Node] = udg_BUSF_GrowthTime[Node] - BUSFR_TimerSpeed()
call SetUnitScale(udg_BUSF_Unit[Node], udg_BUSF_CurrentSize[Node], 0., 0.)
if (udg_BUSF_GrowthTime[Node] <= 0) then
set udg_BUSF_Remove[Node] = true
call DestroyEffect(udg_BUSF_CurrentEffect[Node])
endif
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// SheerForceEvent: The main function, used to start the //
// knockback of units as well as start the effects used in the //
// loop of the ability //
////////////////////////////////////////////////////////////////////
function BUS_SheerForceEvent takes nothing returns boolean
local real rLevel = GetUnitAbilityLevel(udg_BUS_Unit, BUSFR_Ability())
local real x = GetUnitX(udg_BUS_Unit)
local real y = GetUnitY(udg_BUS_Unit)
local real z = GetUnitFlyHeight(udg_BUS_Unit) + BUS_GetZ(x, y)
local real x2
local real y2
local real z2
local real TempReal = BUSFR_AOEBase() + (rLevel * BUSFR_AOEPerLevel())
local real TempReal2 = BUSFR_ForceBase() + (rLevel * BUSFR_ForcePerLevel())
local real TempReal3 = BUSFR_ForceDegradeBase() + (rLevel * BUSFR_ForceDegradePerLevel())
local real TempReal4 = BUSFR_ForceDamageMultiplyerBase() + (rLevel * BUSFR_ForceDamageMultiplyerPerLevel())
local real TempReal5
local real TempReal6
local unit u
local player pl = GetOwningPlayer(udg_BUS_Unit)
local integer Node
if (udg_BUSF_RecyclableNodes == 0) then
set udg_BUSF_NodeNumber = udg_BUSF_NodeNumber + 1
set Node = udg_BUSF_NodeNumber
else
set udg_BUSF_RecyclableNodes = udg_BUSF_RecyclableNodes - 1
set Node = udg_BUSF_RecycleNodes[udg_BUSF_RecyclableNodes]
endif
set udg_BUSF_NextNode[Node] = 0
set udg_BUSF_NextNode[udg_BUSF_PrevNode[0]] = Node
set udg_BUSF_PrevNode[Node] = udg_BUSF_PrevNode[0]
set udg_BUSF_PrevNode[0] = Node
set udg_BUSF_Unit[Node] = CreateUnit(BUSCR_DummyPlayer(), BUSFR_DummyId(), x, y, 0.)
set udg_BUSF_CurrentEffect[Node] = AddSpecialEffectTarget(BUSFR_OrbEffect(), udg_BUSF_Unit[Node], BUSFR_AttachmentPoint())
set udg_BUSF_CurrentSize[Node] = BUSFR_OrbStartSizeBase() + (rLevel * BUSFR_OrbStartSizePerLevel())
set udg_BUSF_GrowthTime[Node] = BUSFR_OrbTimeBase() + (rLevel * BUSFR_OrbTimePerLevel())
set udg_BUSF_ScaleSpeed[Node] = (((BUSFR_OrbEndSizeBase() + (rLevel * BUSFR_OrbEndSizePerLevel())) - udg_BUSF_CurrentSize[Node]) / udg_BUSF_GrowthTime[Node]) * BUSFR_TimerSpeed()
set udg_BUSF_RemoveTimer[Node] = BUSFR_EffectRemove()
set udg_BUSF_Remove[Node] = false
call SetUnitScale(udg_BUSF_Unit[Node], udg_BUSF_CurrentSize[Node], 0.,0.)
if UnitAddAbility(udg_BUSF_Unit[Node], 'Amrf') and UnitRemoveAbility(udg_BUSF_Unit[Node], 'Amrf') then
endif
call SetUnitFlyHeight(udg_BUSF_Unit[Node], z, 0.)
if (udg_BUSF_PrevNode[Node] == 0) then
call TimerStart(udg_BUSF_Timer, BUSFR_TimerSpeed(), true, function BUS_SheerForceLoop)
endif
call GroupEnumUnitsInRange(udg_BUSF_UnitGroup, x, y, TempReal, null)
loop
set u = FirstOfGroup(udg_BUSF_UnitGroup)
exitwhen u == null
call GroupRemoveUnit(udg_BUSF_UnitGroup, u)
if (BUS_FTargetFilter(u, pl)) then
set x2 = GetUnitX(u)
set y2 = GetUnitY(u)
set z2 = GetUnitFlyHeight(u) + BUS_GetZ(x2, y2)
set TempReal5 = SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y) + (z2 - z) * (z2 - z))
if (TempReal5 < TempReal3) then
set TempReal5 = TempReal3
endif
if (TempReal5 <= TempReal) then
set TempReal6 = (TempReal2) / (TempReal5 / TempReal3)
call UnitDamageTarget(udg_BUS_Unit, u, TempReal6 * TempReal3, false, false, BUSFR_AttackType(), BUSFR_DamageType(), BUSFR_WeaponType())
if (BUSFR_DamageMana()) then
call SetUnitState(u, UNIT_STATE_MANA, GetUnitState(u, UNIT_STATE_MANA) - (TempReal6 * TempReal3))
endif
call BUS_StartKnockback(u, TempReal6, x2, x, y2, y, z2, z)
endif
endif
endloop
set pl = null
return false
endfunction
////////////////////////////////////////////////////////////////////
// SheerForceStart: Function used to set up the channeling for //
// the ability //
////////////////////////////////////////////////////////////////////
function BUS_SheerForceStart takes nothing returns boolean
local unit u
if (GetSpellAbilityId() == BUSFR_Ability()) then
set u = GetTriggerUnit()
call BUS_StartChannel(BUS_GetChannelByName(BUSFR_ChannelType()), u, null, 0., 0., BUSFR_ChannelDurationBase() + (GetUnitAbilityLevel(u, BUSFR_Ability()) * BUSFR_ChannelDurationPerLevel()), BUSFR_Event(), BUSFR_HaveHue())
set u = null
endif
return false
endfunction
////////////////////////////////////////////////////////////////////
// InitTrig BUS Sheer Force: Function used to set up the event //
// and starting functions of the ability as well as the timer //
// for the loop //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Sheer_Force takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index >= bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t, Condition(function BUS_SheerForceStart))
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_BUSC_Event", EQUAL, BUSFR_Event())
call TriggerAddCondition(t, Condition(function BUS_SheerForceEvent))
set udg_BUSF_Timer = CreateTimer()
endfunction
////////////////////////////////////////////////////////////////////
// End of the spell //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Boss Ultimate Spellpack Energy Spike V1.00 //
// Author: Tank-Commander //
// Purpose: Boss Huge Damage AOE strike //
// Requires: Dummy.mdl, BUS Channel //
// //
// Notes: //
// - Read the readme before you try modifying the config //
// - Use the "Helpful files" to help you import the system //
// //
// Credits: //
// - (Dummy.mdl) Vexorian //
// - (DragonBlade.mdl) HappyTauren //
// //
// Optimum User: Flyer (large) //
// //
// If you have used this spellpack in your map, you are required //
// to give credits to Tank-Commander for the creation of it //
// If you would like to use snippets of code from this for //
// whatever, getting permission and crediting the source/linking //
// would be much appreciated. //
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// README: //
// Before modifying this spell a few things need to be //
// understood and read, this is one of those things, while //
// most modification can be considered intuitive, it still //
// helps to read through these intstructions, as they will //
// inform you about how to configure this spell to your //
// desire. //
//----------------------------------------------------------------//
// Initial importing: The variable creator trigger can be //
// imported first and if you have the correct settings (file, //
// preferences, General, automatically create unknown variables //
// checked, then when you paste in the variable creator it //
// will automatically give you all the variables you need for //
// this spell //
// //
// While the remaining object editor based data is not required //
// to function (provided they're replaced with equivelents) //
// it's recommended that they are also imported, if their data //
// value are not the same as listed in the configuration, those //
// configurables will need to be changed to work correctly //
//----------------------------------------------------------------//
// CONFIGURABLE INFORMATION/HELP: //
// //
// - Viewing data values: To see data values in the editor you //
// need to press Ctrl + D, to shift back to normal viewing //
// press it again //
// //
// - Effects: Pathnames for effects used in the spells should //
// have two "\"s throughout or the effect will not work (the //
// WE progress bar will not go away when saving, however if //
// fixed afterwards the save will still work, but the progress //
// bar will still remain until the WE is closed) //
// e.g. "units\\human\\Footman\\Footman" //
// //
// - Effect Scaling: Some effects have scale values below them //
// the scale determines the size of the effect and is expressed //
// as a real percentage (1.00 = 100%) //
// //
// - Removing Effects: to remove an effect you don't want from //
// the ability, set the model path to that of Dummy.mdl //
// //
// - Base and Per Values: Most configurables have a base and per //
// value, Base values are what a value is set to regardless of //
// other factors. Per values are what a value is set to based on //
// what the per value is the formula for calculating the result //
// is as follows: //
// - BaseValue + (Factor * PerValue) //
// //
// - Timer: Some configurables have PerSecond values, the code //
// automatically accounts for changes to the timer as to //
// maintain consistency with what the user has chosen //
// All times in the system are expressions of seconds //
// //
// - AttackTypes: This should match the Damage Type of the //
// ability, though it can be something else if you wish //
// //
// - DamageTypes: This changes the damage multiplyer vs. enemy //
// armour types, note that by default the damage filters //
// exclude magic immune units so changing this from MAGIC //
// damage will not make them take damage //
// //
// - WeaponTypes: Generally don't need to be used, should only //
// not be null if you particularly wish or need to use them //
// //
//----------------------------------------------------------------//
// TimerSpeed: This is the amount of time in seconds between //
// each iteration of the Energy Spike Loop function //
constant function BUSER_TimerSpeed takes nothing returns real
return 0.031250000
endfunction
//----------------------------------------------------------------//
// Ability: This is the AbilityId that is used as the dummy //
// ability used for the Energy Spike spell //
constant function BUSER_Ability takes nothing returns integer
return 'A06M'
endfunction
//----------------------------------------------------------------//
// DummyId: This is the UnitId that is used to create effects //
// It is recommended this unit use Dummy.mdl for its model for //
// optimal usage //
constant function BUSER_DummyId takes nothing returns integer
return 'u00A'
endfunction
//----------------------------------------------------------------//
// Event: This is the value of BUS_Event that it will be set to //
// when the channeling ends, this should be unique to each //
// ability which uses the channel system //
constant function BUSER_Event takes nothing returns integer
return 4
endfunction
//----------------------------------------------------------------//
// Order: This is the order ID of the ability used to make sure //
// that the unit is still channeling the ability //
constant function BUSER_Order takes nothing returns integer
return 852089
endfunction
//----------------------------------------------------------------//
// AttachmentPoint: This is the point that effects are attached //
// to on units and dummy units //
constant function BUSER_AttachmentPoint takes nothing returns string
return "origin"
endfunction
//----------------------------------------------------------------//
// HaveHue; This determines whether or not during channeling //
// the hue of the caster changes throughout //
constant function BUSER_HaveHue takes nothing returns boolean
return true
endfunction
//----------------------------------------------------------------//
// ChannelType: This is the name of the channel type used by //
// this ability (it should match the name of the channel type) //
constant function BUSER_ChannelType takes nothing returns string
return "burning fury"
endfunction
//----------------------------------------------------------------//
// HealthDamageBase: This is the amount of damage the swords //
// will do to a unit per second //
constant function BUSER_HealthDamageBase takes nothing returns real
return 600.0
endfunction
//----------------------------------------------------------------//
// HealthDamagePerLevel: This is the per level counterpart of //
// HealthDamageBase //
constant function BUSER_HealthDamagePerLevel takes nothing returns real
return 0.00
endfunction
//----------------------------------------------------------------//
// ManaDamageBase: This is the amount of damage th swords will //
// to a unit's mana per second //
constant function BUSER_ManaDamageBase takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// ManaDamagePerLevel: This is the per level counterpart of //
// ManaDamageBase //
constant function BUSER_ManaDamagePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// ChannelDurationBase: This is the duration of the channeling //
// used by the spell //
constant function BUSER_ChannelDurationBase takes nothing returns real
return 3.
endfunction
//----------------------------------------------------------------//
// ChannelDurationPerLevel: This is the per level counterpart of //
// ChannelDurationBase //
constant function BUSER_ChannelDurationPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// AOEBase: This is the Width of the swords used to damage units //
constant function BUSER_AOEBase takes nothing returns real
return 600.
endfunction
//----------------------------------------------------------------//
// AOEPerLevel: This is the per level counterpart of AOEBase //
constant function BUSER_AOEPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// RangeBase: This is the length of the swords used to damage //
// units //
constant function BUSER_RangeBase takes nothing returns real
return 600.
endfunction
//----------------------------------------------------------------//
// RangePerLevel: This is the per level counterpart of RangeBase //
constant function BUSER_RangePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OrbStartSizeBase: This is the starting size of the orb effect //
// used around the swords //
constant function BUSER_OrbStartSizeBase takes nothing returns real
return 1.
endfunction
//----------------------------------------------------------------//
// OrbStartSizePerLevel: This is the per level counterpart of //
// OrbStartSizeBase //
constant function BUSER_OrbStartSizePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OrbEndSizeBase: This is the ending size of the orb effect //
// used around the swords //
constant function BUSER_OrbEndSizeBase takes nothing returns real
return 5.
endfunction
//----------------------------------------------------------------//
// OrbEndSizePerLevel: This is the per level counterpart of //
// OrbEndSizeBase //
constant function BUSER_OrbEndSizePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OrbTimeBase: This is the length of time it takes for the Orb //
// to become full sized //
constant function BUSER_OrbTimeBase takes nothing returns real
return 0.09
endfunction
//----------------------------------------------------------------//
// OrbTimePerLevel: This is the per level counterpart of //
// OrbTimeBase //
constant function BUSER_OrbTimePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// LaserStartSizeBase: This is the starting size of the //
// swords/lasers //
constant function BUSER_LaserStartSizeBase takes nothing returns real
return 0.01
endfunction
//----------------------------------------------------------------//
// LaserStartSizePerLevel: This is the per level counterpart of //
// LaserStartSizeBase //
constant function BUSER_LaserStartSizePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// LaserEndSizeBase: This is the ending size of the //
// swords/lasers //
constant function BUSER_LaserEndSizeBase takes nothing returns real
return 7.
endfunction
//----------------------------------------------------------------//
// LaserEndSizePerLevel: This is the per level counterpart of //
// LaserEndSizeBase //
constant function BUSER_LaserEndSizePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// LaserTimeBase: This is how long it takes for the //
// swords/lasers to become full sized //
constant function BUSER_LaserTimeBase takes nothing returns real
return 0.25
endfunction
//----------------------------------------------------------------//
// LaserTimePerLevel: This is the per level counterpart of //
// LaserTimeBase //
constant function BUSER_LaserTimePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// LaserXYCountBase: This is the amount of laser sets that will //
// be made on the X and Y axis //
constant function BUSER_LaserXYCountBase takes nothing returns integer
return 8
endfunction
//----------------------------------------------------------------//
// LaserXYCountPerLevel: This is the per level counterpart of //
// LaserXYCountBase //
constant function BUSER_LaserXYCountPerLevel takes nothing returns integer
return 0
endfunction
//----------------------------------------------------------------//
// LaserZCountBase: This is the amount of lasers that are in a //
// single laser set //
constant function BUSER_LaserZCountBase takes nothing returns integer
return 5
endfunction
//----------------------------------------------------------------//
// LaserZCountPerLevel: This is the per level counterpart of //
// LaserZCountBase //
constant function BUSER_LaserZCountPerLevel takes nothing returns integer
return 0
endfunction
//----------------------------------------------------------------//
// LaserEdgeOffset: This is the ZAngle offset that the lasers //
// have (0 will mean one set points directly up and one down) //
constant function BUSER_LaserEdgeOffset takes nothing returns real
return 12.
endfunction
//----------------------------------------------------------------//
// PanningTimeBase: This is the amount of time after becoming //
// full sized that the swords/lasers begin panning //
constant function BUSER_PanningTimeBase takes nothing returns real
return 1.
endfunction
//----------------------------------------------------------------//
// PanningTimePerLevel: This is the per level counterpard of //
// PanningTimeBase //
constant function BUSER_PanningTimePerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// PanningBase: This is how fast the swords/lasers pan downwards //
// positive is a pan downward, negative is a pan upwards //
constant function BUSER_PanningBase takes nothing returns real
return 1.
endfunction
//----------------------------------------------------------------//
// PanningPerLevel: This is the per level counterpard of //
// PanningBase //
constant function BUSER_PanningPerLevel takes nothing returns real
return 0.
endfunction
//----------------------------------------------------------------//
// OrbEffect: This is the filepath of the effect used to denote //
// the orb around the swords/lasers //
constant function BUSER_OrbEffect takes nothing returns string
return "Abilities\\Spells\\Other\\ImmolationRed\\ImmolationRedTarget.mdl"
endfunction
//----------------------------------------------------------------//
// DamageEffect: This is the filepath of the effect used to //
// denote damage being dealt to units by the swords/lasers //
constant function BUSER_DamageEffect takes nothing returns string
return "Abilities\\Spells\\Other\\Incinerate\\IncinerateBuff.mdl"
endfunction
//----------------------------------------------------------------//
// LaserEffect: This is the filepath of the effect used to //
// denote the swords/lasers //
constant function BUSER_LaserEffect takes nothing returns string
return "DragonBladePlusDeathAndBirth.mdx"
endfunction
//----------------------------------------------------------------//
// EndEffect: This is the filepath of the effect used to denote //
// the spell ending //
constant function BUSER_EndEffect takes nothing returns string
return "Abilities\\Spells\\Human\\Resurrect\\ResurrectTarget.mdl"
endfunction
//----------------------------------------------------------------//
// EffectRemove: This is how long after an effect has been //
// completed that it is removed
constant function BUSER_EffectRemove takes nothing returns real
return 2.00
endfunction
//----------------------------------------------------------------//
// AttackType: This is the attacktype used by the spell //
constant function BUSER_AttackType takes nothing returns attacktype
return ATTACK_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
// DamageType: This is the damagetype used by the spell //
constant function BUSER_DamageType takes nothing returns damagetype
return DAMAGE_TYPE_MAGIC
endfunction
//----------------------------------------------------------------//
// WeaponType: This is the weapontype used by the spell // //
constant function BUSER_WeaponType takes nothing returns weapontype
return null
endfunction
//----------------------------------------------------------------//
// TargetFilter: This is the target filter for units that can //
// be turned into spirits, configure this as desired (requires //
// some coding knowledge, u is the target unit, Node is the //
// index of the casting unit //
function BUS_ETargetFilter takes unit u, integer Node returns boolean
return (not(IsUnitType(u, UNIT_TYPE_DEAD)) and not(IsUnitType(u, UNIT_TYPE_STRUCTURE)) and (IsPlayerEnemy(GetOwningPlayer(u), udg_BUSE_POwner[Node])))
endfunction
//----------------------------------------------------------------//
// END OF CONFIGURATION //
//----------------------------------------------------------------//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function used to prevent two casts of the same channel being //
// done simultaneously //
////////////////////////////////////////////////////////////////////
function BUS_CheckEnergySpike takes unit u returns integer
local integer Node = 0
loop
set Node = udg_BUSE_NextNode[Node]
exitwhen (udg_BUSE_Unit[Node] == u) or (Node == 0)
endloop
return Node
endfunction
////////////////////////////////////////////////////////////////////
// EnergySpikeLoop: The main function, used to control the angle //
// of the swords/lasers and damage units, as well as recycle //
// completed effects and make sure that the caster is still //
// channeling the ability //
////////////////////////////////////////////////////////////////////
function BUS_EnergySpikeLoop takes nothing returns nothing
local integer Node = 0
local integer TempNode = 0
local real TempReal
local real x
local real y
local real z
local real x2
local real y2
local real z2
local unit TempUnit
loop
set Node = udg_BUSE_NextNode[Node]
exitwhen Node == 0
if not(GetUnitCurrentOrder(udg_BUSE_Unit[Node]) == BUSER_Order()) or (udg_BUSE_Cancel[Node]) then
set TempNode = 0
loop
set TempNode = udg_BUSE_PNextNode[TempNode]
exitwhen TempNode == 0
if (udg_BUSE_PCaster[TempNode] == udg_BUSE_Unit[Node]) then
call DestroyEffect(udg_BUSE_PCurrentEffect[TempNode])
set udg_BUSE_PRemove[TempNode] = true
if not(udg_BUSE_PDoesPan[TempNode]) then
call DestroyEffect(AddSpecialEffectTarget(BUSER_EndEffect(), udg_BUSE_PUnit[TempNode], BUSER_AttachmentPoint()))
endif
endif
endloop
set udg_BUSE_RecycleNodes[udg_BUSE_RecyclableNodes] = Node
set udg_BUSE_RecyclableNodes = udg_BUSE_RecyclableNodes + 1
set udg_BUSE_NextNode[udg_BUSE_PrevNode[Node]] = udg_BUSE_NextNode[Node]
set udg_BUSE_PrevNode[udg_BUSE_NextNode[Node]] = udg_BUSE_PrevNode[Node]
if (udg_BUSE_PPrevNode[0] + udg_BUSE_PrevNode[0] == 0) then
call PauseTimer(udg_BUSE_Timer)
endif
endif
endloop
set Node = 0
loop
set Node = udg_BUSE_PNextNode[Node]
exitwhen Node == 0
if (udg_BUSE_PRemove[Node]) then
if (udg_BUSE_PTimer[Node] <= 0) then
call RemoveUnit(udg_BUSE_PUnit[Node])
set udg_BUSE_PRecycleNodes[udg_BUSE_PRecyclableNodes] = Node
set udg_BUSE_PRecyclableNodes = udg_BUSE_PRecyclableNodes + 1
set udg_BUSE_PNextNode[udg_BUSE_PPrevNode[Node]] = udg_BUSE_PNextNode[Node]
set udg_BUSE_PPrevNode[udg_BUSE_PNextNode[Node]] = udg_BUSE_PPrevNode[Node]
if (udg_BUSE_PPrevNode[0] + udg_BUSE_PrevNode[0] == 0) then
call PauseTimer(udg_BUSE_Timer)
endif
else
set udg_BUSE_PTimer[Node] = udg_BUSE_PTimer[Node] - BUSER_TimerSpeed()
endif
elseif (udg_BUSE_PGrowing[Node]) then
set udg_BUSE_PCurrentSize[Node] = udg_BUSE_PCurrentSize[Node] + udg_BUSE_PScaleSpeed[Node]
set udg_BUSE_PGrowthTime[Node] = udg_BUSE_PGrowthTime[Node] - BUSER_TimerSpeed()
call SetUnitScale(udg_BUSE_PUnit[Node], udg_BUSE_PCurrentSize[Node], 0., 0.)
if (udg_BUSE_PGrowthTime[Node] <= 0) then
set udg_BUSE_PGrowing[Node] = false
endif
else
if (udg_BUSE_PDoesPan[Node]) then
if (udg_BUSE_PPanningTime[Node] <= 0) then
set udg_BUSE_PDZ[Node] = udg_BUSE_PDZ[Node] - udg_BUSE_PPan[Node]
call SetUnitAnimationByIndex(udg_BUSE_PUnit[Node], R2I(Atan2(udg_BUSE_PDZ[Node], SquareRoot((udg_BUSE_PDX[Node] * udg_BUSE_PDX[Node]) + (udg_BUSE_PDY[Node] * udg_BUSE_PDY[Node]))) * bj_RADTODEG + 0.5) + 90)
else
set udg_BUSE_PPanningTime[Node] = udg_BUSE_PPanningTime[Node] - BUSER_TimerSpeed()
endif
set x = GetUnitX(udg_BUSE_PUnit[Node])
set y = GetUnitY(udg_BUSE_PUnit[Node])
set z = GetUnitFlyHeight(udg_BUSE_PUnit[Node]) + BUS_GetZ(x,y)
set TempReal = 0
loop
set x = x + udg_BUSE_PDX[Node]
set y = y + udg_BUSE_PDY[Node]
set z = z + udg_BUSE_PDZ[Node]
exitwhen (z < BUS_GetZ(x, y)) or (TempReal > udg_BUSE_PRange[Node])
call GroupEnumUnitsInRange(udg_BUSE_UnitGroup, x, y,udg_BUSE_PAOE[Node], null)
loop
set TempUnit = FirstOfGroup(udg_BUSE_UnitGroup)
exitwhen (TempUnit == null)
call GroupRemoveUnit(udg_BUSE_UnitGroup, TempUnit)
set x2 = GetUnitX(TempUnit)
set y2 = GetUnitY(TempUnit)
set z2 = GetUnitFlyHeight(TempUnit) + BUS_GetZ(x2,y2)
if (BUS_ETargetFilter(TempUnit, Node)) and (SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y) + (z2 - z) * (z2 - z)) <= udg_BUSE_PAOE[Node]) then
call UnitDamageTarget(udg_BUSE_PCaster[Node], TempUnit, udg_BUSE_PHealthDamage[Node], false, false, BUSER_AttackType(), BUSER_DamageType(), BUSER_WeaponType())
call SetUnitState(TempUnit, UNIT_STATE_MANA, GetUnitState(TempUnit, UNIT_STATE_MANA) - udg_BUSE_PManaDamage[Node])
call DestroyEffect(AddSpecialEffectTarget(BUSER_DamageEffect(), TempUnit, BUSER_AttachmentPoint()))
endif
endloop
set TempReal = TempReal + udg_BUSE_PAOE[Node]
endloop
endif
endif
endloop
endfunction
////////////////////////////////////////////////////////////////////
// EnergySpikeEvent: Function used to set up all the data and //
// effects that are used in the loop. Activates when the //
// channeling is completed //
////////////////////////////////////////////////////////////////////
function BUS_EnergySpikeEvent takes nothing returns boolean
local integer iLevel = GetUnitAbilityLevel(udg_BUS_Unit, BUSER_Ability())
local real rLevel = I2R(iLevel)
local integer Node = 0
local integer TempNode = 0
local integer iLoop = 0
local integer iLoop2
local integer TempInt
local integer TempInt2
local real x
local real y
local real z
local real TempSin
local real SinIncrement
local real TempAngle = GetUnitFacing(udg_BUS_Unit)
local real AngleIncrement
local real TempAngle2
local real TempAngle3
if (udg_BUSE_RecyclableNodes == 0) then
set udg_BUSE_NodeNumber = udg_BUSE_NodeNumber + 1
set Node = udg_BUSE_NodeNumber
else
set udg_BUSE_RecyclableNodes = udg_BUSE_RecyclableNodes - 1
set Node = udg_BUSE_RecycleNodes[udg_BUSE_RecyclableNodes]
endif
set udg_BUSE_NextNode[Node] = 0
set udg_BUSE_NextNode[udg_BUSE_PrevNode[0]] = Node
set udg_BUSE_PrevNode[Node] = udg_BUSE_PrevNode[0]
set udg_BUSE_PrevNode[0] = Node
set udg_BUSE_Unit[Node] = udg_BUS_Unit
set udg_BUSE_Cancel[Node] = false
set x = GetUnitX(udg_BUSE_Unit[Node])
set y = GetUnitY(udg_BUSE_Unit[Node])
set z = GetUnitFlyHeight(udg_BUSE_Unit[Node])
if (udg_BUSE_PrevNode[Node] + udg_BUSE_PPrevNode[0] == 0) then
call TimerStart(udg_BUSE_Timer, BUSER_TimerSpeed(), true, function BUS_EnergySpikeLoop)
endif
if (udg_BUSE_PRecyclableNodes == 0) then
set udg_BUSE_PNodeNumber = udg_BUSE_PNodeNumber + 1
set TempNode = udg_BUSE_PNodeNumber
else
set udg_BUSE_PRecyclableNodes = udg_BUSE_PRecyclableNodes - 1
set TempNode = udg_BUSE_PRecycleNodes[udg_BUSE_PRecyclableNodes]
endif
set udg_BUSE_PNextNode[TempNode] = 0
set udg_BUSE_PNextNode[udg_BUSE_PPrevNode[0]] = TempNode
set udg_BUSE_PPrevNode[TempNode] = udg_BUSE_PPrevNode[0]
set udg_BUSE_PPrevNode[0] = TempNode
set udg_BUSE_PUnit[TempNode] = CreateUnit(BUSCR_DummyPlayer(), BUSER_DummyId(), x, y, 0.)
set udg_BUSE_PCaster[TempNode] = udg_BUSE_Unit[Node]
set udg_BUSE_PCurrentEffect[TempNode] = AddSpecialEffectTarget(BUSER_OrbEffect(), udg_BUSE_PUnit[TempNode], BUSER_AttachmentPoint())
set udg_BUSE_PCurrentSize[TempNode] = BUSER_OrbStartSizeBase() + (rLevel * BUSER_OrbStartSizePerLevel())
set udg_BUSE_PGrowthTime[TempNode] = BUSER_OrbTimeBase() + (rLevel * BUSER_OrbTimePerLevel())
set udg_BUSE_PScaleSpeed[TempNode] = (((BUSER_OrbEndSizeBase() + (rLevel * BUSER_OrbEndSizePerLevel())) - udg_BUSE_PCurrentSize[TempNode]) / udg_BUSE_PGrowthTime[TempNode]) * BUSER_TimerSpeed()
set udg_BUSE_PGrowing[TempNode] = true
set udg_BUSE_PDoesPan[TempNode] = false
set udg_BUSE_PTimer[TempNode] = BUSER_EffectRemove()
set udg_BUSE_PRemove[TempNode] = false
call SetUnitScale(udg_BUSE_PUnit[TempNode], udg_BUSE_PCurrentSize[TempNode], 0.,0.)
if UnitAddAbility(udg_BUSE_PUnit[TempNode], 'Amrf') and UnitRemoveAbility(udg_BUSE_PUnit[TempNode], 'Amrf') then
endif
call SetUnitFlyHeight(udg_BUSE_PUnit[TempNode], z, 0.)
set TempInt = BUSER_LaserXYCountBase() + (iLevel * BUSER_LaserXYCountPerLevel())
set TempInt2 = BUSER_LaserZCountBase() + (iLevel * BUSER_LaserZCountPerLevel())
set SinIncrement = (180 - (2 * BUSER_LaserEdgeOffset())) / TempInt2
set AngleIncrement = 360 / TempInt
loop
set iLoop = iLoop + 1
exitwhen iLoop > TempInt
set iLoop2 = 0
set TempAngle = TempAngle + AngleIncrement
if (IsUnitType(udg_BUSE_Unit[Node], UNIT_TYPE_GROUND)) then
set TempSin = BUSER_LaserEdgeOffset()
else
set TempSin = -90 + BUSER_LaserEdgeOffset()
endif
set TempAngle2 = bj_DEGTORAD * TempAngle
loop
set iLoop2 = iLoop2 + 1
exitwhen iLoop2 > TempInt2
set TempAngle3 = bj_DEGTORAD * TempSin
if (udg_BUSE_PRecyclableNodes == 0) then
set udg_BUSE_PNodeNumber = udg_BUSE_PNodeNumber + 1
set TempNode = udg_BUSE_PNodeNumber
else
set udg_BUSE_PRecyclableNodes = udg_BUSE_PRecyclableNodes - 1
set TempNode = udg_BUSE_PRecycleNodes[udg_BUSE_PRecyclableNodes]
endif
set udg_BUSE_PNextNode[TempNode] = 0
set udg_BUSE_PNextNode[udg_BUSE_PPrevNode[0]] = TempNode
set udg_BUSE_PPrevNode[TempNode] = udg_BUSE_PPrevNode[0]
set udg_BUSE_PPrevNode[0] = TempNode
set udg_BUSE_PAOE[TempNode] = BUSER_AOEBase() + (rLevel * BUSER_AOEPerLevel())
set udg_BUSE_PUnit[TempNode] = CreateUnit(Player(14), BUSER_DummyId(), x, y, TempAngle)
set udg_BUSE_PCaster[TempNode] = udg_BUSE_Unit[Node]
set udg_BUSE_POwner[TempNode] = GetOwningPlayer(udg_BUS_Unit)
set udg_BUSE_PHealthDamage[TempNode] = (BUSER_HealthDamageBase() + (rLevel * BUSER_HealthDamagePerLevel())) * BUSER_TimerSpeed()
set udg_BUSE_PManaDamage[TempNode] = (BUSER_ManaDamageBase() + (rLevel * BUSER_ManaDamagePerLevel())) * BUSER_TimerSpeed()
set udg_BUSE_PCurrentEffect[TempNode] = AddSpecialEffectTarget(BUSER_LaserEffect(), udg_BUSE_PUnit[TempNode], BUSER_AttachmentPoint())
set udg_BUSE_PCurrentSize[TempNode] = BUSER_LaserStartSizeBase() + (rLevel * BUSER_LaserStartSizePerLevel())
set udg_BUSE_PGrowthTime[TempNode] = BUSER_LaserTimeBase() + (rLevel * BUSER_LaserTimePerLevel())
set udg_BUSE_PScaleSpeed[TempNode] = (((BUSER_LaserEndSizeBase() + (rLevel * BUSER_LaserEndSizePerLevel())) - udg_BUSE_PCurrentSize[TempNode]) / udg_BUSE_PGrowthTime[TempNode]) * BUSER_TimerSpeed()
call SetUnitScale(udg_BUSE_PUnit[TempNode], udg_BUSE_PCurrentSize[TempNode], 0.,0.)
set udg_BUSE_PDX[TempNode] = Cos(TempAngle2) * Cos(TempAngle3) * udg_BUSE_PAOE[TempNode]
set udg_BUSE_PDY[TempNode] = Sin(TempAngle2) * Cos(TempAngle3) * udg_BUSE_PAOE[TempNode]
set udg_BUSE_PDZ[TempNode] = Sin(TempAngle3) * udg_BUSE_PAOE[TempNode]
set udg_BUSE_PPanningTime[TempNode] = BUSER_PanningTimeBase() + (rLevel * BUSER_PanningTimePerLevel())
set udg_BUSE_PPan[TempNode] = BUSER_PanningBase() + (rLevel * BUSER_PanningPerLevel())
set udg_BUSE_PRange[TempNode] = BUSER_RangeBase() + (rLevel * BUSER_RangePerLevel())
set udg_BUSE_PGrowing[TempNode] = true
set udg_BUSE_PDoesPan[TempNode] = true
set udg_BUSE_PTimer[TempNode] = BUSER_EffectRemove()
set udg_BUSE_PRemove[TempNode] = false
if UnitAddAbility(udg_BUSE_PUnit[TempNode], 'Amrf') and UnitRemoveAbility(udg_BUSE_PUnit[TempNode], 'Amrf') then
endif
call SetUnitAnimationByIndex(udg_BUSE_PUnit[TempNode], R2I(Atan2(udg_BUSE_PDZ[TempNode], SquareRoot((udg_BUSE_PDX[TempNode] * udg_BUSE_PDX[TempNode]) + (udg_BUSE_PDY[TempNode] * udg_BUSE_PDY[TempNode]))) * bj_RADTODEG + 0.5) + 90)
call SetUnitFlyHeight(udg_BUSE_PUnit[TempNode], z, 0.)
set TempSin = TempSin + SinIncrement
endloop
endloop
return false
endfunction
////////////////////////////////////////////////////////////////////
// EnergySpikeStart: Function used to set up the channeling //
// for the ability //
////////////////////////////////////////////////////////////////////
function BUS_EnergySpikeStart takes nothing returns boolean
local unit u
if (GetSpellAbilityId() == BUSER_Ability()) then
set u = GetTriggerUnit()
set udg_BUSE_Cancel[BUS_CheckEnergySpike(u)] = true
call BUS_StartChannel(BUS_GetChannelByName(BUSER_ChannelType()), u, null, 0., 0., BUSER_ChannelDurationBase() + (GetUnitAbilityLevel(u, BUSER_Ability()) * BUSER_ChannelDurationPerLevel()), BUSER_Event(), BUSER_HaveHue())
set u = null
endif
return false
endfunction
////////////////////////////////////////////////////////////////////
// InitTrig BUS Energy Spike: Function used to set up the //
// event and starting functions of the ability as well as the //
// timer for the loop //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Energy_Spike takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index >= bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t, Condition(function BUS_EnergySpikeStart))
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_BUSC_Event", EQUAL, BUSER_Event())
call TriggerAddCondition(t, Condition(function BUS_EnergySpikeEvent))
set udg_BUSE_Timer = CreateTimer()
endfunction
////////////////////////////////////////////////////////////////////
// End of the spell //
////////////////////////////////////////////////////////////////////
function InitTrig_BUS_Register_Channels takes nothing returns nothing
set udg_BUSCR_Name[0] = "Arcane Charge"
set udg_BUSCR_Effect[0] = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl"
set udg_BUSCR_MinAOE[0] = 200
set udg_BUSCR_MaxAOE[0] = 300.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 0.1
set udg_BUSCR_MaxSize[0] = 1.5
set udg_BUSCR_SpawnRate[0] = 50
set udg_BUSCR_SpawnCount[0] = 2
set udg_BUSCR_Power[0] = 60
set udg_BUSCR_HueRed[0] = 60
set udg_BUSCR_HueGreen[0] = 60
set udg_BUSCR_HueBlue[0] = 255
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.50
call BUS_RegisterChannel(0)
//Next Channel
set udg_BUSCR_Name[0] = "Burning Fury"
set udg_BUSCR_Effect[0] = "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl"
set udg_BUSCR_MinAOE[0] = 250
set udg_BUSCR_MaxAOE[0] = 250.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 0.3
set udg_BUSCR_MaxSize[0] = 0.6
set udg_BUSCR_SpawnRate[0] = 30
set udg_BUSCR_SpawnCount[0] = 2
set udg_BUSCR_Power[0] = 250
set udg_BUSCR_HueRed[0] = 255
set udg_BUSCR_HueGreen[0] = 0
set udg_BUSCR_HueBlue[0] = 0
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.25
call BUS_RegisterChannel(0)
//Next Channel
set udg_BUSCR_Name[0] = "Gravity"
set udg_BUSCR_Effect[0] = "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl"
set udg_BUSCR_MinAOE[0] = 500
set udg_BUSCR_MaxAOE[0] = 500.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 1.5
set udg_BUSCR_MaxSize[0] = 2.
set udg_BUSCR_SpawnRate[0] = 128
set udg_BUSCR_SpawnCount[0] = 1
set udg_BUSCR_Power[0] = 1100
set udg_BUSCR_HueRed[0] = 0
set udg_BUSCR_HueGreen[0] = 0
set udg_BUSCR_HueBlue[0] = 0
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.25
call BUS_RegisterChannel(0)
//Next Channel
set udg_BUSCR_Name[0] = "Holy Storm"
set udg_BUSCR_Effect[0] = "Abilities\\Spells\\NightElf\\Rejuvenation\\RejuvenationTarget.mdl"
set udg_BUSCR_MinAOE[0] = 200.
set udg_BUSCR_MaxAOE[0] = 250.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 0.25
set udg_BUSCR_MaxSize[0] = 0.5
set udg_BUSCR_SpawnRate[0] = 30
set udg_BUSCR_SpawnCount[0] = 2
set udg_BUSCR_Power[0] = 20
set udg_BUSCR_HueRed[0] = 255
set udg_BUSCR_HueGreen[0] = 255
set udg_BUSCR_HueBlue[0] = 0
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 1
call BUS_RegisterChannel(0)
endfunction
The knockback system used in the spellpack is fairly simplistic and easy to use though is not a main feature
Attributes of the system:
- Ground units can be "bounced" off the ground if a force pushes them down
- Flying units can be knocked back in 3D and will return to their original heights
- Flying units can be killed instantly if they are pushed into the floor
- Ground units (on the ground) can optionally kill or attempt to prevent going through, trees
- Ground knockback decay different from air knockback decay (flying ground units use the air knockback decay)
Using the system:
call BUS_StartKnockback(Target, Force, TargetX, OriginX, TargetY, OriginY, TargetZ, OriginZ)
- This is the only function required the run the knockback from a user perspective
- Target = Unit to knock back
- Force = The force to push the unit
- TargetX = The x co-ordinate of the Target
- OriginX = The x co-ordinate of the origin point of the knockback (used for angle calculation)
- TargetY = The y co-ordinate of the Target
- OriginY = The y co-ordinate of the origin point of the knockback (used for angle calculation)
- TargetZ = The z co-ordinate of the Target
- OriginZ = The z co-ordinate of the origin point of the knockback (used for angle calculation)
When calculating Target and Origin Z values, you should use the BUS_GetZ(x,y) function if you want greater accuracy
though this is optional, to use this effectively use the following formula
set TargetZ = GetUnitFlyHeight(Target) + BUS_GetZ(TargetX,TargetY) + OffsetMod
set OriginZ = GetUnitFlyHeight(Origin) + BUS_GetZ(OriginX,OriginY) + OffsetMod
- If there is no Origin Unit then simply leave out getting its fly height to achieve the same effect
- Offset modifiers can be used to achieve certain effects (assuming they are different from eachother)
such as causing the knockback angle to assume the Target is above the origin point or other similar scenarios
This user guide explains how to use the BUS Channel system for your own abilities.
Instructions:
1) You will need to define some channel types, to do this follow the layout of "BUS Register Channels"
- Set up all the variables which start with the acronym "BUSCR_" to the value you desire
- Follow "Channel Register Explanation" for a more in-depth coverage of this
- Do not set udg_BUSCR_HueSpeed[0] = 0 this will cause the channel to be unusable
- Make sure that they all have 0 as their index number and use the function below at the end.
call BUS_RegisterChannel(0)
- This will register your channel and give it an index number for you to refer to it by
- If you do not know its index number (they are assigned from 1+ in order of registering) use the below function
call BUS_GetChannelByName("Your Channel Name")
This is function is case insensitive
2) If you want to overwrite an existing channel or want to specify the index number specifically you can use these:
- call Bus_RegisterChannel(i) Where i is the index number you wish to register it by (i > 0)
- call BUS_RegisterChannel(BUS_GetChannelByName("Your Channel Name"))
3) If you wish to make an ability which uses the channel system and you have completed the above steps
- You need to initialise a trigger which activates when the ability begins being channeled
- You then need to initialise a trigger which activates when BUS_Event becomes equal to the ability event number
- This second trigger will only activate if the channel is completed, so interrupting and cancelling work as normal
- All abilities need a unique event number this can be any real number so long as only one ability uses it
- A completed JASS example can be found at Example 1, A completed GUI example can be found aT Example 1 & 2
- The Start channel function has many parameters that it can be passed, with quite a few of them being optional
call BUS_StartChannel(BUS_GetChannelByName("My Channel Type"), Caster, TargetUnit, TargetX., TargetY., ChannelDuration, EventNumber, HaveHueChange)
- It is not necessary to pass a Target unit, Target X or Target Y as some abilities may not have or use these things
- If the channel type requested does not exist (the string inputted is wrong) then the last defined channel will
be used by default, if you pass a number which does not correspond to any defined channel, there will be an error
so it is safer to use BUS_GetChannelByName
- Make sure the event number passed matches the event number defined to activate the right function
example 1 uses 5.00 and example 2 uses 6.00 for instance, if they used the same value then both triggers would fire
- While most parameters are self-explanatory the last one "HaveHueChange" is a bit less clear:
It is a boolean value (true/false)
It determines whether or not the caster has their hue (colour) changed while they are channeling the ability
It assumes that the caster has a color of 255/255/255/255 (Red/Green/Blue/Alpha) so if your caster is not then
you should always set this to false
4) Certain globals will have data which can be used by the event function (Example 1 first function, Example 3)
- udg_BUS_Unit Will contain the caster unit, it must be used
- udg_BUS_Target will contain the target unit, it should be null if not used
- udg_BUS_X will contain the X co-ordinate of the target point, it should be 0 if not used
- udg_BUS_Y will contain the Y co-ordinate of the target point, it should be 0 if not used
This section covers the different variables when setting up a channel and what they do
Lets take a look at the first channel from "BUS Register Channel"
set udg_BUSCR_Name[0] = "Arcane Charge"
set udg_BUSCR_Effect[0] = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl"
set udg_BUSCR_MinAOE[0] = 200
set udg_BUSCR_MaxAOE[0] = 300.
set udg_BUSCR_AbsorbAOE[0] = 50.
set udg_BUSCR_MinSize[0] = 0.1
set udg_BUSCR_MaxSize[0] = 1.5
set udg_BUSCR_SpawnRate[0] = 50
set udg_BUSCR_SpawnCount[0] = 2
set udg_BUSCR_Power[0] = 60
set udg_BUSCR_HueRed[0] = 60
set udg_BUSCR_HueGreen[0] = 60
set udg_BUSCR_HueBlue[0] = 255
set udg_BUSCR_HueAlpha[0] = 255
set udg_BUSCR_HueSpeed[0] = 0.50
call BUS_RegisterChannel(0)
set udg_BUSCR_Name[0] = "Arcane Charge"
- This is the name the channel is given and used to locate it with BUS_GetChannelByName("Your Channel Name")
- Names are case insensitive so it does not matter if this is upper, lower or any mix of the few
- Remembering if there is spacing however is important
- This attribute exists as names are significantly easier to remember than ID numbers
set udg_BUSCR_Effect[0] = "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl"
- This is the filepath used for the effect of the channel - the particles that appear and are drawn toward the caster
- The double "\"s are important and if you are getting a string from the object editor it will only have one, be sure
to add the other ones in before you save (this may cause the progress bar to appear stuck, though correcting and
attempting to save again will work, even if it remains bugged
- Having an incorrect path may bug the system, as well as make no effect appear when you are channeling
set udg_BUSCR_MinAOE[0] = 200
set udg_BUSCR_MaxAOE[0] = 300.
- These both are very similar - they determine how far away from the caster effects may spawn
- The gap between these two values is the effective range (all effects will spawn in this range)
- Technically these can take negative values, but it is not recommended as the facing angle of effects will be wrong
set udg_BUSCR_AbsorbAOE[0] = 50.
- This is the distance from the caster that the effects must have (or be closer than) before they are destroyed
- Ideally this is close to melee range, and should be much lower then the MinAOE (effects may spawn which are
instantly removed which is essentially pointless, if they are the same)
set udg_BUSCR_MinSize[0] = 0.1
set udg_BUSCR_MaxSize[0] = 1.5
- These are scaling controls for the effects - determining the upper and lower bounds of their sizes
- They are done in terms of percentages (0.1 = 10%, 1.5 = 150%)
- Most models scale differently so you are unlikely to get the desired sizes first try if you estimate
- setting these values to negatives will invert the models (which may be desirable depending on the effect)
set udg_BUSCR_SpawnRate[0] = 50
- The spawn rate is a measure of how many sets of effects are made per second
- This is inherently limited by the timer speed used by the system (default 0.03125)
- The maximum amount of spawns per second is 32, so setting this value to 32 should reach these maximum but
due to inaccuracies in floating point numbers, it is safer to use a higher number to ensure all 32 sets are made
set udg_BUSCR_SpawnCount[0] = 2
- The spawn count is a measure of how many effects are created within each set
- Unlike the spawn rate this is not limited by the timer but rather by the Warcraft 3 engine with an approximate
maximum of 400 effects being able to be created at any given time, though to do this would cause massive amounts
of lag and lead to freezing, particularly if the spawn rate is also high
- The total amount of effects spawned can be calculated via (ChannelDuration * SpawnRate * SpawnCount) where the
duration is in seconds, so be mindful of this when setting up your channels
set udg_BUSCR_Power[0] = 60
- The power of a channel refers to how strongly the effects are pulled into the caster, the higher this value
the more visually powerful the channel looks (particularly if accompanied by a high spawn rate) conversely a
lower value leads to a more aura-like channel effect
set udg_BUSCR_HueRed[0] = 60
set udg_BUSCR_HueGreen[0] = 60
set udg_BUSCR_HueBlue[0] = 255
set udg_BUSCR_HueAlpha[0] = 255
- These values determine the Red/Green/Blue/Alpha extremes of a hue (colour) change respectively assuming the
instance of the channel is using them
- The system assumes that the default values are 255/255/255/255 respectively for any given caster, these are
the values that it will periodically oscillate to (go to and from) during a channel
- Alpha refers to the transparency of a unit, 0 leads to a completely invisible unit
set udg_BUSCR_HueSpeed[0] = 0.50
- This determines the time it takes for one oscillation to complete (go from default colours to the above hue values
- A complete oscillation is therefore double this time
- When creating a spell it is good to consider what the colour will be when the channel is over, in this case so long
as the channel duration is in complete seconds (1.00, 2.00, 3.00 etc.) then the caster will be at their original
colours when the channel is complete, conversely if ending at a half second (0.50, 1.50, 2.50, etc.) then they
will be at the extreme end of the colour change, however when a channel completes the unit is automatically
restored to default colouring, so this is only important to consider if you wish to avoid a sudden colour change
(this will still happen if the channel is cancelled)
You have reached the end of this explanation
//Channel Finished Event
function ExampleEvent takes nothing returns boolean
return false
endfunction
//Start Channel
function ExampleStart takes nothing returns boolean
local unit u
if (GetSpellAbilityId() == Example_Ability) then
set u = GetTriggerUnit()
call BUS_StartChannel(BUS_GetChannelByName("My Channel Type"), u, TargetUnit, TargetX., TargetY., ChannelDuration, 5.00, HaveHueChange)
set u = null
endif
return false
endfunction
//Init Trig
function InitTrig_Example_1 takes nothing returns nothing
local trigger t = CreateTrigger()
local integer index = 0
loop
call TriggerRegisterPlayerUnitEvent(t, Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index >= bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t, Condition(function ExampleStart))
set t = CreateTrigger()
call TriggerRegisterVariableEvent(t, "udg_BUSC_Event", EQUAL, 5.00)
call TriggerAddCondition(t, Condition(function ExampleEvent))
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
Make sure you have a tick in the following box:
File -> Preferences -> Automatically create unknown variables...
Copy Lightning Speed Laceration ability to your map.
Copy LSL Dummy ability to your map.
Copy Disable Attack ability to your map.
Copy the dummy paladin to your map.
Copy the LSL trigger folder to your map.
In Init Multihit trigger, set
MH_Abilities[0] = Lightning Speed Laceration
MH_Abilities[1] = LSL Dummy
MH_Abilities[0] = Disable Attack
In MH Begin Attack and MH Start Effect triggers some <Trigger - Turn on> are grayed out. Right click them and select "Enable function".
Add the ability to your hero and it is ready to be used.