-- 发送消息(左侧),例如 SendMsg(0, "test_tip", "总输出",90) "test_tip" "{s:player_name}上一波最终阵容{s:locstring_value}低于{d:int_value}%总血量,不计入有效波数" -- 可用固有系统变量名称:{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)