//TESH.scrollpos=0
//TESH.alwaysfold=0
Name | Type | is_array | initial_value |
AcidCloudDamage | real | Yes | |
AcidCloudPoint | location | Yes | |
Active | boolean | Yes | |
AllPlayers | force | No | |
Angle | real | No | |
AngleIndex | real | Yes | |
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 | |
AS_Active | boolean | Yes | |
AS_Angle | real | Yes | |
AS_Caster | unit | Yes | |
AS_ChainDistance | real | No | 50.00 |
AS_Chains | group | Yes | |
AS_Damage | real | Yes | |
AS_Distance | real | Yes | |
AS_LeakPoint | location | Yes | |
AS_LoopIndex | integer | Yes | |
AS_Missile | unit | Yes | |
AS_Speed | real | Yes | |
AS_Target | unit | Yes | |
AS_TempGroup | group | No | |
AS_TempInt | integer | Yes | |
AutoPickupCount | integer | No | |
AutoPickupInteger | integer | Yes | |
AutoPickupItemType | itemcode | Yes | |
AutoPickupRange | rect | No | |
AutoPickupTempLoc | location | No | |
b | boolean | No | |
BallanceLevel | trigger | Yes | |
BarbarianRageDrainTimer | integer | Yes | |
BarbarianRageRegenerationBonus | real | Yes | 1.00 |
blood_sfx | string | Yes | |
blood_sfx_counter | integer | No | |
BlueHeroesDead | integer | No | |
BlueTeam | group | No | |
BlueTeamPoints | integer | No | |
BO_Active | boolean | Yes | |
BO_Angle | real | Yes | |
BO_AOE | real | Yes | |
BO_Caster | unit | Yes | |
BO_Damage | real | Yes | |
BO_Duration | real | Yes | |
BO_LeakPoint | location | Yes | |
BO_LoopIndex | integer | Yes | |
BO_MaxPullSpeed | real | Yes | |
BO_Missile | unit | Yes | |
BO_Speed | real | Yes | |
BolaTarget | unit | Yes | |
BS | integervar | No | |
CameraAngle | real | Yes | |
CastingPoint | location | No | |
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 | |
CleaveRuneEffectBoolean | boolean | Yes | |
ComboInteger | integer | Yes | |
CripplingWaveAOE | real | Yes | |
CripplingWaveDamage | real | Yes | |
CurDistance | real | Yes | |
Damage_ConvertedDamage | string | No | |
DaytimeBoolean | boolean | No | |
DemonAttackPoint | location | No | |
Dialogbutton1 | button | Yes | |
Distance | 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 | |
EF_Integer | integervar | No | |
EG_Active | boolean | Yes | |
EG_Angle | real | Yes | |
EG_Caster | unit | Yes | |
EG_Damage | real | Yes | |
EG_Duration | real | Yes | |
EG_LeakPoint | location | Yes | |
EG_LoopIndex | integer | Yes | |
EG_Missile | unit | Yes | |
EG_RuneBonus | integer | Yes | |
ElectrocuteDamage | real | Yes | |
EnemiesInNear | group | No | |
ES_Active | boolean | Yes | |
ES_Angle | real | Yes | |
ES_AOE | real | Yes | |
ES_Caster | unit | Yes | |
ES_Damage | real | Yes | |
ES_Duration | real | Yes | |
ES_LeakPoint | location | Yes | |
ES_LoopIndex | integer | Yes | |
ES_MaxPullSpeed | real | Yes | |
ES_Missile | unit | Yes | |
ES_Speed | real | Yes | |
ES_TempReal | real | Yes | |
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 | |
Exploding_Palm_Boolean | boolean | Yes | |
ExplodingMongrel | unit | Yes | |
ExplodingPalmChance | integer | Yes | |
ExplodingPalmDamage | real | No | |
FA_LeakPoint | location | Yes | |
FB | integer | 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_Point | location | Yes | |
FB_Speed | real | Yes | |
FB_StartZ | real | Yes | |
FFN_Int | integervar | No | |
FireWall_Left | integervar | No | |
FireWall_Right | integervar | No | |
Fist_Damage | real | Yes | |
Fist_Damage2 | real | Yes | |
FistSFX | effect | Yes | |
FistsOn | boolean | No | true |
FistTarget | unit | Yes | |
Flame_Dps_MUI_Loop | integervar | Yes | |
FlySFX | modelfile | No | |
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 | |
FroschTodPunkt | location | No | |
FrostNovaDamage | real | Yes | |
FuriousChargeInteger | integer | Yes | |
GameVariante | integer | No | |
GameVarianteDialog | dialog | No | |
GoldBonus | integer | No | |
GroundStompDamage | real | Yes | |
HandOfLightningAOE | real | Yes | |
HandsOfLightningDamage | real | Yes | |
HealthOrb | item | Yes | |
Heroes | unit | Yes | |
Heroes_History | unit | Yes | |
HeroItemPoint | location | Yes | |
HeroPoint | location | Yes | |
HeroRunePoint | location | Yes | |
HeroSkillPoint | location | Yes | |
HeroStartPoint | location | Yes | |
HeroTraitPoint | 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 | |
HydraUnitType | unitcode | Yes | |
ImpactSFX | string | No | |
ImpactSFXIndex | string | Yes | |
Inventory_Camera | camerasetup | Yes | |
Inventory_Camera_Test | timer | No | |
Inventory_Player_Is_Viewing | boolean | Yes | |
ItemBuilding | unit | Yes | |
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 | |
Jumper | unit | No | |
JumperIndex | unit | Yes | |
JumpSFX | effect | Yes | |
JumpTimed | boolean | No | |
KillPoints | integer | Yes | |
KillsLeaderboard | leaderboard | Yes | |
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 | |
Landmine | unit | Yes | |
LocationPointCleave | location | Yes | |
LocationPointWelt1 | location | No | |
LocationPointWelt2 | location | No | |
LocationPointWelt3 | location | No | |
LocationPointWelt5 | location | No | |
LoopIndex | integer | Yes | |
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 | |
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 | |
ManaShieldEffect | effect | Yes | |
MaxDistance | real | Yes | |
MeteorDamage | real | Yes | |
MeteorLeakPoint | location | Yes | |
MeteorPoint | location | Yes | |
MongrelGroup | group | No | |
Mongrels | group | Yes | |
MonkRageDrainTimer | integer | Yes | |
MS_ModelofDummy | modelfile | No | |
NextRoundTimer | timer | No | |
NextRoundTimerWindow | timerdialog | No | |
Nova_Loop | integervar | Yes | |
NumberOfPlayers | integer | No | |
NumberOfPlayersTeamBlue | integer | No | |
NumberOfPlayersTeamRed | integer | No | |
NumberRounds | integer | No | |
OrbDropPoint | location | Yes | |
ParabolaHeight | real | No | |
ParabolaHeightIndex | real | Yes | |
Player | force | No | |
PlayerNames | string | Yes | |
PlayerSelectsUnit | boolean | Yes | |
PlayerUnit | unit | Yes | |
PlayerViewing | integer | Yes | |
PN_Int | integervar | No | |
rect | location | No | |
RedHeroesDead | integer | No | |
RedHeroPoint | location | No | |
RedTeam | group | No | |
RedTeamPoints | integer | No | |
Round | integer | No | 1 |
RoundEndTimer | timer | No | |
RoundEndTimerWindow | timerdialog | No | |
RuneBuilding | unit | Yes | |
SacrificeDamage | real | Yes | |
Sample_Group | group | No | |
Sample_Point | location | 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 | |
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 | |
SkillBuilding | unit | Yes | |
SpaltenDamage | real | Yes | |
SpaltenDummy | unit | Yes | |
SpectralBladesDamage | real | Yes | |
SpectralBladesRuneBonus | integer | Yes | |
SpeedIndex | real | Yes | |
SpeedOrTime | real | No | |
SpiritWalkDamage | real | Yes | |
SpiritWalkDuration | real | Yes | |
SpiritWalkOn | boolean | Yes | |
SS_Active | boolean | Yes | |
SS_Angle | real | 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 | |
StartCliffHeight | real | Yes | |
TargetPoint | location | No | |
TargetPointIndex | location | Yes | |
TechPoint | location | Yes | |
TeleportDamage | real | Yes | |
TempPoint | location | Yes | |
TempPoint1 | location | No | |
TempPoint3 | location | No | |
TempReal | real | Yes | |
TempReal2 | real | No | |
TempUnitArray | unit | Yes | |
TempUnitGroup | group | No | |
TimeShieldDuration | integer | Yes | |
TimeShieldGroup | group | No | |
ToadDamage | real | Yes | |
Tor_MUI_Loop | integervar | Yes | |
TraitBuilding | unit | Yes | |
TraitDamageBonusBarbarian | real | Yes | 1.00 |
TraitDamageBonusWizard | real | Yes | 1.00 |
TraitSpiritRegenerationBonus | real | 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_Damage | real | Yes | |
VA_DamagedUnits | group | Yes | |
VA_Effect | effect | Yes | |
VA_LeakPoint | location | Yes | |
VA_LoopIndex | integer | Yes | |
VA_MaxDistance | real | Yes | |
VA_Speed | real | Yes | |
Warden | unit | Yes | |
WardenUnitType | unitcode | Yes | |
WaveDamage | real | No | |
Whirlwind_Integer | integer | Yes | |
WitchDoctorBody | unit | Yes | |
WitchGroup | group | No | |
WizardGroup | group | No | |
WoL_Active | boolean | Yes | |
WoL_Angle | real | Yes | |
WoL_AOE | real | Yes | |
WoL_Caster | unit | Yes | |
WoL_Damage | real | Yes | |
WoL_Duration | real | Yes | |
WoL_LeakPoint | location | Yes | |
WoL_LoopIndex | integer | Yes | |
WoL_MaxPullSpeed | real | Yes | |
WoL_Missile | unit | Yes | |
WoL_Speed | real | Yes | |
WoL_TempReal | real | Yes | |
WT_Active | boolean | Yes | |
WT_Angle | real | Yes | |
WT_AOE | real | Yes | |
WT_Caster | unit | Yes | |
WT_CurDistance | real | Yes | |
WT_Damage | real | Yes | |
WT_Distance | real | Yes | |
WT_Height | real | Yes | |
WT_LeakPoint | location | Yes | |
WT_LoopIndex | integer | Yes | |
WT_Missile | unit | Yes | |
WT_Speed | real | Yes | |
WT_StartZ | real | Yes | |
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
//TESH.scrollpos=0
//TESH.alwaysfold=0
library PoisonDart requires Math
globals
private constant real Tick = 1./30.
private constant real Speed = 900.
private constant real DotInterval=0.1
private attacktype Attacktype = ATTACK_TYPE_PIERCE
private damagetype Damagetype = DAMAGE_TYPE_DEMOLITION
private string DeadEffect = ""
private constant integer DartUnit = 'h00G'
private constant integer PoisionDartSpellID = 'A038'
endglobals
struct Dart
unit Caster
unit Dart
real Damage
real DistanceLeft
real DotDamage
real DotDuration
string DotEffect
vector position
vector velocity
private integer di
private static timer dTim = CreateTimer()
private static integer dTotal = 0
private static thistype array dDarts
private static group g = CreateGroup()
private static thistype temp
private static boolean hit = false
private method onDestroy takes nothing returns nothing
set dTotal = dTotal - 1
set dDarts[di] = dDarts[dTotal]
set dDarts[di].di=di
if dTotal == 0 then
call PauseTimer(dTim)
endif
endmethod
private static method DamageUnits takes nothing returns nothing
if IsUnitEnemy(GetEnumUnit(), GetOwningPlayer(temp.Caster)) and not hit then
call UnitDamageTarget(temp.Caster,GetEnumUnit(),temp.Damage,true, false, Attacktype, Damagetype, WEAPON_TYPE_WHOKNOWS)
set udg_DTA_Target = GetEnumUnit()
set udg_DTA_DmgDealer = temp.Caster
set udg_DTA_TotalDamageDealt = temp.DotDamage
set udg_DTA_Time = temp.DotDuration
set udg_DTA_Interval = DotInterval
set udg_DTA_SpecialEffect = temp.DotEffect
set udg_DTA_EffectAttachmentPoint = "origin"
set udg_DTA_Attacktype = Attacktype
set udg_DTA_DamageType = Damagetype
call TriggerExecute( gg_trg_Get_DOT )
set hit=true
endif
endmethod
private static method onLoop takes nothing returns nothing
local thistype dat
local integer i2 = 0
loop
exitwhen i2 > dTotal - 1
set dat = dDarts[i2]
set dat.DistanceLeft = dat.DistanceLeft - (Speed * Tick)
call dat.position.add(dat.velocity)
call SetUnitXYZ(dat.Dart,dat.position.x,dat.position.y,dat.position.z)
set temp=dat
call GroupEnumUnitsInRange(g,dat.position.x,dat.position.y,40.,null)
call ForGroup(g,function thistype.DamageUnits)
call GroupClear(g)
if (dat.DistanceLeft <=0. or GetLocZ(dat.position.x,dat.position.y)> dat.position.z or hit) then
call RemoveUnit(dat.Dart)
call DestroyEffect(AddSpecialEffect(DeadEffect,dat.position.x,dat.position.y))
call dat.position.destroy()
call dat.velocity.destroy()
set dat.Caster=null
set dat.Dart=null
call dat.destroy()
set hit=false
endif
set i2 = i2+1
endloop
endmethod
static method NewDart takes unit caster, vector target ,real damage, real distance, real dot, real dotdur, string doteffect, real scale returns nothing
local thistype dat
local vector dir
set dat = thistype.allocate()
if dTotal==0 then
call TimerStart(dTim,Tick,true,function thistype.onLoop)
endif
set dat.di=dTotal
set dDarts[dat.di] = dat
set dTotal = dTotal+1
set dat.Caster = caster
set dat.Damage = damage
set dat.DistanceLeft = distance
set dat.DotDamage=dot
set dat.DotDuration=dotdur
set dat.DotEffect=doteffect
set dat.position = vector.create(GetUnitX(dat.Caster),GetUnitY(dat.Caster),GetUnitZ(dat.Caster)+40.)
set dir=vector.difference(target,dat.position)
call dir.vecNormalise()
set dat.velocity = vector.create(Speed*Tick*dir.x,Speed*Tick*dir.y,Speed*Tick*dir.z)
set dat.Dart = CreateUnit(GetOwningPlayer(dat.Caster),DartUnit,dat.position.x,dat.position.y,Atan(dat.velocity.y/dat.velocity.x)*bj_RADTODEG)
call MakeUnitFly(dat.Dart)
call SetUnitZ(dat.Dart,dat.position.z)
call SetUnitScale(dat.Dart,scale,scale,scale)
endmethod
endstruct
private struct PoisionDart
unit Caster
integer DartsLeft
integer SpellLevel
real ShootDelay
real DartDamage
real ShootDistance
real OverTimeDamage
real OverTimeDamageDuration
string OverTimeDamageEffect
real Scale
vector target
timer tim
//============================ settings ==============================
private static method GetDistance takes integer level returns real
return 900.
endmethod
private static method GetDamage takes integer level returns real
return ( I2R(GetHeroStatBJ(bj_HEROSTAT_INT, GetTriggerUnit(), true)) * 0.4 )+ ( I2R(GetHeroStatBJ(bj_HEROSTAT_INT, GetTriggerUnit(), true)) * 0.05 )*I2R(level)
endmethod
private static method GetDartCount takes integer level returns integer
return 4+(1*level)
endmethod
private static method GetShootDelay takes integer level returns real
return 0.1
endmethod
private static method GetDamageOverTime takes integer level returns real
return 7.+(3.*level)
endmethod
private static method GetDamageOverTimeDuration takes integer level returns real
return 5.
endmethod
//========================== end of settings =========================
private static method onEnd takes nothing returns nothing
local timer t = GetExpiredTimer()
local timer t2
local thistype dat = PoisionDart(GetTimerData(t))
if (dat.DartsLeft >0) then
set dat.DartsLeft=dat.DartsLeft-1
call Dart.NewDart(dat.Caster,dat.target,dat.DartDamage,dat.ShootDistance,dat.OverTimeDamage,dat.OverTimeDamageDuration,dat.OverTimeDamageEffect,dat.Scale)
call StartSound(gg_snd_RainOfFireTarget2) // RainOfFireTarget1 ersetzen
set t = NewTimer()
call SetTimerData(t, dat)
call TimerStart(t, dat.ShootDelay, false, function thistype.onEnd)
else
set dat.Caster=null
call dat.target.destroy()
call dat.destroy()
endif
endmethod
private static method Check takes nothing returns boolean
local thistype dat
local timer t
if GetSpellAbilityId() == PoisionDartSpellID then
call StartSound(gg_snd_RainOfFireTarget2) // RainOfFireTarget1 ersetzen
set dat = thistype.allocate()
set dat.SpellLevel = GetUnitAbilityLevel(GetTriggerUnit(), PoisionDartSpellID)
set dat.DartsLeft = GetDartCount(dat.SpellLevel)-1+2*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I020') //rune id
set t = NewTimer()
call SetTimerData(t, dat)
set dat.ShootDelay=GetShootDelay(dat.SpellLevel)//-(0.02*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I000')) // rune id
set dat.Caster = GetTriggerUnit()
set dat.DartDamage = GetDamage(dat.SpellLevel)+(1*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I020')) // rune id
set dat.ShootDistance = GetDistance(dat.SpellLevel)+(100*GetNumberOfItemsFromUnit(GetTriggerUnit(),'I020')) // rune id
set dat.target = vector.create(GetSpellTargetX(),GetSpellTargetY(),GetLocZ(GetSpellTargetX(),GetSpellTargetY())+40.)
set dat.OverTimeDamage = GetDamageOverTime(dat.SpellLevel)
set dat.OverTimeDamageDuration = GetDamageOverTimeDuration(dat.SpellLevel)
set dat.OverTimeDamageEffect="Abilities\\Weapons\\PoisonSting\\PoisonStingTarget.mdl" //DoT effect
if GetNumberOfItemsFromUnit(GetTriggerUnit(),'I020') > 0 then //rune id
set dat.Scale=3.
else
set dat.Scale=1.
endif
call TimerStart(t, dat.ShootDelay, false, function thistype.onEnd)
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=56
//TESH.alwaysfold=0
library TimerUtils initializer init
//*********************************************************************
//* TimerUtils (red+blue+orange flavors for 1.24b+)
//* ----------
//*
//* 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)
//* 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.
endglobals
//==========================================================================================
function NewTimer takes nothing returns timer
if (tN==0) then
//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")
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")
set tT[0]=CreateTimer()
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
else
set tN=tN-1
endif
call SetTimerData(tT[tN],0)
return tT[tN]
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
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=45
//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 = 'h01C' //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=42
//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=0
//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=0
//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 = 'h004'
private constant integer GrenadeSpellID = 'A00N'
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 ( I2R(GetHeroStatBJ(bj_HEROSTAT_AGI, GetTriggerUnit(), true)) * 0.64 )+ ( I2R(GetHeroStatBJ(bj_HEROSTAT_AGI, GetTriggerUnit(), true)) * 0.02 )*I2R(level)
endmethod
private static method GetAOE takes integer level returns real
return 130.+5.*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(),'I02P')
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(),'I02P')
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(),'I02P')>=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=0
//TESH.alwaysfold=0
library Multishot 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 = 'h02A'
private constant integer MultishootSpellID = 'A01U'
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.+(50.*I2R(level))
endmethod
private static method GetDamage takes integer level returns real
return ( I2R(GetHeroStatBJ(bj_HEROSTAT_AGI, GetTriggerUnit(), true)) * 0.4 )+ ( I2R(GetHeroStatBJ(bj_HEROSTAT_AGI, GetTriggerUnit(), true)) * 0.05 )*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 3+(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. 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(),'I03F') //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(),'I03F')) // 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(),'I03F')>=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=27
//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