Large diffs are not rendered by default.

@@ -130,6 +130,7 @@
#base "heroes/hero_witch_doctor.txt"
#base "heroes/hero_crystal_maiden.txt"
#base "heroes/hero_terrorblade.txt"
#base "heroes/hero_troll_warlord.txt"

"DOTAAbilities"
{

Large diffs are not rendered by default.

@@ -103,7 +103,6 @@
"relic_type_unique"
{
"relic_unique_aghanims_amulet" "1"
"relic_unique_ritual_candle" "1"
"relic_unique_frozen_crystal" "1"
"relic_unique_limit_breaker" "1"
"relic_unique_molten_crystal" "1"
@@ -4447,7 +4447,7 @@
"Model" "models/creeps/omniknight_golem/omniknight_golem.vmdl" // Model.
"SoundSet" "Hero_Invoker" // Name of sound set.
"GameSoundsFile" "soundevents/game_sounds_heroes/game_sounds_invoker.vsndevts"
"ModelScale" "1.4"
"ModelScale" "1.65"
"Level" "999"
"IsCelestial" "1"
"MinimapIcon" "minimap_roshancamp"
@@ -8016,6 +8016,8 @@

"HasInventory" "1"
"AttackRange" "0"
"AttackAnimationPoint" "0.3"
"AttackAcquisitionRange" "9999"
"ProjectileSpeed" "0"
}
"npc_chen_creature_1"
@@ -333,6 +333,8 @@ function CHoldoutGameMode:InitGameMode()
ListenToGameEvent('dota_player_used_ability', Dynamic_Wrap(CHoldoutGameMode, 'OnAbilityUsed'), self)
ListenToGameEvent('dota_player_learned_ability', Dynamic_Wrap(CHoldoutGameMode, 'OnAbilityLearned'), self)
ListenToGameEvent( "dota_player_gained_level", Dynamic_Wrap( CHoldoutGameMode, "OnHeroLevelUp" ), self )
ListenToGameEvent( "npc_spawned", Dynamic_Wrap( RoundManager, "OnNPCSpawned" ), RoundManager )
ListenToGameEvent( "dota_holdout_revive_complete", Dynamic_Wrap( RoundManager, 'OnHoldoutReviveComplete' ), RoundManager )

CustomGameEventManager:RegisterListener('Tell_Threat', Dynamic_Wrap( CHoldoutGameMode, 'Tell_threat'))
CustomGameEventManager:RegisterListener('bh_notify_modifier', Dynamic_Wrap( CHoldoutGameMode, 'NotifyBuffs'))
@@ -865,7 +867,7 @@ function CHoldoutGameMode:OnPlayerDisconnected(keys)
if not playerID then return end
local hero = PlayerResource:GetSelectedHeroEntity(playerID)
if hero then hero.disconnect = GameRules:GetGameTime() end
for pID = 0, GameRules.BasePlayers do -- check if game has to die
for pID = 0, 24 do -- check if game has to die
if PlayerResource:IsValidPlayerID( pID ) and PlayerResource:GetConnectionState() == DOTA_CONNECTION_STATE_CONNECTED then
return
end
@@ -24,9 +24,9 @@ end

local function ThirdChoice(self, userid, event)
local hero = PlayerResource:GetSelectedHeroEntity( event.pID )
hero:AddRelic( self:RollRandomGenericRelicForPlayer( event.pID ) )
hero:AddRelic( self:RollRandomGenericRelicForPlayer( event.pID ) )
hero:AddRelic( self:RollRandomGenericRelicForPlayer( event.pID ) )
hero:AddRelic( RelicManager:RollRandomGenericRelicForPlayer( event.pID ) )
hero:AddRelic( RelicManager:RollRandomGenericRelicForPlayer( event.pID ) )
hero:AddRelic( RelicManager:RollRandomGenericRelicForPlayer( event.pID ) )
self._playerChoices[event.pID] = true
CheckPlayerChoices(self)
end
@@ -1 +1,32 @@
terrorblade_conjure_image_bh = class({})
terrorblade_conjure_image_bh = class({})

function terrorblade_conjure_image_bh:GetCooldown(iLvl)
return self.BaseClass.GetCooldown( self, iLvl ) + self:GetCaster():FindTalentValue("special_bonus_unique_terrorblade_conjure_image_1")
end

function terrorblade_conjure_image_bh:OnSpellStart()
self:CreateImage()
end

function terrorblade_conjure_image_bh:CreateImage( position, duration, outgoing, incoming )
local caster = self:GetCaster()

local vPos = position or caster:GetAbsOrigin() + RandomVector(150)
local fDur = duration or self:GetTalentSpecialValueFor("illusion_duration")
local fOut = outgoing or self:GetTalentSpecialValueFor("illusion_outgoing_damage")
local fInc = incoming or self:GetTalentSpecialValueFor("illusion_incoming_damage")

local illusion = caster:ConjureImage( vPos, fDur, 100 - fOut, 100 - fInc, "modifier_terrorblade_conjureimage", self, true, caster )
illusion:StartGesture( ACT_DOTA_SPAWN )
if caster:HasTalent("special_bonus_unique_terrorblade_conjure_image_2") then
local heal = caster:GetMaxHealth() * caster:FindTalentValue("special_bonus_unique_terrorblade_conjure_image_2") / 100
Timers:CreateTimer(function()
if not illusion:IsNull() and illusion:IsAlive() then
return 0.33
else
caster:HealEvent( heal, self, caster )
end
end)
end
return illusion
end
@@ -33,19 +33,14 @@ function modifier_terrorblade_metamorphosis_bh:GetAuraSearchTeam()
end

function modifier_terrorblade_metamorphosis_bh:GetAuraEntityReject(entity)
if entity == self:GetParent()
or entity:GetUnitName() == self:GetParent():GetUnitName()
if entity:GetUnitName() == self:GetParent():GetUnitName()
or ( self:GetParent():HasTalent("special_bonus_unique_terrorblade_metamorphosis_1") and entity:IsRealHero() ) then
return false
else
return true
end
end

function modifier_terrorblade_metamorphosis_bh:IsHidden()
return true
end

function modifier_terrorblade_metamorphosis_bh:GetAuraSearchType()
return DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_HERO
end
@@ -57,12 +52,50 @@ function modifier_terrorblade_metamorphosis_bh_aura:OnCreated()
self.damage = self:GetTalentSpecialValueFor("bonus_damage")
self.movespeed = self:GetTalentSpecialValueFor("speed_loss")
self.range = self:GetTalentSpecialValueFor("bonus_range")
if IsServer() then
self:GetParent():StartGesture( ACT_DOTA_CAST_ABILITY_3 )
self:GetParent():SetAttackCapability( DOTA_UNIT_CAP_RANGED_ATTACK )
self:GetParent():SetRangedProjectileName( "particles/units/heroes/hero_terrorblade/terrorblade_metamorphosis_base_attack.vpcf" )
end
end

function modifier_terrorblade_metamorphosis_bh_aura:OnDestroy()
if IsServer() then
self:GetParent():StartGesture( ACT_DOTA_CAST_ABILITY_3_END )
self:GetParent():SetAttackCapability( self:GetParent():GetOriginalAttackCapability() )
self:GetParent():RevertProjectile()
end
end

function modifier_terrorblade_metamorphosis_bh_aura:DeclareFunctions()
return {MODIFIER_PROPERTY_MODEL_CHANGE, MODIFIER_PROPERTY_BASEATTACK_BONUSDAMAGE, MODIFIER_PROPERTY_MOVESPEED_BONUS_CONSTANT}
return {MODIFIER_PROPERTY_MODEL_CHANGE, MODIFIER_PROPERTY_BASEATTACK_BONUSDAMAGE, MODIFIER_PROPERTY_MOVESPEED_BONUS_CONSTANT, MODIFIER_PROPERTY_ATTACK_RANGE_BONUS,
MODIFIER_PROPERTY_PROJECTILE_SPEED_BONUS}
end

function modifier_terrorblade_metamorphosis_bh_aura:GetModifierModelChange()
return "models/heroes/terrorblade/demon.vmdl"
end

function modifier_terrorblade_metamorphosis_bh_aura:GetModifierBaseAttack_BonusDamage()
return self.damage
end

OnModelChange
GetModifierBaseAttack_BonusDamage
GetModifierMoveSpeedBonus_Constant
function modifier_terrorblade_metamorphosis_bh_aura:GetModifierMoveSpeedBonus_Constant()
return self.movespeed
end

function modifier_terrorblade_metamorphosis_bh_aura:GetModifierAttackRangeBonus()
return self.range
end

function modifier_terrorblade_metamorphosis_bh_aura:GetModifierProjectileSpeedBonus()
if self:GetCaster() ~= self:GetParent() then
return 900
end
end

function modifier_terrorblade_metamorphosis_bh_aura:IsHidden()
return self:GetCaster() == self:GetParent()
end


@@ -1 +1,74 @@
terrorblade_reflection_bh = class({})
terrorblade_reflection_bh = class({})

function terrorblade_reflection_bh:GetAOERadius()
return self:GetTalentSpecialValueFor("radius")
end

function terrorblade_reflection_bh:OnSpellStart()
local caster = self:GetCaster()
local position = self:GetCursorPosition()

local radius = self:GetTalentSpecialValueFor("radius")
local outgoing = self:GetTalentSpecialValueFor("illusion_outgoing_damage")
local illusions = self:GetTalentSpecialValueFor("illusion_count")
local duration = self:GetTalentSpecialValueFor("duration")

for _, enemy in ipairs( caster:FindEnemyUnitsInRadius( position, radius ) ) do
enemy:AddNewModifier( caster, self, "modifier_terrorblade_reflection_bh_slow", {duration = duration})
end

for _, hero in ipairs( HeroList:GetRealHeroes() ) do
for i = 1, illusions do
local reflection = self:CreateReflection( hero, position + ActualRandomVector( radius, 125 ), duration, outgoing, caster )
reflection:MoveToPositionAggressive( position )
end
end
end

function terrorblade_reflection_bh:CreateReflection( hero, position, duration, outgoing, caster)
local illusion = hero:ConjureImage( position, duration, 100 - outgoing, -100, "modifier_terrorblade_conjureimage", self, false, caster )
illusion:AddNewModifier(caster, self, "modifier_terrorblade_reflection_bh_illusion", {})

illusion:AddAbility("terrorblade_zeal")
return illusion
end

modifier_terrorblade_reflection_bh_illusion = class({})
LinkLuaModifier( "modifier_terrorblade_reflection_bh_illusion", "heroes/hero_terrorblade/terrorblade_reflection_bh", LUA_MODIFIER_MOTION_NONE )

function modifier_terrorblade_reflection_bh_illusion:CheckState()
return {[MODIFIER_STATE_ATTACK_IMMUNE] = true,
[MODIFIER_STATE_INVULNERABLE] = true,
[MODIFIER_STATE_MAGIC_IMMUNE] = true,
[MODIFIER_STATE_UNSELECTABLE] = true,
[MODIFIER_STATE_NO_UNIT_COLLISION] = true,
[MODIFIER_STATE_FLYING_FOR_PATHING_PURPOSES_ONLY] = true,
[MODIFIER_STATE_UNTARGETABLE] = true,}
end

function modifier_terrorblade_reflection_bh_illusion:IsHidden()
return true
end

modifier_terrorblade_reflection_bh_slow = class({})
LinkLuaModifier( "modifier_terrorblade_reflection_bh_slow", "heroes/hero_terrorblade/terrorblade_reflection_bh", LUA_MODIFIER_MOTION_NONE )

function modifier_terrorblade_reflection_bh_slow:OnCreated()
self.slow = self:GetTalentSpecialValueFor("slow")
end

function modifier_terrorblade_reflection_bh_slow:OnRefresh()
self.slow = self:GetTalentSpecialValueFor("slow")
end

function modifier_terrorblade_reflection_bh_slow:CheckState()
return {[MODIFIER_STATE_ROOTED] = self:GetCaster():HasTalent("special_bonus_unique_terrorblade_reflection_2")}
end

function modifier_terrorblade_reflection_bh_slow:DeclareFunctions()
return {MODIFIER_PROPERTY_MOVESPEED_BONUS_PERCENTAGE}
end

function modifier_terrorblade_reflection_bh_slow:GetModifierMoveSpeedBonus_Percentage()
return self.slow
end
@@ -4,7 +4,7 @@ function terrorblade_zeal:GetIntrinsicModifierName()
return "modifier_terrorblade_zeal_passive"
end

LinkLuaModifier( "modifier_terrorblade_zeal_passive", "lua_abilities/heroes/terrorblade.lua" ,LUA_MODIFIER_MOTION_NONE )
LinkLuaModifier( "modifier_terrorblade_zeal_passive", "heroes/hero_terrorblade/terrorblade_zeal", LUA_MODIFIER_MOTION_NONE )
modifier_terrorblade_zeal_passive = class({})

function modifier_terrorblade_zeal_passive:OnCreated()
@@ -31,17 +31,28 @@ function modifier_terrorblade_zeal_passive:OnDeath(params)
if params.unit == self:GetParent() then
local radius = self:GetAbility():GetTalentSpecialValueFor("illusion_explosion_radius")
local damage = self:GetAbility():GetTalentSpecialValueFor("illusion_explosion_damage")
local owner = self:GetParent()
if owner:IsRealHero() then
local parent = self:GetParent()
local owner = PlayerResource:GetSelectedHeroEntity( self:GetParent():GetPlayerID() )
if parent:IsRealHero() then
damage = self:GetAbility():GetTalentSpecialValueFor("self_explosion_damage")
if parent:HasTalent("special_bonus_unique_terrorblade_zeal_2") then
local conjure = parent:FindAbilityByName("terrorblade_conjure_image_bh")
if conjure then
for i = 1, parent:FindTalentValue("special_bonus_unique_terrorblade_zeal_2") do
local image = conjure:CreateImage( )
image:SetHealth( image:GetMaxHealth() )
end
end
end
end
EmitSoundOn("Hero_Terrorblade.Sunder.Cast", owner)
ParticleManager:FireParticle( "particles/units/heroes/hero_terrorblade/terrorblade_death.vpcf", PATTACH_POINT_FOLLOW, owner, {[15] = Vector(100,100,255),

EmitSoundOn("Hero_Terrorblade.Sunder.Cast", parent)
ParticleManager:FireParticle( "particles/units/heroes/hero_terrorblade/terrorblade_death.vpcf", PATTACH_WORLDORIGIN, parent, {[0] = parent:GetAbsOrigin(), [15] = Vector(100,100,255),
[16] = Vector(radius,radius,radius) } )
ParticleManager:CreateParticle("particles/units/heroes/hero_dragon_knight/dragon_knight_transform_blue.vpcf", PATTACH_POINT_FOLLOW, owner )
ParticleManager:FireParticle("particles/units/heroes/hero_dragon_knight/dragon_knight_transform_blue.vpcf", PATTACH_WORLDORIGIN, parent, {[0] = parent:GetAbsOrigin()} )
local units = FindUnitsInRadius(self:GetParent():GetTeamNumber(), self:GetParent():GetAbsOrigin(), nil, radius, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, 0, 0, false)
for _,unit in pairs(units) do
ApplyDamage({victim = unit, attacker = self:GetParent(), damage = damage, damage_type = self:GetAbility():GetAbilityDamageType(), ability = self:GetAbility()})
ApplyDamage({victim = unit, attacker = owner, damage = damage, damage_type = self:GetAbility():GetAbilityDamageType(), ability = self:GetAbility()})
end
end
end
@@ -0,0 +1 @@
troll_warlord_berserk = class({})
@@ -0,0 +1 @@
troll_warlord_berserk = class({})
@@ -0,0 +1 @@
troll_warlord_berserk = class({})
@@ -0,0 +1 @@
troll_warlord_berserk = class({})
@@ -0,0 +1 @@
troll_warlord_berserk = class({})
@@ -0,0 +1 @@
troll_warlord_berserk = class({})
@@ -3,15 +3,15 @@ modifier_base_attack_time_handler = class({})
if IsServer() then
function modifier_base_attack_time_handler:OnCreated()
self.baseAttackTime = self:GetParent():GetBaseAttackTime()
self:SetStackCount( self.baseAttackTime * 10 )
self:SetStackCount( self.baseAttackTime * 100 )
self:StartIntervalThink(0.1)
end

function modifier_base_attack_time_handler:OnIntervalThink()
local baseAttackTime = self.baseAttackTime * 10
local baseAttackTime = self.baseAttackTime * 100
for _, modifier in ipairs( self:GetParent():FindAllModifiers() ) do
if modifier.GetBaseAttackTime_Bonus and modifier:GetBaseAttackTime_Bonus() then
baseAttackTime = baseAttackTime + (modifier:GetBaseAttackTime_Bonus() * 10)
baseAttackTime = baseAttackTime + (modifier:GetBaseAttackTime_Bonus() * 100)
end
end
self:SetStackCount( baseAttackTime )
@@ -23,7 +23,7 @@ function modifier_base_attack_time_handler:DeclareFunctions()
end

function modifier_base_attack_time_handler:GetModifierBaseAttackTimeConstant()
return self:GetStackCount() / 10
return self:GetStackCount() / 100
end

function modifier_base_attack_time_handler:IsHidden()
@@ -721,6 +721,25 @@ function CDOTA_BaseNPC:GetStunResistance()
end
end

function CDOTA_BaseNPC:GetOriginalAttackCapability()
if GameRules.UnitKV[self:GetUnitName()] then
self.originalAttackCapability = self.originalAttackCapability or GameRules.UnitKV[self:GetUnitName()]["AttackCapabilities"]
if self.originalAttackCapability == "DOTA_UNIT_CAP_MELEE_ATTACK" then
return DOTA_UNIT_CAP_MELEE_ATTACK
elseif self.originalAttackCapability == "DOTA_UNIT_CAP_RANGED_ATTACK" then
return DOTA_UNIT_CAP_RANGED_ATTACK
else
return DOTA_UNIT_CAP_NO_ATTACK
end
end
end

function CDOTA_BaseNPC:GetOriginalModel()
if GameRules.UnitKV[self:GetUnitName()] then
return GameRules.UnitKV[self:GetUnitName()]["Model"] or nil
end
end

function CDOTA_BaseNPC:GetBaseProjectileModel()
if self:IsRangedAttacker() then
return GameRules.UnitKV[self:GetUnitName()]["ProjectileModel"] or nil
@@ -824,7 +843,7 @@ function CDOTA_BaseNPC:ConjureImage( position, duration, outgoing, incoming, sp
bControl = controllable
if bControl == nil then bControl = true end
-- handle_UnitOwner needs to be nil, else it will crash the game.
local illusion = CreateUnitByName("npc_illusion_template", origin, true, self, self, owner:GetTeamNumber())
local illusion = CreateUnitByName("npc_illusion_template", origin, true, owner, owner, owner:GetTeamNumber())
if bControl then illusion:SetControllableByPlayer(player, true) end

for abilitySlot=0,15 do
@@ -852,8 +871,8 @@ function CDOTA_BaseNPC:ConjureImage( position, duration, outgoing, incoming, sp
illusion:SetBaseAttackTime( self:GetBaseAttackTime() )
illusion:SetBaseMoveSpeed( self:GetBaseMoveSpeed() )

illusion:SetOriginalModel( self:GetModelName() )
illusion:SetModel( self:GetModelName() )
illusion:SetOriginalModel( self:GetOriginalModel() )
illusion:SetModel( self:GetOriginalModel() )
illusion:SetModelScale( self:GetModelScale() )

local moveCap = DOTA_UNIT_CAP_MOVE_NONE
@@ -864,7 +883,7 @@ function CDOTA_BaseNPC:ConjureImage( position, duration, outgoing, incoming, sp
end
end
illusion:SetMoveCapability( moveCap )
illusion:SetAttackCapability( self:GetAttackCapability() )
illusion:SetAttackCapability( self:GetOriginalAttackCapability() )
illusion:SetUnitName( self:GetUnitName() )
if self:IsRangedAttacker() then
illusion:SetRangedProjectileName( self:GetRangedProjectileName() )
@@ -906,6 +925,9 @@ function CDOTA_BaseNPC:ConjureImage( position, duration, outgoing, incoming, sp
newWearable:AddNewModifier(nil, nil, "modifier_wearable", {})
newWearable:AddNewModifier(owner, ability, "modifier_kill", { duration = duration })
newWearable:AddNewModifier(owner, ability, "modifier_illusion", { duration = duration })
if specIllusionModifier then
newWearable:AddNewModifier(owner, ability, specIllusionModifier, { duration = duration })
end
newWearable:SetParent(illusion, nil)
newWearable:FollowEntity(illusion, true)
-- newWearable:SetRenderColor(100,100,255)

This file was deleted.

@@ -10,6 +10,7 @@ end
function relic_cursed_crimson_gauntlet:OnIntervalThink()
if IsServer() then
local parent = self:GetParent()
if parent:HasRelic("relic_unique_ritual_candle") then return end
for _, enemy in ipairs( parent:FindEnemyUnitsInRadius( parent:GetAbsOrigin(), 900 ) ) do
enemy:AddNewModifier(parent, self:GetAbility(), "modifier_relic_cursed_crimson_gauntlet", {duration = 0.5})
end
@@ -4,6 +4,10 @@ function relic_unique_eagles_beak:CheckState()
return {[MODIFIER_STATE_CANNOT_MISS] = true}
end

function relic_unique_eagles_beak:GetAccuracy()
return 100
end

function relic_unique_eagles_beak:GetPriority()
return MODIFIER_PRIORITY_SUPER_ULTRA
end
@@ -42,8 +42,6 @@ function RoundManager:Initialize(context)

self.eventsCreated = nil

ListenToGameEvent( "npc_spawned", Dynamic_Wrap( RoundManager, "OnNPCSpawned" ), self )
ListenToGameEvent( "dota_holdout_revive_complete", Dynamic_Wrap( RoundManager, 'OnHoldoutReviveComplete' ), self )
CustomGameEventManager:RegisterListener('bh_player_voted_to_skip', Context_Wrap( RoundManager, 'VoteSkipPrepTime'))
CustomGameEventManager:RegisterListener('bh_player_voted_to_ng', Context_Wrap( RoundManager, 'VoteNewGame'))
self:PrecacheRounds(context)
@@ -592,9 +590,11 @@ function RoundManager:InitializeUnit(unit, bElite)
unit:SetModelScale(unit:GetModelScale()*1.15)

local eliteTypes = {}
for eliteType, activated in pairs(GameRules._Elites) do
if activated ~= "0" then
table.insert(eliteTypes, eliteType)
for eliteType, weight in pairs(GameRules._Elites) do
if tonumber(weight) > 0 then
for i = 1, tonumber(weight) do
table.insert(eliteTypes, eliteType)
end
end
end