//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
AcidCloudDamage | real | Yes | |
AcidCloudPoint | location | Yes | |
AllPlayers | force | No | |
Anfuehrer | unit | No | |
AO | integer | No | |
AO_Angle | real | Yes | |
AO_AoE | real | Yes | |
AO_Big | boolean | Yes | |
AO_Colision | real | Yes | |
AO_Damage | real | Yes | |
AO_Distance | real | Yes | |
AO_Effect1 | effect | Yes | |
AO_Effect2 | effect | Yes | |
AO_Group | group | Yes | |
AO_Height | real | Yes | |
AO_Hero | unit | Yes | |
AO_MaxDistance | real | Yes | |
AO_Missile | unit | Yes | |
AO_Off | boolean | Yes | |
AO_Parabola | real | Yes | |
AO_Point | location | Yes | |
AO_Scale | real | Yes | |
AO_Skip | integer | No | |
AO_Speed | real | Yes | |
AO_Times | integer | No | |
Asheara | unit | No | |
AT_AOE | real | Yes | |
AT_CasterPoint | location | Yes | |
AT_CastingPoint | location | Yes | |
AT_Damage | real | Yes | |
AT_EffectPoint | location | No | |
AutoPickupCount | integer | No | |
AutoPickupInteger | integervar | Yes | |
AutoPickupItemType | itemcode | Yes | |
AutoPickupRange | rect | No | |
AutoPickupTempLoc | location | No | |
AzmodanGroup | group | No | |
b | boolean | No | |
BallanceLevel | trigger | Yes | |
BarbarianRageDrainTimer | integer | Yes | |
BelialMirror | unit | Yes | |
blood_sfx | string | Yes | |
blood_sfx_counter | integer | No | |
BloodInteger | integer | No | |
BO | integer | No | |
BO_Angle | real | Yes | |
BO_AoE | real | Yes | |
BO_Big | boolean | Yes | |
BO_Colision | real | Yes | |
BO_Damage | real | Yes | |
BO_Distance | real | Yes | |
BO_Group | group | Yes | |
BO_Height | real | Yes | |
BO_Hero | unit | Yes | |
BO_MaxDistance | real | Yes | |
BO_Missile | unit | Yes | |
BO_Off | boolean | Yes | |
BO_Parabola | real | Yes | |
BO_Point | location | Yes | |
BO_Scale | real | No | |
BO_Skip | integer | No | |
BO_Speed | real | Yes | |
BO_Times | integer | No | |
Boss | unit | Yes | |
Boss_HP | real | No | |
BossEffekt | effect | Yes | |
BuergerGerettet | integer | No | |
CameraAngle | real | Yes | |
CameraHeroOn | boolean | Yes | true |
CB_Active | boolean | Yes | |
CB_Angle | real | Yes | |
CB_Caster | unit | Yes | |
CB_CurDistance | real | Yes | |
CB_Damage | real | Yes | |
CB_DamagedUnits | group | Yes | |
CB_Effect | effect | Yes | |
CB_Effect2 | effect | Yes | |
CB_LeakPoint | location | Yes | |
CB_LoopIndex | integer | Yes | |
CB_MaxDistance | real | Yes | |
CB_Speed | real | Yes | |
ComboInteger | integer | Yes | |
CripplingWaveAOE | real | Yes | |
CripplingWaveDamage | real | Yes | |
DaytimeBoolean | boolean | No | |
DeathCam_CurrentHero | integer | Yes | |
DeathLocations | location | Yes | |
Dialogbutton1 | button | Yes | |
DifficultyLevel | integer | No | 1 |
DisableRepick | boolean | Yes | |
Dispatch_Level | real | No | |
DT_Attacktype | attacktype | Yes | |
DT_Damage | real | Yes | |
DT_DamagePerInterval | real | Yes | |
DT_DamageTypes | damagetype | Yes | |
DT_Dealers | unit | Yes | |
DT_Effects | effect | Yes | |
DT_Integers | integer | Yes | |
DT_IntervalReals | real | Yes | |
DT_ReachedDamage | real | Yes | |
DT_ReachedInterval | real | Yes | |
DT_Targets | unit | Yes | |
DTA_Attacktype | attacktype | No | |
DTA_DamageType | damagetype | No | |
DTA_DmgDealer | unit | No | |
DTA_EffectAttachmentPoint | string | No | |
DTA_Interval | real | No | |
DTA_SpecialEffect | string | No | |
DTA_Target | unit | No | |
DTA_Time | real | No | |
DTA_TotalDamageDealt | real | No | |
Dummy_Sichtbarkeit | unit | Yes | |
DummyFeuerregen | unit | No | |
DummyFinalAttack | unit | Yes | |
DummySichtnachTod | unit | Yes | |
Dungeon_Staub | effect | Yes | |
EF_Integer | integervar | No | |
EG_LoopIndex | integervar | Yes | |
ElectrocuteDamage | real | Yes | |
ElectrocuteRuneDamage | real | Yes | |
EnemiesInNear | group | No | |
ET_Active | boolean | Yes | |
ET_Angle | real | Yes | |
ET_AOE | real | Yes | |
ET_Caster | unit | Yes | |
ET_Damage | real | Yes | |
ET_Duration | real | Yes | |
ET_LeakPoint | location | Yes | |
ET_LoopIndex | integer | Yes | |
ET_MaxPullSpeed | real | Yes | |
ET_Speed | real | Yes | |
ET_TempReal | real | Yes | |
ET_Twister | unit | Yes | |
ExInteger | integervar | No | |
Exp_Bonus_On | boolean | Yes | true |
Exp_Integer | integer | Yes | |
Exploding_Palm_Boolean | boolean | Yes | |
ExplodingMongrel | unit | Yes | |
ExplodingPalmChance | integer | Yes | |
ExplodingPalmDamage | real | No | |
FallendeSteine | unit | Yes | |
FallendeSteineHoehe | real | No | |
FallendeSteineHoehe2 | real | No | |
FallendeSteineOn | boolean | No | true |
FallendeSteineZeit | real | No | |
FallenGroup | group | No | |
FallenImpGroup | group | No | |
FB | integervar | No | |
FB_Active | boolean | Yes | |
FB_Angle | real | Yes | |
FB_AOE | real | Yes | |
FB_BurnDuration | real | Yes | |
FB_BurnInterval | real | Yes | |
FB_Caster | unit | Yes | |
FB_CurDistance | real | Yes | |
FB_Damage | real | Yes | |
FB_DamageOverTime | real | Yes | |
FB_Distance | real | Yes | |
FB_Height | real | Yes | |
FB_LeakPoint | location | Yes | |
FB_LoopIndex | integer | Yes | |
FB_Missile | unit | Yes | |
FB_Speed | real | Yes | |
FB_StartZ | real | Yes | |
FFN_Int | integervar | No | |
FinalEffect | effect | Yes | |
FireWall_Left | integervar | No | |
FireWall_Right | integervar | No | |
Fist_Damage | real | Yes | |
Fist_Damage2 | real | Yes | |
FistSFX | effect | Yes | |
FistTarget | unit | Yes | |
Flame_Dps_MUI_Loop | integervar | Yes | |
FoK_Active | boolean | Yes | |
FoK_Angle | real | Yes | |
FoK_AOE | real | Yes | |
FoK_Caster | unit | Yes | |
FoK_Damage | real | Yes | |
FoK_Duration | real | Yes | |
FoK_LeakPoint | location | Yes | |
FoK_LoopIndex | integer | Yes | |
Fragezeichen | effect | Yes | |
FroschTodPunkt | location | No | |
FuriousChargeInteger | integer | Yes | |
Fury_Integer | integer | No | |
GameHandicap | real | No | |
GameVarianteDialog | dialog | No | |
GefangeneBefreit | integer | No | |
GeneralInteger | integer | No | |
GeneralLeakPoint | location | Yes | |
GhostInteger | integer | No | |
GhostTempGroup | group | No | |
GroundStompDamage | real | Yes | |
Heroes | unit | Yes | |
Heroes_History | unit | Yes | |
HeroIsRevivable | boolean | Yes | |
HeroPoint | location | Yes | |
HO_Damage | real | Yes | |
HoActive | boolean | Yes | |
HoCaster | unit | Yes | |
HoCurDuration | real | Yes | |
HoDuration | real | Yes | |
HoLeakPoint | location | Yes | |
HoLoopIndex | integer | Yes | |
HoSpirit | unit | Yes | |
HunterGroup | group | No | |
Hydra_Angle | real | Yes | |
i | integer | No | |
IDS_Item | itemcode | Yes | |
IDS_NumOfItems | integer | No | |
IDS_PercentOfDropping | real | Yes | |
Inventory_Camera | camerasetup | Yes | |
Inventory_Camera_Test | timer | No | |
Inventory_Player_Is_Viewing | boolean | Yes | |
Item_Drops | integer | No | |
JB_Active | boolean | Yes | |
JB_Angle | real | Yes | |
JB_AOE | real | Yes | |
JB_Caster | unit | Yes | |
JB_CurDuration | real | Yes | |
JB_Damage | real | Yes | |
JB_Duration | real | Yes | |
JB_Effect | effect | Yes | |
JB_JumpHeight | real | Yes | |
JB_LandEffect | string | Yes | |
JB_LeakPoint | location | Yes | |
JB_LoopIndex | integer | Yes | |
JB_Speed | real | Yes | |
JB_UseKnockback | boolean | Yes | |
JKS_CDummy | unitcode | No | |
JKS_J_AttachSfxString1 | modelfile | No | |
JKS_J_AttachSfxString2 | modelfile | No | |
Jungfrau | unit | No | |
KS_Active | boolean | Yes | |
KS_Angle | real | No | |
KS_AngleIndex | real | Yes | |
KS_AnglePont | location | Yes | |
KS_DestroyTrees | boolean | No | |
KS_DestroyTreesIndex | boolean | Yes | |
KS_KnockbackUnit | unit | No | |
KS_KnockbackUnitIndex | unit | Yes | |
KS_LeakPoint | location | Yes | |
KS_LoopIndex | integervar | Yes | |
KS_PausedDuringKnockback | boolean | No | |
KS_SfxString | string | No | |
KS_SfxString2 | string | No | |
KS_SfxStringIndex | string | Yes | |
KS_SfxStringIndex2 | string | Yes | |
KS_SfxTimer | integer | Yes | |
KS_SfxTimer2 | integer | Yes | |
KS_Speed | real | No | |
KS_SpeedIndex | real | Yes | |
KS_VectorLeakPoint | location | Yes | |
KultistEffekt | effect | No | |
Landmine | unit | Yes | |
LawineEinheit | unit | Yes | |
LawineHoehe | real | Yes | |
LawineZeit | real | Yes | |
LocationPointBeben | location | No | |
LocationPointBoss | location | No | |
LocationPointCleave | location | Yes | |
LocationPointGrab | location | No | |
LocationPointGrab2 | location | No | |
LocationPointGrab3 | location | No | |
LocationPointTod | location | No | |
LocationPointTodOrb | location | No | |
LocationPointWelt1 | location | No | |
LocationPointWelt2 | location | No | |
LocationPointWelt3 | location | No | |
LocationPointWelt4 | location | No | |
LocationPointWelt5 | location | No | |
LS_Active | boolean | Yes | |
LS_Caster | unit | Yes | |
LS_CoolDown | real | Yes | |
LS_CurTarget | unit | Yes | |
LS_JumpsLeft | integer | Yes | |
LS_LeakPoint | location | Yes | |
LS_Level | integer | Yes | |
LS_LoopIndex | integer | Yes | |
LS_MaxDuration | real | Yes | |
LS_MaxLocusts | integer | No | |
LS_TempGroup | group | No | |
LvlUpSoundOn | boolean | Yes | |
MA_Active | boolean | Yes | |
MA_Angle | real | Yes | |
MA_AOE | real | Yes | |
MA_Caster | unit | Yes | |
MA_Damage | real | Yes | |
MA_Duration | real | Yes | |
MA_LeakPoint | location | Yes | |
MA_LoopIndex | integer | Yes | |
MA_MaxPullSpeed | real | Yes | |
MA_Missile | unit | Yes | |
MA_Speed | real | Yes | |
MA_TempReal | real | Yes | |
MageDrop | boolean | No | |
ManaShieldEffect | effect | Yes | |
MongrelGroup | group | No | |
Mongrels | group | Yes | |
MonkRageDrainTimer | integer | Yes | |
MorluTeleportEffekt | effect | No | |
MS_ModelofDummy | modelfile | No | |
MusicBoolean | boolean | No | |
Nova_Loop | integervar | Yes | |
NumberOfPlayers | integer | No | |
Pendant | item | No | |
Player | force | No | |
PlayerNames | string | Yes | |
PlayerSelectsUnit | boolean | Yes | |
PlayerUnit | unit | Yes | |
PlayerViewing | integer | Yes | |
PN_Int | integervar | No | |
PulseDamage | real | Yes | |
Quest | quest | Yes | |
Random_Item_Drop | integer | No | |
RandomSoundInteger | integer | No | |
rect | location | No | |
RedHeroPoint | location | No | |
Revive | boolean | Yes | |
Revive_Check | integer | No | |
Sample_Group | group | No | |
Sample_Point | location | No | |
Sandstorm | unit | No | |
SB_LeakPoint | location | Yes | |
SB_RandomSize | real | No | |
Schild_on | boolean | Yes | |
SDSE_Dummy1 | unit | Yes | |
SDSE_Dummy2 | unit | Yes | |
SDSE_Dummy3 | unit | Yes | |
SDSE_Dummy4 | unit | Yes | |
SDSE_Dummy5 | unit | Yes | |
SDSE_Dummy6 | unit | Yes | |
SerentyDamage | real | Yes | |
SetBoniInteger | integer | Yes | |
SH_Area | real | No | |
SH_Area_Increasement | real | No | |
SH_Damage | real | No | |
SH_Damage_Increasement | real | No | |
SH_Effect | string | No | |
SH_Group | group | No | |
SH_HealthBoost | real | No | |
SH_HealthBoost_Increasement | real | No | |
SH_loc | location | Yes | |
SH_ManaBoost | real | No | |
SH_ManaBoost_Increasement | real | No | |
SH_TempReal | real | No | |
SH_TempReal2 | real | No | |
ShakeMagnitude | real | No | |
Sieben_Ebenen_Point | location | Yes | |
SiebenEbenen_Gebiet | rect | Yes | |
SiebenEbenenAbbild | unit | Yes | |
SiebenEbenenDamage | real | Yes | |
SiebenEbenenLeuchtenEffekt | effect | Yes | |
SpaltenDamage | real | Yes | |
SpaltenDummy | unit | Yes | |
SpawnInteger | integer | No | |
SpecialItem | itemcode | Yes | |
SS_Active | boolean | Yes | |
SS_Angle | real | Yes | |
SS_Caster | unit | Yes | |
SS_CurSlams | integer | Yes | |
SS_Damage | real | Yes | |
SS_LeakPoint | location | Yes | |
SS_LoopIndex | integer | Yes | |
SS_MaxSlams | integer | Yes | |
SS_Slamer | unit | Yes | |
SS_StartLocation | location | Yes | |
TargetLoc | location | No | |
TempInt | integer | No | |
TempLoc | location | No | |
TempPoint | location | No | |
TempPoint2 | location | No | |
TempPoint3 | location | No | |
TempUnitArray | unit | Yes | |
TempUnitGroup | group | No | |
TimeShieldDuration | integer | Yes | |
TimeShieldGroup | group | No | |
TimeShieldPick | unit | No | |
Tor_MUI_Loop | integervar | Yes | |
TrapDamage | real | Yes | |
TrapLeakPoint | location | Yes | |
TrapUnit | unit | Yes | |
TurnCameraOff | boolean | No | |
TW_Int | integervar | No | |
TW_loop2_int | integervar | No | |
TW_loop_int | integervar | No | |
VA_Active | boolean | Yes | |
VA_Angle | real | Yes | |
VA_Caster | unit | Yes | |
VA_CurDistance | real | Yes | |
VA_Effect | effect | Yes | |
VA_LeakPoint | location | Yes | |
VA_LoopIndex | integer | Yes | |
VA_MaxDistance | real | Yes | |
VA_Speed | real | Yes | |
Vipergruppe | group | No | |
Wanderer | unit | No | |
WaveDamage | real | No | |
Whirlwind_Integer | integer | Yes | |
WitchGroup | group | No | |
WizardGroup | group | No | |
WW_Angle | real | Yes | |
WW_Boolean | boolean | Yes | |
WW_Caster | unit | Yes | |
WW_CountInteger | integer | No | |
WW_CountIntegerArray | integer | No | |
WW_DistanceBetweenPoints | real | Yes | |
WW_Location2 | location | Yes | |
WW_Location3 | location | Yes | |
WW_Location4 | location | Yes | |
WW_Location5 | location | Yes | |
WW_Time | real | Yes | |
WW_UnitCount | integer | Yes | |
WW_UnitGroup | group | No | |
XPHandicap | real | No | |
z | real | No |
//TESH.scrollpos=0
//TESH.alwaysfold=0
function Trig_Setup_Run takes nothing returns nothing
local integer i = 0
local player p = GetEnumPlayer()
loop
exitwhen i > 5
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
call SetPlayerAlliance(Player(i), p, ALLIANCE_SHARED_ADVANCED_CONTROL, true)
call SetPlayerAlliance(p, Player(i), ALLIANCE_SHARED_ADVANCED_CONTROL, true)
endif
set i = i + 1
endloop
endfunction
function Trig_Setup_Actions takes nothing returns nothing
local force f = CreateForce()
call ForceEnumAllies(f, Player(0), null)
call ForForce(f, function Trig_Setup_Run)
call DestroyForce(f)
endfunction
function InitTrig_Setup takes nothing returns nothing
set gg_trg_Setup = CreateTrigger( )
call TriggerAddAction( gg_trg_Setup, function Trig_Setup_Actions )
endfunction
//===========================================================================
//function InitTrig_Setup takes nothing returns nothing
// set gg_trg_Setup = CreateTrigger( )
// call TriggerRegisterDialogEventBJ( gg_trg_Setup, udg_GameVarianteDialog )
// call TriggerAddAction( gg_trg_Setup, function Trig_Setup_Actions )
//endfunction
//TESH.scrollpos=3
//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 = 'e003'
constant integer XE_HEIGHT_ENABLER = 'A009'
constant integer XE_TREE_RECOGNITION = 'A00S'
constant real XE_ANIMATION_PERIOD = 0.025
constant real XE_MAX_COLLISION_SIZE = 197.0
endglobals
endlibrary
//TESH.scrollpos=33
//TESH.alwaysfold=0
library ChargedBolt initializer Init requires xebasic
//---------------------------------------------------
// Spell: Charged Bolt v1.0 (2010-01-24)
//
// Implementation instructions:
// Copy this trigger or paste it in yours
// Copy the xebasic library and read the info there
// Copy the universal dummy unit and use the
// imported dummy model as said in xebasic
// Copy the spell ability to your map
// Alter all constants to fit your needs
// Do not forget the ability rawcode and the dummy
//
// Credits:
// Vexorian - JassHelper, xebasic
// PitzerMike, MindWorX - JNGP
// Blizzard - Tooltip inspired
//
// The spell has been created by Eccho
// Give proper credits when used
//---------------------------------------------------
//---------------------------------------------------
// Native including
// If you have this in your code somewhere else,
// make sure to not double define it
//---------------------------------------------------
native UnitAlive takes unit id returns boolean
//---------------------------------------------------
// Configuration section
//---------------------------------------------------
globals
private constant integer ABILITY_ID = 'A011' //Id of the casting ability
private constant integer ABILITY_MAX_LVL = 1 //Max level of the casting ability. Match these with the level value field of the ability in the ability editor
private constant integer MISSILE_QTY_BASE = 9 //Amount of missile bolts released on level 1
private constant integer MISSILE_QTY_INC = 2 //Amount increased on levels > 1, eg, in this case, lvl 2 gives 3+2*(level-1) bolts
private constant integer MISSILE_QTY_MAX = 50 //Due to a JassHelper bug, set this constant to be at least your qty_base+qty_inc*(max_lvl-1). Note that this should be a fixed integer value.
//Self explanatory, hopefully
private constant string MISSILE_ART = "Abilities\\Spells\\Orc\\LightningBolt\\LightningBoltMissile.mdl"
private constant integer MISSILE_SPEED = 500
private constant integer MISSILE_RANGE = 800
private constant integer MISSILE_HEIGHT = 32
private constant real MISSILE_SCALE = 0.8
private constant real MISSILE_VIB_PER_MIN = 6*bj_PI //The min value factor describing how fast the missile vibrates. (see a formula as y = A*sin(kx) where k is this vibration factor.)
private constant real MISSILE_VIB_PER_MAX = 12*bj_PI //The max value factor describing how fast the missile vibrates.
private constant integer MISSILE_VIB_RADIUS = 32 //The altitude factor of the missile vibration. (see the formula above, where A is this radius factor.)
private constant real MISSILE_QTY_SPREAD = bj_PI/16 //The max radian angle possible between the missiles.
private constant real MISSILE_MAX_SPREAD = bj_PI/4 //The max radian angle spread, in which all missiles are moving in. For instance bj_PI/4 means that all missiles move within the caster_facing+-spread
private constant string IMPACT_ART = "Abilities\\Spells\\Items\\AIlb\\AIlbSpecialArt.mdl"
private constant string IMPACT_ATTACH_POINT = "chest"
private constant integer IMPACT_DAMAGE_BASE = 6 //Amount of damage at level 1
private constant integer IMPACT_DAMAGE_INC = 3 //Amount of damage added per each increased level
private constant integer IMPACT_RADIUS = 32 //See this as the missile collision size. Note that the missile will only collide and deal damage to one unit.
//Self explanatory, hopefully
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_UNIVERSAL
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
endglobals
// Target filter, used to determinate what enemies the spell will hit.
private function TargetFilter takes unit enemy, player caster, real x, real y returns boolean
return UnitAlive(enemy) and IsUnitEnemy(enemy, caster) and IsUnitType(enemy, UNIT_TYPE_GROUND) and IsUnitInRangeXY(enemy, x, y, IMPACT_RADIUS)
endfunction
//---------------------------------------------------
// Main spell code below
// Don't edit unless you know what you are doing
//---------------------------------------------------
globals
//Preserved in case of JassHelper being fixed
//private constant integer MISSILE_QTY_MAX = (MISSILE_QTY_BASE+(MISSILE_QTY_INC*(ABILITY_MAX_LVL-1)))
private constant real MISSILE_TIME_MAX = 1.0*MISSILE_RANGE/MISSILE_SPEED
private constant group ENUM_GROUP = CreateGroup()
private constant timer ANIM_TIMER = CreateTimer()
endglobals
//Missile struct used upon creating then charged missiles
private struct missile
unit mob
effect gfx
real xvel
real yvel
real vvel
static method create takes player sp, real sx, real sy, real ra returns missile
local missile m = missile.allocate()
set m.mob = CreateUnit(sp, XE_DUMMY_UNITID, sx, sy, ra)
set m.gfx = AddSpecialEffectTarget(MISSILE_ART, m.mob, "origin")
call UnitAddAbility(m.mob, XE_HEIGHT_ENABLER)
call UnitRemoveAbility(m.mob, XE_HEIGHT_ENABLER)
call SetUnitAnimationByIndex(m.mob, 90)
call SetUnitFlyHeight(m.mob, MISSILE_HEIGHT, 0)
call SetUnitScale(m.mob, MISSILE_SCALE, MISSILE_SCALE, MISSILE_SCALE)
set m.xvel = MISSILE_SPEED*Cos(ra)
set m.yvel = MISSILE_SPEED*Sin(ra)
set m.vvel = GetRandomReal(MISSILE_VIB_PER_MIN, MISSILE_VIB_PER_MAX)
return m
endmethod
method onDestroy takes nothing returns nothing
call DestroyEffect(.gfx)
call KillUnit(.mob)
set .mob = null
set .gfx = null
endmethod
endstruct
//Main struct used to handle and run spell data
private struct data
player sp
integer slvl
real sx
real sy
real t1
missile array mis[MISSILE_QTY_MAX]
integer mqty
static data array dat
static integer dqty = 0
static method callback takes nothing returns nothing
local data d
local missile m
local integer i = 0
local integer j
local real x
local real y
local unit u
loop
exitwhen i >= data.dqty
set d = data.dat[i]
set d.t1 = d.t1+XE_ANIMATION_PERIOD
set j = 0
loop
exitwhen j >= d.mqty
set m = d.mis[j]
set x = d.sx+m.xvel*d.t1
set y = d.sy+m.yvel*d.t1
call GroupEnumUnitsInRange(ENUM_GROUP, x, y, XE_MAX_COLLISION_SIZE+IMPACT_RADIUS, null)
loop
set u = FirstOfGroup(ENUM_GROUP)
exitwhen u == null
call GroupRemoveUnit(ENUM_GROUP, u)
exitwhen TargetFilter(u, d.sp, x, y)
endloop
call GroupClear(ENUM_GROUP)
// RectContainsCoords is a basic bj inline for GetRectMinX < x... blabla
if d.t1 <= MISSILE_TIME_MAX and RectContainsCoords(bj_mapInitialPlayableArea, x, y) and u == null then
call SetUnitX(m.mob, x+MISSILE_VIB_RADIUS*Sin(m.vvel*d.t1))
call SetUnitY(m.mob, y+MISSILE_VIB_RADIUS*Sin(m.vvel*d.t1))
set j = j+1
else
if u != null then
call UnitDamageTarget(m.mob, u, IMPACT_DAMAGE_BASE+IMPACT_DAMAGE_INC*(d.slvl-1), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
call DestroyEffect(AddSpecialEffectTarget(IMPACT_ART, u, IMPACT_ATTACH_POINT))
endif
call m.destroy()
set d.mqty = d.mqty-1
set d.mis[j] = d.mis[d.mqty]
endif
endloop
if d.mqty == 0 then
call d.destroy()
set data.dqty = data.dqty-1
set data.dat[i] = data.dat[data.dqty]
if data.dqty == 0 then
call PauseTimer(ANIM_TIMER)
endif
else
set i = i+1
endif
endloop
set u = null
endmethod
static method create takes unit su, real nx, real ny returns data
local data d = data.allocate()
local integer i = 0
local real ra
local real spr
local real ramin
set d.sx = GetUnitX(su)
set d.sy = GetUnitY(su)
set ra = Atan2(ny-d.sy, nx-d.sx)
set d.sp = GetOwningPlayer(su)
set d.slvl = GetUnitAbilityLevel(su, ABILITY_ID)
set d.mqty = MISSILE_QTY_BASE+MISSILE_QTY_INC*(d.slvl-1)
set spr = MISSILE_QTY_SPREAD*(d.mqty-1)
if spr > MISSILE_MAX_SPREAD then
set spr = MISSILE_MAX_SPREAD
endif
set ramin = ra-spr/2
set spr = spr/(d.mqty-1)
loop
exitwhen i >= d.mqty
set d.mis[i] = missile.create(d.sp, d.sx, d.sy, ramin+spr*i)
set i = i+1
endloop
set d.t1 = 0
set data.dat[data.dqty] = d
if data.dqty == 0 then
call TimerStart(ANIM_TIMER, XE_ANIMATION_PERIOD, true, function data.callback)
endif
set data.dqty = data.dqty+1
return d
endmethod
endstruct
private function Evaluate takes nothing returns boolean
if GetSpellAbilityId() == ABILITY_ID then
call data.create(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY())
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Filter(function Evaluate))
set t = null
endfunction
endlibrary
//TESH.scrollpos=75
//TESH.alwaysfold=0
//=====================================================================================
// | Health Reserve System |
// | by hell gate and Deaod |
//=====================================================================================
// how to use:
// Cnp this system in your map
// if you don't have BoundSentinel in your map also Cnp it else this system can cause a critical error!
// how to create a new Health Ball:
// call NewHealthBall(X ,Y ,Z ,ModelPath ,Heal ,ManaHeal ,SpeedX ,SpeedY ,SpeedZ ,HealingUnit, Scale)
// real real real string real real real real real unit real
//=====================================================================================
library HealthReserve initializer Init //requires BoundSentinel
globals
private real SpeedIncraise = 10. //
private real MaxSpeed = 500. //the maximum speed of a ball
private constant real RopeLength = 750. //
private constant real RefreshTime = 1./40 //refresh intervall
private constant integer DummyId = 'h01M' //the health reserve dummy
private constant real DistanceNeeded = 100. //how far away the ball have to be to heal
private constant string HealEffect = "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl"
endglobals
private struct HealthBalls
real x
real y
real z
//----- vectors -----
real Heal
real Mana
unit Ball
unit Target
effect Model
private integer i
private static group RecycledDummys=CreateGroup()
private static integer Count =0
private static timer Tim = CreateTimer()
private static integer Total = 0
private static thistype array Balls
private static location LocZ=Location(0,0)
private static method GetUnitZ takes unit u returns real
call MoveLocation(LocZ, GetUnitX(u), GetUnitY(u))
return GetLocationZ(LocZ)+GetUnitFlyHeight(u)
endmethod
private static method SetUnitZ takes unit u, real z returns nothing
call MoveLocation(LocZ, GetUnitX(u), GetUnitY(u))
call SetUnitFlyHeight(u, z-GetLocationZ(LocZ), 0)
endmethod
private method onDestroy takes nothing returns nothing
set Total = Total - 1
set Balls[i] = Balls[Total]
set Balls[i].i=i
if Total==0 then
call PauseTimer(Tim)
endif
endmethod
private static method BallLoop takes nothing returns nothing
local thistype dat
local integer i = Total-1
local real x
local real y
local real z
local real dx // delta x
local real dy // delta y
local real dz // delta z
local real d // absolute distance
loop
exitwhen i < 0
set dat = Balls[i]
if IsUnitType(dat.Target, UNIT_TYPE_DEAD) == false then
set x=GetUnitX(dat.Ball)
set y=GetUnitY(dat.Ball)
set z=GetUnitZ(dat.Ball)
set dx=GetUnitX(dat.Target)-x
set dy=GetUnitY(dat.Target)-y
set dz=GetUnitZ(dat.Target)-z
set d=SquareRoot(dx*dx+dy*dy+dz*dz)
set dat.x=dat.x+dx/d*(SpeedIncraise*RopeLength/d)
set dat.y=dat.y+dy/d*(SpeedIncraise*RopeLength/d)
set dat.z=dat.z+dz/d*(SpeedIncraise*RopeLength/d)
// reuse d
if d <= DistanceNeeded then
call DestroyEffect(dat.Model)
call GroupAddUnit(RecycledDummys,dat.Ball)
set Count=Count+1
call SetWidgetLife(dat.Target,GetWidgetLife(dat.Target)+dat.Heal)
call SetUnitState(dat.Target, UNIT_STATE_MANA, GetUnitState(dat.Target,UNIT_STATE_MANA)+dat.Mana)
call DestroyEffect(AddSpecialEffectTarget(HealEffect,dat.Target,"origin"))
call dat.destroy()
else
set d=SquareRoot(dat.x*dat.x+dat.y*dat.y+dat.z*dat.z)
if d>MaxSpeed then
set dat.x=dat.x/d*MaxSpeed
set dat.y=dat.y/d*MaxSpeed
set dat.z=dat.z/d*MaxSpeed
endif
call SetUnitX(dat.Ball, x+dat.x)
call SetUnitY(dat.Ball, y+dat.y)
call SetUnitZ(dat.Ball, z+dat.z)
endif
else
call RemoveUnit(dat.Ball)
call dat.destroy()
endif
set i = i-1
endloop
endmethod
static method create takes real X, real Y, real Z, string modeleffect, real HP_Add, real Mana_Add, real vX, real vY, real vZ, unit TargetUnit, real Scale returns thistype
local thistype dat = allocate()
set Balls[Total] = dat
if Total==0 then
call TimerStart(Tim,RefreshTime,true,function thistype.BallLoop)
endif
set dat.i=Total
set Total = Total+1
set dat.Heal = HP_Add
set dat.Mana = Mana_Add
set dat.x = vX
set dat.y = vY
set dat.z = vZ
set dat.Target = TargetUnit
if Count == 0 then
set dat.Ball=CreateUnit(Player(15),DummyId,X,Y,0.)
call UnitAddAbility(dat.Ball,'Amrf')
call UnitRemoveAbility(dat.Ball,'Amrf')
call SetUnitPathing(dat.Ball,false)
else
set dat.Ball=FirstOfGroup(RecycledDummys)
call GroupRemoveUnit(RecycledDummys,dat.Ball)
set Count=Count-1
call SetUnitX(dat.Ball,X)
call SetUnitY(dat.Ball,Y)
endif
set dat.Model = AddSpecialEffectTarget(modeleffect,dat.Ball,"chest")
call SetUnitFlyHeight(dat.Ball,Z,0.)
call SetUnitScale(dat.Ball,Scale*0.01,Scale*0.01,Scale*0.01)
return dat
endmethod
endstruct
function NewHealthBall takes real X, real Y, real Z, string modeleffect, real HP_Add, real Mana_Add, real vX, real vY, real vZ, unit TargetUnit, real Scale returns nothing
call HealthBalls.create( X, Y, Z, modeleffect, HP_Add, Mana_Add, vX, vY, vZ, TargetUnit, Scale)
endfunction
private function Init takes nothing returns nothing
set SpeedIncraise = SpeedIncraise*RefreshTime
set MaxSpeed = MaxSpeed*RefreshTime
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library ReserveExample initializer Init
globals
private constant real HPHeal=10.
private constant real MPHeal=10.
private constant string DummyModel="Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl"
private constant real Scale = 50
endglobals
private function Heal takes nothing returns nothing
if GetUnitTypeId(GetAttacker())=='h001' and GetUnitState(GetTriggerUnit(),UNIT_STATE_MAX_MANA)!= GetUnitState(GetTriggerUnit(),UNIT_STATE_MANA) then
call NewHealthBall(GetUnitX(GetAttacker()),GetUnitY(GetAttacker()),0.,DummyModel,0.,MPHeal,0.,0.,150.,GetTriggerUnit(),Scale)
elseif GetUnitTypeId(GetAttacker())=='h002' and GetUnitState(GetTriggerUnit(),UNIT_STATE_MAX_LIFE)!= GetUnitState(GetTriggerUnit(),UNIT_STATE_LIFE) then
call NewHealthBall(GetUnitX(GetAttacker()),GetUnitY(GetAttacker()),0.,DummyModel,HPHeal,0.,0.,0.,150.,GetTriggerUnit(),Scale)
endif
endfunction
private function Init takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddAction(t, function Heal)
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library BoundSentinel initializer init
//*************************************************
//* BoundSentinel
//* -------------
//* Don't leave your units unsupervised, naughty
//* them may try to get out of the map bounds and
//* crash your game.
//*
//* To implement, just get a vJass compiler and
//* copy this library/trigger to your map.
//*
//*************************************************
//==================================================
globals
// High enough so the unit is no longer visible, low enough so the
// game doesn't crash...
//
// I think you need 0.0 or soemthing negative prior to patch 1.22
//
private constant real EXTRA = 500.0
endglobals
//=========================================================================================
globals
private real maxx
private real maxy
private real minx
private real miny
endglobals
//=======================================================================
private function dis takes nothing returns nothing
local unit u=GetTriggerUnit()
local real x=GetUnitX(u)
local real y=GetUnitY(u)
if(x>maxx) then
set x=maxx
elseif(x<minx) then
set x=minx
endif
if(y>maxy) then
set y=maxy
elseif(y<miny) then
set y=miny
endif
call SetUnitX(u,x)
call SetUnitY(u,y)
set u=null
endfunction
private function init takes nothing returns nothing
local trigger t=CreateTrigger()
local region r=CreateRegion()
local rect rc
set minx=GetCameraBoundMinX() - EXTRA
set miny=GetCameraBoundMinY() - EXTRA
set maxx=GetCameraBoundMaxX() + EXTRA
set maxy=GetCameraBoundMaxY() + EXTRA
set rc=Rect(minx,miny,maxx,maxy)
call RegionAddRect(r, rc)
call RemoveRect(rc)
call TriggerRegisterLeaveRegion(t,r, null)
call TriggerAddAction(t, function dis)
//this is not necessary but I'll do it anyway:
set t=null
set r=null
set rc=null
endfunction
endlibrary
//TESH.scrollpos=18
//TESH.alwaysfold=0
library Vector requires Math
struct vector
real x
real y
real z
static constant real accuracy = 1.
static method create takes real x, real y, real z returns vector
local vector v = vector.allocate()
set v.x=x
set v.y=y
set v.z=z
return v
endmethod
method set takes real x, real y, real z returns nothing
set this.x=x
set this.y=y
set this.z=z
endmethod
method getLength takes nothing returns real
return SquareRoot(.x*.x + .y*.y + .z*.z)
endmethod
static method sum takes vector augend, vector addend returns vector
local vector v = vector.allocate()
set v.x = augend.x+addend.x
set v.y = augend.y+addend.y
set v.z = augend.z+addend.z
return v
endmethod
method add takes vector addend returns nothing
set this.x=this.x+addend.x
set this.y=this.y+addend.y
set this.z=this.z+addend.z
endmethod
method addscaled takes vector addend, real scale returns nothing
set this.x=this.x+addend.x*scale
set this.y=this.y+addend.y*scale
set this.z=this.z+addend.z*scale
endmethod
static method difference takes vector minuend, vector subtrahend returns vector
local vector v = vector.allocate()
set v.x = minuend.x-subtrahend.x
set v.y = minuend.y-subtrahend.y
set v.z = minuend.z-subtrahend.z
return v
endmethod
method subtract takes vector subtrahend returns nothing
set this.x=this.x-subtrahend.x
set this.y=this.y-subtrahend.y
set this.z=this.z-subtrahend.z
endmethod
method scale takes real factor returns nothing
set this.x=this.x*factor
set this.y=this.y*factor
set this.z=this.z*factor
endmethod
method setLength takes real length returns nothing
local real l = SquareRoot(.x*.x + .y*.y + .z*.z)
if l == 0.0 then
return
endif
set l = length/l
set this.x = this.x*l
set this.y = this.y*l
set this.z = this.z*l
endmethod
static method dotProduct takes vector a, vector b returns real
return (a.x*b.x+a.y*b.y+a.z*b.z)
endmethod
static method crossProduct takes vector a, vector b returns vector
local vector v = vector.allocate()
set v.x = a.y*b.z - a.z*b.y
set v.y = a.z*b.x - a.x*b.z
set v.z = a.x*b.y - a.y*b.x
return v
endmethod
method ProjToPoint takes real x,real y,real z,real speed,real per,real Zforce returns boolean
local real d
local real des
set speed = speed*per
set Zforce=Zforce*per*per
if Zforce != 0.0 then
set d = SquareRoot(x*x + y*y) + 0.001
set des = speed*speed*speed*speed - Zforce*Zforce*d*d + 2*Zforce*speed*speed*z
if des >= 0.0 then
set des = Atan((-speed*speed-SquareRoot(des))/(Zforce*d))
set this.z = (speed*Sin(des)/per)
set des = speed*Cos(des)/d
set this.x = (des*x/per)
set this.y = (des*y/per)
return true
endif
return false
else
set des = speed/(SquareRoot(x*x + y*y + z*z) + 0.001)
set this.x = x*des/per
set this.y = y*des/per
set this.z = z*des/per
return true
endif
endmethod
// bounce functions
method vecNormalise takes nothing returns nothing
local real length = SquareRoot(this.x*this.x+this.y*this.y+this.z*this.z)
if (length>0) then
set this.x=this.x/length
set this.y=this.y/length
set this.z=this.z/length
else
set this.z=1.
endif
endmethod
static method vecTerrainNormal takes real x, real y returns vector
local vector v=vector.allocate()
local real h1
local real h2
local real h3
local real h4
set h1 = GetLocZ(x-accuracy,y)
set h2 = GetLocZ(x+accuracy,y)
set h3 = GetLocZ(x,y-accuracy)
set h4 = GetLocZ(x,y+accuracy)
set v.x = h1-h2
set v.y = h3-h4
set v.z = 2*accuracy
call v.vecNormalise()
return v
endmethod
method vecBounce takes real x, real y, real b returns nothing
local real scale
local real vecdot
local vector terr = vecTerrainNormal(x,y)
set vecdot = dotProduct(this,terr)
set scale = -(1+b)*vecdot
set this.x = this.x+(terr.x*scale)
set this.y = this.y+(terr.y*scale)
set this.z = this.z+(terr.z*scale)
call terr.destroy()
endmethod
endstruct
endlibrary
//TESH.scrollpos=30
//TESH.alwaysfold=0
library Grenade requires Math
globals
private constant real Tick = 1./30.
private constant real Gravity = -5.
private constant real Speed = 50.
private constant real BounceFactor = 0.5
private string NormalEffect="Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl"
private attacktype Attacktype = ATTACK_TYPE_MELEE
private damagetype Damagetype = DAMAGE_TYPE_DEMOLITION
private constant integer GrenadeUnit = 'h01A'
private constant integer GrenadeSpellID = 'A01V'
endglobals
private struct Grenade
unit Caster
unit Grenade
real Damage
real AOE
real Duration
real Bounce
real Slow //slowmo effect
string Effect
vector position
vector velocity
private static location LocZ = Location(0.,0.)
private integer i
private static timer Tim = CreateTimer()
private static integer Total = 0
private static thistype array Grenades
private static group g = CreateGroup()
private static thistype temp
//============================ settings ==============================
private static method GetDuration takes integer level returns real
return 1.
endmethod
private static method GetDamage takes integer level returns real
return 37.+3.*I2R(level)
endmethod
private static method GetAOE takes integer level returns real
return 130.+3.*I2R(level)
endmethod
private static method GetGrenadeCount takes integer level returns integer
return 2+level
endmethod
//========================== end of settings =========================
private static method onDamage takes nothing returns nothing
if IsUnitEnemy(GetEnumUnit(), GetOwningPlayer(temp.Caster)) then
call UnitDamageTarget(temp.Caster,GetEnumUnit(),temp.Damage,true, false, Attacktype, Damagetype, WEAPON_TYPE_WHOKNOWS)
endif
endmethod
private method onDestroy takes nothing returns nothing
set Total = Total - 1
set Grenades[i] = Grenades[Total]
set Grenades[i].i=i
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
private static method onLoop takes nothing returns nothing
local thistype dat
local integer i2 = 0
loop
exitwhen i2 > Total - 1
set dat = Grenades[i2]
set dat.Duration = dat.Duration-(Tick*dat.Slow)
set dat.velocity.z=dat.velocity.z+(Gravity*dat.Slow)
call dat.position.addscaled(dat.velocity,dat.Slow)
call SetUnitXYZ(dat.Grenade,dat.position.x,dat.position.y,dat.position.z)
if dat.position.z<=GetLocZ(dat.position.x,dat.position.y)+1. then
set dat.position.z=GetLocZ(dat.position.x,dat.position.y)+1.5
call dat.velocity.vecBounce(dat.position.x,dat.position.y,dat.Bounce)
call dat.velocity.scale(0.925)
endif
if dat.Duration <=0. then
set temp = dat
call GroupEnumUnitsInRange(g,dat.position.x,dat.position.y,dat.AOE,null)
call ForGroup(g,function thistype.onDamage)
call GroupClear(g)
call RemoveUnit(dat.Grenade)
call DestroyEffect(AddSpecialEffect(NormalEffect,dat.position.x,dat.position.y))
call DestroyEffect(AddSpecialEffect(dat.Effect,dat.position.x,dat.position.y))
call dat.position.destroy()
call dat.velocity.destroy()
set dat.Caster=null
set dat.Grenade=null
call dat.destroy()
endif
set i2 = i2+1
endloop
endmethod
private static method Check takes nothing returns boolean
local thistype dat
local integer x =0
local real speedleft
local real targetx
local real targety
local integer lvl = GetUnitAbilityLevel(GetTriggerUnit(), GrenadeSpellID)
if GetSpellAbilityId() == GrenadeSpellID then
loop
exitwhen x > GetGrenadeCount(lvl)-1+2*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I023')
set dat = thistype.allocate()
if Total==0 then
call TimerStart(Tim,Tick,true,function thistype.onLoop)
endif
set dat.i=Total
set Grenades[dat.i] = dat
set Total = Total+1
set dat.Caster = GetTriggerUnit()
set dat.AOE = GetAOE(lvl)
set dat.Damage = GetDamage(lvl)//+0*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I023')
set dat.Duration = GetDuration(lvl)
set dat.position = vector.create(GetUnitX(dat.Caster),GetUnitY(dat.Caster),GetUnitZ(dat.Caster)+60.)
set dat.velocity = vector.create(0.,0.,0.)
set targetx = GetSpellTargetX() + GetRandomReal(-75.,75.)
set targety = GetSpellTargetY() + GetRandomReal(-75.,75.)
if dat.velocity.ProjToPoint(targetx-dat.position.x,targety-dat.position.y,GetLocZ(targetx,targety)-dat.position.z,Speed,Tick,Gravity) == false then
set dat.velocity.z = Speed*Sin(45.*bj_DEGTORAD)
set speedleft = Speed*Cos(45.*bj_DEGTORAD)
set dat.velocity.x = speedleft*Cos(Atan2(targety-dat.position.y,targetx-dat.position.x))
set dat.velocity.y = speedleft*Sin(Atan2(targety-dat.position.y,targetx-dat.position.x))
endif
set dat.Slow = 0.7
set dat.Bounce = BounceFactor
if (GetNumberOfItemsFromUnit(GetTriggerUnit(),'I023')>=1) then
set dat.Effect="Objects\\Spawnmodels\\NightElf\\NEDeathSmall\\NEDeathSmall.mdl"
else
set dat.Effect=""
endif
set dat.Grenade = CreateUnit(GetOwningPlayer(dat.Caster),GrenadeUnit,dat.position.x,dat.position.y,0.)
call MakeUnitFly(dat.Grenade)
call SetUnitZ(dat.Grenade,dat.position.z)
set x=x+1
endloop
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.Check))
endmethod
endstruct
endlibrary
//TESH.scrollpos=68
//TESH.alwaysfold=0
library Multishoot requires Math
globals
private constant real Tick = 1./30.
private constant real AngleBetween = 6.
private constant real ShootOffset = 50.
private constant real Speed = 1000.
private attacktype Attacktype = ATTACK_TYPE_PIERCE
private damagetype Damagetype = DAMAGE_TYPE_DEMOLITION
private string DeadEffect = ""
private constant integer ArrowUnit = 'h02I'
private constant integer MultishootSpellID = 'A04B'
endglobals
private struct Arrow
unit Caster
unit Arrow
real Damage
real AOE
real DistanceLeft
string HitEffect
group DamagedUnits = CreateGroup()
vector position
vector velocity
private integer i
private static timer Tim = CreateTimer()
private static integer Total = 0
private static thistype array Arrows
private static group g = CreateGroup()
private static thistype temp
//============================ settings ==============================
private static method GetDistance takes integer level returns real
return 650.+(75.*I2R(level))
endmethod
private static method GetDamage takes integer level returns real
return 17.+(4*I2R(level))
endmethod
private static method GetAOE takes integer level returns real
return 60.
endmethod
private static method GetArrowCount takes integer level returns integer
return 4+(1*level)
endmethod
//========================== end of settings =========================
private static method onDamage takes nothing returns nothing
local vector unitpos = vector.create(GetUnitX(GetEnumUnit()),GetUnitY(GetEnumUnit()),GetUnitZ(GetEnumUnit()))
if IsUnitEnemy(GetEnumUnit(), GetOwningPlayer(temp.Caster)) and Get2DDistance(temp.position,unitpos)<=temp.AOE and not IsUnitInGroup(GetEnumUnit(),temp.DamagedUnits) then
call UnitDamageTarget(temp.Caster,GetEnumUnit(),temp.Damage,true, false, Attacktype, Damagetype, WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffectTarget(temp.HitEffect,GetEnumUnit(),"chest"))
call GroupAddUnit(temp.DamagedUnits,GetEnumUnit())
endif
call unitpos.destroy()
endmethod
private method onDestroy takes nothing returns nothing
set Total = Total - 1
set Arrows[i] = Arrows[Total]
set Arrows[i].i=i
if Total == 0 then
call PauseTimer(Tim)
endif
endmethod
private static method onLoop takes nothing returns nothing
local thistype dat
local integer i2 = 0
loop
exitwhen i2 > Total - 1
set dat = Arrows[i2]
set dat.DistanceLeft = dat.DistanceLeft - (Speed * Tick)
call dat.position.add(dat.velocity)
call SetUnitXYZ(dat.Arrow,dat.position.x,dat.position.y,dat.position.z)
set temp = dat
call GroupEnumUnitsInRange(g,dat.position.x,dat.position.y,dat.AOE,null)
call ForGroup(g,function thistype.onDamage)
call GroupClear(g)
if dat.DistanceLeft <=0. then //or GetLocZ(dat.position.x,dat.position.y)> dat.position.z then
call RemoveUnit(dat.Arrow)
call DestroyEffect(AddSpecialEffect(DeadEffect,dat.position.x,dat.position.y))
call dat.position.destroy()
call dat.velocity.destroy()
call DestroyGroup(dat.DamagedUnits)
set dat.Caster=null
set dat.Arrow=null
call dat.destroy()
endif
set i2 = i2+1
endloop
endmethod
private static method Check takes nothing returns boolean
local thistype dat
local integer x = 0
local integer lvl
local integer counter
local real arrowspread
local real angletotarget
local real ang
local real offsetx
local real offsety
if GetSpellAbilityId() == MultishootSpellID then
call PlaySoundOnUnitBJ( gg_snd_Diablo_3_Hunter_Molten_Arrow, 80.00, GetTriggerUnit() ) // RainOfFireTarget1 ersetzten
set lvl = GetUnitAbilityLevel(GetTriggerUnit(), MultishootSpellID)
set counter = GetArrowCount(lvl)-1+2*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I028') //rune id
set arrowspread = counter*AngleBetween
set angletotarget = Atan2(GetSpellTargetY()-GetUnitY(GetTriggerUnit()),GetSpellTargetX()-GetUnitX(GetTriggerUnit()))*bj_RADTODEG
set ang = angletotarget-(arrowspread/2)
set offsetx = ShootOffset*Cos(angletotarget*bj_DEGTORAD)
set offsety = ShootOffset*Sin(angletotarget*bj_DEGTORAD)
loop
exitwhen x > counter
set dat = thistype.allocate()
if Total==0 then
call TimerStart(Tim,Tick,true,function thistype.onLoop)
endif
set dat.i=Total
set Arrows[dat.i] = dat
set Total = Total+1
set ang = ang + AngleBetween
set dat.Caster = GetTriggerUnit()
set dat.AOE = GetAOE(lvl)
set dat.Damage = GetDamage(lvl)+(1*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I028')) // rune id
set dat.DistanceLeft = GetDistance(lvl)
set dat.position = vector.create(GetUnitX(dat.Caster)+offsetx,GetUnitY(dat.Caster)+offsety,GetUnitZ(dat.Caster)+40.)
set dat.velocity = vector.create(Speed*Tick*Cos(ang*bj_DEGTORAD),Speed*Tick*Sin(ang*bj_DEGTORAD),0.)
if (GetNumberOfItemsFromUnit(GetTriggerUnit(),'I028')>=1) then
set dat.HitEffect="Abilities\\Spells\\Other\\ForkedLightning\\ForkedLightningTarget.mdl"
else
set dat.HitEffect="Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageDeathCaster.mdl"
endif
set dat.Arrow = CreateUnit(GetOwningPlayer(dat.Caster),ArrowUnit,dat.position.x,dat.position.y,ang)
call MakeUnitFly(dat.Arrow)
call SetUnitZ(dat.Arrow,dat.position.z)
set x=x+1
endloop
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function thistype.Check))
endmethod
endstruct
endlibrary
//TESH.scrollpos=70
//TESH.alwaysfold=0
//=====================================================================================
// by hell gate
//=====================================================================================
library Math initializer Init
globals
private location p = Location(0.,0.)
private item i
endglobals
function GetUnitZ takes unit u returns real
call MoveLocation(p,GetUnitX(u),GetUnitY(u))
return GetLocationZ(p)+GetUnitFlyHeight(u)
endfunction
function SetUnitZ takes unit u, real z returns nothing
call MoveLocation(p,GetUnitX(u),GetUnitY(u))
call SetUnitFlyHeight(u,z-GetLocationZ(p),0.)
endfunction
function SetUnitXYZ takes unit u, real x, real y, real z returns nothing
call MoveLocation(p,GetUnitX(u),GetUnitY(u))
call SetUnitFlyHeight(u,z-GetLocationZ(p),0.)
call SetUnitX(u,x)
call SetUnitY(u,y)
endfunction
function GetLocZ takes real x, real y returns real
call MoveLocation(p,x,y)
return GetLocationZ(p)
endfunction
function GetNumberOfItemsFromUnit takes unit u, integer searchitem returns integer
local integer i2 = 0
local integer count=0
loop
exitwhen i2 == 6
if GetItemTypeId(UnitItemInSlot(u,i2)) == searchitem then
set count = count+1
endif
set i2 = i2+1
endloop
return count
endfunction
function Get3DDistance takes vector p1, vector p2 returns real
local real distX = p1.x-p2.x
local real distY = p1.y-p2.y
local real distZ = p1.z-p2.z
return SquareRoot((distX*distX)+(distY*distY)+(distZ*distZ))
endfunction
function Get2DDistance takes vector p1, vector p2 returns real
local real distX = p1.x-p2.x
local real distY = p1.y-p2.y
return SquareRoot((distX*distX)+(distY*distY))
endfunction
function MakeUnitFly takes unit u returns nothing
call UnitAddAbility(u,'Arav')
call UnitRemoveAbility(u,'Arav')
endfunction
function PolarProjectionX takes real x, real angle, real dist returns real
return x+dist*Cos(angle*bj_DEGTORAD)
endfunction
function PolarProjectionY takes real y, real angle, real dist returns real
return y+dist*Sin(angle*bj_DEGTORAD)
endfunction
function CreateEffectAtLocForPlayer takes real x, real y, string file, player p returns effect
local string s
if GetLocalPlayer()==p then
set s=file
endif
return AddSpecialEffect(s,x,y)
endfunction
function CreateEffectOnUnitForPlayer takes widget target, string file, string attach, player p returns effect
local string s
if GetLocalPlayer()==p then
set s=file
endif
return AddSpecialEffectTarget(s,target,attach)
endfunction
function IsLocPathable takes real x, real y returns boolean
local real tx = x
local real ty = y
call SetItemVisible(i,true)
call SetItemPosition(i,x,y)
set tx = GetItemX(i) - tx
set ty = GetItemY(i) - ty
call SetItemVisible(i,false)
return (tx < 1. and tx > -1. and ty < 1. and ty > -1.)
endfunction
private function Init takes nothing returns nothing
set i = CreateItem('kysn',0,0)
call SetItemVisible(i,false)
endfunction
endlibrary