var tSettings = CustomNetTables.GetTableValue("common", "settings"); var HeroXpPerLevelTable = CustomNetTables.GetTableValue("common", "hero_xp_per_level_table"); var NonheroXpPerLevelTable = CustomNetTables.GetTableValue("common", "nonhero_xp_per_level_table"); var T35XpPerLevelTable = CustomNetTables.GetTableValue("common", "t35_xp_per_level_table"); var tPlayerEliteBossList = CustomNetTables.GetTableValue("common", "player_elite_boss_list"); // 建筑头顶 // BuildingOverhead var pBuildingOverheadContainer = $("#BuildingOverheadContainer"); var pRecycleBin = $("#RecycleBin"); var tBuildings = {}; function UpdateBuildings() { let data = CustomNetTables.GetAllTableValues("buildings"); tBuildings = {}; for (let index = 0; index < data.length; index++) { tBuildings[data[index].key] = data[index].value; } } function UpdateBuildingOverhead() { let iLocalPlayerID = Players.GetLocalPlayer(); let iCursorEntIndex = GameUI.GetCursorEntity(); let index = 0; for (const sKey in tBuildings) { const iUnitEntIndex = parseInt(sKey); const tInfo = tBuildings[sKey]; if (!Entities.IsValidEntity(iUnitEntIndex)) continue; //--尝试解决进攻怪头顶显示英雄建筑头顶信息 if (!IsBuilding(iUnitEntIndex)) continue; //-- let vOrigin = Entities.GetAbsOrigin(iUnitEntIndex); let fScreenX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2]); let fScreenY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2]); if (fScreenX < 0 || fScreenX > Game.GetScreenWidth() || fScreenY < 0 || fScreenY > Game.GetScreenHeight()) continue; let bControllable = Entities.IsControllableByPlayer(iUnitEntIndex, iLocalPlayerID); let pPanel = pBuildingOverheadContainer.GetChild(index); if (pPanel == null || pPanel == undefined) { pPanel = $.CreatePanel("Panel", pBuildingOverheadContainer, ""); pPanel.BLoadLayoutSnippet("BuildingOverhead"); } // pPanel.RemoveClass("Hidden"); pPanel.iUnitEntIndex = iUnitEntIndex; pPanel.tInfo = tInfo; let sUnitName = tInfo.sName; let iPlayerOwnerID = Entities.GetPlayerOwnerID(iUnitEntIndex); pPanel.SetHasClass("is_owner", iPlayerOwnerID == iLocalPlayerID); let fOffset = Entities.GetHealthBarOffset(iUnitEntIndex); fOffset = fOffset == -1 ? 100 : fOffset; let fX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); let fY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); pPanel.SetPositionInPixels((fX - pPanel.actuallayoutwidth / 2) / pPanel.actualuiscale_x, (fY - pPanel.actuallayoutheight) / pPanel.actualuiscale_y, 0); if (iCursorEntIndex != -1) pPanel.SetHasClass("UpperLevel", iUnitEntIndex == iCursorEntIndex); pPanel.SetHasClass("IsCursor", iUnitEntIndex == iCursorEntIndex); let iQualificationLevel = Math.min(tInfo.iQualificationLevel, 7); pPanel.SetHasClass("Star1", iQualificationLevel == 3); pPanel.SetHasClass("Star2", iQualificationLevel == 4); pPanel.SetHasClass("Star3", iQualificationLevel == 5); pPanel.SetHasClass("Star4", iQualificationLevel == 6); pPanel.SetHasClass("Star5", iQualificationLevel == 7); let sRarity = GetCardRarity(sUnitName); pPanel.SetHasClass("rarity_n", sRarity == "n"); pPanel.SetHasClass("rarity_r", sRarity == "r"); pPanel.SetHasClass("rarity_sr", sRarity == "sr"); pPanel.SetHasClass("rarity_ssr", sRarity == "ssr"); pPanel.SetDialogVariable("unit_name", $.Localize("#" + sUnitName)); let fManaPercent = Entities.GetMana(iUnitEntIndex) / Entities.GetMaxMana(iUnitEntIndex); pPanel.FindChildTraverse("ManaProgress").value = fManaPercent; let fHealthPercent = Entities.GetHealth(iUnitEntIndex) / Entities.GetMaxHealth(iUnitEntIndex); pPanel.FindChildTraverse("HealthProgress").value = fHealthPercent; let iLevel = Entities.GetLevel(iUnitEntIndex); pPanel.SetDialogVariable("level", iLevel); let fXPPercent = 0; let iLevelXP = 0; let iLevelNeedXP = 0; let iXP = tInfo.iCurrentXP || 0; let iNeedXP = tInfo.iNeededXPToLevel || 0; if (Entities.GetUnitLabel(iUnitEntIndex) != "HERO") { if (sUnitName == "t35") { iLevelXP = (iXP - T35XpPerLevelTable[String(iLevel)]); iLevelNeedXP = (iNeedXP - T35XpPerLevelTable[String(iLevel)]); } else { iLevelXP = (iXP - NonheroXpPerLevelTable[String(iLevel)]); iLevelNeedXP = (iNeedXP - NonheroXpPerLevelTable[String(iLevel)]); } } else { iLevelXP = (iXP - HeroXpPerLevelTable[String(iLevel)]); iLevelNeedXP = (iNeedXP - HeroXpPerLevelTable[String(iLevel)]); } if (iNeedXP == 0) { fXPPercent = 1; } else { fXPPercent = iLevelXP / iLevelNeedXP; } if (fXPPercent == 1) { pPanel.SetDialogVariable("level", $.Localize("#Level_Max")); } pPanel.FindChildTraverse("CircularXPProgress").value = fXPPercent; pPanel.FindChildTraverse("CircularXPProgressBlur").value = fXPPercent; pPanel.SetHasClass("HasAbilityToSpend", false); if (bControllable) { let iStar = iQualificationLevel - 2; let n = 0; let bCanSelected = true; let bHasAbilityToSpend = false; for (let index = 0; index < Entities.GetAbilityCount(iUnitEntIndex); index++) { let iAbility = Entities.GetAbility(iUnitEntIndex, index); if (iAbility != -1 && !Abilities.IsHidden(iAbility)) { let canLevelUp = tInfo.iAbilityPoints > 0 && Abilities.GetAbilityType(iAbility) != ABILITY_TYPES.ABILITY_TYPE_ATTRIBUTES && Entities.GetLevel(iUnitEntIndex) >= Abilities.GetHeroLevelRequiredToUpgrade(iAbility) && Abilities.CanAbilityBeUpgraded(iAbility) != AbilityLearnResult_t.ABILITY_NOT_LEARNABLE; if (canLevelUp) { bHasAbilityToSpend = true; break; } } if (iAbility != -1 && Abilities.GetAbilityName(iAbility).indexOf("special_bonus_") != -1) { let iLevel = Abilities.GetLevel(iAbility); let bDisabled = (iStar <= (Math.floor(n / 2) + 1)) || !bControllable; let BranchChosen = iLevel > 0; bCanSelected = bCanSelected && (!bDisabled && !BranchChosen); ++n; if (n % 2 == 0) { bHasAbilityToSpend = bHasAbilityToSpend || bCanSelected; bCanSelected = true; if (bHasAbilityToSpend) { break; } } } } pPanel.SetHasClass("HasAbilityToSpend", bHasAbilityToSpend); } pPanel.SetHasClass("no_health_bar", Entities.HasBuff(iUnitEntIndex, "modifier_no_health_bar")); let n = 0; let tQualificationAbilities = tInfo.tQualificationAbilities; if (tQualificationAbilities) { for (const key in tQualificationAbilities) { let sQualificationAbility = tQualificationAbilities[key]; let sCardName = GetCardNameByQualificationAbility(sQualificationAbility); let sUnitRarity = GetCardRarity(sCardName); let pImage = pPanel.FindChildTraverse("BuildingQualificationAbilities").GetChild(n); if (pImage == undefined || pImage == null) { pImage = $.CreatePanel("Image", pPanel.FindChildTraverse("BuildingQualificationAbilities"), ""); } pImage.AddClass("UnitIcon"); pImage.SetHasClass("rarity_n", sUnitRarity == "n"); pImage.SetHasClass("rarity_r", sUnitRarity == "r"); pImage.SetHasClass("rarity_sr", sUnitRarity == "sr"); pImage.SetHasClass("rarity_ssr", sUnitRarity == "ssr"); pImage.SetImage(GetCardIcon(sCardName)); // pImage.RemoveClass("Hidden"); ++n; } } for (let i = n; i < pPanel.FindChildTraverse("BuildingQualificationAbilities").GetChildCount(); i++) { let pImage = pPanel.FindChildTraverse("BuildingQualificationAbilities").GetChild(i); // pImage.AddClass("Hidden"); pImage.SetParent(pRecycleBin); } ++index; } for (let i = index; i < pBuildingOverheadContainer.GetChildCount(); i++) { let pPanel = pBuildingOverheadContainer.GetChild(i); // pPanel.AddClass("Hidden"); pPanel.SetParent(pRecycleBin); } } // 英雄头顶 // HeroOverhead var pHeroOverheadContainer = $("#HeroOverheadContainer"); var tPlayerDesignation = {}; function UpdateHeroOverhead() { let iLocalPlayerID = Players.GetLocalPlayer(); let aHeroes = Entities.GetAllEntitiesByName(tSettings.force_picked_hero); let index = 0; for (let i in aHeroes) { let iUnitEntIndex = aHeroes[i]; if (!Entities.IsValidEntity(iUnitEntIndex) || !Entities.IsAlive(iUnitEntIndex) || Entities.HasBuff(iUnitEntIndex, "modifier_no_health_bar")) continue; if (!Entities.IsHero(iUnitEntIndex) || !Entities.IsControllableByAnyPlayer(iUnitEntIndex)) continue; let vOrigin = Entities.GetAbsOrigin(iUnitEntIndex); let fScreenX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2]); let fScreenY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2]); if (fScreenX < 0 || fScreenX > Game.GetScreenWidth() || fScreenY < 0 || fScreenY > Game.GetScreenHeight()) continue; let pPanel = pHeroOverheadContainer.GetChild(index); if (pPanel == undefined || pPanel == null) { pPanel = $.CreatePanel("Panel", pHeroOverheadContainer, ""); pPanel.BLoadLayoutSnippet("HeroOverhead"); } // pPanel.RemoveClass("Hidden"); pPanel.iUnitEntIndex = iUnitEntIndex; let iPlayerOwnerID = Entities.GetPlayerOwnerID(iUnitEntIndex); pPanel.SetHasClass("IsLocal", iPlayerOwnerID == iLocalPlayerID); pPanel.SwitchClass("Designation", tPlayerDesignation[iPlayerOwnerID.toString()]) pPanel.SetDialogVariable("over_head_text", $.Localize("#" + tPlayerDesignation[iPlayerOwnerID.toString()])); let fOffset = Entities.GetHealthBarOffset(iUnitEntIndex); fOffset = fOffset == -1 ? 100 : fOffset; let fX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); let fY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); pPanel.SetPositionInPixels((fX - pPanel.actuallayoutwidth / 2) / pPanel.actualuiscale_x, (fY - pPanel.actuallayoutheight) / pPanel.actualuiscale_y, 0); ++index; } for (let i = index; i < pHeroOverheadContainer.GetChildCount(); i++) { let pPanel = pHeroOverheadContainer.GetChild(i); // pPanel.AddClass("Hidden"); pPanel.SetParent(pRecycleBin); } } // BOSS头顶 // BossOverhead var pBossOverheadContainer = $("#BossOverheadContainer"); var tWaveGoldTotalDamage = {}; function UpdateBossOverhead() { let iLocalPlayerID = Players.GetLocalPlayer(); let iCursorEntIndex = GameUI.GetCursorEntity(); var aEntities = Entities.GetAllEntitiesByName("npc_dota_creature"); for (const sUnitEntIndex in tWaveGoldTotalDamage) { const iUnitEntIndex = parseInt(sUnitEntIndex); if (!Entities.IsValidEntity(iUnitEntIndex) || !Entities.IsAlive(iUnitEntIndex)) { delete tWaveGoldTotalDamage[sUnitEntIndex]; } } const tBossModifier = ["modifier_wave_roshan", "modifier_wave_gold", "modifier_wave_phantom_roshan", "modifier_boss"]; const sEliteModifier = "modifier_elite"; let index = 0; for (let i in aEntities) { let iUnitEntIndex = aEntities[i]; if (!Entities.IsValidEntity(iUnitEntIndex) || !Entities.IsAlive(iUnitEntIndex)) continue; //过滤 let bIsElite = false; if (Entities.HasBuff(iUnitEntIndex, sEliteModifier)) { bIsElite = true; } // 是否是boss let bIsBoss = false; for (let index = 0; index < tBossModifier.length; index++) { const sBuffName = tBossModifier[index]; if (Entities.HasBuff(iUnitEntIndex, sBuffName)) { bIsBoss = true; break; } } if (!bIsBoss && !bIsElite) continue; let vOrigin = Entities.GetAbsOrigin(iUnitEntIndex); let fScreenX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2]); let fScreenY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2]); if (fScreenX < 0 || fScreenX > Game.GetScreenWidth() || fScreenY < 0 || fScreenY > Game.GetScreenHeight()) continue; let pPanel = pBossOverheadContainer.GetChild(index); if (pPanel == undefined || pPanel == null) { pPanel = $.CreatePanel("Panel", pBossOverheadContainer, ""); pPanel.BLoadLayoutSnippet("BossOverhead"); } // pPanel.RemoveClass("Hidden"); if (iCursorEntIndex != -1) pPanel.SetHasClass("UpperLevel", iUnitEntIndex == iCursorEntIndex); pPanel.SetHasClass("IsCursor", iUnitEntIndex == iCursorEntIndex); pPanel.SetHasClass("IsBoss", Entities.HasBuff(iUnitEntIndex, "modifier_boss")); pPanel.SetHasClass("IsElite", Entities.HasBuff(iUnitEntIndex, "modifier_elite")); pPanel.SetHasClass("IsRoshan", Entities.HasBuff(iUnitEntIndex, "modifier_wave_roshan")); pPanel.SetHasClass("IsWaveGold", Entities.HasBuff(iUnitEntIndex, "modifier_wave_gold")); pPanel.FindChildTraverse("BossOverheadHealthProgressBar").value = Entities.GetHealth(iUnitEntIndex) / Entities.GetMaxHealth(iUnitEntIndex); if (pPanel.BHasClass("IsWaveGold")) { pPanel.SetDialogVariable("total_damage", formatNumByLanguage(tWaveGoldTotalDamage[String(iUnitEntIndex)] || 0)); } pPanel.SetHasClass("no_health_bar", Entities.HasBuff(iUnitEntIndex, "modifier_no_health_bar")); let fOffset = Entities.GetHealthBarOffset(iUnitEntIndex); fOffset = fOffset == -1 ? 100 : fOffset; let fX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); let fY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); pPanel.SetPositionInPixels((fX - pPanel.actuallayoutwidth / 2) / pPanel.actualuiscale_x, (fY - pPanel.actuallayoutheight) / pPanel.actualuiscale_y, 0); ++index; } for (let i = index; i < pBossOverheadContainer.GetChildCount(); i++) { let pPanel = pBossOverheadContainer.GetChild(i); // pPanel.AddClass("Hidden"); pPanel.SetParent(pRecycleBin); } } //封印技能头顶 var pSealOverheadContainer = $("#SealOverheadContainer"); function UpdateSealOverhead() { let iLocalPlayerID = Players.GetLocalPlayer(); let iCursorEntIndex = GameUI.GetCursorEntity(); var aEntities = Entities.GetAllEntitiesByName("npc_dota_creature"); const sBuffName = "modifier_seal_buff"; let index = 0; for (const i in aEntities) { let iUnitEntIndex = aEntities[i]; if (!Entities.IsValidEntity(iUnitEntIndex) || !Entities.IsAlive(iUnitEntIndex)) continue; if (Entities.HasBuff(iUnitEntIndex, sBuffName)) { let vOrigin = Entities.GetAbsOrigin(iUnitEntIndex); let fScreenX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2]); let fScreenY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2]); if (fScreenX < 0 || fScreenX > Game.GetScreenWidth() || fScreenY < 0 || fScreenY > Game.GetScreenHeight()) continue; let pPanel = pSealOverheadContainer.GetChild(index); if (pPanel == undefined || pPanel == null) { pPanel = $.CreatePanel("Panel", pSealOverheadContainer, ""); pPanel.BLoadLayoutSnippet("SealAbilityOverhead"); } // pPanel.RemoveClass("Hidden"); let hBuff = Entities.FindBuffByName(iUnitEntIndex, sBuffName); let hAbilityIndex = Buffs.GetStackCount(iUnitEntIndex, hBuff); let sAbilityName = Abilities.GetAbilityName(hAbilityIndex); pPanel.FindChildTraverse("SealAbilityOverheadImage").SetHasClass("Hidden", hAbilityIndex == 0); if (sAbilityName) { pPanel.FindChildTraverse("SealAbilityOverheadImage").abilityname = sAbilityName; } if (iCursorEntIndex != -1) pPanel.SetHasClass("UpperLevel", iUnitEntIndex == iCursorEntIndex); pPanel.SetHasClass("IsCursor", iUnitEntIndex == iCursorEntIndex); let fOffset = Entities.GetHealthBarOffset(iUnitEntIndex); fOffset = fOffset == -1 ? 50 : fOffset; let fX = Game.WorldToScreenX(vOrigin[0] + 30, vOrigin[1], vOrigin[2] + fOffset); let fY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset) - 10; pPanel.SetPositionInPixels((fX - pPanel.actuallayoutwidth / 2) * pPanel.actualuiscale_x, (fY - pPanel.actuallayoutheight) / pPanel.actualuiscale_y, 0); ++index; } } for (let i = index; i < pSealOverheadContainer.GetChildCount(); i++) { let pPanel = pSealOverheadContainer.GetChild(i); // pPanel.AddClass("Hidden"); pPanel.SetParent(pRecycleBin); } } //挑战精英怪头顶 var pChallengeOverheadContainer = $("#ChallengeOverheadContainer") function UpdateChallengeOverhead() { let iCursorEntIndex = GameUI.GetCursorEntity(); var aEntities = Entities.GetAllEntitiesByName("npc_dota_creature"); const sBuffName = "modifier_elite_boss"; let index = 0; for (const i in aEntities) { let iUnitEntIndex = aEntities[i]; if (!Entities.IsValidEntity(iUnitEntIndex) || !Entities.IsAlive(iUnitEntIndex)) continue; if (Entities.HasBuff(iUnitEntIndex, sBuffName)) { let vOrigin = Entities.GetAbsOrigin(iUnitEntIndex); let fScreenX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2]); let fScreenY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2]); if (fScreenX < 0 || fScreenX > Game.GetScreenWidth() || fScreenY < 0 || fScreenY > Game.GetScreenHeight()) continue; let pPanel = pChallengeOverheadContainer.GetChild(index); if (pPanel == undefined || pPanel == null) { pPanel = $.CreatePanel("Panel", pChallengeOverheadContainer, ""); pPanel.BLoadLayoutSnippet("ChallengeOverhead"); } for (const iPlayerID in tPlayerEliteBossList) { for (const key in tPlayerEliteBossList[iPlayerID]) { if (tPlayerEliteBossList[iPlayerID][key].unit_index == iUnitEntIndex) { let playerInfo = Game.GetPlayerInfo(Number(iPlayerID)); pPanel.FindChildTraverse("PlayerName").steamid = playerInfo.player_steamid; break; } } } let fOffset = Entities.GetHealthBarOffset(iUnitEntIndex); fOffset = fOffset == -1 ? 50 : fOffset; let fX = Game.WorldToScreenX(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); let fY = Game.WorldToScreenY(vOrigin[0], vOrigin[1], vOrigin[2] + fOffset); pPanel.SetPositionInPixels((fX - pPanel.actuallayoutwidth / 2) / pPanel.actualuiscale_x, (fY - pPanel.actuallayoutheight) / pPanel.actualuiscale_y, 0); ++index; } } for (let i = index; i < pChallengeOverheadContainer.GetChildCount(); i++) { let pPanel = pChallengeOverheadContainer.GetChild(i); pPanel.SetParent(pRecycleBin); } } function Update() { $.Schedule(Game.GetGameFrameTime(), Update); UpdateBuildingOverhead(); UpdateHeroOverhead(); UpdateBossOverhead(); UpdateSealOverhead(); UpdateChallengeOverhead(); pRecycleBin.RemoveAndDeleteChildren(); } function UpdateServiceNetTable(tableName, tableKeyName, table) { if (tableKeyName == "player_data") { for (var sPlayerID in table) { var iPlayerID = parseInt(sPlayerID); var tData = table[sPlayerID]; var sDesignation = tData.skin_prop.designation || "designation_default"; tPlayerDesignation[sPlayerID] = sDesignation; } } } function UpdateCommonNetTable(sTableName, sTableKey, tData) { if (sTableKey == "player_elite_boss_list") { tPlayerEliteBossList = tData; } } function OnEntityHurt(tData) { var iUnitEntIndex = tData.entindex_killed; if (iUnitEntIndex != -1 && Entities.HasBuff(iUnitEntIndex, "modifier_wave_gold")) { if (!tWaveGoldTotalDamage[iUnitEntIndex]) tWaveGoldTotalDamage[iUnitEntIndex] = 0; tWaveGoldTotalDamage[iUnitEntIndex] += tData.damage; } } (function () { pBuildingOverheadContainer.RemoveAndDeleteChildren(); GameEvents.Subscribe("entity_hurt", OnEntityHurt); CustomUIConfig.SubscribeNetTableListener("service", UpdateServiceNetTable); UpdateServiceNetTable("service", "player_data", CustomNetTables.GetTableValue("service", "player_data")); CustomUIConfig.SubscribeNetTableListener("buildings", UpdateBuildings); CustomUIConfig.SubscribeNetTableListener("common", UpdateCommonNetTable); UpdateCommonNetTable("common", "player_elite_boss_list", CustomNetTables.GetTableValue("common", "player_elite_boss_list")); UpdateBuildings(); Update(); })();