DC_FIFTEEN_PACKET_FOCUS=true; DC_FIFTEEN_ORIGIN=Vector(-4500,0,256); DC_FIFTEEN_RUN_ID='native15_packets_20261030' -- Dedicated local-only observations. Never install/run in an ordinary match. -- Built for Valve7.41f source capture; runtime build/revision must be observed separately. local ORIGIN=DC_FIFTEEN_ORIGIN or Vector(-4500,0,256) local HEROES={'juggernaut','ursa','slardar','drow_ranger','life_stealer'} local INNATE={lina_slow_burn=true,sven_wrath_of_god=true,juggernaut_bladeform=true,ursa_maul=true,slardar_seaborn_sentinel=true,drow_ranger_trueshot=true,life_stealer_ghoul_frenzy=true} local function json(v) local t=type(v) if t=='number' then if v~=v or math.abs(v)==math.huge then return 'null' end;return tostring(v) elseif t=='boolean' then return tostring(v) elseif t=='string' then return '"'..v:gsub('\\','\\\\'):gsub('"','\\"'):gsub('\n','\\n'):gsub('\r','\\r')..'"' elseif t=='table' then local out={};for k,x in pairs(v) do out[#out+1]=json(tostring(k))..':'..json(x) end;return '{'..table.concat(out,',')..'}' end return 'null' end local function read(u,k,...) local args={...};local n=select('#',...);local ok,v=pcall(function() return u[k](u,unpack(args,1,n)) end) if ok and (type(v)=='number' or type(v)=='boolean' or type(v)=='string') then return v end;return nil end local function send(v) v.runId=DC_FIFTEEN_RUN_ID local r=CreateHTTPRequestScriptVM('POST','http://127.0.0.1:5214/fifteen-native') r:SetHTTPRequestRawPostBody('application/json',json(v));r:Send(function(reply) print('DC_FIFTEEN '..(v.id or v.kind)..' HTTP '..tostring(reply.StatusCode)) end) end local function mods(u) local out={};for _,m in ipairs(u:FindAllModifiers()) do local n=m:GetName() out[n]={stacks=m:GetStackCount(),remaining=m:GetRemainingTime(),duration=m:GetDuration()} end;return out end local function abilities(u) local out={};for i=0,31 do local a=u:GetAbilityByIndex(i);if a and not a:GetAbilityName():find('special_bonus_') then local n=a:GetAbilityName() out[n]={level=a:GetLevel(),innate=INNATE[n]==true,castPoint=read(a,'GetCastPoint'),channelTime=read(a,'GetChannelTime'),mana=read(a,'GetManaCost',math.max(0,a:GetLevel()-1)),cooldown=read(a,'GetCooldown',math.max(0,a:GetLevel()-1)),autoCast=read(a,'GetAutoCastState'),hidden=a:IsHidden()} end end;return out end local function requireCleanEnvironment(u) for _,m in ipairs(u:FindAllModifiers()) do local n=m:GetName() if n:find('tower') or n:find('fountain') or n:find('path_movespeed') or n:find('healing_ward') or n:find('puddle') or n:find('river') or n:find('truesight') then error('external_environment_modifier') end end end local function talentLevels(u) local out={};for i=0,31 do local a=u:GetAbilityByIndex(i);if a and a:GetAbilityName():find('^special_bonus_') and a:GetAbilityName()~='special_bonus_attributes' then out[a:GetAbilityName()]=a:GetLevel() end end;return out end local function stats(u,target) return {level=u:GetLevel(),strength=u:GetStrength(),agility=u:GetAgility(),intelligence=u:GetIntellect(false),maxHp=u:GetMaxHealth(),hp=u:GetHealth(),maxMana=u:GetMaxMana(),mana=u:GetMana(),damage=u:GetAverageTrueAttackDamage(target),baseDamageMin=u:GetBaseDamageMin(),baseDamageMax=u:GetBaseDamageMax(),armor=u:GetPhysicalArmorValue(false),baseArmor=read(u,'GetPhysicalArmorBaseValue'),baseHealthRegen=read(u,'GetBaseHealthRegen'),baseMoveSpeed=u:GetBaseMoveSpeed(),magicResistance=u:Script_GetMagicalArmorValue(nil)*100,attackInterval=u:GetSecondsPerAttack(false),attackPoint=u:GetAttackAnimationPoint(),attackRange=u:Script_GetAttackRange(),moveSpeed=u:GetMoveSpeedModifier(u:GetBaseMoveSpeed(),false),healthRegen=u:GetHealthRegen(),manaRegen=u:GetManaRegen(),statusResistance=read(u,'GetStatusResistance')} end local function maulSnapshot(a,b) local maul=a:FindAbilityByName('ursa_maul');local talent=a:FindAbilityByName('special_bonus_unique_ursa_maul_health') return {special=read(maul,'GetSpecialValueFor','health_as_damage_pct'),levelSpecial=read(maul,'GetLevelSpecialValueFor','health_as_damage_pct',0),talentValue=read(talent,'GetSpecialValueFor','value'),maulLevel=maul:GetLevel(),talentLevel=talent:GetLevel(),hp=a:GetHealth(),maxHp=a:GetMaxHealth(),damageTarget=a:GetAverageTrueAttackDamage(b),damageNil=read(a,'GetAverageTrueAttackDamage',nil),baseDamageMin=a:GetBaseDamageMin(),baseDamageMax=a:GetBaseDamageMax()} end local function make(hero,level,pos,team) local u=CreateUnitByName('npc_dota_hero_'..hero,pos,true,nil,nil,team) for i=2,level do u:HeroLevelUp(false) end for i=0,31 do local a=u:GetAbilityByIndex(i);if a and not INNATE[a:GetAbilityName()] then a:SetLevel(0) end end local attr=u:FindAbilityByName('special_bonus_attributes');if attr then attr:SetLevel(0);u:RemoveModifierByName('modifier_special_bonus_attributes') end u:SetIdleAcquire(false);u:SetAcquisitionRange(0);u:CalculateStatBonus(true);return u end local function equip(u,c) for _,k in ipairs(c.items or {}) do u:AddItemByName('item_'..k) end for k,n in pairs(c.skills or {}) do local a=u:FindAbilityByName(k);if not a then error('missing_prerequisite') end;a:SetLevel(n) end if c.ability then local a=u:FindAbilityByName(c.ability);if not a then error('missing_ability') end;a:SetLevel(c.rank or 4) end u:CalculateStatBonus(true) end local function ward(a) for _,u in ipairs(FindUnitsInRadius(a:GetTeamNumber(),ORIGIN,nil,2000,DOTA_UNIT_TARGET_TEAM_FRIENDLY,DOTA_UNIT_TARGET_ALL,DOTA_UNIT_TARGET_FLAG_INVULNERABLE+DOTA_UNIT_TARGET_FLAG_OUT_OF_WORLD,FIND_ANY_ORDER,false)) do if u:GetUnitName()=='npc_dota_juggernaut_healing_ward' then return u end end return nil end local function cleanWorld() local summary={unitsRemoved=0,thinkersRemoved=0,thinkerApiAvailable=false} for _,u in ipairs(FindUnitsInRadius(DOTA_TEAM_GOODGUYS,ORIGIN,nil,4000,DOTA_UNIT_TARGET_TEAM_BOTH,DOTA_UNIT_TARGET_ALL,DOTA_UNIT_TARGET_FLAG_INVULNERABLE+DOTA_UNIT_TARGET_FLAG_OUT_OF_WORLD,FIND_ANY_ORDER,false)) do if not u:IsHero() and not u:IsBuilding() then UTIL_Remove(u);summary.unitsRemoved=summary.unitsRemoved+1 end end local ok,thinkers=pcall(function() return Entities:FindAllByClassname('npc_dota_thinker') end) summary.thinkerApiAvailable=ok and type(thinkers)=='table' if summary.thinkerApiAvailable then for _,u in ipairs(thinkers) do if u and not u:IsNull() and (u:GetAbsOrigin()-ORIGIN):Length2D()<=4000 then UTIL_Remove(u);summary.thinkersRemoved=summary.thinkersRemoved+1 end end end return summary end function Precache(ctx) for _,hero in ipairs(HEROES) do PrecacheUnitByNameSync('npc_dota_hero_'..hero,ctx) end PrecacheUnitByNameSync('npc_dota_hero_sven',ctx) PrecacheUnitByNameSync('npc_dota_hero_sniper',ctx) PrecacheUnitByNameSync('npc_dota_hero_lina',ctx) PrecacheUnitByNameSync('npc_dota_hero_lion',ctx) end function Activate() LinkLuaModifier('modifier_dc_fifteen','addon_game_mode',LUA_MODIFIER_MOTION_NONE) pcall(function() GameRules:SetCreepSpawningEnabled(false) end) GameRules:SetHeroSelectionTime(0);GameRules:SetStrategyTime(0);GameRules:SetShowcaseTime(0);GameRules:SetPreGameTime(0) GameRules:GetGameModeEntity():SetCustomGameForceHero('npc_dota_hero_sniper') local queue={} if DC_FIFTEEN_CONTROLS then for _,hero in ipairs({'lina','sven'}) do for _,level in ipairs({1,18}) do queue[#queue+1]={id=hero..'_control_stats_'..level,kind='stat',hero=hero,level=level,maxLevelTalents=level==30} end end end for _,hero in ipairs(HEROES) do for _,level in ipairs({1,18,30}) do queue[#queue+1]={id=hero..'_stats_'..level,kind='stat',hero=hero,level=level,maxLevelTalents=level==30} end for _,k in ipairs({'ultimate_scepter','aghanims_shard','power_treads'}) do queue[#queue+1]={id=hero..'_stats_'..k,kind='stat',hero=hero,level=18,items={k}} end end local spells={ {id='juggernaut_fury',hero='juggernaut',ability='juggernaut_blade_fury',rank=4,noTarget=true,distance=150,seconds=6}, {id='juggernaut_omni_single',hero='juggernaut',ability='juggernaut_omni_slash',rank=3,allowCasterMove=true,seconds=5}, {id='juggernaut_omni_treads',hero='juggernaut',ability='juggernaut_omni_slash',rank=3,items={'power_treads'},allowCasterMove=true,seconds=5}, {id='juggernaut_swift_single',hero='juggernaut',ability='juggernaut_swift_slash',rank=1,items={'ultimate_scepter'},allowCasterMove=true,seconds=3}, {id='juggernaut_ward_heal',hero='juggernaut',ability='juggernaut_healing_ward',rank=4,point=true,castAtCaster=true,casterHealthPercent=50,seconds=5}, {id='juggernaut_ward_forced_destruction',hero='juggernaut',ability='juggernaut_healing_ward',rank=4,point=true,castAtCaster=true,wardForced=true,casterHealthPercent=50,seconds=5}, {id='juggernaut_ward_natural_attack_order',hero='juggernaut',ability='juggernaut_healing_ward',rank=4,point=true,castAtCaster=true,wardNatural=true,allowTargetMove=true,casterHealthPercent=50,seconds=6}, {id='juggernaut_crit_packets',hero='juggernaut',skills={juggernaut_blade_dance=4},attacks=12,attackEvery=.6,seconds=8}, {id='ursa_earthshock',hero='ursa',ability='ursa_earthshock',rank=4,noTarget=true,allowCasterMove=true,distance=180,seconds=3}, {id='ursa_fury_first_stack',hero='ursa',skills={ursa_fury_swipes=4},attacks=5,attackEvery=.6,seconds=4}, {id='ursa_overpower_hit_charges',hero='ursa',ability='ursa_overpower',rank=4,noTarget=true,attacks=4,attackEvery=.7,attackDelay=.5,seconds=4}, {id='ursa_overpower_miss_charges',hero='ursa',ability='ursa_overpower',rank=4,noTarget=true,skills={ursa_fury_swipes=4},attacks=4,attackEvery=.7,attackDelay=.5,forceMiss=true,seconds=4}, {id='ursa_scepter_enrage_stunned',hero='ursa',ability='ursa_enrage',rank=3,items={'ultimate_scepter'},noTarget=true,preStatus='stun',seconds=3}, {id='ursa_scepter_enrage_hexed',hero='ursa',ability='ursa_enrage',rank=3,items={'ultimate_scepter'},noTarget=true,preStatus='hex',targetHero='lion',seconds=3}, {id='ursa_scepter_enrage_silenced',hero='ursa',ability='ursa_enrage',rank=3,items={'ultimate_scepter'},noTarget=true,preStatus='silence',targetHero='drow_ranger',seconds=3}, {id='ursa_enrage',hero='ursa',ability='ursa_enrage',rank=3,noTarget=true,incomingAttacks=4,seconds=4}, {id='slardar_sprint',hero='slardar',ability='slardar_sprint',rank=4,noTarget=true,allowCasterMove=true,moveAfter=.5,seconds=3}, {id='slardar_crush',hero='slardar',ability='slardar_slithereen_crush',rank=4,noTarget=true,distance=180,seconds=4}, {id='slardar_bash_counter',hero='slardar',skills={slardar_bash=4},attacks=6,attackEvery=.65,seconds=5}, {id='slardar_bash_miss_counter',hero='slardar',skills={slardar_bash=4},attacks=6,attackEvery=.65,forceMiss=true,seconds=5}, {id='slardar_amplify',hero='slardar',ability='slardar_amplify_damage',rank=3,seconds=3}, {id='slardar_crush_shard',hero='slardar',ability='slardar_slithereen_crush',rank=4,skills={slardar_amplify_damage=3},items={'aghanims_shard'},noTarget=true,distance=180,seconds=4}, {id='drow_arrows_three',hero='drow_ranger',ability='drow_ranger_frost_arrows',rank=4,noInitialCast=true,autocast=true,attacks=3,attackEvery=.8,distance=500,seconds=4}, {id='drow_gust',hero='drow_ranger',ability='drow_ranger_wave_of_silence',rank=4,point=true,allowTargetMove=true,distance=500,seconds=3}, {id='drow_gust_250',hero='drow_ranger',ability='drow_ranger_wave_of_silence',rank=4,point=true,allowTargetMove=true,distance=250,seconds=3}, {id='drow_gust_700',hero='drow_ranger',ability='drow_ranger_wave_of_silence',rank=4,point=true,allowTargetMove=true,distance=700,seconds=3}, {id='drow_multishot_500',hero='drow_ranger',ability='drow_ranger_multishot',rank=4,point=true,distance=500,seconds=3}, {id='drow_multishot_1000',hero='drow_ranger',ability='drow_ranger_multishot',rank=4,point=true,distance=1000,seconds=3.5}, {id='drow_multishot_interrupt',hero='drow_ranger',ability='drow_ranger_multishot',rank=4,point=true,distance=500,interruptAt=.9,seconds=3}, {id='drow_glacier',hero='drow_ranger',ability='drow_ranger_glacier',rank=1,items={'aghanims_shard'},noTarget=true,allowCasterMove=true,seconds=3}, {id='drow_marksman_far',hero='drow_ranger',skills={drow_ranger_marksmanship=3},distance=700,attacks=12,attackEvery=.6,seconds=8}, {id='drow_marksman_near',hero='drow_ranger',skills={drow_ranger_marksmanship=3},distance=180,attacks=6,attackEvery=.6,seconds=5}, {id='lifestealer_rage',hero='life_stealer',ability='life_stealer_rage',rank=4,noTarget=true,seconds=3}, {id='lifestealer_wounds',hero='life_stealer',ability='life_stealer_open_wounds',rank=4,casterHealthPercent=50,attacks=3,attackEvery=.8,attackDelay=.6,seconds=4}, {id='lifestealer_feast',hero='life_stealer',skills={life_stealer_feast=4},casterHealthPercent=50,attacks=3,attackEvery=.8,seconds=4}, {id='lifestealer_infest_scepter_full',hero='life_stealer',ability='life_stealer_infest',rank=3,items={'ultimate_scepter'},allowCasterMove=true,casterHealthPercent=50,seconds=7}, {id='lifestealer_infest_scepter_consume',hero='life_stealer',ability='life_stealer_infest',rank=3,items={'ultimate_scepter'},allowCasterMove=true,consumeAt=1.6,casterHealthPercent=50,seconds=4}, } for _,c in ipairs(spells) do c.kind='spell';c.level=18;queue[#queue+1]=c end -- Focus-only cases never alter the default67-case capture queue. local focusedSpells={ {id='ursa_enrage_hexed_settled',hero='ursa',ability='ursa_enrage',rank=3,items={'ultimate_scepter'},noTarget=true,preStatus='hex',targetHero='lion',seconds=3}, {id='ursa_enrage_silenced_settled',hero='ursa',ability='ursa_enrage',rank=3,items={'ultimate_scepter'},noTarget=true,preStatus='silence',targetHero='drow_ranger',seconds=3}, {id='juggernaut_swift_with_omni',hero='juggernaut',ability='juggernaut_swift_slash',rank=1,skills={juggernaut_omni_slash=3},items={'ultimate_scepter'},allowCasterMove=true,seconds=3}, {id='lifestealer_feast_uncapped',hero='life_stealer',skills={life_stealer_feast=4},casterExtraHealth=100000,casterHealthPercent=10,attacks=3,attackEvery=.8,seconds=4}, } for _,c in ipairs(focusedSpells) do if DC_FIFTEEN_INCLUDE_FOCUSED or (DC_FIFTEEN_ONLY and DC_FIFTEEN_ONLY[c.id]) then c.kind='spell';c.level=18;queue[#queue+1]=c end end if DC_FIFTEEN_SKIP_STATS then local selected={};for _,c in ipairs(queue) do if c.kind=='spell' then selected[#selected+1]=c end end;queue=selected end if DC_FIFTEEN_ONLY then local selected={};for _,c in ipairs(queue) do if DC_FIFTEEN_ONLY[c.id] then selected[#selected+1]=c end end;queue=selected end if DC_FIFTEEN_ENVIRONMENT_GRID then queue={} local places={{x=0,y=0},{x=-4500,y=0},{x=-3000,y=2000},{x=3000,y=-2000},{x=0,y=2500},{x=3000,y=3500},{x=-3500,y=-4000},{x=3500,y=-4000}} for i,place in ipairs(places) do queue[#queue+1]={id='juggernaut_environment_'..i,kind='stat',hero='juggernaut',level=1,origin=place,environment=true} end end if DC_FIFTEEN_PACKET_FOCUS then queue={ {id='ursa_fury_crit_packets',kind='spell',hero='ursa',level=18,skills={ursa_fury_swipes=4},items={'greater_crit'},packetProbe=true,targetExtraHealth=20000,attacks=60,attackEvery=.12,attackDelay=.3,seconds=9}, {id='slardar_bash_crit_packets',kind='spell',hero='slardar',level=18,skills={slardar_bash=4},items={'greater_crit'},packetProbe=true,targetExtraHealth=20000,attacks=60,attackEvery=.12,attackDelay=.3,seconds=9}, {id='lifestealer_feast_crit_packets',kind='spell',hero='life_stealer',level=18,skills={life_stealer_feast=4},items={'greater_crit'},packetProbe=true,targetExtraHealth=20000,attacks=60,attackEvery=.12,attackDelay=.3,seconds=9}, {id='ursa_maul_talent30_refresh_packets',kind='spell',hero='ursa',level=30,maxLevelTalents=true,maulProbe=true,packetProbe=true,targetExtraHealth=20000,attacks=3,attackEvery=.6,seconds=3}, } end local phase,c,a,b,spell,started=0,nil,nil,nil,nil,nil;local sent,failed=0,0;local preApplied=false;local worldCleanup={} local function remove() local previous=GameRules.DCFifteen GameRules.DCFifteen=nil if previous and previous.ward and not previous.ward:IsNull() then UTIL_Remove(previous.ward) end for _,u in ipairs({a,b}) do if u and not u:IsNull() then u:Stop();UTIL_Remove(u) end end for _,u in ipairs(FindUnitsInRadius(DOTA_TEAM_GOODGUYS,ORIGIN,nil,2000,DOTA_UNIT_TARGET_TEAM_FRIENDLY,DOTA_UNIT_TARGET_BASIC,DOTA_UNIT_TARGET_FLAG_INVULNERABLE+DOTA_UNIT_TARGET_FLAG_OUT_OF_WORLD,FIND_ANY_ORDER,false)) do if u:GetUnitName()=='npc_dota_juggernaut_healing_ward' then UTIL_Remove(u) end end cleanWorld();a=nil;b=nil;spell=nil end local function cast() if not spell then return end if c.point then a:CastAbilityOnPosition(c.castAtCaster and a:GetAbsOrigin() or b:GetAbsOrigin(),spell,-1) elseif c.noTarget then a:CastAbilityNoTarget(spell,-1) else a:CastAbilityOnTarget(b,spell,-1) end end if DCFifteenEntityHurtListener then StopListeningToGameEvent(DCFifteenEntityHurtListener) end DCFifteenEntityHurtListener=ListenToGameEvent('entity_hurt',function(e) local d=GameRules.DCFifteen;if not d then return end local source=e.entindex_inflictor and EntIndexToHScript(e.entindex_inflictor);local ability=source and source:GetAbilityName() or 'attack' local direction=nil;if e.entindex_killed==d.target:entindex() and e.entindex_attacker==d.caster:entindex() then direction='outgoing' elseif e.entindex_killed==d.caster:entindex() and e.entindex_attacker==d.target:entindex() then direction='incoming' end if direction then d.integerEvents[#d.integerEvents+1]={at=Time()-d.start,amount=e.damage,source=ability,direction=direction} end if d.ward and not d.ward:IsNull() and e.entindex_killed==d.ward:entindex() then d.summonEvents[#d.summonEvents+1]={at=Time()-d.start,kind='hurt',amount=e.damage,source=ability} end end,nil) GameRules:GetGameModeEntity():SetContextThink('dc_fifteen_heroes',function() local ok,delay=pcall(function() if phase==0 then if GameRules:State_Get()==DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP then GameRules:FinishCustomGameSetup();return .3 end if GameRules:State_Get()=c.interruptAt then a:AddNewModifier(b,nil,'modifier_stunned',{duration=.4});d.interrupted=true;d.interruptActual=elapsed end if c.consumeAt and not d.consumeActual and elapsed>=c.consumeAt then local consume=a:FindAbilityByName('life_stealer_consume');if not consume or consume:IsHidden() then error('consume_unavailable') end;a:CastAbilityNoTarget(consume,-1);d.consumeActual=elapsed;d.orders=d.orders+1 end if c.moveAfter and not d.moved and elapsed>=c.moveAfter then a:MoveToPosition(ORIGIN+Vector(600,0,0));d.moved=true;d.orders=d.orders+1 end if c.attacks and elapsed>=(c.attackDelay or 0) and d.attacks=d.lastAttack+(c.attackEvery or .6) then local packet=nil if c.packetProbe then b:SetHealth(b:GetMaxHealth()) packet={ordinal=d.attacks+1,at=elapsed,beforeTargetHp=b:GetHealth(),targetMaxHp=b:GetMaxHealth(),casterHp=a:GetHealth(),casterMaxHp=a:GetMaxHealth(),targetArmor=b:GetPhysicalArmorValue(false),baseDamageMin=a:GetBaseDamageMin(),baseDamageMax=a:GetBaseDamageMax(),damageTarget=a:GetAverageTrueAttackDamage(b),damageNil=read(a,'GetAverageTrueAttackDamage',nil),beforeCasterMods=mods(a),beforeTargetMods=mods(b)} d.activePacket=packet.ordinal end a:PerformAttack(b,true,true,true,true,true,false,not c.forceMiss) if packet then packet.afterTargetHp=b:GetHealth();packet.afterCasterHp=a:GetHealth();packet.afterCasterMods=mods(a);packet.afterTargetMods=mods(b);packet.hpLoss=packet.beforeTargetHp-packet.afterTargetHp;d.packetSnapshots[#d.packetSnapshots+1]=packet;d.activePacket=nil end d.attacks=d.attacks+1;d.lastAttack=elapsed end if c.incomingAttacks and d.incoming=.4+d.incoming*.7 then b:PerformAttack(a,true,true,true,true,false,false,true);d.incoming=d.incoming+1 end if c.ability=='juggernaut_healing_ward' then local w=ward(a);if w and not d.ward then d.ward=w;d.summonEvents[#d.summonEvents+1]={at=elapsed,kind='appeared',hp=w:GetHealth(),maxHp=w:GetMaxHealth()} end if d.ward and (d.ward:IsNull() or not d.ward:IsAlive()) and not d.wardDead then d.wardDead=true;d.summonEvents[#d.summonEvents+1]={at=elapsed,kind='removed'} end if c.wardNatural and w and not d.wardOrder then b:MoveToTargetToAttack(w);d.wardOrder=true;d.orders=d.orders+1;d.summonEvents[#d.summonEvents+1]={at=elapsed,kind='natural_attack_order'} end if c.wardForced and w and elapsed>=.7+(d.wardForced or 0)*.6 and (d.wardForced or 0)<5 then b:PerformAttack(w,true,true,true,true,false,false,true);d.wardForced=(d.wardForced or 0)+1;d.summonEvents[#d.summonEvents+1]={at=elapsed,kind='forced_attack',ordinal=d.wardForced} end if w then d.summonSamples[#d.summonSamples+1]={at=elapsed,hp=w:GetHealth(),maxHp=w:GetMaxHealth(),x=w:GetAbsOrigin().x,alive=w:IsAlive(),targetDistance=(w:GetAbsOrigin()-b:GetAbsOrigin()):Length2D()} end end if not d.lastSample or elapsed-d.lastSample>=.06 then d.lastSample=elapsed;local enemies=FindUnitsInRadius(a:GetTeamNumber(),b:GetAbsOrigin(),nil,800,DOTA_UNIT_TARGET_TEAM_ENEMY,DOTA_UNIT_TARGET_HERO+DOTA_UNIT_TARGET_BASIC,DOTA_UNIT_TARGET_FLAG_INVULNERABLE+DOTA_UNIT_TARGET_FLAG_OUT_OF_WORLD,FIND_ANY_ORDER,false) d.samples[#d.samples+1]={at=elapsed,casterHp=a:GetHealth(),targetHp=b:GetHealth(),casterMana=a:GetMana(),targetMana=b:GetMana(),casterX=a:GetAbsOrigin().x,casterY=a:GetAbsOrigin().y,targetX=b:GetAbsOrigin().x,targetY=b:GetAbsOrigin().y,casterChanneling=channel,casterStunned=a:IsStunned(),targetStunned=b:IsStunned(),casterInvulnerable=a:IsInvulnerable(),casterOutOfGame=read(a,'IsOutOfGame'),casterDamage=a:GetAverageTrueAttackDamage(b),casterInterval=a:GetSecondsPerAttack(false),casterMoveSpeed=a:GetMoveSpeedModifier(a:GetBaseMoveSpeed(),false),targetArmor=b:GetPhysicalArmorValue(false),casterRegen=a:GetHealthRegen(),targetRegen=b:GetHealthRegen(),casterManaRegen=a:GetManaRegen(),targetManaRegen=b:GetManaRegen(),targetEnemyUnits=#enemies,casterMods=mods(a),targetMods=mods(b)} end if elapsed