Name | Type | is_array | initial_value |
DamageBlockingAbility | abilcode | No | |
DamageEvent | real | No | |
DamageEventAmount | real | No | |
DamageEventExplodesUnit | boolean | No | |
DamageEventOverride | boolean | No | |
DamageEventPrevAmt | real | No | |
DamageEventSource | unit | No | |
DamageEventsWasted | integer | No | |
DamageEventTarget | unit | No | |
DamageEventTrigger | trigger | No | |
DamageEventType | integer | No | |
DamageModifierEvent | real | No | |
DamageTaken | real | No | |
DamageTypeDOT | integer | No | |
DamageTypeRanged | integer | No | |
DamageTypeSpell | integer | No | |
DemoVelocity | real | No | |
DmgEvLife | real | No | |
DmgEvN | integer | No | |
DmgEvStack | unit | Yes | |
DmgEvTimer | timer | No | |
DmgTypPrev | integer | No | |
DyingTree | destructable | No | |
Footie | unit | No | |
Hashtable_Split_Dimension | hashtable | No | |
HealAmount | real | No | |
HealUnit | unit | No | |
JD_Angle | real | Yes | |
JD_Animations | string | Yes | |
JD_Distances | real | Yes | |
JD_Effect | string | Yes | |
JD_Group | group | No | |
JD_HighSettings | real | Yes | |
JD_Integers | integer | Yes | |
JD_JumpHigh | real | Yes | |
JD_ReachedDistance | real | Yes | |
JD_RealTimer | real | Yes | |
JD_SpeedUnits | real | Yes | |
JD_TempPoint | location | Yes | |
JD_TreesDestroy | boolean | Yes | |
JD_Unit | unit | Yes | |
JDA_Animation | string | No | |
JDA_AnimationSpeed | real | No | |
JDA_Collusion | boolean | No | |
JDA_DestroyTrees_Dash | boolean | No | |
JDA_JumpHigh_Distance | real | No | |
JDA_SpecialEffect | string | No | |
JDA_Speed | real | No | |
JDA_TargetPoint | location | No | |
JDA_Unit | unit | No | |
KB_Angle | real | Yes | |
KB_Casters | unit | Yes | |
KB_CountBuffs | integer | No | |
KB_DestroyTrees | boolean | 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 | |
KejutiSoundz | string | No | |
KejutiSoundzNaah | sound | No | |
LS_Dummy | unit | No | |
LS_GeneralInteger | integervar | No | |
LS_Groups | group | Yes | |
LS_TempPoint | location | Yes | |
Point | location | No | |
Point_Split_Dimension | location | Yes | |
Split_Dimension_Group | group | No | |
Temp_Integer | integer | No | |
TempLoc1 | location | No | |
TempUnit | unit | No | |
TempX | real | No | |
TempY | real | No | |
TimesBlockCaster | unit | No | |
UDex | integer | No | |
UDexGen | integer | No | |
UDexNext | integer | Yes | |
UDexPrev | integer | Yes | |
UDexRecycle | integer | No | |
UDexUnits | unit | Yes | |
UDexWasted | integer | No | |
UMovNext | integer | Yes | |
UMovPrev | integer | Yes | |
UnitDamageRegistered | boolean | Yes | |
UnitIndexerEnabled | boolean | No | |
UnitIndexEvent | real | No | |
UnitIndexLock | integer | Yes | |
UnitMoving | boolean | Yes | |
UnitMovingEvent | real | No | |
UnitMovingX | real | Yes | |
UnitMovingY | real | Yes | |
UnitSpeedX | real | Yes | |
zz_ActionAndTrig | trigger | No | |
zz_AdjustCam | boolean | Yes | |
zz_ai_only_mode | button | No | |
zz_AllItems | item | Yes | |
zz_AllUnits | unit | Yes | |
zz_Anfangsfarbe | integer | Yes | |
zz_AnyDamageTrig | trigger | No | |
zz_AnzahlVoter | integer | No | |
zz_ATLastSound | sound | Yes | |
zz_AttackDiceUpgr | integer | Yes | |
zz_AttackRateUpgr | integer | Yes | |
zz_ATToBeSkipped | boolean | Yes | |
zz_BnsBit | integer | Yes | |
zz_CamAlreadyOff | boolean | Yes | |
zz_CamAngle | real | Yes | |
zz_CameraSettingVal | real | Yes | |
zz_CamFollowUnit | unit | Yes | |
zz_CamOffset | real | Yes | |
zz_CamPid | integer | Yes | |
zz_CamPidIndex | integer | No | |
zz_CamRoll | real | Yes | |
zz_CamRotation | real | Yes | |
zz_CamSysPlayer | player | No | |
zz_CamSysT | real | No | |
zz_CamSysTime | real | No | |
zz_CamZOffset | real | Yes | |
zz_cdlg_button | button | Yes | |
zz_cdlg_dialog | dialog | Yes | |
zz_cdlg_length | integer | No | |
zz_cdlg_number | integer | Yes | |
zz_chat_no_ally | string | No | |
zz_CheckLocation | location | No | |
zz_ClosestDestructable | destructable | No | |
zz_ClosestDistance | real | No | |
zz_ClosestItem | item | No | |
zz_CodeIdA | string | Yes | |
zz_CodeIdB | string | Yes | |
zz_CodeRow | string | No | |
zz_CodeRows | integer | Yes | |
zz_color_board | leaderboard | No | |
zz_command_dlg1 | string | Yes | |
zz_command_dlg2 | string | Yes | |
zz_command_dlg3 | string | Yes | |
zz_command_hotkey1 | integer | Yes | |
zz_command_hotkey2 | integer | Yes | |
zz_command_hotkey3 | integer | Yes | |
zz_command_key1 | string | Yes | |
zz_command_key2 | string | Yes | |
zz_command_key3 | string | Yes | |
zz_command_language | string | No | |
zz_command_length | integer | No | |
zz_command_msg | string | Yes | |
zz_command_number | integer | Yes | |
zz_command_par1 | integer | Yes | |
zz_command_par2 | integer | Yes | |
zz_command_par3 | integer | Yes | |
zz_command_prefix | string | No | |
zz_commanded_player | player | No | |
zz_commander_mode | button | No | |
zz_commanding_player | player | No | |
zz_Comp | boolean | No | |
zz_current_command | integer | No | |
zz_current_number_par | integer | No | |
zz_current_player_par | integer | No | |
zz_CurrentlySelectedHero | unit | Yes | |
zz_CustomBooleanValue | boolean | Yes | |
zz_CustomRealValue | real | Yes | |
zz_CustomStringValue | string | Yes | |
zz_DamageTaken | real | No | |
zz_debug_BlackMaskTrig | trigger | No | |
zz_debugCamAoaTrig | trigger | No | |
zz_debugCamDistTrig | trigger | No | |
zz_debugCamFarzTrig | trigger | No | |
zz_debugCamFovTrig | trigger | No | |
zz_debugCamInfoTrig | trigger | No | |
zz_debugCamResetTrig | trigger | No | |
zz_debugCamRollTrig | trigger | No | |
zz_debugCamRotTrig | trigger | No | |
zz_debugCloneTrig | trigger | No | |
zz_debugDemoTrig | trigger | No | |
zz_debugDifficultyTrig | trigger | No | |
zz_debugDispelTrig | trigger | No | |
zz_debugFingerOfDeathEnabled | boolean | Yes | |
zz_debugFingerOfDeathTrig | trigger | Yes | |
zz_debugGimmeTrig | trigger | No | |
zz_debugGotoUnits | integer | No | |
zz_debugGotoUnitTrig | trigger | No | |
zz_debugGotoUnitX | real | No | |
zz_debugGotoUnitY | real | No | |
zz_debugGotoXTrig | trigger | No | |
zz_debugGotoXYTrig | trigger | No | |
zz_debugGotoYTrig | trigger | No | |
zz_debugTeleportTrig | trigger | No | |
zz_debugToolOfDeathTrig | trigger | Yes | |
zz_debugUnitInfoTrig | trigger | No | |
zz_DefendCaster | sound | No | |
zz_DetectRandom | real | No | |
zz_DetectSelected | real | No | |
zz_deutsch_button | button | No | |
zz_dialog_in_use | boolean | No | |
zz_DialogAktion | string | Yes | |
zz_DialogButton | button | Yes | |
zz_DialogFolge | trigger | Yes | |
zz_DialogShortcut | integer | Yes | |
zz_DialogSpieler | dialog | Yes | |
zz_DivineShield | sound | No | |
zz_dlg_dialog | dialog | Yes | |
zz_dlg_length | integer | No | |
zz_dlg_string | string | Yes | |
zz_dlgbutton_ai_only | string | No | |
zz_dlgbutton_all | string | No | |
zz_dlgbutton_cancel | string | No | |
zz_dlgbutton_commander | string | No | |
zz_dlgbutton_gold | string | No | |
zz_dlgbutton_lumber | string | No | |
zz_dlgbutton_no_human | string | No | |
zz_dlgbutton_tribute | string | No | |
zz_dlghdr_choose_ally | string | No | |
zz_dlghdr_choose_number | string | No | |
zz_dlghdr_choose_player | string | No | |
zz_dlghdr_game_type | string | No | |
zz_dlghdr_root | string | No | |
zz_dlghdr_tribute_amount | string | No | |
zz_dlghdr_tribute_type | string | No | |
zz_Empty0p5 | sound | No | |
zz_Empty1 | sound | No | |
zz_Empty10 | sound | No | |
zz_Empty11 | sound | No | |
zz_Empty12 | sound | No | |
zz_Empty14 | sound | No | |
zz_Empty16 | sound | No | |
zz_Empty18 | sound | No | |
zz_Empty1p5 | sound | No | |
zz_Empty2 | sound | No | |
zz_Empty20 | sound | No | |
zz_Empty22 | sound | No | |
zz_Empty24 | sound | No | |
zz_Empty26 | sound | No | |
zz_Empty28 | sound | No | |
zz_Empty2p5 | sound | No | |
zz_Empty3 | sound | No | |
zz_Empty30 | sound | No | |
zz_Empty32 | sound | No | |
zz_Empty4 | sound | No | |
zz_Empty5 | sound | No | |
zz_Empty6 | sound | No | |
zz_Empty7 | sound | No | |
zz_Empty8 | sound | No | |
zz_Empty9 | sound | No | |
zz_EngineTimerDialogs | timerdialog | Yes | |
zz_EngineTimers | timer | Yes | |
zz_english_button | button | No | |
zz_EnumItemType | integer | No | |
zz_EnumItemTypeT | itemtype | No | |
zz_ErweckteIndex | integer | No | |
zz_ErweckteKreaturen | unit | Yes | |
zz_Farbinterval | real | Yes | |
zz_ForRectItem | boolean | No | |
zz_french_button | button | No | |
zz_game_start_dialog | dialog | No | |
zz_game_start_trigger | trigger | No | |
zz_GewitterBlitze | integer | No | |
zz_GewitterCenter | location | No | |
zz_GlowEffect | effect | Yes | |
zz_GlowEffectPlus | effect | Yes | |
zz_heap_array_0 | integer | Yes | |
zz_heap_array_1 | integer | Yes | |
zz_heap_array_2 | integer | Yes | |
zz_heap_array_begin | integer | No | |
zz_heap_array_end | integer | No | |
zz_heap_arraycount | integer | No | |
zz_heap_descriptor_alloccursor | integer | No | |
zz_heap_descriptor_array_0 | integer | Yes | |
zz_heap_descriptor_array_1 | integer | Yes | |
zz_heap_descriptor_arraycount | integer | No | |
zz_heap_descriptor_begin | integer | No | |
zz_heap_descriptor_end | integer | No | |
zz_heap_descriptor_first | integer | No | |
zz_heap_descriptor_last | integer | No | |
zz_heap_descriptor_record_size | integer | No | |
zz_HeroChoice | trigger | No | |
zz_HeroDiedMsg | trigger | No | |
zz_HeroSkill1 | integer | Yes | |
zz_HeroSkill2 | integer | Yes | |
zz_HeroSkill3 | integer | Yes | |
zz_HeroSkill4 | integer | Yes | |
zz_HeroSkill5 | integer | Yes | |
zz_IsAlreadyPathing | boolean | Yes | |
zz_ItemIndex | integer | No | |
zz_language_dialog | dialog | No | |
zz_language_trigger | trigger | No | |
zz_LastClickedButtonNr | integer | Yes | |
zz_LastCreatedMovingSFX | integer | No | |
zz_LastCreatedMultiboardItem | multiboarditem | No | |
zz_LastMidiSound | sound | No | |
zz_LastMultipleChoice | integer | Yes | |
zz_LifeRegenUpgr | integer | Yes | |
zz_ManaRegenUpgr | integer | Yes | |
zz_MissileLength | integer | No | |
zz_MissileModel | string | Yes | |
zz_MissileOrder | string | Yes | |
zz_MissileUnitType | integer | Yes | |
zz_MJAuswahl | boolean | Yes | |
zz_MJAuswahleinheit | unit | Yes | |
zz_MJLastSound | sound | Yes | |
zz_MJPlayerPointer | integer | No | |
zz_MJSelected | group | Yes | |
zz_MJTrig1 | trigger | Yes | |
zz_MJTrig2 | trigger | Yes | |
zz_ModuloHex | integer | No | |
zz_MoveRateUpgr | integer | Yes | |
zz_MovForward | trigger | No | |
zz_MovingSFX | effect | Yes | |
zz_MovingSFXAbstand | real | Yes | |
zz_MovingSFXCenter | location | Yes | |
zz_MovingSFXCounter | integer | Yes | |
zz_MovingSFXKilled | boolean | Yes | |
zz_MovingSFXLength | integer | No | |
zz_MovingSFXLoop | boolean | Yes | |
zz_MovingSFXNach | rect | Yes | |
zz_MovingSFXNr | integer | Yes | |
zz_MovingSFXPath | string | Yes | |
zz_MovingSFXRadius | real | Yes | |
zz_MovingSFXStartAngle | real | Yes | |
zz_MovingSFXTrigger | trigger | Yes | |
zz_MovingSFXType | integer | Yes | |
zz_MovingSFXUnit | unit | Yes | |
zz_MovingSFXVor | rect | Yes | |
zz_MovingSFXWait | real | Yes | |
zz_MovLeft | integer | Yes | |
zz_MovMoving | boolean | Yes | |
zz_MovRight | integer | Yes | |
zz_MovSidewards | trigger | No | |
zz_MovUnit | unit | Yes | |
zz_ndbn_button | button | Yes | |
zz_ndbn_length | integer | No | |
zz_no_human_mode | button | No | |
zz_NoBuildIndex | integer | No | |
zz_NoBuildRects | rect | Yes | |
zz_NoBuildTrig | trigger | No | |
zz_number_dialog | dialog | No | |
zz_observer_god | boolean | No | |
zz_parsed_command | string | Yes | |
zz_pcbn_button | button | Yes | |
zz_pcbn_length | integer | No | |
zz_pcbn_number | integer | Yes | |
zz_player_dialog | dialog | No | |
zz_PlayerLeftMsg | trigger | No | |
zz_PortaleffektA | effect | Yes | |
zz_PortaleffektB | effect | No | |
zz_PortaltriggerA | trigger | No | |
zz_PortaltriggerB | trigger | No | |
zz_PressDown | trigger | No | |
zz_PressLeft | trigger | No | |
zz_PressRight | trigger | No | |
zz_PressUp | trigger | No | |
zz_PrevCam | camerasetup | Yes | |
zz_RangeUpgr | integer | Yes | |
zz_RegrowingTrees | trigger | No | |
zz_ReleaseLeft | trigger | No | |
zz_ReleaseRight | trigger | No | |
zz_ReleaseUp | trigger | No | |
zz_root_dialog | dialog | No | |
zz_SaveLoadSettings | boolean | Yes | |
zz_sdbn_button | button | Yes | |
zz_sdbn_length | integer | No | |
zz_sdbn_number | integer | Yes | |
zz_SEAnzahl | integer | No | |
zz_SECaster | unit | No | |
zz_SECastingType | integer | Yes | |
zz_SEFunc | string | Yes | |
zz_SEId | integer | Yes | |
zz_SEIndex | integer | No | |
zz_SELastOrder | string | No | |
zz_SelectableHeros | group | No | |
zz_SEMana | real | Yes | |
zz_SEOrder | string | Yes | |
zz_SERange | real | Yes | |
zz_SETarget | unit | No | |
zz_SETX | real | No | |
zz_SETY | real | No | |
zz_ShortcutId | string | Yes | |
zz_start_dialog | dialog | No | |
zz_StimmeAbgegeben | boolean | Yes | |
zz_Stimmen | integer | Yes | |
zz_StimmenAbgabe | trigger | No | |
zz_StimmenAbgegeben | integer | No | |
zz_StringIdent | string | No | |
zz_swedish_button | button | No | |
zz_TargetDistance | real | Yes | |
zz_TargetUpgr | integer | Yes | |
zz_TimerCounter | integer | No | |
zz_TPCenter | rect | No | |
zz_TPCondition | triggercondition | Yes | |
zz_TPEingang | rect | Yes | |
zz_TPNextTown | rect | No | |
zz_TPOpen | boolean | Yes | |
zz_TPPointer | integer | No | |
zz_TPRestrictGroup | group | No | |
zz_TPRestrictType | integer | No | |
zz_TPWatchersA | real | No | |
zz_TPWatchersB | real | No | |
zz_tribute_amount | string | No | |
zz_tribute_dlg | dialog | No | |
zz_tribute_dlg_button | button | Yes | |
zz_tribute_dlg_length | integer | No | |
zz_tribute_g | button | No | |
zz_tribute_l | button | No | |
zz_tribute_type | string | No | |
zz_TrigAlways | trigger | No | |
zz_UnfertigeGebaeude | unit | Yes | |
zz_UnfertigeGebIndex | integer | No | |
zz_UnfertigeUpgrades | unit | Yes | |
zz_UnfertigeUpgradesIndex | integer | No | |
zz_UnitIndex | integer | No | |
zz_UseAngle | boolean | Yes | |
zz_UseDistance | boolean | Yes | |
zz_UseOffset | boolean | Yes | |
zz_UseRoll | boolean | Yes | |
zz_UseRotation | boolean | Yes | |
zz_UseZOffset | boolean | Yes | |
zz_VotingAuswahl | string | Yes | |
zz_VotingBoard | leaderboard | Yes | |
zz_VotingErgebnis | string | No | |
zz_VotingFolge | string | Yes | |
zz_VotingGeheim | boolean | No | |
zz_VotingTimer | timerdialog | No | |
zz_XAcquiredItem | item | Yes | |
zz_XBuiltConstruction | unit | Yes | |
zz_XDroppedItem | item | Yes | |
zz_XLearnedSkill | integer | Yes | |
zz_XResearchedUpgrade | integer | Yes | |
zz_XSoldItem | item | Yes | |
zz_XSoldUnit | unit | Yes | |
zz_XSummonedUnit | unit | Yes | |
zz_XTrainedUnit | unit | Yes |
function Trig_Footie_Spawn_1_Actions takes nothing returns nothing
call CreateNUnitsAtLoc( 1, 'h001', Player(1), GetRectCenter(gg_rct_Land_Of_Remake), bj_UNIT_FACING )
endfunction
//===========================================================================
function InitTrig_Footie_Spawn_1 takes nothing returns nothing
set gg_trg_Footie_Spawn_1 = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Footie_Spawn_1, Player(0), "-footie", false )
call TriggerAddAction( gg_trg_Footie_Spawn_1, function Trig_Footie_Spawn_1_Actions )
endfunction
function Trig_Balack_Spawn_1_Actions takes nothing returns nothing
call CreateNUnitsAtLoc( 1, 'h002', Player(1), GetRectCenter(gg_rct_Land_Of_Remake), bj_UNIT_FACING )
endfunction
//===========================================================================
function InitTrig_Balack_Spawn_1 takes nothing returns nothing
set gg_trg_Balack_Spawn_1 = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Balack_Spawn_1, Player(0), "-balack", false )
call TriggerAddAction( gg_trg_Balack_Spawn_1, function Trig_Balack_Spawn_1_Actions )
endfunction
//TESH.scrollpos=19
//TESH.alwaysfold=0
//*******
//* This request was made here:
//* http://www.hiveworkshop.com/forums/requests-341/mr_beans-spell-workshop-215436/index72.html#post2356053
//* http://www.hiveworkshop.com/forums/requests-341/mr_beans-spell-workshop-215436/index73.html#post2356355
//*
//* If you are having trouble importing your spells, check out this guide:
//* http://tiny.cc/importing-guide
//*
//* If you are still having problems, feel free to contact me:
//* http://tiny.cc/mrbean-hive
//* [email protected]
//*
//* You can find my spell workshop here:
//* http://tiny.cc/spellworkshop
//*******
- Copy all of the triggers in the "Requirements" folder that you don't alreay have.
* If you copied "xebasic", do the following:
> Import the included "dummy.mdx" file. Don't change the import path.
> Copy over the "Dummy" unit. Make sure it's model is set to the imported one.
> Open the copied "xebasic" trigger. Make sure XE_DUMMY_UNITID is set to the raw ID of the
copied Dummy unit.
* If you copied "Damage Engine", do the following:
> Copy the "Cheat Death Ability (+500,000)" ability.
> Open the "Damage Engine" trigger and make sure the second action sets the "DamageBlockingAbility"
variable to the copied ability.
- Copy all of the triggers in the "Spells" folder.
- Copy all of the custom abilities.
- For each spell, open it's trigger. Update all of the raw IDs in the configurables section
(for example, SPELL_ID) to the values as specified next to each configurable.
//TESH.scrollpos=24
//TESH.alwaysfold=0
scope Hesoyham
// -----
// Start of Configurables
// -----
globals
private constant integer SPELL_ID = 'A008' // "Hesoyham" ability.
//============================================================
//=== CHANNELLING
private constant real CHANNEL_TIME = 2.0 // Channel duration.
private constant real START_SCALE = 0.0 // Starting scale of the orb.
private constant real END_SCALE = 4.0 // Ending scale of the orb.
private constant real CREATE_DIST = 0.0 // Distance the orb is created from the caster.
// Order ID of the spell:
private constant string ORDER_ID = "shockwave"
//============================================================
//=== ORB MOVEMENT
private constant real DISTANCE = 1000.0 // Orb travel distance.
private constant real MISSILE_HEIGHT = 50.0 // Orb travel height.
private constant real MISSILE_SPEED = 500.0 // Orb travel speed.
private constant real MISSILE_ARC = 0.0 // Orb travel arc.
private constant real DAMAGE_AOE = 240.0 // Distance enemies must get to be damaged.
private constant real KNOCK_DAMAGE = 200.0 // Damage dealt.
// Orb model:
private constant string MISSILE_ART = "OrbWaterX.mdx"
//============================================================
//=== EXPLOSION
private constant real EXPLODE_AOE = 400.0 // Final explosion AoE.
private constant real EXPLODE_DAMAGE = 400.0 // Final explosion damage.
//============================================================
//=== KNOCKBACK
private constant real KNOCK_DISTANCE = 400.0 // Knockback distance.
private constant real KNOCK_SPEED = 200.0 // Knockback speed.
private constant real EFFECT_FREQ = 0.25 // How often effects are created on knocked back units.
// Knockback effect:
private constant string KNOCK_EFFECT = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveDamage.mdl"
// Effect attachment point:
private constant string KNOCK_ATTACH = "chest"
endglobals
// -----
// End of Configurables
// -----
private struct Knockback
static constant real INCREMENT = KNOCK_SPEED * T32_PERIOD
//-----
static hashtable data = InitHashtable()
//-----
unit target
integer id
real dist = KNOCK_DISTANCE
real cos
real sin
real ticker
//-----
private method destroy takes nothing returns nothing
call stopPeriodic()
call SaveInteger(data, id, 0, 0)
call PauseUnit(target, false)
call SetUnitPathing(target, true)
set target = null
call deallocate()
endmethod
private method periodic takes nothing returns nothing
local real x = GetUnitX(target) + INCREMENT * cos
local real y = GetUnitY(target) + INCREMENT * sin
if (not IsUnitType(target, UNIT_TYPE_DEAD) and IsTerrainWalkable(x, y) and dist > 0.0) then
call SetUnitX(target, x)
call SetUnitY(target, y)
set dist = dist - INCREMENT
// Create effect if necessary:
if (ticker >= EFFECT_FREQ) then
call DestroyEffect(AddSpecialEffectTarget(KNOCK_EFFECT, target, KNOCK_ATTACH))
set ticker = 0.0
else
set ticker = ticker + T32_PERIOD
endif
else
call destroy()
endif
endmethod
implement T32x
static method start takes unit whichUnit, real angle returns thistype
local thistype this = allocate()
local thistype other
set target = whichUnit
set id = GetHandleId(target)
set other = LoadInteger(data, id, 0)
if (other != 0) then
call other.destroy()
endif
set cos = Cos(angle)
set sin = Sin(angle)
set ticker = EFFECT_FREQ // So that effect is created on first tick.
call PauseUnit(target, true)
call SetUnitPathing(target, false)
call SaveInteger(data, id, 0, this)
call startPeriodic()
return this
endmethod
endstruct
private struct SpellData
static constant real GROWTH = ((END_SCALE - START_SCALE) / CHANNEL_TIME) * T32_PERIOD
static constant real INCREMENT = MISSILE_SPEED * T32_PERIOD
static integer ORDER_ID_INT = 0 // set in onInit method.
//-----
static group enumG = CreateGroup()
static unit temp
//-----
unit caster
player owner
group hit
boolean moving = false
real scale = START_SCALE
real time = CHANNEL_TIME
real cos
real sin
xefx fx
//-----
private method destroy takes nothing returns nothing
call ReleaseGroup(hit)
call fx.destroy()
call stopPeriodic()
set caster = null
set hit = null
set owner = null
call deallocate()
endmethod
private method unitFilter takes unit u returns boolean
return IsUnitEnemy(u, owner) /*
*/ and not IsUnitType(u, UNIT_TYPE_DEAD) /*
*/ and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) /*
*/ and not IsUnitType(u, UNIT_TYPE_STRUCTURE)
endmethod
private method explode takes nothing returns nothing
call GroupEnumUnitsInRange(enumG, fx.x, fx.y, EXPLODE_AOE, null)
for temp in enumG
if (unitFilter(temp)) then
call UnitDamageTarget(caster, temp, EXPLODE_DAMAGE, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
call Knockback.start(temp, Atan2(GetUnitY(temp) - fx.y, GetUnitX(temp) - fx.x))
endif
endfor
endmethod
private method checkNearby takes nothing returns nothing
call GroupEnumUnitsInRange(enumG, fx.x, fx.y, DAMAGE_AOE, null)
for temp in enumG
if (not IsUnitInGroup(temp, hit) and unitFilter(temp)) then
call GroupAddUnit(hit, temp)
call UnitDamageTarget(caster, temp, KNOCK_DAMAGE, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
call Knockback.start(temp, Atan2(GetUnitY(temp) - fx.y, GetUnitX(temp) - fx.x))
endif
endfor
endmethod
private method periodic takes nothing returns nothing
// Missile has been launched:
if (moving) then
set fx.x = fx.x + cos
set fx.y = fx.y + sin
call checkNearby()
set time = time - T32_PERIOD
if (time <= 0.0) then
call explode()
call destroy()
endif
// Still channelling and caster cancelled:
elseif (GetUnitCurrentOrder(caster) != ORDER_ID_INT) then
call destroy()
// Still channelling:
else
set time = time - T32_PERIOD
// Time is up:
if (time <= 0.0) then
call IssueImmediateOrder(caster, "stop")
set moving = true
set time = DISTANCE / MISSILE_SPEED
// Grow orb:
else
set scale = scale + GROWTH
set fx.scale = scale
endif
endif
endmethod
implement T32x
private static method create takes nothing returns thistype
local thistype this = allocate()
local real angle
set caster = GetTriggerUnit()
set owner = GetTriggerPlayer()
set hit = NewGroup()
set angle = Atan2(GetSpellTargetY() - GetUnitY(caster), GetSpellTargetX() - GetUnitX(caster))
set cos = INCREMENT * Cos(angle)
set sin = INCREMENT * Sin(angle)
set fx = xefx.create(GetUnitX(caster) + CREATE_DIST * Cos(angle), GetUnitY(caster) + CREATE_DIST * Sin(angle), 0.0)
set fx.fxpath = MISSILE_ART
set fx.scale = scale
call startPeriodic()
return this
endmethod
private static method onInit takes nothing returns nothing
set ORDER_ID_INT = OrderId(ORDER_ID)
call RegisterSpellEffectEvent(SPELL_ID, function thistype.create)
call Preload(MISSILE_ART)
call Preload(KNOCK_EFFECT)
endmethod
endstruct
endscope
//TESH.scrollpos=27
//TESH.alwaysfold=0
scope Restart initializer OnInit
// -----
// Start of Configurables
// -----
globals
private constant integer SPELL_ID = 'A009' // "Restart" ability.
private constant real MIN_HEALTH = 1.0 // The target cannot have less that this much HP.
// Effect created on target for the duration:
private constant string TARGET_EFFECT = "Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl"
// Attachment point for the above effect:
private constant string TARGET_ATTACH = "overhead"
// Effect created on target if it gets fully restored:
private constant string HEAL_EFFECT = "Abilities\\Spells\\Items\\AIre\\AIreTarget.mdl"
// Attachment point for the above effect:
private constant string HEAL_ATTACH = "origin"
endglobals
// Configure how the duration is calculated:
private function GetDuration takes integer level returns real
return 1.0 + level
endfunction
// -----
// End of Configurables
// -----
globals
private group units = CreateGroup()
endglobals
private struct SpellData
static integer array instances
//-----
unit target
effect fx
boolean heal = false
//-----
static method get takes unit u returns thistype
return instances[GetUnitUserData(u)]
endmethod
private static method expire takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
if (heal) then
call SetWidgetLife(target, GetUnitState(target, UNIT_STATE_MAX_LIFE))
call SetUnitState(target, UNIT_STATE_MANA, GetUnitState(target, UNIT_STATE_MAX_MANA))
call UnitRemoveBuffs(target, true, true)
call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT, target, HEAL_ATTACH))
endif
call ReleaseTimer(GetExpiredTimer())
call DestroyEffect(fx)
call GroupRemoveUnit(units, target)
set instances[GetUnitUserData(target)] = 0
set target = null
set fx = null
call deallocate()
endmethod
static method create takes nothing returns thistype
local thistype this = allocate()
set target = GetSpellTargetUnit()
set fx = AddSpecialEffectTarget(TARGET_EFFECT, target, TARGET_ATTACH)
set instances[GetUnitUserData(target)] = this
call GroupAddUnit(units, target)
call TimerStart(NewTimerEx(this), GetDuration(GetUnitAbilityLevel(GetTriggerUnit(), SPELL_ID)), false, function thistype.expire)
return this
endmethod
endstruct
private function OnDamage takes nothing returns boolean
local real life
if (IsUnitInGroup(udg_DamageEventTarget, units)) then
set life = GetWidgetLife(udg_DamageEventTarget)
if (udg_DamageEventPrevAmt >= life) then
set udg_DamageEventAmount = life - MIN_HEALTH
set SpellData(SpellData.get(udg_DamageEventTarget)).heal = true
endif
endif
return false
endfunction
private function OnInit takes nothing returns nothing
local trigger t = CreateTrigger()
call RegisterSpellEffectEvent(SPELL_ID, function SpellData.create)
call TriggerAddCondition(t, Condition(function OnDamage))
call TriggerRegisterVariableEvent(t, "udg_DamageModifierEvent", EQUAL, 1.0)
call Preload(TARGET_EFFECT)
call Preload(HEAL_EFFECT)
endfunction
endscope
function Trig_STOP_Actions takes nothing returns nothing
call ResetToGameCameraForPlayer( Player(0), 0 )
endfunction
//===========================================================================
function InitTrig_STOP takes nothing returns nothing
set gg_trg_STOP = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_STOP, Player(0), "STOP", true )
call TriggerAddAction( gg_trg_STOP, function Trig_STOP_Actions )
endfunction
function Trig_Kejuti_Actions takes nothing returns nothing
call CameraSetEQNoiseForPlayer( Player(0), 2000.00 )
call DisplayTextToForce( GetPlayersAll(), "TRIGSTR_023" )
endfunction
//===========================================================================
function InitTrig_Kejuti takes nothing returns nothing
set gg_trg_Kejuti = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Kejuti, Player(0), "-kejuti", true )
call TriggerAddAction( gg_trg_Kejuti, function Trig_Kejuti_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Balack_Spawn_Actions takes nothing returns nothing
call CreateNUnitsAtLoc( S2I(SubStringBJ(GetEventPlayerChatString(), 17, 24)), 'h002', Player(1), GetRectCenter(gg_rct_Land_Of_Remake_Spawns), bj_UNIT_FACING )
endfunction
//===========================================================================
function InitTrig_Balack_Spawn takes nothing returns nothing
set gg_trg_Balack_Spawn = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Balack_Spawn, Player(0), "-balack warrior", false )
call TriggerAddAction( gg_trg_Balack_Spawn, function Trig_Balack_Spawn_Actions )
endfunction
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Footie_Spawn_Actions takes nothing returns nothing
call CreateNUnitsAtLoc( S2I(SubStringBJ(GetEventPlayerChatString(), 9, 20)), 'h001', Player(1), GetRectCenter(gg_rct_Land_Of_Remake_Spawns), bj_UNIT_FACING )
endfunction
//===========================================================================
function InitTrig_Footie_Spawn takes nothing returns nothing
set gg_trg_Footie_Spawn = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Footie_Spawn, Player(0), "-footie", false )
call TriggerAddAction( gg_trg_Footie_Spawn, function Trig_Footie_Spawn_Actions )
endfunction
function Trig_Respawn_Func001A takes nothing returns nothing
call ReviveHeroLoc( GetEnumUnit(), GetRectCenter(gg_rct_Land_Of_Remake), false )
endfunction
function Trig_Respawn_Actions takes nothing returns nothing
call ForGroupBJ( GetUnitsInRectOfPlayer(GetEntireMapRect(), Player(0)), function Trig_Respawn_Func001A )
endfunction
//===========================================================================
function InitTrig_Respawn takes nothing returns nothing
set gg_trg_Respawn = CreateTrigger( )
call TriggerRegisterPlayerChatEvent( gg_trg_Respawn, Player(0), "-Respawn", true )
call TriggerAddAction( gg_trg_Respawn, function Trig_Respawn_Actions )
endfunction
//TESH.scrollpos=175
//TESH.alwaysfold=0
library MoveSpeedXGUI /* v1.1.0.0
*************************************************************************************
*
* This library allows you to set unit movement speeds beyond 522 without bugs.
* This is an extension of the library MoveSpeedX, but is formatted for GUI use.
* Credits to Jesus4Lyf for the original system.
*
************************************************************************************
*
* SETTINGS
*/
globals
private constant real PERIOD = 0.03125
// This is the period on which all units will be run.
// If you lower this value, movement bonuses will be smoother,
// but will require more processing power (lag more).
// Also, the lower this is, the higher the move speed can be
// before it starts bugging on waypoints. The lowest valid
// period is 0.00125. A period of 0.00625 is very robust.
private constant real MARGIN = 0.01
// This is the margin of approximation when comparing reals.
// You will most likely not need to change this.
endglobals
/*
************************************************************************************
*
* Functions
*
* function GetUnitMoveSpeedX takes unit whichUnit returns real
* - Returns a unit movement speed. The GUI function will
* - not return the correct value. This function will always
* - return the correct value regardless of whether the unit
* - has a movement speed beyond 522.
*
************************************************************************************
*
* REQUIREMENTS
*
* 1. JassNewGen Pack v5d
* 2. JassHelper 0.A.2.B
* 3. Any unit indexer
*
* HOW TO IMPLEMENT
*
* 1. Copy the 'folder' MoveSpeedX.
* 2. Paste it into your map.
* 3. Open "Advanced -> Gameplay Constants".
* 4. Checkmark "Use Custom Gameplay Constants".
* 5. Find the field, "Movement - Unit Speed - Maximum", change
* that to 522.
* 6. Find the field, "Movement - Unit Speed - Minimum", hold
* shift and click, and change it to 0.
* 7. Read HOW TO USE.
*
************************************************************************************
*
* HOW TO USE
*
* This system will automatically work by itself. You can use the
* normal GUI function for modifying unit movement speeds. Simply
* use "Unit - Set Movement Speed", input whatever value you want,
* and you are good to go! It will handle values beyond 522 by itself.
*
* HOWEVER, the GUI function will not return correct values if a unit
* has a movement speed greater than 522. To fix this, use the function
* GetUnitMoveSpeedX to return the correct value. A sample is given in
* the trigger "Speed Change" in the test map.
*
************************************************************************************
*
* NOTES
*
* Units that were issued orders as groups might not *always* end up in the proper
* "order". (they might not end up in an organized formation) They do sometimes though.
* This is only for units with speeds above 522.
*
* This also will not factor in bonuses and probably not slows either.
*
* Units may waddle around the point for a little bit. Reduce PERIOD to fix
* it a little bit. I recommend about 0.02 if you have really high speeds.
*
************************************************************************************/
private function ApproxEqual takes real A, real B returns boolean
return (A >= (B - MARGIN)) and (A <= (B + MARGIN))
endfunction
private module M
private static trigger issued = CreateTrigger()
thistype next
thistype prev
boolean enabled
unit curr
real speed
real x
real y
real ox
real oy
method destroy takes nothing returns nothing
set this.next.prev = this.prev
set this.prev.next = this.next
set this.enabled = false
endmethod
private static method periodic takes nothing returns nothing
local thistype this = thistype(0).next // first instance in list
local real nx // the x-coordinate after tick
local real ny // the y-coordinate after tick
local real dx // distance between new-x and old-x
local real dy // distance between new-y and old-y
local real d // distance between new point and old point
local integer order // the unit's current order
local unit u // unit being affected
loop
exitwhen this == 0
set u = .curr
set nx = GetUnitX(u)
set ny = GetUnitY(u)
if IsUnitType(u, UNIT_TYPE_DEAD) then
call this.destroy()
elseif not ApproxEqual(nx, .x) or not ApproxEqual(ny, .y) then
if (not IsUnitPaused(u)) and GetUnitAbilityLevel(u, 'BSTN') == 0 and GetUnitAbilityLevel(u, 'BPSE') == 0 then
set order = GetUnitCurrentOrder(u)
set dx = nx - .x
set dy = ny - .y
set d = SquareRoot(dx * dx + dy * dy)
set dx = dx / d * .speed // move the unit offset-x by this
set dy = dy / d * .speed // move the unit offset-y by this
if (order == 851986 or order == 851971) and /*
*/ (this.ox - nx)*(this.ox - nx) < (dx*dx) and /*
*/ (this.oy - ny)*(this.oy - ny) < (dy*dy) then
// if the unit is issued a move or smart order and they are near their destination
// then move them there instantly (removes a bit of glitchyness towards the end)
call SetUnitX(u, .ox)
call SetUnitY(u, .oy)
set .x = .ox
set .y = .oy
call IssueImmediateOrderById(u, 851972) // order them to stop
else
set .x = nx + dx
set .y = ny + dy
call SetUnitX(u, .x)
call SetUnitY(u, .y)
endif
endif
endif
set this = this.next
endloop
set u = null
endmethod
static method create takes unit whichUnit, real newSpeed returns thistype
local thistype this = GetUnitUserData(whichUnit)
set this.next = thistype(0).next
set thistype(0).next.prev = this
set thistype(0).next = this
set this.prev = 0
set this.curr = whichUnit
set this.speed = (newSpeed - 522) * PERIOD
set this.x = GetUnitX(whichUnit)
set this.y = GetUnitY(whichUnit)
set this.enabled = true
return this
endmethod
static method update takes unit whichUnit, real newSpeed returns nothing
local thistype this = GetUnitUserData(whichUnit)
if this.enabled then
if newSpeed > 522 then
set this.speed = (newSpeed - 522) * PERIOD
else
call this.destroy()
endif
elseif newSpeed > 522 then
call thistype.create(whichUnit, newSpeed)
endif
endmethod
private static method storeOrderPoint takes nothing returns boolean
local thistype this = GetUnitUserData(GetTriggerUnit())
set this.ox = GetOrderPointX()
set this.oy = GetOrderPointY()
return false
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), PERIOD, true, function thistype.periodic)
call TriggerRegisterAnyUnitEventBJ(issued, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerAddCondition(issued, Condition(function thistype.storeOrderPoint))
endmethod
endmodule
private struct MoveSpeedStruct extends array
implement M
endstruct
function GetUnitMoveSpeedX takes unit whichUnit returns real
if MoveSpeedStruct(GetUnitUserData(whichUnit)).enabled then
return udg_UnitSpeedX[GetUnitUserData(whichUnit)]
endif
return GetUnitMoveSpeed(whichUnit)
endfunction
function SetUnitMoveSpeedX takes unit whichUnit, real newSpeed returns nothing
call MoveSpeedStruct.update(whichUnit, newSpeed)
set udg_UnitSpeedX[GetUnitUserData(whichUnit)] = newSpeed
endfunction
hook SetUnitMoveSpeed SetUnitMoveSpeedX
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/***************************************
*
* GroupTools
* v1.1.2.2
* By Magtheridon96
*
* - Original version by Rising_Dusk
*
* - Recycles groups, and allows the
* enumeration of units while taking
* into account collision.
*
* API:
* ----
*
* - group ENUM_GROUP
*
* - function NewGroup takes nothing returns group
* - function ReleaseGroup takes group g returns nothing
* - Get and release group handles
*
* - function GroupRefresh takes group g returns nothing
* - Refresh a group so that null units are removed
*
* - function GroupUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
* - Groups units while taking into account collision
*
***************************************/
library GroupTools
globals
// The highest collision size you're using in your map.
private constant real MAX_COLLISION_SIZE = 197.
// Data Variables
private group array groups
private group gT = null
private integer gN = 0
private boolean f = false
// Global Group (Change it to CreateGroup() if you want)
group ENUM_GROUP = bj_lastCreatedGroup
endglobals
static if DEBUG_MODE then
private struct V extends array
debug static hashtable ht = InitHashtable()
endstruct
endif
private function AE takes nothing returns nothing
if (f) then
call GroupClear(gT)
set f = false
endif
call GroupAddUnit(gT,GetEnumUnit())
endfunction
function GroupRefresh takes group g returns nothing
debug if null==g then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Attempt to refresh null group!")
debug return
debug endif
set f = true
set gT = g
call ForGroup(gT,function AE)
if (f) then
call GroupClear(g)
endif
endfunction
function NewGroup takes nothing returns group
if 0==gN then
return CreateGroup()
endif
set gN = gN - 1
debug call SaveBoolean(V.ht,GetHandleId(groups[gN]),0,false)
return groups[gN]
endfunction
function ReleaseGroup takes group g returns nothing
debug if null==g then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Attempt to release null group!")
debug return
debug endif
debug if LoadBoolean(V.ht,GetHandleId(g),0) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Double free!")
debug return
debug endif
debug call SaveBoolean(V.ht,GetHandleId(g),0,true)
call GroupClear(g)
set groups[gN] = g
set gN = gN + 1
endfunction
function GroupUnitsInArea takes group whichGroup, real x, real y, real radius returns nothing
local unit u
debug if null==whichGroup then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"[GroupUtils]Error: Null group passed to GroupUnitsInArea!")
debug return
debug endif
call GroupEnumUnitsInRange(ENUM_GROUP,x,y,radius+MAX_COLLISION_SIZE,null)
loop
set u = FirstOfGroup(ENUM_GROUP)
exitwhen null==u
if IsUnitInRangeXY(u,x,y,radius) then
call GroupAddUnit(whichGroup,u)
endif
call GroupRemoveUnit(ENUM_GROUP,u)
endloop
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/**************************************************************
*
* RegisterPlayerUnitEvent
* v4.2.0.0
* By Magtheridon96
*
* I would like to give a special thanks to Bribe, azlier
* and BBQ for improving this library. For modularity, it only
* supports player unit events.
*
* Functions passed to RegisterPlayerUnitEvent must
* return false. They can return nothing as well.
*
* Disclaimer:
* -----------
*
* - Don't use TriggerSleepAction inside registered code.
*
* API:
* ----
*
* function RegisterPlayerUnitEvent
* takes
* playerunitevent whichEvent : The event you would like to register
* code whichFunction : The code you would like to register
* returns
* nothing
*
* - Registers code that will execute when an event fires.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
endlibrary
//TESH.scrollpos=20
//TESH.alwaysfold=0
//============================================================================
// SpellEffectEvent by Bribe
// - Version 1.1.0.0
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table
//============================================================================
private module M
static if LIBRARY_Table then
static Table tb
else
static hashtable ht = InitHashtable()
endif
static method onCast takes nothing returns nothing
static if LIBRARY_Table then
call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
else
call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set .tb = Table.create()
endif
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
static if LIBRARY_Table then
if not S.tb.handle.has(abil) then
set S.tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
else
if not HaveSavedHandle(S.ht, 0, abil) then
call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
endif
call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
endif
endfunction
endlibrary
//TESH.scrollpos=72
//TESH.alwaysfold=0
library TerrainPathability initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//*
//******************************************************************************
//*
//* > function IsTerrainDeepWater takes real x, real y returns boolean
//* > function IsTerrainShallowWater takes real x, real y returns boolean
//* > function IsTerrainLand takes real x, real y returns boolean
//* > function IsTerrainPlatform takes real x, real y returns boolean
//* > function IsTerrainWalkable takes real x, real y returns boolean
//*
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//*
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//*
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//*
//* Variables that can be used from the library:
//* [real] TerrainPathability_X
//* [real] TerrainPathability_Y
//*
globals
private constant real MAX_RANGE = 10.
private constant integer DUMMY_ITEM_ID = 'wolg'
endglobals
globals
private item Item = null
private rect Find = null
private item array Hid
private integer HidMax = 0
public real X = 0.
public real Y = 0.
endglobals
function IsTerrainDeepWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
function IsTerrainShallowWater takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
function IsTerrainLand takes real x, real y returns boolean
return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
endfunction
function IsTerrainPlatform takes real x, real y returns boolean
return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
endfunction
private function HideItem takes nothing returns nothing
if IsItemVisible(GetEnumItem()) then
set Hid[HidMax] = GetEnumItem()
call SetItemVisible(Hid[HidMax], false)
set HidMax = HidMax + 1
endif
endfunction
function IsTerrainWalkable takes real x, real y returns boolean
//Hide any items in the area to avoid conflicts with our item
call MoveRectTo(Find, x, y)
call EnumItemsInRect(Find ,null, function HideItem)
//Try to move the test item and get its coords
call SetItemPosition(Item, x, y) //Unhides the item
set X = GetItemX(Item)
set Y = GetItemY(Item)
static if LIBRARY_IsTerrainWalkable then
//This is for compatibility with the IsTerrainWalkable library
set IsTerrainWalkable_X = X
set IsTerrainWalkable_Y = Y
endif
call SetItemVisible(Item, false)//Hide it again
//Unhide any items hidden at the start
loop
exitwhen HidMax <= 0
set HidMax = HidMax - 1
call SetItemVisible(Hid[HidMax], true)
set Hid[HidMax] = null
endloop
//Return walkability
return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
endfunction
private function Init takes nothing returns nothing
set Find = Rect(0., 0., 128., 128.)
set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
call SetItemVisible(Item, false)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library TimerUtils initializer init
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+) 2.0
//* ----------
//*
//* To implement it , create a custom text trigger called TimerUtils
//* and paste the contents of this script there.
//*
//* To copy from a map to another, copy the trigger holding this
//* library to your map.
//*
//* (requires vJass) More scripts: htt://www.wc3c.net
//*
//* For your timer needs:
//* * Attaching
//* * Recycling (with double-free protection)
//*
//* set t=NewTimer() : Get a timer (alternative to CreateTimer)
//* set t=NewTimerEx(x) : Get a timer (alternative to CreateTimer), call
//* Initialize timer data as x, instead of 0.
//*
//* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer)
//* SetTimerData(t,2) : Attach value 2 to timer
//* GetTimerData(t) : Get the timer's value.
//* You can assume a timer's value is 0
//* after NewTimer.
//*
//* Multi-flavor:
//* Set USE_HASH_TABLE to true if you don't want to complicate your life.
//*
//* If you like speed and giberish try learning about the other flavors.
//*
//********************************************************************
//================================================================
globals
//How to tweak timer utils:
// USE_HASH_TABLE = true (new blue)
// * SAFEST
// * SLOWEST (though hash tables are kind of fast)
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true (orange)
// * kinda safe (except there is a limit in the number of timers)
// * ALMOST FAST
//
// USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
// * THE FASTEST (though is only faster than the previous method
// after using the optimizer on the map)
// * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
// work)
//
private constant boolean USE_HASH_TABLE = true
private constant boolean USE_FLEXIBLE_OFFSET = false
private constant integer OFFSET = 0x100000
private integer VOFFSET = OFFSET
//Timers to preload at map init:
private constant integer QUANTITY = 256
//Changing this to something big will allow you to keep recycling
// timers even when there are already AN INCREDIBLE AMOUNT of timers in
// the stack. But it will make things far slower so that's probably a bad idea...
private constant integer ARRAY_SIZE = 8190
endglobals
//==================================================================================================
globals
private integer array data[ARRAY_SIZE]
private hashtable ht
endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
function SetTimerData takes timer t, integer value returns nothing
static if(USE_HASH_TABLE) then
// new blue
call SaveInteger(ht,0,GetHandleId(t), value)
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-VOFFSET]=value
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
set data[GetHandleId(t)-OFFSET]=value
endif
endfunction
function GetTimerData takes timer t returns integer
static if(USE_HASH_TABLE) then
// new blue
return LoadInteger(ht,0,GetHandleId(t) )
elseif (USE_FLEXIBLE_OFFSET) then
// orange
static if (DEBUG_MODE) then
if(GetHandleId(t)-VOFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-VOFFSET]
else
// new red
static if (DEBUG_MODE) then
if(GetHandleId(t)-OFFSET<0) then
call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
endif
endif
return data[GetHandleId(t)-OFFSET]
endif
endfunction
//==========================================================================================
globals
private timer array tT[ARRAY_SIZE]
private integer tN = 0
private constant integer HELD=0x28829022
//use a totally random number here, the more improbable someone uses it, the better.
private boolean didinit = false
endglobals
private keyword init
//==========================================================================================
// I needed to decide between duplicating code ignoring the "Once and only once" rule
// and using the ugly textmacros. I guess textmacros won.
//
//! textmacro TIMERUTIS_PRIVATE_NewTimerCommon takes VALUE
// On second thought, no.
//! endtextmacro
function NewTimerEx takes integer value returns timer
if (tN==0) then
if (not didinit) then
//This extra if shouldn't represent a major performance drawback
//because QUANTITY rule is not supposed to be broken every day.
call init.evaluate()
set tN = tN - 1
else
//If this happens then the QUANTITY rule has already been broken, try to fix the
// issue, else fail.
debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
set tT[0]=CreateTimer()
static if( not USE_HASH_TABLE) then
debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
static if( USE_FLEXIBLE_OFFSET) then
if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
else
if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
//all right, couldn't fix it
call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
return null
endif
endif
endif
endif
else
set tN=tN-1
endif
call SetTimerData(tT[tN],value)
return tT[tN]
endfunction
function NewTimer takes nothing returns timer
return NewTimerEx(0)
endfunction
//==========================================================================================
function ReleaseTimer takes timer t returns nothing
if(t==null) then
debug call BJDebugMsg("Warning: attempt to release a null timer")
return
endif
if (tN==ARRAY_SIZE) then
debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug
call DestroyTimer(t)
else
call PauseTimer(t)
if(GetTimerData(t)==HELD) then
debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
return
endif
call SetTimerData(t,HELD)
set tT[tN]=t
set tN=tN+1
endif
endfunction
private function init takes nothing returns nothing
local integer i=0
local integer o=-1
local boolean oops = false
if ( didinit ) then
return
else
set didinit = true
endif
static if( USE_HASH_TABLE ) then
set ht = InitHashtable()
loop
exitwhen(i==QUANTITY)
set tT[i]=CreateTimer()
call SetTimerData(tT[i], HELD)
set i=i+1
endloop
set tN = QUANTITY
else
loop
set i=0
loop
exitwhen (i==QUANTITY)
set tT[i] = CreateTimer()
if(i==0) then
set VOFFSET = GetHandleId(tT[i])
static if(USE_FLEXIBLE_OFFSET) then
set o=VOFFSET
else
set o=OFFSET
endif
endif
if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
exitwhen true
endif
if (GetHandleId(tT[i])-o>=0) then
set i=i+1
endif
endloop
set tN = i
exitwhen(tN == QUANTITY)
set oops = true
exitwhen not USE_FLEXIBLE_OFFSET
debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")
endloop
if(oops) then
static if ( USE_FLEXIBLE_OFFSET) then
debug call BJDebugMsg("The problem has been fixed.")
//If this message doesn't appear then there is so much
//handle id fragmentation that it was impossible to preload
//so many timers and the thread crashed! Therefore this
//debug message is useful.
elseif(DEBUG_MODE) then
call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
endif
endif
endif
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ Timer32 ~~ By Jesus4Lyf ~~ Version 1.06 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Timer32?
// - Timer32 implements a fully optimised timer loop for a struct.
// - Instances can be added to the loop, which will call .periodic every
// PERIOD until .stopPeriodic() is called.
//
// =Pros=
// - Efficient.
// - Simple.
//
// =Cons=
// - Only allows one period.
// - The called method must be named ".periodic".
//
// Methods:
// - struct.startPeriodic()
// - struct.stopPeriodic()
//
// - private method periodic takes nothing returns nothing
//
// This must be defined in structs that implement Periodic Module.
// It will be executed by the module every PERIOD until .stopPeriodic() is called.
// Put "implement T32x" BELOW this method.
//
// Modules:
// - T32x
// Has no safety on .stopPeriodic or .startPeriodic (except debug messages
// to warn).
//
// - T32xs
// Has safety on .stopPeriodic and .startPeriodic so if they are called
// multiple times, or while otherwise are already stopped/started respectively,
// no error will occur, the call will be ignored.
//
// - T32
// The original, old version of the T32 module. This remains for backwards
// compatability, and is deprecated. The periodic method must return a boolean,
// false to continue running or true to stop.
//
// Details:
// - Uses one timer.
//
// - Do not, within a .periodic method, follow a .stopPeriodic call with a
// .startPeriodic call.
//
// How to import:
// - Create a trigger named T32.
// - Convert it to custom text and replace the whole trigger text with this.
//
// Thanks:
// - Infinitegde for finding a bug in the debug message that actually altered
// system operation (when in debug mode).
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library T32 initializer OnInit
globals
public constant real PERIOD=0.03125
public constant integer FPS=R2I(1/PERIOD)
public integer Tick=0 // very useful.
//==============================================================================
private trigger Trig=CreateTrigger()
endglobals
//==============================================================================
// The standard T32 module, T32x.
//
module T32x
private thistype next
private thistype prev
private static method PeriodicLoop takes nothing returns boolean
local thistype this=thistype(0).next
loop
exitwhen this==0
call this.periodic()
set this=this.next
endloop
return false
endmethod
method startPeriodic takes nothing returns nothing
debug if this.prev!=0 or thistype(0).next==this then
debug call BJDebugMsg("T32 ERROR: Struct #"+I2S(this)+" had startPeriodic called while already running!")
debug endif
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
endmethod
method stopPeriodic takes nothing returns nothing
debug if this.prev==0 and thistype(0).next!=this then
debug call BJDebugMsg("T32 ERROR: Struct #"+I2S(this)+" had stopPeriodic called while not running!")
debug endif
// This is some real magic.
set this.prev.next=this.next
set this.next.prev=this.prev
// This will even work for the starting element.
debug set this.prev=0
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(Trig,Condition(function thistype.PeriodicLoop))
endmethod
endmodule
//==============================================================================
// The standard T32 module with added safety checks on .startPeriodic() and
// .stopPeriodic(), T32xs.
//
module T32xs
private thistype next
private thistype prev
private boolean runningPeriodic
private static method PeriodicLoop takes nothing returns boolean
local thistype this=thistype(0).next
loop
exitwhen this==0
call this.periodic()
set this=this.next
endloop
return false
endmethod
method startPeriodic takes nothing returns nothing
if not this.runningPeriodic then
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
set this.runningPeriodic=true
endif
endmethod
method stopPeriodic takes nothing returns nothing
if this.runningPeriodic then
// This is some real magic.
set this.prev.next=this.next
set this.next.prev=this.prev
// This will even work for the starting element.
set this.runningPeriodic=false
endif
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(Trig,Condition(function thistype.PeriodicLoop))
endmethod
endmodule
//==============================================================================
// The original T32 module, for backwards compatability only.
//
module T32 // deprecated.
private thistype next
private thistype prev
private static method PeriodicLoop takes nothing returns boolean
local thistype this=thistype(0).next
loop
exitwhen this==0
if this.periodic() then
// This is some real magic.
set this.prev.next=this.next
set this.next.prev=this.prev
// This will even work for the starting element.
debug set this.prev=0
endif
set this=this.next
endloop
return false
endmethod
method startPeriodic takes nothing returns nothing
debug if this.prev!=0 or thistype(0).next==this then
debug call BJDebugMsg("T32 ERROR: Struct #"+I2S(this)+" had startPeriodic called while already running!")
debug endif
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(Trig,Condition(function thistype.PeriodicLoop))
endmethod
endmodule
//==============================================================================
// System Core.
//
private function OnExpire takes nothing returns nothing
set Tick=Tick+1
call TriggerEvaluate(Trig)
endfunction
private function OnInit takes nothing returns nothing
call TimerStart(CreateTimer(),PERIOD,true,function OnExpire)
endfunction
endlibrary
//TESH.scrollpos=27
//TESH.alwaysfold=0
library xebasic
//**************************************************************************
//
// xebasic 0.4
// =======
// XE_DUMMY_UNITID : Rawcode of the dummy unit in your map. It should
// use the dummy.mdx model, so remember to import it as
// well, just use copy&paste to copy the dummy from the
// xe map to yours, then change the rawcode.
//
// XE_HEIGHT_ENABLER: Medivh's raven form ability, you may need to change
// this rawcode to another spell that morphs into a flier
// in case you modified medivh's spell in your map.
//
// XE_TREE_RECOGNITION: The ancients' Eat tree ability, same as with medivh
// raven form, you might have to change it.
//
// XE_ANIMATION_PERIOD: The global period of animation used by whatever
// timer that depends on it, if you put a low value
// the movement will look good but it may hurt your
// performance, if instead you use a high value it
// will not lag but will be fast.
//
// XE_MAX_COLLISION_SIZE: The maximum unit collision size in your map, if
// you got a unit bigger than 197.0 it would be
// a good idea to update this constant, since some
// enums will not find it. Likewise, if none of
// your units can go bellow X and X is much smaller
// than 197.0, it would be a good idea to update
// as well, since it will improve the performance
// those enums.
//
// Notice you probably don't have to update this library, unless I specify
// there are new constants which would be unlikely.
//
//**************************************************************************
//===========================================================================
globals
constant integer XE_DUMMY_UNITID = 'e002'
constant integer XE_HEIGHT_ENABLER = 'Amrf'
constant integer XE_TREE_RECOGNITION = 'Aeat'
constant real XE_ANIMATION_PERIOD = 0.025
constant real XE_MAX_COLLISION_SIZE = 197.0
endglobals
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library xefx initializer init requires xebasic, optional xedummy
//**************************************************
// xefx 0.9
// --------
// Recommended: ARGB (adds ARGBrecolor method)
// For your movable fx needs
//
//**************************************************
//==================================================
globals
private constant integer MAX_INSTANCES = 8190 //change accordingly.
//Delay in order to show the death animation of the effect correctly when xefx is destroyed.
//You may need to increase this if you are using effects with longer death animations.
private constant real MIN_RECYCLE_DELAY = 4.0
//The delay does not need to be exact so we do cleanup in batches instead of individually.
//This determines how often the recycler runs, should be less than MIN_RECYCLE_DELAY.
private constant real RECYCLE_INTERVAL = 0.5
//if this is true and the xedummy library is present, units will be recycled instead of removed.
private constant boolean RECYCLE_DUMMY_UNITS = true
private timer recycler
endglobals
private struct recyclebin
unit u
private recyclebin next=0
private static recyclebin array list
private static integer readindex=1
private static integer writeindex=0
private static integer count=0
static method Recycle takes nothing returns nothing
local recyclebin this = .list[readindex]
loop
exitwhen this==0
static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
call XE_ReleaseDummyUnit(this.u)
else
call RemoveUnit(this.u)
endif
set this.u=null
set .count=.count-1
call this.destroy()
set this=this.next
endloop
set .list[readindex]=0
set .writeindex=.readindex
set .readindex=.readindex+1
if .readindex>R2I(MIN_RECYCLE_DELAY/RECYCLE_INTERVAL+1.0) then
set .readindex=0
endif
if count!=0 then
call TimerStart(recycler, RECYCLE_INTERVAL, false, function recyclebin.Recycle)
endif
endmethod
static method create takes unit u returns recyclebin
local recyclebin this=recyclebin.allocate()
if .count==0 then
call TimerStart(recycler, RECYCLE_INTERVAL, false, function recyclebin.Recycle)
endif
set .count=.count+1
set .u=u
call SetUnitOwner(u,Player(15),false)
set .next=.list[.writeindex]
set .list[.writeindex]=this
return this
endmethod
endstruct
private function init takes nothing returns nothing
set recycler=CreateTimer()
endfunction
struct xefx[MAX_INSTANCES]
public integer tag=0
private unit dummy
private effect fx=null
private real zang=0.0
private integer r=255
private integer g=255
private integer b=255
private integer a=255
private integer abil=0
static method create takes real x, real y, real facing returns xefx
local xefx this=xefx.allocate()
static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
set this.dummy= XE_NewDummyUnit(Player(15), x,y, facing*bj_RADTODEG)
else
set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, facing*bj_RADTODEG)
call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER)
call UnitAddAbility(this.dummy,'Aloc')
call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER)
call SetUnitX(this.dummy,x)
call SetUnitY(this.dummy,y)
endif
return this
endmethod
method operator owner takes nothing returns player
return GetOwningPlayer(this.dummy)
endmethod
method operator owner= takes player p returns nothing
call SetUnitOwner(this.dummy,p,false)
endmethod
method operator teamcolor= takes playercolor c returns nothing
call SetUnitColor(this.dummy,c)
endmethod
method operator scale= takes real value returns nothing
call SetUnitScale(this.dummy,value,value,value)
endmethod
//! textmacro XEFX_colorstuff takes colorname, colorvar
method operator $colorname$ takes nothing returns integer
return this.$colorvar$
endmethod
method operator $colorname$= takes integer value returns nothing
set this.$colorvar$=value
call SetUnitVertexColor(this.dummy,this.r,this.g,this.b,this.a)
endmethod
//! endtextmacro
//! runtextmacro XEFX_colorstuff("red","r")
//! runtextmacro XEFX_colorstuff("green","g")
//! runtextmacro XEFX_colorstuff("blue","b")
//! runtextmacro XEFX_colorstuff("alpha","a")
method recolor takes integer r, integer g , integer b, integer a returns nothing
set this.r=r
set this.g=g
set this.b=b
set this.a=a
call SetUnitVertexColor(this.dummy,this.r,this.g,this.b,this.a)
endmethod
implement optional ARGBrecolor
method operator abilityid takes nothing returns integer
return this.abil
endmethod
method operator abilityid= takes integer a returns nothing
if(this.abil!=0) then
call UnitRemoveAbility(this.dummy,this.abil)
endif
if(a!=0) then
call UnitAddAbility(this.dummy,a)
endif
set this.abil=a
endmethod
method operator abilityLevel takes nothing returns integer
return GetUnitAbilityLevel( this.dummy, this.abil)
endmethod
method operator abilityLevel= takes integer newLevel returns nothing
call SetUnitAbilityLevel(this.dummy, this.abil, newLevel)
endmethod
method flash takes string fx returns nothing
call DestroyEffect(AddSpecialEffectTarget(fx,this.dummy,"origin"))
endmethod
method operator xyangle takes nothing returns real
return GetUnitFacing(this.dummy)*bj_DEGTORAD
endmethod
method operator xyangle= takes real value returns nothing
call SetUnitFacing(this.dummy,value*bj_RADTODEG)
endmethod
method operator zangle takes nothing returns real
return this.zang
endmethod
method operator zangle= takes real value returns nothing
local integer i=R2I(value*bj_RADTODEG+90.5)
set this.zang=value
if(i>=180) then
set i=179
elseif(i<0) then
set i=0
endif
call SetUnitAnimationByIndex(this.dummy, i )
endmethod
method operator x takes nothing returns real
return GetUnitX(this.dummy)
endmethod
method operator y takes nothing returns real
return GetUnitY(this.dummy)
endmethod
method operator z takes nothing returns real
return GetUnitFlyHeight(this.dummy)
endmethod
method operator z= takes real value returns nothing
call SetUnitFlyHeight(this.dummy,value,0)
endmethod
method operator x= takes real value returns nothing
call SetUnitX(this.dummy,value)
endmethod
method operator y= takes real value returns nothing
call SetUnitY(this.dummy,value)
endmethod
method operator fxpath= takes string newpath returns nothing
if (this.fx!=null) then
call DestroyEffect(this.fx)
endif
if (newpath=="") then
set this.fx=null
else
set this.fx=AddSpecialEffectTarget(newpath,this.dummy,"origin")
endif
endmethod
method hiddenReset takes string newfxpath, real newfacing returns nothing
local real x = GetUnitX(this.dummy)
local real y = GetUnitY(this.dummy)
local real z = this.z
local real za = this.zangle
local integer level = this.abilityLevel
set .fxpath=null
static if RECYCLE_DUMMY_UNITS and LIBRARY_xedummy then
if(this.abil!=0) then
call UnitRemoveAbility(this.dummy,this.abil)
endif
call recyclebin.create(this.dummy)
set this.dummy=XE_NewDummyUnit(Player(15), x,y, newfacing*bj_RADTODEG)
else
call RemoveUnit(this.dummy)
set this.dummy= CreateUnit(Player(15), XE_DUMMY_UNITID, x,y, newfacing*bj_RADTODEG)
call UnitAddAbility(this.dummy,XE_HEIGHT_ENABLER)
call UnitAddAbility(this.dummy,'Aloc')
call UnitRemoveAbility(this.dummy,XE_HEIGHT_ENABLER)
call SetUnitX(this.dummy,x)
call SetUnitY(this.dummy,y)
endif
set .fxpath=newfxpath
if(level != 0) then
call UnitAddAbility(this.dummy, this.abil)
call SetUnitAbilityLevel(this.dummy, this.abil, level)
endif
set this.z = z
set zangle = za
endmethod
method destroy takes nothing returns nothing
if(this.abil!=0) then
call UnitRemoveAbility(this.dummy,this.abil)
endif
if(this.fx!=null) then
call DestroyEffect(this.fx)
set this.fx=null
endif
call recyclebin.create(this.dummy)
set this.dummy=null
call this.deallocate()
endmethod
method hiddenDestroy takes nothing returns nothing
call ShowUnit(dummy,false)
call destroy()
endmethod
endstruct
endlibrary