HearthBuddy卡牌无法识别
界面上無法識別,提示是
[Unidentified card ID :DAL_010]
[Unidentified card ID :DAL_415]
?
搜索getcardid,在所有的相關函數處設置斷點,看會進入哪里的斷點
發現是進入了namespace Triton.Game.Mapping
[Attribute38("EntityBase")]
public class EntityBase : MonoClass
這個類
public string GetCardId() {return base.method_13("GetCardId", Array.Empty<object>()); }?
namespace Triton.Game
public class HSCard
public string Id{get{return this.Entity_0.GetCardId();}}?
namespace HREngine.Bots
public class Silverfish
// HREngine.Bots.Silverfish // Token: 0x06000048 RID: 72 RVA: 0x0000A16C File Offset: 0x0000836C private void getDecks() {Dictionary<string, int> tmpDeck = new Dictionary<string, int>(this.startDeck);List<GraveYardItem> graveYard = new List<GraveYardItem>();Dictionary<CardDB.cardIDEnum, int> og = new Dictionary<CardDB.cardIDEnum, int>();Dictionary<CardDB.cardIDEnum, int> eg = new Dictionary<CardDB.cardIDEnum, int>();int owncontroler = TritonHs.OurHero.GetTag(GAME_TAG.CONTROLLER);int enemycontroler = TritonHs.EnemyHero.GetTag(GAME_TAG.CONTROLLER);this.turnDeck.Clear();this.noDuplicates = false;List<HSCard> allcards = TritonHs.GetAllCards();int allcardscount = allcards.Count;for (int i = 0; i < allcardscount; i++){HSCard entity = allcards[i];if (entity.Id != null && !(entity.Id == "")){if (CardDB.Instance.cardIdstringToEnum(entity.Id) == CardDB.cardIDEnum.UNG_116t){this.ownMinionsCost0 = true;}if (entity.GetZone() == TAG_ZONE.GRAVEYARD){CardDB.cardIDEnum cide = CardDB.Instance.cardIdstringToEnum(entity.Id);GraveYardItem gyi = new GraveYardItem(cide, entity.EntityId, entity.GetTag(GAME_TAG.CONTROLLER) == owncontroler);graveYard.Add(gyi);if (entity.GetTag(GAME_TAG.CONTROLLER) == owncontroler){if (og.ContainsKey(cide)){Dictionary<CardDB.cardIDEnum, int> dictionary;CardDB.cardIDEnum key;(dictionary = og)[key = cide] = dictionary[key] + 1;}else{og.Add(cide, 1);}}else if (entity.GetTag(GAME_TAG.CONTROLLER) == enemycontroler){if (eg.ContainsKey(cide)){Dictionary<CardDB.cardIDEnum, int> dictionary;CardDB.cardIDEnum key;(dictionary = eg)[key = cide] = dictionary[key] + 1;}else{eg.Add(cide, 1);}}if (cide == CardDB.cardIDEnum.UNG_067t1){this.ownCrystalCore = 5;}}string entityId = entity.Id;TAG_ZONE entZone = entity.GetZone();if (i < 30){if (entityId != ""){if (entZone != TAG_ZONE.DECK){if (tmpDeck.ContainsKey(entityId)){Dictionary<string, int> dictionary2;string key2;(dictionary2 = tmpDeck)[key2 = entityId] = dictionary2[key2] - 1;}}}}else if (i >= 60 && entity.ControllerId == owncontroler){if (this.extraDeck.ContainsKey(i)){if (entityId != "" && entityId != this.extraDeck[i].id){this.extraDeck[i].setId(entityId);}if (entZone == TAG_ZONE.DECK != this.extraDeck[i].isindeck){this.extraDeck[i].setisindeck(entZone == TAG_ZONE.DECK);}}else if (entZone == TAG_ZONE.DECK){this.extraDeck.Add(i, new Silverfish.extraCard(entityId, true));}}}}Action a = Ai.Instance.bestmove;foreach (KeyValuePair<int, Silverfish.extraCard> c in this.extraDeck){if (c.Value.isindeck){string entityId = c.Value.id;if (entityId == ""){if (a != null){actionEnum actionType = a.actionType;if (actionType == actionEnum.playcard){CardDB.cardIDEnum cardIDEnum = a.card.card.cardIDenum;if (cardIDEnum <= CardDB.cardIDEnum.LOE_019t){if (cardIDEnum == CardDB.cardIDEnum.BRM_007){goto IL_42B;}if (cardIDEnum != CardDB.cardIDEnum.LOE_002){if (cardIDEnum == CardDB.cardIDEnum.LOE_019t){entityId = "LOE_019t2";}}else{entityId = "LOE_002t";}}else if (cardIDEnum != CardDB.cardIDEnum.LOE_079){if (cardIDEnum == CardDB.cardIDEnum.LOE_104){goto IL_42B;}if (cardIDEnum == CardDB.cardIDEnum.LOE_110){entityId = "LOE_110t";}}else{entityId = "LOE_019t";}goto IL_485;IL_42B:if (a.target != null){entityId = a.target.handcard.card.cardIDenum.ToString();}}IL_485:;}if (entityId == ""){Dictionary<CardDB.cardIDEnum, int> oldCardsOut = Probabilitymaker.Instance.enemyCardsOut;foreach (KeyValuePair<CardDB.cardIDEnum, int> tmp in eg){if (!oldCardsOut.ContainsKey(tmp.Key) || tmp.Value != oldCardsOut[tmp.Key]){CardDB.cardIDEnum cardIDEnum = tmp.Key;if (cardIDEnum != CardDB.cardIDEnum.AT_035){if (cardIDEnum != CardDB.cardIDEnum.GVG_031){if (cardIDEnum == CardDB.cardIDEnum.LOE_111){entityId = "LOE_111";}}else{entityId = "aiextra1";}}else{entityId = "AT_035t";}}}if (entityId == "" && this.lastpf != null){int num = 0;foreach (Minion j in this.enemyMinions){if (j.handcard.card.cardIDenum == CardDB.cardIDEnum.GVG_056){num++;}}if (num > 0){foreach (Minion j in this.lastpf.enemyMinions){if (j.handcard.card.cardIDenum == CardDB.cardIDEnum.GVG_056){num--;}}}if (num > 0){entityId = "GVG_056t";}else{num = 0;foreach (Minion j in this.lastpf.ownMinions){if (j.handcard.card.cardIDenum == CardDB.cardIDEnum.GVG_035){num++;}}if (num > 0){foreach (Minion j in this.ownMinions){if (j.handcard.card.cardIDenum == CardDB.cardIDEnum.GVG_035){num--;}}}if (num > 0){entityId = "GVG_035";}}}}if (entityId == ""){entityId = "aiextra1";}}c.Value.setId(entityId);CardDB.cardIDEnum ce = CardDB.Instance.cardIdstringToEnum(entityId);if (this.turnDeck.ContainsKey(ce)){Dictionary<CardDB.cardIDEnum, int> dictionary;CardDB.cardIDEnum key;(dictionary = this.turnDeck)[key = ce] = dictionary[key] + 1;}else{this.turnDeck.Add(ce, 1);}}}foreach (KeyValuePair<string, int> c2 in tmpDeck){if (c2.Value >= 1){CardDB.cardIDEnum ce = CardDB.Instance.cardIdstringToEnum(c2.Key);if (ce != CardDB.cardIDEnum.None){if (this.turnDeck.ContainsKey(ce)){Dictionary<CardDB.cardIDEnum, int> dictionary;CardDB.cardIDEnum key;(dictionary = this.turnDeck)[key = ce] = dictionary[key] + c2.Value;}else{this.turnDeck.Add(ce, c2.Value);}}}}Probabilitymaker.Instance.setOwnCardsOut(og);Probabilitymaker.Instance.setEnemyCardsOut(eg);bool isTurnStart = false;if (Ai.Instance.nextMoveGuess.mana == -100){isTurnStart = true;Ai.Instance.updateTwoTurnSim();}Probabilitymaker.Instance.setGraveYard(graveYard, isTurnStart);if (this.startDeck.Count != 0){this.noDuplicates = true;foreach (int i in this.turnDeck.Values){if (i > 1){this.noDuplicates = false;break;}}} }?
在updateEverything函數里面的this.getDecks();的下一行設置斷點,發現這個執行完,就看到卡牌錯誤提示
// HREngine.Bots.Silverfish // Token: 0x06000044 RID: 68 RVA: 0x00008154 File Offset: 0x00006354 public bool updateEverything(Behavior botbase, int numcal, out bool sleepRetry) {this.needSleep = false;this.updateBehaveString(botbase);this.ownPlayerController = TritonHs.OurHero.ControllerId;Hrtprozis.Instance.clearAllRecalc();Handmanager.Instance.clearAllRecalc();this.getHerostuff();this.getMinions();this.getHandcards();this.getDecks();Hrtprozis.Instance.updateTurnDeck(this.turnDeck, this.noDuplicates);Hrtprozis.Instance.setOwnPlayer(this.ownPlayerController);Handmanager.Instance.setOwnPlayer(this.ownPlayerController);this.numOptionPlayedThisTurn = 0;this.numOptionPlayedThisTurn += this.cardsPlayedThisTurn + this.ownHero.numAttacksThisTurn;foreach (Minion i in this.ownMinions){if (i.Hp >= 1){this.numOptionPlayedThisTurn += i.numAttacksThisTurn;}}List<HSCard> list = TritonHs.GetCards(CardZone.Graveyard, true);foreach (GraveYardItem gi in Probabilitymaker.Instance.turngraveyard){if (gi.own){foreach (HSCard entiti in list){if (gi.entity == entiti.EntityId){this.numOptionPlayedThisTurn += entiti.NumAttackThisTurn;break;}}}}Hrtprozis.Instance.updatePlayer(this.ownMaxMana, this.currentMana, this.cardsPlayedThisTurn, this.numMinionsPlayedThisTurn, this.numOptionPlayedThisTurn, this.ueberladung, this.lockedMana, TritonHs.OurHero.EntityId, TritonHs.EnemyHero.EntityId);Hrtprozis.Instance.updateSecretStuff(this.ownSecretList, this.enemySecretList.Count);Hrtprozis.Instance.updateHero(this.ownWeapon, this.heroname, this.heroAbility, this.ownAbilityisReady, this.ownHeroPowerCost, this.ownHero, 10);Hrtprozis.Instance.updateHero(this.enemyWeapon, this.enemyHeroname, this.enemyAbility, false, this.enemyHeroPowerCost, this.enemyHero, this.enemyMaxMana);Questmanager.Instance.updatePlayedMobs(this.gTurnStep);Hrtprozis.Instance.updateMinions(this.ownMinions, this.enemyMinions);Hrtprozis.Instance.updateLurkersDB(this.LurkersDB);Handmanager.Instance.setHandcards(this.handCards, this.anzcards, this.enemyAnzCards);Hrtprozis.Instance.updateFatigueStats(this.ownDecksize, this.ownHeroFatigue, this.enemyDecksize, this.enemyHeroFatigue);Hrtprozis.Instance.updateJadeGolemsInfo(GameState.Get().GetFriendlySidePlayer().GetTag(GAME_TAG.JADE_GOLEM), GameState.Get().GetOpposingSidePlayer().GetTag(GAME_TAG.JADE_GOLEM));Hrtprozis.Instance.updateTurnInfo(this.gTurn, this.gTurnStep);this.updateCThunInfobyCThun();Hrtprozis.Instance.updateCThunInfo(this.anzOgOwnCThunAngrBonus, this.anzOgOwnCThunHpBonus, this.anzOgOwnCThunTaunt);Hrtprozis.Instance.updateCrystalCore(this.ownCrystalCore);Hrtprozis.Instance.updateOwnMinionsInDeckCost0(this.ownMinionsCost0);Probabilitymaker.Instance.setEnemySecretGuesses(this.enemySecretList);sleepRetry = this.needSleep;bool result;if (sleepRetry && numcal == 0){result = false;}else{if (!Hrtprozis.Instance.setGameRule){RulesEngine.Instance.setCardIdRulesGame(this.ownHero.cardClass, this.enemyHero.cardClass);Hrtprozis.Instance.setGameRule = true;}Playfield p = new Playfield();p.enemyCardsOut = new Dictionary<CardDB.cardIDEnum, int>(Probabilitymaker.Instance.enemyCardsOut);if (this.lastpf != null){if (this.lastpf.isEqualf(p)){return false;}if (p.gTurnStep > 0 && Ai.Instance.nextMoveGuess.ownMinions.Count == p.ownMinions.Count){if (Ai.Instance.nextMoveGuess.ownHero.Ready != p.ownHero.Ready && !p.ownHero.Ready){sleepRetry = true;Helpfunctions.Instance.ErrorLog("[AI] Hero ready = " + p.ownHero.Ready + ". Attempting recover....");Ai.Instance.nextMoveGuess = new Playfield{mana = -100};return false;}for (int j = 0; j < p.ownMinions.Count; j++){if (Ai.Instance.nextMoveGuess.ownMinions[j].Ready != p.ownMinions[j].Ready && !p.ownMinions[j].Ready){sleepRetry = true;Helpfunctions.Instance.ErrorLog(string.Concat(new object[]{"[AI] Minion ready = ",p.ownMinions[j].Ready," (",p.ownMinions[j].entitiyID," ",p.ownMinions[j].handcard.card.cardIDenum," ",p.ownMinions[j].name,"). Attempting recover...."}));Ai.Instance.nextMoveGuess = new Playfield{mana = -100};return false;}}}Probabilitymaker.Instance.updateSecretList(p, this.lastpf);this.lastpf = p;}else{this.lastpf = p;}p = new Playfield();Helpfunctions.Instance.ErrorLog("calculating stuff... " + DateTime.Now.ToString("HH:mm:ss.ffff"));using (TritonHs.Memory.ReleaseFrame(true)){this.printstuff();Ai.Instance.dosomethingclever(botbase);}Helpfunctions.Instance.ErrorLog("calculating ended! " + DateTime.Now.ToString("HH:mm:ss.ffff"));if (this.sttngs.printRules > 0){string[] rulesStr = Ai.Instance.bestplay.rulesUsed.Split(new char[]{'@'});if (rulesStr.Count<string>() > 0 && rulesStr[0] != ""){Helpfunctions.Instance.ErrorLog("ruleWeight " + Ai.Instance.bestplay.ruleWeight * -1);foreach (string rs in rulesStr){if (!(rs == "")){Helpfunctions.Instance.ErrorLog("rule: " + rs);}}}}result = true;}return result; }?
namespace HREngine.Bots
public class DefaultRoutine : IRoutine, IRunnable, IAuthored, IBase, IConfigurable
在update everything函數調用的地方設置斷點,發現執行pdate everything函數,就有錯誤提示。
所以卡牌的錯誤,是在update everything里面出來的。
// HREngine.Bots.DefaultRoutine // Token: 0x06000017 RID: 23 RVA: 0x00005A54 File Offset: 0x00003C54 public async Task OurTurnLogic() {if (this.behave.BehaviorName() != DefaultRoutineSettings.Instance.DefaultBehavior){this.behave = this.sf.getBehaviorByName(DefaultRoutineSettings.Instance.DefaultBehavior);Silverfish.Instance.lastpf = null;}if (this.learnmode && (TritonHs.IsInTargetMode() || TritonHs.IsInChoiceMode())){await Coroutine.Sleep(50);}else if (TritonHs.IsInTargetMode()){if (this.dirtytarget >= 0){DefaultRoutine.Log.Info("targeting...");HSCard source = null;if (this.dirtyTargetSource == 9000){source = TritonHs.OurHeroPowerCard;}else{source = this.getEntityWithNumber(this.dirtyTargetSource);}HSCard target = this.getEntityWithNumber(this.dirtytarget);if (target == null){DefaultRoutine.Log.Error("target is null...");TritonHs.CancelTargetingMode();}else{this.dirtytarget = -1;this.dirtyTargetSource = -1;if (source == null){await TritonHs.DoTarget(target);}else{await source.DoTarget(target);}await Coroutine.Sleep(555);}}else{DefaultRoutine.Log.Error("target failure...");TritonHs.CancelTargetingMode();}}else if (TritonHs.IsInChoiceMode()){await Coroutine.Sleep(555 + this.makeChoice());switch (this.dirtychoice){case 0:TritonHs.ChooseOneClickMiddle();break;case 1:TritonHs.ChooseOneClickLeft();break;case 2:TritonHs.ChooseOneClickRight();break;}this.dirtychoice = -1;await Coroutine.Sleep(555);}else{bool sleepRetry = false;bool templearn = Silverfish.Instance.updateEverything(this.behave, 0, out sleepRetry);if (sleepRetry){DefaultRoutine.Log.Error("[AI] Readiness error. Attempting recover...");await Coroutine.Sleep(500);templearn = Silverfish.Instance.updateEverything(this.behave, 1, out sleepRetry);}if (templearn){this.printlearnmode = true;}if (this.learnmode){if (this.printlearnmode){Ai.Instance.simmulateWholeTurnandPrint();}this.printlearnmode = false;await Coroutine.Sleep(50);}else{Action moveTodo = Ai.Instance.bestmove;if (moveTodo == null || moveTodo.actionType == actionEnum.endturn || Ai.Instance.bestmoveValue < -9999f){bool doEndTurn = false;bool doConcede = false;if (Ai.Instance.bestmoveValue > -10000f){doEndTurn = true;}else if (Settings.Instance.concedeMode != 0){doConcede = true;}else if (new Playfield().ownHeroHasDirectLethal()){Playfield lastChancePl = Ai.Instance.bestplay;bool lastChance = false;if (lastChancePl.owncarddraw > 0){foreach (Handmanager.Handcard hc in lastChancePl.owncards){if (hc.card.name == CardDB.cardName.unknown){lastChance = true;}}if (!lastChance){doConcede = true;}}else{doConcede = true;}if (doConcede){foreach (Minion i in lastChancePl.ownMinions){if (i.playedThisTurn){CardDB.cardName name = i.handcard.card.name;if (name <= CardDB.cardName.nzoththecorruptor){if (name != CardDB.cardName.barongeddon){if (name != CardDB.cardName.cthun){if (name == CardDB.cardName.nzoththecorruptor){lastChance = true;}}else{lastChance = true;}}else if (lastChancePl.enemyHero.Hp < 3){lastChance = true;}}else if (name != CardDB.cardName.ragnarosthefirelord){if (name != CardDB.cardName.sirfinleymrrgglton){if (name == CardDB.cardName.yoggsaronhopesend){lastChance = true;}}else{lastChance = true;}}else if (lastChancePl.enemyHero.Hp < 9){lastChance = true;}}}}if (lastChance){doConcede = false;}}else if (moveTodo == null || moveTodo.actionType == actionEnum.endturn){doEndTurn = true;}if (doEndTurn){Helpfunctions.Instance.ErrorLog("end turn");await TritonHs.EndTurn();return;}if (doConcede){Helpfunctions.Instance.ErrorLog("Lethal detected. Concede...");Helpfunctions.Instance.logg("Concede... Lethal detected###############################################");TritonHs.Concede(true);return;}}Helpfunctions.Instance.ErrorLog("play action");if (moveTodo == null){Helpfunctions.Instance.ErrorLog("moveTodo == null. EndTurn");await TritonHs.EndTurn();}else{moveTodo.print(false);if (moveTodo.actionType == actionEnum.playcard){Questmanager.Instance.updatePlayedCardFromHand(moveTodo.card);HSCard cardtoplay = this.getCardWithNumber(moveTodo.card.entity);if (cardtoplay == null){Helpfunctions.Instance.ErrorLog("[Tick] cardtoplay == null");}else if (moveTodo.target != null){HSCard target2 = this.getEntityWithNumber(moveTodo.target.entitiyID);if (target2 != null){Helpfunctions.Instance.ErrorLog(string.Concat(new object[]{"play: ",cardtoplay.Name," (",cardtoplay.EntityId,") target: ",target2.Name," (",target2.EntityId,")"}));Helpfunctions.Instance.logg(string.Concat(new object[]{"play: ",cardtoplay.Name," (",cardtoplay.EntityId,") target: ",target2.Name," (",target2.EntityId,") choice: ",moveTodo.druidchoice}));if (moveTodo.druidchoice >= 1){this.dirtytarget = moveTodo.target.entitiyID;this.dirtychoice = moveTodo.druidchoice;this.choiceCardId = moveTodo.card.card.cardIDenum.ToString();}this.dirtyTargetSource = moveTodo.card.entity;this.dirtytarget = moveTodo.target.entitiyID;await cardtoplay.Pickup(500);if (moveTodo.card.card.type == CardDB.cardtype.MOB){await cardtoplay.UseAt(moveTodo.place);}else if (moveTodo.card.card.type == CardDB.cardtype.WEAPON){await cardtoplay.UseOn(target2.Card);}else if (moveTodo.card.card.type == CardDB.cardtype.SPELL){await cardtoplay.UseOn(target2.Card);}else{await cardtoplay.UseOn(target2.Card);}}else{Helpfunctions.Instance.ErrorLog("[AI] Target is missing. Attempting recover...");Helpfunctions.Instance.logg("[AI] Target " + moveTodo.target.entitiyID + "is missing. Attempting recover...");}await Coroutine.Sleep(500);}else{Helpfunctions.Instance.ErrorLog(string.Concat(new object[]{"play: ",cardtoplay.Name," (",cardtoplay.EntityId,") target nothing"}));Helpfunctions.Instance.logg(string.Concat(new object[]{"play: ",cardtoplay.Name," (",cardtoplay.EntityId,") choice: ",moveTodo.druidchoice}));if (moveTodo.druidchoice >= 1){this.dirtychoice = moveTodo.druidchoice;this.choiceCardId = moveTodo.card.card.cardIDenum.ToString();}this.dirtyTargetSource = -1;this.dirtytarget = -1;await cardtoplay.Pickup(500);if (moveTodo.card.card.type == CardDB.cardtype.MOB){await cardtoplay.UseAt(moveTodo.place);}else{await cardtoplay.Use();}await Coroutine.Sleep(500);}}else if (moveTodo.actionType == actionEnum.attackWithMinion){HSCard attacker = this.getEntityWithNumber(moveTodo.own.entitiyID);HSCard target3 = this.getEntityWithNumber(moveTodo.target.entitiyID);if (attacker != null){if (target3 != null){Helpfunctions.Instance.ErrorLog("minion attack: " + attacker.Name + " target: " + target3.Name);Helpfunctions.Instance.logg("minion attack: " + attacker.Name + " target: " + target3.Name);await attacker.DoAttack(target3);}else{Helpfunctions.Instance.ErrorLog("[AI] Target is missing. Attempting recover...");Helpfunctions.Instance.logg("[AI] Target " + moveTodo.target.entitiyID + "is missing. Attempting recover...");}}else{Helpfunctions.Instance.ErrorLog("[AI] Attacker is missing. Attempting recover...");Helpfunctions.Instance.logg("[AI] Attacker " + moveTodo.own.entitiyID + " is missing. Attempting recover...");}await Coroutine.Sleep(250);}else if (moveTodo.actionType == actionEnum.attackWithHero){HSCard attacker2 = this.getEntityWithNumber(moveTodo.own.entitiyID);HSCard target4 = this.getEntityWithNumber(moveTodo.target.entitiyID);if (attacker2 != null){if (target4 != null){this.dirtytarget = moveTodo.target.entitiyID;Helpfunctions.Instance.ErrorLog("heroattack: " + attacker2.Name + " target: " + target4.Name);Helpfunctions.Instance.logg("heroattack: " + attacker2.Name + " target: " + target4.Name);this.dirtyTargetSource = moveTodo.own.entitiyID;this.dirtytarget = moveTodo.target.entitiyID;await attacker2.DoAttack(target4);}else{Helpfunctions.Instance.ErrorLog("[AI] Target is missing. Attempting recover...");Helpfunctions.Instance.logg("[AI] Target " + moveTodo.target.entitiyID + "is missing (H). Attempting recover...");}}else{Helpfunctions.Instance.ErrorLog("[AI] Attacker is missing. Attempting recover...");Helpfunctions.Instance.logg("[AI] Attacker " + moveTodo.own.entitiyID + " is missing (H). Attempting recover...");}await Coroutine.Sleep(250);}else if (moveTodo.actionType == actionEnum.useHeroPower){HSCard cardtoplay2 = TritonHs.OurHeroPowerCard;if (moveTodo.target != null){HSCard target5 = this.getEntityWithNumber(moveTodo.target.entitiyID);if (target5 != null){Helpfunctions.Instance.ErrorLog("use ablitiy: " + cardtoplay2.Name + " target " + target5.Name);Helpfunctions.Instance.logg(string.Concat(new string[]{"use ablitiy: ",cardtoplay2.Name," target ",target5.Name,(moveTodo.druidchoice > 0) ? (" choice: " + moveTodo.druidchoice) : ""}));if (moveTodo.druidchoice > 0){this.dirtytarget = moveTodo.target.entitiyID;this.dirtychoice = moveTodo.druidchoice;this.choiceCardId = moveTodo.card.card.cardIDenum.ToString();}this.dirtyTargetSource = 9000;this.dirtytarget = moveTodo.target.entitiyID;await cardtoplay2.Pickup(500);await cardtoplay2.UseOn(target5.Card);}else{Helpfunctions.Instance.ErrorLog("[AI] Target is missing. Attempting recover...");Helpfunctions.Instance.logg("[AI] Target " + moveTodo.target.entitiyID + "is missing. Attempting recover...");}await Coroutine.Sleep(500);}else{Helpfunctions.Instance.ErrorLog("use ablitiy: " + cardtoplay2.Name + " target nothing");Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay2.Name + " target nothing" + ((moveTodo.druidchoice > 0) ? (" choice: " + moveTodo.druidchoice) : ""));if (moveTodo.druidchoice >= 1){this.dirtychoice = moveTodo.druidchoice;this.choiceCardId = moveTodo.card.card.cardIDenum.ToString();}this.dirtyTargetSource = -1;this.dirtytarget = -1;await cardtoplay2.Pickup(500);}}else{await TritonHs.EndTurn();}}}} }?
最后發現錯誤提示,是從
namespace HREngine.Bots
public class CardDB里面報錯的
把cardid的字符串轉換為cardIDEnum的時候出錯
public CardDB.cardIDEnum cardIdstringToEnum(string s){CardDB.cardIDEnum CardEnum;CardDB.cardIDEnum result;if (Enum.TryParse<CardDB.cardIDEnum>(s, false, out CardEnum)){result = CardEnum;}else{Logger.GetLoggerInstanceForType().ErrorFormat("[Unidentified card ID :" + s + "]", new object[0]);result = CardDB.cardIDEnum.None;}return result;}?
根據我的印象,https://github.com/HearthSim/Hearthdb?這個項目就是用來生成卡牌的。
1.生成data
clone項目,編譯之后,得到能識別的的CardDefs.xml。然后重命名成_carddb.txt,然后替換掉HearthBuddy里面的
2.自己實現卡牌
另外,這個文件不在HearthBuddy的exe里面,是外部加載進來的。HearthbuddyRelease\Routines\DefaultRoutine\Silverfish\ai\CardDB.cs
卡牌的實現需要自己寫在Silverfish\cards文件夾下,并且卡牌在實現的時候,根據需要從Silverfish\ai的某一個類中繼承,實現對應的方法
?github上面嘗試找了一下實現https://github.com/search?l=C%23&o=desc&q=getBattlecryEffect&s=indexed&type=Code
<Entity CardID="DAL_010" ID="51375" version="2">
<MasterPower>773590e3-24fa-4564-994a-94049b32d3f3</MasterPower>
<Tag enumID="185" name="CARDNAME" type="LocString">
<deDE>Togwaggels Plan</deDE>
<enUS>Togwaggle's Scheme</enUS>
<esES>Plan de Togafloja</esES>
<esMX>Complot de Togwaggle</esMX>
<frFR>Man?uvre de Cire-Pilleur</frFR>
<itIT>Piano di Cobaldo</itIT>
<jaJP>トグワグルの計略</jaJP>
<koKR>????? ??</koKR>
<plPL>Intryga Trz?sibrzucha</plPL>
<ptBR>Estratagema de Fubalumba</ptBR>
<ruRU>Козни Вихлепыха</ruRU>
<thTH>?????????????????????</thTH>
<zhCN>托瓦格爾的陰謀</zhCN>
<zhTW>托戈瓦哥的陰謀</zhTW>
</Tag>
?
?
<Entity CardID="DAL_415" ID="52111" version="2">
<MasterPower>2ef4d4c2-dbdf-4ae4-9f14-079984458f86</MasterPower>
<Tag enumID="185" name="CARDNAME" type="LocString">
<deDE>ü.B.E.L.-T?ter</deDE>
<enUS>EVIL Miscreant</enUS>
<esES>Malhechor del MAL</esES>
<esMX>Bellaco del MAL</esMX>
<frFR>Voyou du M.A.L.</frFR>
<itIT>Furfante del M.A.L.E.</itIT>
<jaJP>悪黨同盟の悪漢</jaJP>
<koKR>?.?.?.?. ??</koKR>
<plPL>Szubrawiec Ligi Z.?.A.</plPL>
<ptBR>Mandri?o da MAL</ptBR>
<ruRU>Негодяй ЗЛА</ruRU>
<thTH>?????? EVIL</thTH>
<zhCN>怪盜惡霸</zhCN>
<zhTW>邪惡陣線無賴</zhTW>
</Tag>
?
對了,貌似貼吧已經有部分教程了。https://tieba.baidu.com/p/5663869359
?
?
偶數薩電鰻狼王添加方法
==================================
1.編寫新卡SIM,
在\Hearthbuddy\Routines\DefaultRoutine\Silverfish\cards\,
在目錄下新建一個Sim_擴展包縮寫+卡牌編號.cs文件,
編寫SIM后保存。
==================================
2.編寫并增加新卡識別信息,
\Hearthbuddy\Routines\DefaultRoutine\Silverfish\data\ 下的 _carddb.txt 文件,
其中存儲所有卡牌信息。
含:185、184等等。
注意特效卡牌后面添加playRequirement,
每個節點后退兩個字符。
(上述是新卡描述)
==================================
3.增加新卡編號及英文名稱
在\Routines\DefaultRoutine\Silverfish\ai的CardDB.cs中的3550行后增加新卡
擴展包簡稱_卡牌編號,
如:
LOOT_149,
LOOT_149e,
擴展包簡稱均為大寫,可以聯想GVG,
==================================
在\Routines\DefaultRoutine\Silverfish\ai的CardDB.cs中的6303行后,增加新增卡牌英文名稱。
注意卡牌英文名稱沒有空格且奇數偶數卡牌需添加兩個名字,編寫兩個卡牌信息。
2費電鰻murksparkeel
6費偶數狼王geengreymane
戰斗號角calltoarms
5費吵吵gigglingInventor
5費菌菇fungalmancer
3費荊棘Hench-ClanThug
刺殺花vilespineslayer
9費奇數bakuthemooneater
?
?
?
轉載于:https://www.cnblogs.com/chucklu/p/11192069.html
總結
以上是生活随笔為你收集整理的HearthBuddy卡牌无法识别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一、大话HTTP协议-HTTP的前世今生
- 下一篇: 大话设计模式笔记