initial commit

This commit is contained in:
2021-10-24 15:36:18 -04:00
commit b9a5a8fe23
11982 changed files with 220468 additions and 0 deletions

2687
scripts/vscripts/system/ai.lua Executable file

File diff suppressed because it is too large Load Diff

634
scripts/vscripts/system/combo.lua Executable file
View File

@@ -0,0 +1,634 @@
local thtd_combo_table =
{
["cirno"] =
{
["letty_cirno"] =
{
["abilityName"] = "thtd_cirno_01",
}
},
["letty"] =
{
["letty_cirno"] =
{
["abilityName"] = "thtd_letty_01",
}
},
["lyrica"] =
{
["lyrica_lunasa_merlin"] =
{
["delay"] = 3,
["duration"] = 3,
["abilityName"] = "thtd_lyrica_01",
}
},
["lunasa"] =
{
["lyrica_lunasa_merlin"] =
{
["delay"] = 3,
["duration"] = 3,
}
},
["merlin"] =
{
["lyrica_lunasa_merlin"] =
{
["delay"] = 3,
["duration"] = 3,
}
},
["youmu"] =
{
["yuyuko_youmu"] =
{
["delay"] = 9,
["duration"] = 5,
["abilityName"] = "thtd_youmu_01",
},
["youmu_reisen"] =
{
["abilityName"] = "thtd_youmu_02",
}
},
["yuyuko"] =
{
["yuyuko_youmu"] =
{
["delay"] = 13,
["duration"] = 5,
["abilityName"] = "thtd_yuyuko_02",
},
["yuyuko_yukari"] =
{
["abilityName"] = "thtd_yuyuko_01",
}
},
["marisa"] =
{
["reimu_marisa"] =
{
["delay"] = 3,
["duration"] = 2,
["abilityName"] = "thtd_marisa_01",
["abilityName2"] = "thtd_marisa_03",
},
["marisa_alice"] =
{
["delay"] = 2,
["duration"] = 3,
["abilityName"] = "thtd_marisa_02",
}
},
["alice"] =
{
["marisa_alice"] =
{
["delay"] = 3,
["duration"] = 3,
["abilityName"] = "thtd_alice_03",
},
["reimu_alice"] =
{
["delay"] = 3,
["duration"] = 3,
["abilityName"] = "thtd_alice_02",
}
},
["koishi"] =
{
["koishi_satori"] =
{
["delay"] = 5,
["duration"] = 2,
["abilityName"] = "thtd_koishi_01",
}
},
["satori"] =
{
["koishi_satori"] =
{
["abilityName"] = "thtd_satori_02",
}
},
["sakuya"] =
{
["remilia_sakuya"] =
{
["delay"] = 3,
["duration"] = 3,
["abilityName"] = "thtd_sakuya_02",
},
["meirin_sakuya"] =
{
["abilityName"] = "thtd_sakuya_03",
}
},
["koakuma"] =
{
["koakuma_patchouli"] =
{
["delay"] = 7,
["duration"] = 3,
["abilityName"] = "thtd_koakuma_01",
}
},
["patchouli"] =
{
["koakuma_patchouli"] =
{
["delay"] = 5,
["duration"] = 2,
["abilityName"] = "thtd_patchouli_04",
}
},
["eirin"] =
{
["eirin_kaguya"] =
{
["delay"] = 2,
["duration"] = 2,
["abilityName"] = "thtd_eirin_01",
}
},
["kaguya"] =
{
["eirin_kaguya"] =
{
["delay"] = 2,
["duration"] = 3,
["abilityName"] = "thtd_kaguya_01",
}
},
["yukari"] =
{
["reimu_yukari"] =
{
["abilityName"] = "thtd_yukari_01",
},
["chen_yukari_ran"] =
{
["abilityName"] = "thtd_yukari_04",
}
},
["remilia"] =
{
["remilia_sakuya"] =
{
["abilityName"] = "thtd_remilia_04",
},
["remilia_flandre"] =
{
["abilityName"] = "thtd_remilia_02",
}
},
["reimu"] =
{
["rumia_reimu"] =
{
["abilityName"] = "thtd_reimu_01",
},
["reimu_marisa"] =
{
["abilityName"] = "thtd_reimu_02",
},
["reimu_yukari"] =
{
["abilityName"] = "thtd_reimu_04",
},
},
["flandre"] =
{
["remilia_flandre"] =
{
["abilityName"] = "thtd_flandre_02",
}
},
["soga"] =
{
["futo_soga"] =
{
["abilityName"] = "thtd_soga_03",
}
},
["minamitsu"] =
{
["nue_minamitsu"] =
{
["abilityName"] = "thtd_minamitsu_02",
}
},
["futo"] =
{
["futo_soga"] =
{
["abilityName"] = "thtd_futo_02",
}
},
["sanae"] =
{
["suwako_kanako_sanae"] =
{
["abilityName"] = "thtd_sanae_04",
}
},
["tenshi"] =
{
["tenshi_iku"] =
{
["abilityName"] = "thtd_tenshi_03",
}
},
["mokou"] =
{
["mokou_keine"] =
{
["abilityName"] = "thtd_mokou_01",
}
},
["reisen"] =
{
["youmu_reisen"] =
{
["abilityName"] = "thtd_reisen_02",
}
},
["utsuho"] =
{
["utsuho_rin"] =
{
["abilityName"] = "thtd_utsuho_01",
}
},
["keine"] =
{
["mokou_keine"] =
{
["abilityName"] = "thtd_keine_03",
}
},
["ran"] =
{
["chen_yukari_ran"] =
{
["abilityName"] = "thtd_ran_03",
}
},
["yoshika"] =
{
["yoshika_seiga"] =
{
["abilityName"] = "thtd_yoshika_01",
}
},
["rumia"] =
{
["rumia_reimu"] =
{
["abilityName"] = "thtd_rumia_04",
}
},
["meirin"] =
{
["meirin_sakuya"] =
{
["abilityName"] = "thtd_meirin_02",
}
},
["iku"] =
{
["tenshi_iku"] =
{
["abilityName"] = "thtd_iku_01",
}
},
["junko"] =
{
["junko_hecatia"] =
{
["abilityName"] = "thtd_junko_01",
}
},
["hecatia"] =
{
["junko_hecatia"] =
{
["abilityName"] = "thtd_hecatia_03",
}
},
["daiyousei"] =
{
["daiyousei_cirno"] =
{
["abilityName"] = "thtd_daiyousei_03",
}
},
}
function HasCombo(combo,name)
for k,v in pairs(combo) do
if k == name then
return true
end
end
return false
end
function CDOTA_BaseNPC:THTD_GetComboVoice(comboName)
local data = thtd_combo_table[self:GetUnitName()][comboName]
if data ~= nil and data["delay"] ~= nil then
data["comboName"] = comboName
else
data = nil
end
return data
end
-- 设置组合技能的生效或关闭返回组合语音数据组组合影响升级技能为2级可设置此等级下光环开启、增加buff、返回语音。和或
function CDOTA_BaseNPC:THTD_Set_Combo(combo)
local comboVoiceTable = {}
local unitName = self:GetUnitName()
local comboList = thtd_combo_table[unitName]
if comboList == nil then
combo = {}
return comboVoiceTable
end
for k,v in pairs(comboList) do
local isChange = false
if v["abilityName"] ~= nil then
local ability = self:FindAbilityByName(v["abilityName"])
if ability == nil then
print("----------- "..unitName..": combo error, combo: "..k..", ability: "..v["abilityName"]..", ability is nil")
combo = {}
return comboVoiceTable
end
if ability:IsActivated() then
if HasCombo(combo, k) then
-- buff等级如果为1则仅开启buff不升级否则升级名称格式固定
local buffOrLevel = ability:GetSpecialValueFor("has_combo_buff")
if buffOrLevel > 0 and self:HasModifier("modifier_"..v["abilityName"].."_combo_buff") == false then
isChange = true
ability:ApplyDataDrivenModifier(self, self, "modifier_"..v["abilityName"].."_combo_buff", nil)
end
if ability:GetLevel() ~= 2 and buffOrLevel ~= 1 then
isChange = true
ability:SetLevel(2)
self[v["abilityName"].."bonus_level"] = nil
-- 升级后是否存在光环技能,名称格式固定
local auraName = "modifier_"..v["abilityName"].."_aura"
local auraLevel = ability:GetSpecialValueFor("open_aura_level") --开启等级要求
if auraLevel == 2 and self:HasModifier(auraName) == false then
ability:ApplyDataDrivenModifier(self, self, auraName, nil)
end
end
else
-- buff等级如果为1则仅开启buff不升级否则升级
local buffOrLevel = ability:GetSpecialValueFor("has_combo_buff")
if buffOrLevel > 0 and self:HasModifier("modifier_"..v["abilityName"].."_combo_buff") then
isChange = true
self:RemoveModifierByName("modifier_"..v["abilityName"].."_combo_buff")
end
if ability:GetLevel() > 1 and buffOrLevel ~= 1 then
isChange = true
ability:SetLevel(1)
self[v["abilityName"].."bonus_level"] = nil
local auraName = "modifier_"..v["abilityName"].."_aura"
local auraLevel = ability:GetSpecialValueFor("open_aura_level")
if auraLevel > 1 and self:HasModifier(auraName) then
self:RemoveModifierByName(auraName)
end
end
end
end
end
if v["abilityName2"] ~= nil then
local ability = self:FindAbilityByName(v["abilityName2"])
if ability == nil then
print("----------- "..unitName..": combo error, combo: "..k..", ability: "..v["abilityName2"]..", ability is nil")
combo = {}
return comboVoiceTable
end
if ability:IsActivated() then
if HasCombo(combo, k) then
-- buff等级如果为1则仅开启buff不升级否则升级名称格式固定
local buffOrLevel = ability:GetSpecialValueFor("has_combo_buff")
if buffOrLevel > 0 and self:HasModifier("modifier_"..v["abilityName2"].."_combo_buff") == false then
isChange = true
ability:ApplyDataDrivenModifier(self, self, "modifier_"..v["abilityName2"].."_combo_buff", nil)
end
if ability:GetLevel() ~= 2 and buffOrLevel ~= 1 then
isChange = true
ability:SetLevel(2)
self[v["abilityName2"].."bonus_level"] = nil
-- 升级后是否存在光环技能,名称格式固定
local auraName = "modifier_"..v["abilityName2"].."_aura"
local auraLevel = ability:GetSpecialValueFor("open_aura_level")
if auraLevel == 2 and self:HasModifier(auraName) == false then
ability:ApplyDataDrivenModifier(self, self, auraName, nil)
end
end
else
-- buff等级如果为1则仅开启buff不升级否则升级
local buffOrLevel = ability:GetSpecialValueFor("has_combo_buff")
if buffOrLevel > 0 and self:HasModifier("modifier_"..v["abilityName2"].."_combo_buff") then
isChange = true
self:RemoveModifierByName("modifier_"..v["abilityName2"].."_combo_buff")
end
if ability:GetLevel() > 1 and buffOrLevel ~= 1 then
isChange = true
ability:SetLevel(1)
self[v["abilityName2"].."bonus_level"] = nil
local auraName = "modifier_"..v["abilityName2"].."_aura"
local auraLevel = ability:GetSpecialValueFor("open_aura_level")
if auraLevel > 1 and self:HasModifier(auraName) then
self:RemoveModifierByName(auraName)
end
end
end
end
end
if isChange then
local voiceData = self:THTD_GetComboVoice(k)
if voiceData ~= nil then
table.insert(comboVoiceTable, voiceData)
end
end
end
combo = {}
return comboVoiceTable
end
function CDOTA_BaseNPC:THTD_chen_thtd_combo(combo)
local comboVoiceTable = {}
if HasCombo(combo,"chen_yukari_ran") then
if self.thtd_chen_01_distance_increase ~= 75 then
self.thtd_chen_01_distance_increase = 75
end
else
if self.thtd_chen_01_distance_increase ~= 100 then
self.thtd_chen_01_distance_increase = 100
end
end
combo = {}
return comboVoiceTable
end
function CDOTA_BaseNPC:THTD_sunny_thtd_combo(combo)
local comboVoiceTable = {}
if HasCombo(combo,"luna_star_sunny") and self.thtd_combo_fairyList == nil then
local hero = self:GetOwner()
local sunny = nil
local luna = nil
local star = nil
local sunnyList = {}
local lunaList = {}
local starList = {}
for k,v in pairs(hero.thtd_hero_tower_list) do
if v:GetUnitName() == "sunny" and v.thtd_is_in_fairy_combo~=true then
table.insert(sunnyList,v)
elseif v:GetUnitName() == "luna" and v.thtd_is_in_fairy_combo~=true then
table.insert(lunaList,v)
elseif v:GetUnitName() == "star" and v.thtd_is_in_fairy_combo~=true then
table.insert(starList,v)
end
end
if #sunnyList > 0 and #lunaList > 0 and #starList > 0 then
--最大连线距离
local maxDistance = 2000
for sunnyK,sunnyV in pairs(sunnyList) do
for lunaK,lunaV in pairs(lunaList) do
--计算连线距离,如果小于
if math.floor(GetDistanceBetweenTwoVec2D(sunnyV:GetAbsOrigin(), lunaV:GetAbsOrigin()) + 0.5) <= maxDistance then
for starK,starV in pairs(starList) do
--计算连线距离,如果小于
if math.floor(GetDistanceBetweenTwoVec2D(starV:GetAbsOrigin(), lunaV:GetAbsOrigin()) + 0.5) <= maxDistance and math.floor(GetDistanceBetweenTwoVec2D(starV:GetAbsOrigin(), sunnyV:GetAbsOrigin()) + 0.5) <= maxDistance then
sunny = sunnyV
luna = lunaV
star = starV
break
end
end
end
if sunny ~= nil then break end
end
if sunny ~= nil then break end
end
end
if sunny~=nil and luna~=nil and star~=nil then
local sunny_effectIndex = ParticleManager:CreateParticle("particles/heroes/daiyousei/ability_daiyousei_03.vpcf", PATTACH_CUSTOMORIGIN, sunny)
ParticleManager:SetParticleControlEnt(sunny_effectIndex , 0, sunny, 5, "attach_hitloc", Vector(0,0,0), true)
ParticleManager:SetParticleControlEnt(sunny_effectIndex , 1, luna, 5, "attach_hitloc", Vector(0,0,0), true)
local luna_effectIndex = ParticleManager:CreateParticle("particles/heroes/daiyousei/ability_daiyousei_03.vpcf", PATTACH_CUSTOMORIGIN, luna)
ParticleManager:SetParticleControlEnt(luna_effectIndex , 0, luna, 5, "attach_hitloc", Vector(0,0,0), true)
ParticleManager:SetParticleControlEnt(luna_effectIndex , 1, star, 5, "attach_hitloc", Vector(0,0,0), true)
local star_effectIndex = ParticleManager:CreateParticle("particles/heroes/daiyousei/ability_daiyousei_03.vpcf", PATTACH_CUSTOMORIGIN, star)
ParticleManager:SetParticleControlEnt(star_effectIndex , 0, star, 5, "attach_hitloc", Vector(0,0,0), true)
ParticleManager:SetParticleControlEnt(star_effectIndex , 1, sunny, 5, "attach_hitloc", Vector(0,0,0), true)
sunny.thtd_is_in_fairy_combo = true
star.thtd_is_in_fairy_combo = true
luna.thtd_is_in_fairy_combo = true
self.thtd_combo_fairyList =
{
sunny = sunny,
star = star,
luna = luna,
}
self:SetContextThink(DoUniqueString("thtd_fairy_combo"),
function()
if GameRules:IsGamePaused() then return 0.03 end
if THTD_IsValid(self) == false or THTD_IsValid(star) == false or THTD_IsValid(luna) == false then
ParticleManager:DestroyParticleSystem(luna_effectIndex,true)
luna.thtd_is_in_fairy_combo = nil
ParticleManager:DestroyParticleSystem(star_effectIndex,true)
star.thtd_is_in_fairy_combo = nil
ParticleManager:DestroyParticleSystem(sunny_effectIndex,true)
sunny.thtd_is_in_fairy_combo = nil
sunny.thtd_combo_fairyList = nil
self:GetOwner():THTD_HeroComboRefresh()
return nil
end
return 0.03
end,
0)
end
end
combo = {}
return comboVoiceTable
end
function CDOTA_BaseNPC:THTD_wriggle_thtd_combo(combo)
local comboVoiceTable = {}
if HasCombo(combo,"wriggle_rumia") then
if self.thtd_wriggle_rumia_combo ~= true then
self.thtd_wriggle_rumia_combo = true
end
else
if self.thtd_wriggle_rumia_combo ~= false then
self.thtd_wriggle_rumia_combo = false
end
end
combo = {}
return comboVoiceTable
end
function UpdatePrismriverComboName(caster,target)
if target.thtd_prismriver_comboName == nil then
target.thtd_prismriver_comboName = {[1]="",[2]="",[3]=""}
end
target.thtd_prismriver_comboName[1] = target.thtd_prismriver_comboName[2]
target.thtd_prismriver_comboName[2] = target.thtd_prismriver_comboName[3]
target.thtd_prismriver_comboName[3] = caster:GetUnitName()
end
function GetPrismriverComboName(target)
if target.thtd_prismriver_comboName == nil then
target.thtd_prismriver_comboName = {[1]="",[2]="",[3]=""}
end
return target.thtd_prismriver_comboName[1]..target.thtd_prismriver_comboName[2]..target.thtd_prismriver_comboName[3]
end
function ResetPrismriverComboName(target)
target.thtd_prismriver_comboName = {[1]="",[2]="",[3]=""}
end
function GetCountPrismriver(target)
if target.thtd_prismriver_comboName == nil then return 0 end
local count = 0
if target.thtd_prismriver_comboName[1] ~= "" then
count = count + 1
end
if target.thtd_prismriver_comboName[2] ~= "" then
count = count + 1
end
if target.thtd_prismriver_comboName[3] ~= "" then
count = count + 1
end
return count
end

View File

@@ -0,0 +1,626 @@
-- 发送消息(左侧),例如 SendMsg(0, "test_tip", "总输出",90) "test_tip" "{s:player_name}<font color='red'>上一波最终阵容{s:locstring_value}低于{d:int_value}%总血量,不计入有效波数</font>"
-- 可用固有系统变量名称:{s:player_name} 玩家姓名(会显示玩家头像)
-- 可用变量(名称不可变):{s:locstring_value} 文本,可以是本地化字符如"#DOTA_Tooltip_Ability_item_life_rune"{d:int_value}数字,{s:ability_name}技能名称,%s1替代文本用string_replace_token取代
-- 可以直接发送非本地化的文字,使用上述变量
function SendMsg(playerID, message_text, locstring_value, int_value, ability_name, string_replace)
local gameEvent = {}
gameEvent["player_id"] = playerID
gameEvent["locstring_value"] = locstring_value
gameEvent["teamnumber"] = -1 --DOTA_TEAM_GOODGUYS
gameEvent["int_value"] = int_value
gameEvent["message"] = message_text
gameEvent["string_replace_token"] = string_replace
gameEvent["ability_name"] = ability_name
FireGameEvent( "dota_combat_event_message", gameEvent )
end
if CustomEvent == nil then
CustomEvent = {}
end
function CustomEvent:GetHero(data)
local player = PlayerResource:GetPlayer(data.PlayerID)
if player then
local hero = player:GetAssignedHero()
if hero then
return hero
end
end
return nil
end
CustomEvent.on = function( event, func )
CustomGameEventManager:RegisterListener(event, function(unused, data) func(data) end)
end
-- 聊天栏显示消息配合js实现变量化
CustomEvent.on('custom_game_chat_msg', function(data)
GameRules:SendCustomMessage(data.msg, PlayerResource:GetTeam(data.PlayerID), 0)
end)
-- 选择难度
PlayersSelectedDifficulty = {}
CustomEvent.on('custom_game_select_difficulty', function(data)
if #PlayersSelectedDifficulty == 0 then
for i=0,PlayerResource:GetPlayerCount()-1 do
if PlayerResource:IsValidPlayer(i) then
PlayersSelectedDifficulty[i] = 0
end
end
end
local player = PlayerResource:GetPlayer(data.PlayerID)
if player ==nil then return end
PlayersSelectedDifficulty[data.PlayerID] = data.level or 0
CustomNetTables:SetTableValue("CustomGameInfo", "PlayersSelectedDifficulty", PlayersSelectedDifficulty )
end)
-- 完成状态
local PlayersCompleteStatus = {}
CustomEvent.on('custom_game_complete_select_cards', function(data)
if PlayersCompleteStatus[data.PlayerID] == 1 then return end
for k,v in pairs(data["cards"]) do
local itemTable =
{
["itemName"] = k,
["quality"]= towerNameList[k]["quality"],
["count"]= v,
}
table.insert(towerPlayerList[data.PlayerID+1],itemTable)
end
PlayersCompleteStatus[data.PlayerID] = 1
CustomNetTables:SetTableValue("CustomGameInfo", "PlayersCompleteStatus", PlayersCompleteStatus )
SetNetTableTowerPlayerList(data.PlayerID)
end)
-- 投票踢人
local playerVote =
{
vote_time = 0,
vote_player = -1,
kicked_player = -1,
kicked_line = -1,
agree_players = {}
}
CustomEvent.on('custom_game_kick_vote', function(data)
if SpawnSystem.CurWave > 50 + 20 then
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(data.PlayerID), "display_custom_error", {msg="cannot_vote_when_over_some_waves"})
return
end
local player = PlayerResource:GetPlayer(data.PlayerID)
if player ==nil then return end
local hero = player:GetAssignedHero()
if hero.is_game_over == true then return end
if playerVote.kicked_player ~= - 1 and (math.floor(GameRules:GetGameTime()) - playerVote.vote_time) < 60 then
CustomGameEventManager:Send_ServerToPlayer(player, "show_message", {msg="player_in_vote", duration=10, params={count=playerVote.kicked_player+1}, color="#ff0"})
return
end
local kicked_player = -1
local spawner = SpawnSystem.AttackingSpawner
if spawner == nil or #spawner == 0 then return end
for _, spawnerLine in pairs(spawner) do
if spawnerLine.index == data.line_index then
kicked_player = spawnerLine.hero.thtd_player_id
break
end
end
if kicked_player == -1 then return end
playerVote.vote_time = math.floor(GameRules:GetGameTime())
playerVote.vote_player = data.PlayerID
playerVote.kicked_player = kicked_player
playerVote.kicked_line = data.line_index
playerVote.agree_players = {}
CustomGameEventManager:Send_ServerToAllClients("kick_player", {vote_player=playerVote.vote_player, kicked_player=playerVote.kicked_player, kicked_line = playerVote.kicked_line})
end)
CustomEvent.on('custom_game_kick_accept', function(data)
local player = PlayerResource:GetPlayer(data.PlayerID)
if player ==nil then return end
local hero = player:GetAssignedHero()
if hero.is_game_over == true then return end
if playerVote.kicked_player == -1 then return end
if data.accept == 1 then
table.insert(playerVote.agree_players, data.PlayerID)
local agrees = playerVote.agree_players
if #agrees >= (GetValidVotePlayerCount() - 1) then
KickPlayer()
end
else
playerVote.vote_time = 0
playerVote.vote_player = -1
playerVote.kicked_player = -1
playerVote.kicked_line = - 1
playerVote.agree_players = {}
CustomGameEventManager:Send_ServerToAllClients("show_message", {msg="player_vote_no_pass", duration=10, params={count=data.PlayerID+1}, color="#ff0"})
end
end)
function KickPlayer()
for index,hero in pairs(GameRules.HeroList) do
if hero ~= nil and hero.is_game_over ~= true and hero.thtd_player_id == playerVote.kicked_player then
SpawnSystem:GameOver(hero)
CustomGameEventManager:Send_ServerToAllClients("show_message", {msg="player_vote_pass", duration=10, params={count=playerVote.kicked_player+1}, color="#ff0"})
break
end
end
playerVote.vote_time = 0
playerVote.vote_player = -1
playerVote.kicked_player = -1
playerVote.kicked_line = - 1
playerVote.agree_players = {}
end
function GetValidVotePlayerCount()
local count = 0
for index,hero in pairs(GameRules.HeroList) do
if hero~=nil and hero:IsNull()==false and hero:IsAlive() and hero.is_game_over~=true and hero.thtd_game_info["is_player_connected"] then
count = count + 1
end
end
return count
end
-- 选择初始卡
CustomEvent.on('custom_game_select_start_card', function(data)
local player = PlayerResource:GetPlayer(data.PlayerID)
if player ==nil then return end
local hero = player:GetAssignedHero()
if hero:GetLevel() >= 6 then
CustomGameEventManager:Send_ServerToPlayer(player, "select_start_card_finish", {})
return
end
if hero:GetNumItemsInInventory() >= THTD_MAX_ITEM_SLOT then
CustomGameEventManager:Send_ServerToPlayer(player, "display_custom_error", {msg="not_enough_item_slot"})
return
end
local item = CreateItem(data.ItemName, nil, nil)
if item ~= nil then
item.owner_player_id = hero.thtd_player_id
item.is_bonus_item = true
hero:AddItem(item)
-- if data.ItemName == "item_0003" then
-- item = CreateItem("item_0088", nil, nil)
-- item.owner_player_id = hero.thtd_player_id
-- item.is_bonus_item = true
-- hero:AddItem(item)
-- end
for i=1,5 do
hero:HeroLevelUp(false)
end
-- hero:SetAbilityPoints(0)
CustomGameEventManager:Send_ServerToPlayer(player, "select_start_card_finish", {})
end
end)
-- 选择初始奖励卡
CustomEvent.on('custom_game_select_bonus_card', function(data)
local player = PlayerResource:GetPlayer(data.PlayerID)
if player ==nil then return end
local hero = player:GetAssignedHero()
if hero:GetLevel() >= 9 then return end
if hero:GetNumItemsInInventory() >= THTD_MAX_ITEM_SLOT then
CustomGameEventManager:Send_ServerToPlayer(player, "select_bonus_card_no_finish", {})
CustomGameEventManager:Send_ServerToPlayer(player, "display_custom_error", {msg="not_enough_item_slot"})
return
end
local item = CreateItem(data.ItemName, nil, nil)
if item ~= nil then
item.owner_player_id = hero.thtd_player_id
item.is_bonus_item = true
hero:AddItem(item)
if data.ItemName == "item_3149" then
for i=1,3 do
local itemNew = CreateItem("item_3149", nil, nil)
if itemNew ~= nil then
itemNew.owner_player_id = playerId
itemNew:SetPurchaser(hero)
hero:AddItem(itemNew)
end
end
end
local cardName = item:THTD_GetCardName()
if item:THTD_IsCardHasVoice() == true then EmitSoundOn(THTD_GetVoiceEvent(cardName,"spawn"),hero) end
if item:THTD_IsCardHasPortrait() == true then
local portraits= item:THTD_GetPortraitPath(cardName)
local effectIndex = ParticleManager:CreateParticle(portraits, PATTACH_WORLDORIGIN, nil)
ParticleManager:SetParticleControl(effectIndex, 0, Vector(-58,-80,0))
ParticleManager:SetParticleControl(effectIndex, 1, Vector(80,0,0))
ParticleManager:DestroyParticleSystemTime(effectIndex,6.0)
effectIndex = ParticleManager:CreateParticle("particles/portraits/portraits_ssr_get_screen_effect.vpcf", PATTACH_WORLDORIGIN, nil)
ParticleManager:DestroyParticleSystemTime(effectIndex,4.0)
hero:EmitSound("Sound_THTD.thtd_draw_ssr")
end
for i=1,3 do
hero:HeroLevelUp(false)
end
end
end)
-- 御币选择卡片
CustomEvent.on('select_card', function(data)
local player = PlayerResource:GetPlayer(data.PlayerID)
if player==nil then return end
local caster = player:GetAssignedHero()
if caster == nil then return end
local itemName = data.itemname
if itemName ~= nil and THTD_GetItemCountByName(data.PlayerID,itemName) > 0 then
if caster.thtd_last_select_item~=nil and caster.thtd_last_select_item:IsNull()==false then
OnItemDestroyed(caster, caster.thtd_last_select_item, false)
caster:THTD_AddCardPoolItem(itemName)
end
end
end)
-- 战利品奖励选择
CustomEvent.on('select_battle_bonus_card', function(data)
local itemName = data.itemname
local hero = GameRules.HeroList[data.PlayerID]
if hero.bb_buff == nil then hero.bb_buff = {} end
if #hero.bb_buff > 5 then return end
if string.sub(itemName,1,6) == "item_3" then
if itemName == "item_3011" then
GameRules.player_bb_buff[data.PlayerID]["item_3011"] = GameRules.player_bb_buff[data.PlayerID]["item_3011"] + 30
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3011", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3012" then
GameRules.player_bb_buff[data.PlayerID]["item_3012"] = GameRules.player_bb_buff[data.PlayerID]["item_3012"] + 15
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3012", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3013" then
GameRules.player_bb_buff[data.PlayerID]["item_3013"] = GameRules.player_bb_buff[data.PlayerID]["item_3013"] * (1 - 0.5)
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3013", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3014" then
GameRules.player_bb_buff[data.PlayerID]["item_3014"] = GameRules.player_bb_buff[data.PlayerID]["item_3014"] + 1
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3014", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3015" then
GameRules.player_bb_buff[data.PlayerID]["item_3015"] = GameRules.player_bb_buff[data.PlayerID]["item_3015"] + 15
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3015", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3016" then
GameRules.player_bb_buff[data.PlayerID]["item_3016"] = GameRules.player_bb_buff[data.PlayerID]["item_3016"] + 1
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3016", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3017" then
GameRules.player_bb_buff[data.PlayerID]["item_3017"] = GameRules.player_bb_buff[data.PlayerID]["item_3017"] + 5
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3017", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3018" then
GameRules.player_bb_buff[data.PlayerID]["item_3018"] = GameRules.player_bb_buff[data.PlayerID]["item_3018"] * (1 - 0.2)
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3018", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3019" then
GameRules.player_bb_buff[data.PlayerID]["item_3019"] = GameRules.player_bb_buff[data.PlayerID]["item_3019"] + 50
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3019", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3020" then
GameRules.player_bb_buff[data.PlayerID]["item_3020"] = GameRules.player_bb_buff[data.PlayerID]["item_3020"] + 50
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3020", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3021" then
GameRules.player_bb_buff[data.PlayerID]["item_3021"] = GameRules.player_bb_buff[data.PlayerID]["item_3021"] + 75
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3021", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3022" then
local gold = 10000
THTD_ModifyGoldEx(data.PlayerID, gold , true, DOTA_ModifyGold_Unspecified)
SendOverheadEventMessage(hero:GetPlayerOwner(), OVERHEAD_ALERT_GOLD, hero, gold, hero:GetPlayerOwner())
hero:EmitSound("Sound_THTD.thtd_nazrin_01")
elseif itemName == "item_3023" then
GameRules.player_bb_buff[data.PlayerID]["item_3023"] = GameRules.player_bb_buff[data.PlayerID]["item_3023"] + 50
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3023", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3024" then
GameRules.player_bb_buff[data.PlayerID]["item_3024"] = GameRules.player_bb_buff[data.PlayerID]["item_3024"] + 50
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3024", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3025" then
GameRules.player_bb_buff[data.PlayerID]["item_3025"] = GameRules.player_bb_buff[data.PlayerID]["item_3025"] + 5
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3025", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3026" then
GameRules.player_bb_buff[data.PlayerID]["item_3026"] = GameRules.player_bb_buff[data.PlayerID]["item_3026"] + 30
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3026", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3027" then
GameRules.player_bb_buff[data.PlayerID]["item_3027"] = GameRules.player_bb_buff[data.PlayerID]["item_3027"] + 1
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3027", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3028" then
GameRules.player_bb_buff[data.PlayerID]["item_3028"] = GameRules.player_bb_buff[data.PlayerID]["item_3028"] + 1
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3028", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3029" then
GameRules.player_bb_buff[data.PlayerID]["item_3029"] = GameRules.player_bb_buff[data.PlayerID]["item_3029"] + 20
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3029", nil)
table.insert(hero.bb_buff, itemName)
elseif itemName == "item_3030" then
GameRules.player_bb_buff[data.PlayerID]["item_3030"] = GameRules.player_bb_buff[data.PlayerID]["item_3030"] + 50
hero:AddNewModifier(hero, nil, "modifier_bb_buff_3030", nil)
table.insert(hero.bb_buff, itemName)
else
end
else
local item = CreateItem(itemName, nil, nil)
if item ~= nil then
item.owner_player_id = hero.thtd_player_id
item:SetPurchaser(hero)
item:SetPurchaseTime(1.0)
if hero:GetNumItemsInInventory() >= THTD_MAX_ITEM_SLOT then
CreateItemOnPositionSync(hero:GetAbsOrigin(), item)
else
hero:AddItem(item)
end
end
end
end)
-- AI选择
CustomEvent.on('custom_game_choose_ai', function(data)
local caster = EntIndexToHScript(data.entity)
if caster == nil then return end
if data.result == 1 or data.result == true then
caster["thtd_"..data.name.."_0"..tostring(data.skill).."_cast"] = true
else
caster["thtd_"..data.name.."_0"..tostring(data.skill).."_cast"] = false
end
end)
CustomEvent.on('custom_game_command', function(data)
if data["cmd"] == "wave" then
SpawnSystem.ReachToWave = data["param"]
CustomGameEventManager:Send_ServerToAllClients("show_message", {msg="reach_to_wave", duration=20, params={count=data["param"]}, color="#ff0"})
return
end
if data["cmd"] == "add" then
PlayerResource:ModifyGold(data["PlayerID"], 95000 , true, DOTA_ModifyGold_Unspecified)
local player = PlayerResource:GetPlayer(data["PlayerID"])
local itemName = "item_"..data["param"]
if string.len(itemName) ~= 9 then return end
local item = CreateItem(itemName, nil, nil)
if player ~= nil and item ~= nil then
local hero = player:GetAssignedHero()
if hero:GetNumItemsInInventory() < THTD_MAX_ITEM_SLOT then
item.owner_player_id = hero.thtd_player_id
hero:AddItem(item)
end
end
return
end
if data["cmd"] == "tp" then
local pos = string.split(data["param"], ",")
if pos == nil or #pos < 2 then
local player = PlayerResource:GetPlayer(data["PlayerID"])
local hero = player:GetAssignedHero()
local targets = THTD_FindUnitsInRadius(hero, hero:GetAbsOrigin(), 1000)
for k,v in pairs(targets) do
print("----------")
print(v.thtd_next_corner)
print(v.next_move_forward)
print(v.next_move_point)
hero:SetAbsOrigin(v.next_move_point)
break
end
return
end
local vec = Vector(tonumber(pos[1]), tonumber(pos[2]), 144)
if vec ~= nil then
local player = PlayerResource:GetPlayer(data["PlayerID"])
local hero = player:GetAssignedHero()
hero:SetAbsOrigin(vec)
end
return
end
if data["cmd"] == "clearrank" then
Service:ClearSameRank()
return
end
if data["cmd"] == "lv" then
local player = PlayerResource:GetPlayer(data["PlayerID"])
if player then
local hero = player:GetAssignedHero()
for k,v in pairs(hero.thtd_hero_tower_list) do
if v~=nil and v:IsNull()==false and v:IsAlive() and v:THTD_IsTower() then
v:THTD_SetAbilityLevelUp()
v:THTD_SetAbilityLevelUp()
v:THTD_SetAbilityLevelUp()
v:THTD_SetAbilityLevelUp()
if v:THTD_GetStar() < 5 then
v:THTD_SetStar(5)
end
if v:THTD_GetLevel() < THTD_MAX_LEVEL then
v:THTD_SetLevel(THTD_MAX_LEVEL)
end
end
end
end
return
end
if data["cmd"] == "boss" then
SpawnSystem.AttackingSpawner[data["PlayerID"]+1].nextBossName = data["param"]
return
end
end)
CustomEvent.on('custom_game_save_cardgroup', function(data)
Service:SaveCardGroup(data.PlayerID, data.groupkey, data.groupdata)
end)
CustomEvent.on('custom_game_rank_detail', function(data)
local playerid = data.PlayerID
local rankdata = {}
rankdata['index'] = data.index
local playerRankData
if data.type == 1 then
playerRankData = GameRules.players_rank_data[data.index]
else
playerRankData = GameRules.players_team_rank_data[data.index]
end
if tostring(PlayerResource:GetSteamID(playerid)) == tostring(playerRankData.steamid) then
rankdata['is_local_player'] = 1
else
rankdata['is_local_player'] = 0
end
rankdata['wave'] = playerRankData['wave']
for k,v in pairs(playerRankData) do
if string.sub(k,1,4) == "card" then
rankdata[k] = v
end
end
if data.type == 1 then
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerid), "thtd_rank_detail", rankdata)
else
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerid), "thtd_team_rank_detail", rankdata)
end
rankdata = {}
end)
CustomEvent.on('custom_game_rank_reset', function(data)
if tostring(PlayerResource:GetSteamID(data.PlayerID)) ~= GameRules.GameData.admin then return end
if data.index > 0 then
if data.type == 1 then
Service:ResetRank(data.index,"S")
else
Service:ResetRank(data.index,"D")
end
else
if data.type == 1 then
local total = #GameRules.players_rank
local count = 1
GameRules:GetGameModeEntity():SetContextThink(DoUniqueString("ResetRankAll"),
function()
Service:ResetRank(count,"S")
count = count + 1
if count > total then
return nil
else
return 1.0
end
end,
0)
else
local total = #GameRules.players_team_rank
local count = 1
GameRules:GetGameModeEntity():SetContextThink(DoUniqueString("ResetRankAll"),
function()
Service:ResetRank(count,"D")
count = count + 1
if count > total then
return nil
else
return 1.0
end
end,
0)
end
end
end)
CustomEvent.on('custom_game_train_card', function(data)
local playerid = data.PlayerID
local itemName = data.item_name
local levelUp = data.level_up
if towerNameList[itemName] == nil then
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerid), "thtd_train_card_complete", {code = 0, msg = "该卡牌还在制作中,请关注后续更新"})
return
end
local maxLevel = THTD_GetMaxPowerLevel(towerNameList[itemName]["cardname"])
if GameRules.PlayerData[playerid] == nil then
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerid), "thtd_train_card_complete", {code = 0, msg = "没有用户数据"})
elseif GameRules.PlayerData[playerid]["level_list"] == nil then
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerid), "thtd_train_card_complete", {code = 0, msg = "获取已培养清单出错"})
elseif GameRules.PlayerData[playerid]["level_list"][itemName] ~= nil and GameRules.PlayerData[playerid]["level_list"][itemName] >= maxLevel then
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerid), "thtd_train_card_complete", {code = 0, msg = "已达到最大潜能"})
else
local point = 10
if towerNameList[itemName]["quality"] == 1 then
point = 5
end
local addLevel = math.min(levelUp, maxLevel - (GameRules.PlayerData[playerid]["level_list"][itemName] or 0))
point = point * addLevel
if GameRules.PlayerData[playerid]["point"] >= point then
Service:SaveCardLevel(playerid, itemName, addLevel)
else
CustomGameEventManager:Send_ServerToPlayer(PlayerResource:GetPlayer(playerid), "thtd_train_card_complete", {code = 0, msg = "符卡精华数量不足"})
end
end
end)
CustomEvent.on('custom_game_pay_select', function(data)
Service:CreateShopOrder(data.PlayerID, data.method, data.amount, data.price, data.type)
end)
CustomEvent.on('custom_game_pay_query', function(data)
Service:PayCheck(data.PlayerID)
end)
CustomEvent.on('custom_game_pay_auto_query', function(data)
Service:PayAutoCheck(data.PlayerID)
end)
CustomEvent.on('custom_game_show_dps_card', function(data)
local ent = data.ent
if ent == 0 then return end
local unit = EntIndexToHScript(ent)
if not THTD_IsValid(unit) then return end
if unit.show_pds_card ~= true then
unit.show_pds_card = true
local count = 5
unit:SetContextThink(DoUniqueString("custom_game_show_dps_card"),
function()
count = count - 1
if count < 0 then
unit:THTD_CreateLevelEffect()
unit.show_pds_card = nil
return nil
end
if count%2 == 0 then
unit:THTD_DestroyLevelEffect()
else
unit:THTD_CreateLevelEffect()
end
return 0.3
end,
0.3)
end
end)
CustomEvent.on('custom_game_pause_game', function(data)
if GameRules:IsGamePaused() then
PauseGame(false)
else
PauseGame(true)
GameRules:SendCustomMessage("#pause_game_forever", DOTA_TEAM_GOODGUYS, 0)
end
end)
CustomEvent.on('custom_game_update_data', function(data)
Service:GetPlayerBaseData(data.PlayerID)
end)

View File

@@ -0,0 +1,518 @@
-- 生命移除伤害,只会计算少女之抵抗,参数:单位、目标、百分比值、是否按当前生命值
function UnitDamageHpRemove(caster, target, percent, isCurrentHp)
if THTD_IsValid(caster) and THTD_IsValid(target) then
local tower = nil
if caster:THTD_IsTower() then
tower = caster
elseif THTD_IsValid(caster.thtd_spawn_unit_owner) and caster.thtd_spawn_unit_owner:THTD_IsTower() then
tower = caster.thtd_spawn_unit_owner
end
local health = target:GetHealth()
local damage = 0
if isCurrentHp == true then
damage = health * percent / 100
else
damage = target:GetMaxHealth() * percent / 100
end
local factor = 1.0
if target.unlimited_resist ~= nil then
factor = 1 - target.unlimited_resist/100
end
if damage * factor >= health then
if tower ~= nil then
tower:THTD_AddTowerDamage(health)
end
target:SetHealth(1)
local DamageTable = {
ability = nil,
victim = target,
attacker = caster,
damage = 10000,
damage_type = DAMAGE_TYPE_PURE,
damage_flags = DOTA_DAMAGE_FLAG_NONE
}
ApplyDamage(DamageTable)
else
target:SetHealth(health - damage * factor)
if tower ~= nil then
tower:THTD_AddTowerDamage(damage * factor)
end
end
end
end
-- 强制击杀
function CDOTA_BaseNPC:NpcKill(target)
if target == nil or target:IsNull() or target:IsAlive() == false then
return
end
local health = target:GetHealth()
target.diseble_buff = true
target:ForceKill(false)
self:THTD_AddTowerDamage(health)
end
-- 卡牌秒杀技能,具有统一的上限
function CDOTA_BaseNPC:AbilityKill(target, ability)
local tower
if self:THTD_IsTower() then
tower = self
elseif self.thtd_spawn_unit_owner ~= nil and self.thtd_spawn_unit_owner:THTD_IsTower() then
tower = self.thtd_spawn_unit_owner
else
print("----- error : AbilityKill is not a tower cast")
return
end
-- if GameRules.player_bb_buff[playerid]["item_3019"] > 0 and GameRules.player_bb_buff[playerid]["item_3019_enable"] then
-- factor = 1 + GameRules.player_bb_buff[playerid]["item_3019"]/100
-- end
local damage = tower:GetKillDamage()
local damageType = DAMAGE_TYPE_PURE
if ability ~= nil then
damageType = ability:GetAbilityDamageType()
end
local DamageTable = {
ability = ability,
victim = target,
attacker = tower,
damage = damage,
damage_type = damageType,
damage_flags = DOTA_DAMAGE_FLAG_NONE
}
UnitDamageTarget(DamageTable)
end
-- 获取卡牌秒杀伤害
function CDOTA_BaseNPC:GetKillDamage()
return self:THTD_GetStarDamage() * 100
end
-- 造成溢出伤害
function THTD_OverDamage(caster, ability, damage, point, range)
if not THTD_IsValid(caster) then return end
if damage == nil or damage <= 0 then return end
local targetRange = range or 400
local damageType = DAMAGE_TYPE_PURE
if ability ~= nil then
damageType = ability:GetAbilityDamageType()
end
caster:SetContextThink(DoUniqueString("thtd_over_damage"),
function()
if GameRules:IsGamePaused() then return 0.03 end
local targets = THTD_FindUnitsInRadius(caster,point,range)
for k,v in pairs(targets) do
local DamageTable = {
ability = ability,
victim = v,
attacker = caster,
damage = damage,
damage_type = damageType,
damage_flags = DOTA_DAMAGE_FLAG_NONE
}
UnitDamageTarget(DamageTable)
local effectIndex = ParticleManager:CreateParticle("particles/heroes/thtd_flandre/abiilty_flandre_02_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
ParticleManager:SetParticleControl(effectIndex , 0 , v:GetOrigin())
ParticleManager:DestroyParticleSystem(effectIndex,false)
end
return nil
end,
0.1)
end
-- 汇总式伤害结算
function UnitDamageApply(unit)
if unit == nil or unit:IsNull() or unit:IsAlive() == false then return end
if unit.thtd_player_index == nil then return end
if unit.incoming_damage == nil or unit.incoming_damage == 0 then return end
local DamageTable = {
ability = nil,
victim = unit,
attacker = GameRules.HeroList[unit.thtd_player_index],
damage = unit.incoming_damage,
damage_type = DAMAGE_TYPE_PURE,
damage_flags = DOTA_DAMAGE_FLAG_NONE
}
unit.incoming_damage = 0
ApplyDamage(DamageTable)
end
-- 汇总式伤害计算如果isTest为true则返回生命/伤害占比,即目标当前生命值/本次伤害量的值isAttack为普通攻击
function UnitDamageTarget(DamageTable, isTest, isAttack)
local caster = DamageTable.attacker
local target = DamageTable.victim
-- local ability = DamageTable.ability
local damageType = DamageTable.damage_type
local damage = DamageTable.damage or 0
local returnNull = 9999
if damage <= 0 then return returnNull end
if target == nil or target:IsNull() or target:IsAlive() == false then return returnNull end
if target.thtd_damage_lock == true then return returnNull end
-- 召唤物继承主人的装备和buff效果
local tower
if caster:THTD_IsTower() then
tower = caster
elseif caster.thtd_spawn_unit_owner ~= nil and caster.thtd_spawn_unit_owner:THTD_IsTower() then
tower = caster.thtd_spawn_unit_owner
else
return returnNull
end
-- 伤害类型转换
if tower:HasModifier("modifier_junko_01") then
damageType = DAMAGE_TYPE_PURE
elseif tower:HasModifier("modifier_daiyousei_03") then
damageType = DAMAGE_TYPE_MAGICAL
elseif tower:HasModifier("modifier_momiji_02") then
damageType = DAMAGE_TYPE_PHYSICAL
elseif target:HasModifier("modifier_sunny_02_debuff") then
damageType = DAMAGE_TYPE_PURE
end
-- 附加星能伤害如相机、BOSS键山雏
local extra = tower:GetExtraStarDamagePercentage()
if extra >= 1000000 then
local down = math.floor(extra/10000)
local up = extra - down * 10000 - 5000
if up ~= 0 then
damage = damage + tower:THTD_GetStarDamage() * up/100
end
if damage > tower:THTD_GetStarDamage() * math.floor(down/100) then
damage = damage * (down - math.floor(down/100) * 100)/100
end
elseif extra ~= 0 then
damage = damage + tower:THTD_GetStarDamage() * extra/100
end
-- 计算双抗伤害
if isAttack == true then --普通攻击已经是税后伤害
if damageType ~= DAMAGE_TYPE_PHYSICAL then
damage = damage / target:GetPhysicalFactor()
if damageType == DAMAGE_TYPE_MAGICAL then
damage = damage * target:GetMagicalFactor()
end
end
else
if damageType == DAMAGE_TYPE_MAGICAL then
damage = damage * target:GetMagicalFactor()
elseif damageType == DAMAGE_TYPE_PHYSICAL then
damage = damage * target:GetPhysicalFactor()
end
end
-- 装备4件套
if target:GetHealthPercent() > 70 and tower:HasModifier("modifier_item_2009_damage") then
damage = damage * 2
end
if target:GetHealthPercent() < 30 and tower:HasModifier("modifier_item_2010_damage") then
damage = damage * 2
end
-- 爆击伤害
if RollPercentage(tower:THTD_GetCritChance()) then
damage = damage * (1 + tower:THTD_GetCritDamage()/100)
end
-- 增伤效果
if damageType == DAMAGE_TYPE_PHYSICAL then
-- 攻击者物理增伤
damage = damage * (1 + tower:GetDamageOutgoingPhysical()/100)
-- 被攻击者物理伤害加深
damage = damage * (1 + target:GetDamageIncomingPhysical()/100)
-- 被攻击者物理伤害抵挡或附加
-- print("---- damage : ", damage)
damage = damage - target:GetDamageBlockPhysical()
-- print("damage block: ", damage)
elseif damageType == DAMAGE_TYPE_MAGICAL then
-- 攻击者魔法增伤
damage = damage * (1 + tower:GetDamageOutgoingMagical()/100)
-- 被攻击者魔法伤害加深
damage = damage * (1 + target:GetDamageIncomingMagical()/100)
-- 被攻击者魔法伤害抵挡或附加
damage = damage - target:GetDamageBlockMagical()
elseif damageType == DAMAGE_TYPE_PURE then
-- 攻击者纯粹增伤
damage = damage * (1 + tower:GetDamageOutgoingPure()/100)
-- 被攻击者纯粹伤害加深
damage = damage * (1 + target:GetDamageIncomingPure()/100)
-- 被攻击者纯粹伤害抵挡或附加
damage = damage - target:GetDamageBlockPure()
end
if damage <= 0 then return returnNull end
-- 少女之抵抗
if target.unlimited_resist ~= nil then
damage = damage * (1 - target.unlimited_resist/100)
end
damage = math.floor(damage)
-- 伤害统计
if target.incoming_damage == nil then
target.incoming_damage = 0
end
local health = math.max(0, target:GetHealth() - target.incoming_damage)
if isTest ~= true then
local towerName = tower:GetUnitName()
tower:THTD_AddTowerDamage(math.min(damage, health))
-- 击杀则立即结算
if damage >= health then
local isDamageLock = false
if target.komachi_04_damage_lock == true then
isDamageLock = true
elseif target.flandre_damage_lock == true then
isDamageLock = true
if towerName == "flandre" then
if target.flandre_04_lock == true then
if DamageTable.ability ~= nil and DamageTable.ability:GetAbilityName() == "thtd_flandre_04" then
isDamageLock = false
end
else
isDamageLock = false
end
end
end
if isDamageLock == true then
target.incoming_damage = target.incoming_damage + math.max(0, health - 100)
UnitDamageApply(target)
else
target.incoming_damage = target.incoming_damage + damage
UnitDamageOnKill(tower, target)
UnitDamageApply(target)
if towerName == "flandre" and damage - health > 100 then
THTD_OverDamage(tower, tower:FindAbilityByName("thtd_flandre_02"), damage - health, target:GetOrigin(), 400)
end
end
else
target.incoming_damage = target.incoming_damage + damage
end
return returnNull
else
return health/damage
end
end
-- 技能的OnKill事件
function UnitDamageOnKill(caster, target)
local unitName = caster:GetUnitName()
if unitName == "nue" then
if caster:FindAbilityByName("thtd_nue_03"):GetLevel() >= 1 then
caster:FindAbilityByName("thtd_nue_01"):EndCooldown()
caster:FindAbilityByName("thtd_nue_02"):EndCooldown()
end
elseif unitName == "rumia" then
if caster.rumia_01_bonus == nil then
caster.rumia_01_bonus = 0
end
local max_count = caster:GetAbilityValue("thtd_rumia_01", "max_bonus")
if caster:IsPower999() then
if caster.rumia_01_bonus < max_count * 10 then
caster.rumia_01_bonus = caster.rumia_01_bonus + 1
caster:THTD_AddBasePower(1)
end
else
if caster.rumia_01_bonus < max_count then
caster.rumia_01_bonus = caster.rumia_01_bonus + 1
caster:THTD_AddBasePower(1)
elseif caster.rumia_01_bonus > max_count then
caster:THTD_AddBasePower(-(caster.rumia_01_bonus - max_count))
caster.rumia_01_bonus = max_count
end
end
elseif unitName == "yuyuko" then
if caster:HasModifier("modifier_yuyuko_03_think") then
if caster.yuyuko_kill_bonus_count == nil then
caster.yuyuko_kill_bonus_count = 0
end
local max_count = caster:GetAbilityValue("thtd_yuyuko_03", "max_count")
local power_bonus = caster:GetAbilityValue("thtd_yuyuko_03", "power_bonus")
if caster:IsPower999() then
if caster.yuyuko_kill_bonus_count < max_count * 3 then
caster.yuyuko_kill_bonus_count = caster.yuyuko_kill_bonus_count + 1
caster:THTD_AddBasePower(power_bonus)
end
else
if caster.yuyuko_kill_bonus_count < max_count then
caster.yuyuko_kill_bonus_count = caster.yuyuko_kill_bonus_count + 1
caster:THTD_AddBasePower(power_bonus)
elseif caster.yuyuko_kill_bonus_count > max_count then
caster:THTD_AddBasePower(-(caster.yuyuko_kill_bonus_count - max_count) * power_bonus)
caster.yuyuko_kill_bonus_count = max_count
end
end
end
elseif unitName == "koishi" then
if caster:HasModifier("passive_koishi_04_attack") then
local effectIndex = ParticleManager:CreateParticle("particles/heroes/moluo/ability_moluo03_explosion.vpcf", PATTACH_CUSTOMORIGIN, caster)
ParticleManager:SetParticleControl(effectIndex , 0, target:GetOrigin())
ParticleManager:SetParticleControl(effectIndex , 3, target:GetOrigin())
ParticleManager:DestroyParticleSystem(effectIndex,false)
end
elseif unitName == "sanae" or unitName == "kanako" or unitName == "suwako" then
caster:THTD_AddFaith()
elseif unitName == "futo" then
local modifier = caster:FindModifierByName("modifier_futo_02_buff")
if modifier == nil then
local ability = caster:FindAbilityByName("thtd_futo_02")
if ability:IsActivated() then
modifier = ability:ApplyDataDrivenModifier(caster, caster, "modifier_futo_02_buff", {Duration = caster:GetAbilityValue("thtd_futo_02", "duration_time")})
modifier:SetStackCount(1)
end
else
if modifier:GetStackCount() < caster:GetAbilityValue("thtd_futo_02", "max_count") then
modifier:IncrementStackCount()
end
modifier:SetDuration(caster:GetAbilityValue("thtd_futo_02", "duration_time"),false)
end
end
if caster:HasModifier("modifier_shinki_01_buff_kill") and caster.thtd_shinki_01_kill_count < 100 then
caster.thtd_shinki_01_kill_count = caster.thtd_shinki_01_kill_count + 1
caster:THTD_AddBasePower(1 * caster.thtd_shinki_01_kill_count, "thtd_shinki_01_kill")
caster:FindModifierByName("modifier_shinki_01_buff_kill"):SetStackCount(caster.thtd_shinki_01_kill_count)
end
if target:HasModifier("modifier_thtd_yuuka_03_death") then
local modifier = target:FindModifierByName("modifier_thtd_yuuka_03_death")
local yuuka = modifier:GetCaster()
local max_count = yuuka:GetAbilityValue("thtd_yuuka_03", "max_count")
local damage_up = yuuka:GetAbilityValue("thtd_yuuka_03", "damage_up")
if yuuka.thtd_yuuka_03_kill_count == nil then
yuuka.thtd_yuuka_03_kill_count = 0
end
if yuuka.thtd_yuuka_03_kill_count < max_count then
yuuka.thtd_yuuka_03_kill_count = yuuka.thtd_yuuka_03_kill_count + 1
local bonus = yuuka.thtd_yuuka_03_kill_count * damage_up
yuuka:AddDamageOutgoingAll(bonus, "thtd_yuuka_03_kill_bonus")
yuuka:THTD_AddBaseAttack(bonus, "thtd_yuuka_03_kill_bonus")
yuuka:THTD_AddBasePower(bonus, "thtd_yuuka_03_kill_bonus")
elseif yuuka.thtd_yuuka_03_kill_count > max_count then
yuuka.thtd_yuuka_03_kill_count = max_count
yuuka:AddDamageOutgoingAll(max_count * damage_up, "thtd_yuuka_03_kill_bonus")
yuuka:THTD_AddBaseAttack(max_count * damage_up, "thtd_yuuka_03_kill_bonus")
yuuka:THTD_AddBasePower(max_count * damage_up, "thtd_yuuka_03_kill_bonus")
end
end
end
-- 魔法抗性百分比更新正增负减如果小于0则设置为0
function CDOTA_BaseNPC:AddMagicalResist(addCount)
if addCount == nil or addCount == 0 then return end
addCount = math.floor(addCount)
if self.base_magical_resistance == nil then
self.base_magical_resistance = self:GetBaseMagicalResistanceValue()
end
if self.magical_resistance_to_zero == true then
self:SetBaseMagicalResistanceValue(0)
else
local magical_resistance = self.base_magical_resistance + addCount
self.base_magical_resistance = magical_resistance
if magical_resistance > 0 then
self:SetBaseMagicalResistanceValue(magical_resistance)
else
self:SetBaseMagicalResistanceValue(0)
end
end
end
-- 移除魔法抗性即一直设置为0
function CDOTA_BaseNPC:RemoveMagicalResist()
self.magical_resistance_to_zero = true
self:SetBaseMagicalResistanceValue(0)
end
-- 物理护甲更新正增负减如果小于0则设置为0注意只用基础护甲Dota2自带减甲类modifier不可使用
function CDOTA_BaseNPC:AddPhysicalArmor(addCount)
if addCount == nil or addCount == 0 then return end
addCount = math.floor(addCount*100)/100
if self.base_armor == nil then
self.base_armor = self:GetPhysicalArmorBaseValue()
end
if self.physical_armor_to_zero == true then
self:SetPhysicalArmorBaseValue(0)
else
local armor = self.base_armor + addCount
self.base_armor = armor
if armor > 0 then
self:SetPhysicalArmorBaseValue(armor)
else
self:SetPhysicalArmorBaseValue(0)
end
end
end
-- 移除物理护甲即强制一直设置为0
function CDOTA_BaseNPC:RemovePhysicalArmor()
self.physical_armor_to_zero = true
self:SetPhysicalArmorBaseValue(0)
end
-- 获取物理护甲后的伤害系数
function CDOTA_BaseNPC:GetPhysicalFactor()
local armor = self:GetPhysicalArmorValue(false)
if armor > 0 then
return 1 - (0.06 * armor /(1 + 0.06 * armor)) -- 7.27版本护甲计算
else
return 1 - (0.06 * armor /(1 - 0.06 * armor)) -- 7.27版本负护甲计算,负甲增伤
end
end
-- 获取魔法抗性后的伤害系数
function CDOTA_BaseNPC:GetMagicalFactor()
return 1 - self:GetBaseMagicalResistanceValue()/100
end
--增加毒的层数创建或更新对应buff
function CDOTA_BaseNPC:AddPoison(stackCount, caster)
local modifierName = "modifier_touhoutd_poison"
local modifier = self:FindModifierByName(modifierName)
if stackCount == nil then stackCount = 1 end
if modifier == nil then
if stackCount > 0 then
if caster == nil then caster = self end
modifier = self:AddNewModifier(caster, nil, modifierName, nil)
if modifier == nil then return end
modifier:SetStackCount(stackCount)
end
else
local count = modifier:GetStackCount() + stackCount
if count > 0 then
modifier:SetStackCount(count)
else
self:RemoveModifierByName(modifierName)
end
end
end
--获取毒的层数没有则返回0
function CDOTA_BaseNPC:GetPoisonCount()
local modifierName = "modifier_touhoutd_poison"
local modifier = self:FindModifierByName(modifierName)
if modifier == nil then
return 0
else
return modifier:GetStackCount()
end
end

164
scripts/vscripts/system/items.lua Executable file
View File

@@ -0,0 +1,164 @@
function CDOTABaseAbility:THTD_UpdateItemStarLevel()
local tower = self:THTD_GetTower()
if tower == nil then
return
end
local star = tower:THTD_GetStar()
local level = tower:THTD_GetLevel()
local item_level = (star-1) * 10 + level
self:SetLevel(item_level) -- 也可以用 self:GetSecondaryCharges()
-- star = math.floor((item_level-1)/10) + 1
-- level = item_level - (star-1) * 10
end
function CDOTABaseAbility:THTD_GetTower()
return self.tower or nil
end
function CDOTABaseAbility:THTD_RemoveItemInList(PlayerID)
local list_num = PlayerID+1
local itemName = self:GetAbilityName()
if itemName~=nil then
for k,v in pairs(towerPlayerList[list_num]) do
if v["itemName"] == itemName then
v["count"] = v["count"] - 1
if v["count"] <= 0 then
table.remove(towerPlayerList[list_num],k)
end
SetNetTableTowerPlayerList(PlayerID)
return
end
end
end
end
function THTD_AddItemToListByName(PlayerID,itemNameRelease)
local list_num = PlayerID+1
local itemName = itemNameRelease
if itemName~=nil then
for k,v in pairs(towerPlayerList[list_num]) do
if v["itemName"] == itemName then
v["count"] = v["count"] + 1
SetNetTableTowerPlayerList(PlayerID)
return
end
end
local itemTable =
{
["itemName"] = itemName,
["quality"]= towerNameList[itemName]["quality"],
["count"]= 1,
}
table.insert(towerPlayerList[PlayerID+1],itemTable)
SetNetTableTowerPlayerList(PlayerID)
end
end
function CDOTABaseAbility:THTD_GetCardName()
if towerNameList[self:GetAbilityName()] ~= nil then
return towerNameList[self:GetAbilityName()]["cardname"]
else
return nil
end
end
function CDOTABaseAbility:THTD_GetCardQuality()
local unitName = self:GetAbilityName()
if towerNameList[unitName] ~= nil then
return towerNameList[unitName]["quality"]
elseif unitName == "item_3150" or unitName == "item_3151" or unitName == "item_3152" then
return 5
else
return nil
end
end
function CDOTABaseAbility:THTD_IsCardHasPortrait()
if towerNameList[self:GetAbilityName()] ~= nil then
return towerNameList[self:GetAbilityName()]["hasPortrait"]
else
return nil
end
end
function CDOTABaseAbility:THTD_GetPortraitPath(unitName)
return "particles/portraits/"..unitName.."/thtd_"..unitName.."_portraits.vpcf"
end
function CDOTABaseAbility:THTD_IsCardHasVoice()
if towerNameList[self:GetAbilityName()] ~= nil then
return towerNameList[self:GetAbilityName()]["hasVoice"]
else
return nil
end
end
function THTD_GetVoiceEvent(cardName,key)
return "Voice_THTD."..cardName.."."..key
end
function THTD_GetItemCountByName(playerid,itemName)
for k,v in pairs(towerPlayerList[playerid+1]) do
if v["itemName"] == itemName then
return v["count"]
end
end
return 0
end
function ItemSetScale(item, scale)
if item == nil then return end
local box = item:GetContainer()
if box == nil then return end
box:SetModelScale(scale)
end
local thtd_item_scale =
{
["kokoro"] = 0.55,
["yoshika"] = 0.55,
["aya"] = 0.55,
["cirno"] = 0.55,
["marisa"] = 0.55,
["reimu"] = 0.55,
["remilia"] = 0.65,
["flandre"] = 0.65,
["yukari"] = 0.45,
["satori"] = 0.55,
["patchouli"] = 0.55,
["sakuya"] = 0.55,
["youmu"] = 0.55,
["tenshi"] = 0.55,
["yuuka"] = 0.55,
["clownpiece"] = 0.6,
["wriggle"] = 1.3,
["komachi"] = 0.55,
["shikieiki"] = 0.65,
["inaba"] = 0.65,
["shinki"] = 0.50,
["koishi"] = 0.55,
}
function THTD_ItemSetScale(item)
if item == nil then return end
local cardName = item:THTD_GetCardName()
if cardName ~= nil then
if thtd_item_scale[cardName] == nil then
-- ItemSetScale(item, 1.0)
else
ItemSetScale(item, thtd_item_scale[cardName])
end
end
end
function THTD_HasItemScale(item)
if item == nil then return false end
local cardName = item:THTD_GetCardName()
if cardName ~= nil and thtd_item_scale[cardName] ~= nil then
return true
end
return false
end

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2643
scripts/vscripts/system/tower.lua Executable file

File diff suppressed because it is too large Load Diff