/// <summary> /// /// </summary> /// <param name="log"></param> /// <param name="hero"></param> /// <param name="attackerNum"></param> /// <param name="cofferSize"></param> /// <param name="defenderObject"></param> public static void Battle(BattleLog log, Hero hero, BigInteger attackerNum, object cofferSize, BigInteger defenderObject) { // Get Hero of Defender string key; byte[] bytes; if (log.BattleType == GeneralContract.PVC) { Runtime.Log("Attack to city"); key = GeneralContract.CITY_MAP + log.DefenderObject; bytes = Storage.Get(Storage.CurrentContext, key); if (bytes.Length <= 0) { Runtime.Notify(7005); throw new Exception(); } else { City city = (City)Neo.SmartContract.Framework.Helper.Deserialize(bytes); if (city.Hero > 0 && city.Hero == attackerNum) { Runtime.Notify(7006); throw new System.Exception(); } else { byte[] feeBytes = Storage.Get(Storage.CurrentContext, GeneralContract.FEE_PVC); if (!GeneralContract.AttachmentExistAB(feeBytes, GeneralContract.GameOwner)) { if (!GeneralContract.AttachmentExistAB(feeBytes, GeneralContract.GameOwner2)) { Runtime.Notify(7007); throw new Exception(); } } // Increase city coffer byte[] pvcCofferAdditionBytes = Storage.Get(Storage.CurrentContext, GeneralContract.PVC_COFFER_ADDITION_AMOUNT); byte[] cofferSizeBytes = (byte[])cofferSize; if (pvcCofferAdditionBytes.Length > 0) { if (!pvcCofferAdditionBytes.Equals(cofferSizeBytes)) { Runtime.Notify(7020, cofferSizeBytes, pvcCofferAdditionBytes); throw new Exception(); } } BigInteger cofferSizeNum = (BigInteger)cofferSize; BigInteger cityCoffer = Helper.GetCoffer(defenderObject); cityCoffer = BigInteger.Add(cityCoffer, cofferSizeNum); if (log.BattleResult == GeneralContract.ATTACKER_WON) { // change city owner city.Hero = attackerNum; } else if (log.BattleResult != GeneralContract.ATTACKER_LOSE) { Runtime.Notify(7008); throw new Exception(); } Helper.SetCoffer(defenderObject, cityCoffer); key = GeneralContract.CITY_MAP + log.DefenderObject; bytes = Neo.SmartContract.Framework.Helper.Serialize(city); Storage.Put(Storage.CurrentContext, key, bytes); } } } else if (log.BattleType == GeneralContract.PVP) { key = GeneralContract.STRONGHOLD_MAP + log.DefenderObject; bytes = Storage.Get(Storage.CurrentContext, key); if (bytes.Length <= 0) { Runtime.Notify(7009); throw new Exception(); } else { Runtime.Log("Stronghold is on blockchain"); if (hero.StrongholdsAmount > 0) { Runtime.Notify(7010); throw new Exception(); } Stronghold stronghold = (Stronghold)Neo.SmartContract.Framework.Helper.Deserialize(bytes); if (stronghold.Hero > 0 && stronghold.Hero == attackerNum) { Runtime.Notify(7010); throw new Exception(); } else { Runtime.Log("Stronghold is not owned by player"); byte[] feeBytes = Storage.Get(Storage.CurrentContext, GeneralContract.FEE_PVP); if (!GeneralContract.AttachmentExistAB(feeBytes, GeneralContract.GameOwner)) { if (!GeneralContract.AttachmentExistAB(feeBytes, GeneralContract.GameOwner2)) { Runtime.Notify(7012); throw new Exception(); } } Runtime.Log("Attachment is included"); if (log.BattleResult == GeneralContract.ATTACKER_WON) { // Can not compile // byte[] oldHeroIdBytes = stronghold.Hero.ToByteArray(); BigInteger oldHeroKeyInt = stronghold.Hero; byte[] oldHeroIdBytes = oldHeroKeyInt.ToByteArray(); string oldHeroKey = GeneralContract.HERO_MAP + oldHeroIdBytes; byte[] oldHeroBytes = Storage.Get(oldHeroKey); if (oldHeroKeyInt > 0 && oldHeroIdBytes.Length <= 0) { Runtime.Notify(7022); throw new Exception(); } else if (oldHeroKeyInt > 0) { Hero oldHero = (Hero)Neo.SmartContract.Framework.Helper.Deserialize(oldHeroBytes); oldHero.StrongholdsAmount = BigInteger.Subtract(oldHero.StrongholdsAmount, 1); oldHeroBytes = Neo.SmartContract.Framework.Helper.Serialize(oldHero); Storage.Put(oldHeroKey, oldHeroBytes); } // change stronghold owner stronghold.Hero = attackerNum; stronghold.CreatedBlock = Blockchain.GetHeight(); hero.StrongholdsAmount = BigInteger.Add(hero.StrongholdsAmount, 1); string heroKey = GeneralContract.HERO_MAP + log.Attacker; byte[] heroBytes = Neo.SmartContract.Framework.Helper.Serialize(hero); Storage.Put(Storage.CurrentContext, heroKey, heroBytes); } else if (log.BattleResult != GeneralContract.ATTACKER_LOSE) { Runtime.Notify(7013); throw new Exception(); } Runtime.Log("Stronghold attack data prepared"); key = GeneralContract.STRONGHOLD_MAP + log.DefenderObject; bytes = Neo.SmartContract.Framework.Helper.Serialize(stronghold); Storage.Put(Storage.CurrentContext, key, bytes); Runtime.Log("Stronghold data inserted"); } } } else if (log.BattleType == GeneralContract.PVE) { Runtime.Log("Bandit camp attack"); key = GeneralContract.BANDIT_CAMP_MAP + log.DefenderObject; bytes = Storage.Get(Storage.CurrentContext, key); if (bytes.Length <= 0) { Runtime.Notify(7014); throw new System.Exception(); } else { Runtime.Log("Bandit camp on blockchain"); byte[] feeBytes = Storage.Get(Storage.CurrentContext, GeneralContract.FEE_PVE); if (!GeneralContract.AttachmentExistAB(feeBytes, GeneralContract.GameOwner)) { if (!GeneralContract.AttachmentExistAB(feeBytes, GeneralContract.GameOwner2)) { Runtime.Notify(7015); throw new Exception(); } } BigInteger exp = (BigInteger)cofferSize; if (log.BattleResult == GeneralContract.ATTACKER_WON) { Runtime.Log("Bandit camp attacker won"); UpdateItemStats(log.AttackerItem1, log.AttackerItem2, log.AttackerItem3, log.AttackerItem4, log.AttackerItem5, log.BattleId, exp); } else if (log.BattleResult == GeneralContract.ATTACKER_LOSE) { Runtime.Log("Bandit camp attacker Lose"); UpdateItemStats(log.AttackerItem1, log.AttackerItem2, log.AttackerItem3, log.AttackerItem4, log.AttackerItem5, log.BattleId, exp); } else { Runtime.Notify(7016); throw new System.Exception(); } } } else { Runtime.Notify(7017); throw new Exception(); } Runtime.Log("Battle typ specific data change finished"); log.Time = Blockchain.GetHeader(Blockchain.GetHeight()).Timestamp; Runtime.Log("Battle data returned"); string battleIdKey = GeneralContract.BATTLE_LOG_MAP + log.BattleId; byte[] battleLogBytes = Storage.Get(Storage.CurrentContext, battleIdKey); battleLogBytes = Neo.SmartContract.Framework.Helper.Serialize(log); Storage.Put(Storage.CurrentContext, battleIdKey, battleLogBytes); Runtime.Log("Battle Data on blockchain"); Runtime.Notify(7000, log.BattleId, log.BattleResult, log.BattleType, log.Attacker, log.AttackerTroops, log.AttackerRemained, log.AttackerItem1, log.AttackerItem2, log.AttackerItem3, log.AttackerItem4, log.AttackerItem5, log.DefenderObject, log.DefenderTroops, log.DefenderRemained); }
private static void UpdateItemStats(byte[] id1, byte[] id2, byte[] id3, byte[] id4, byte[] id5, byte[] battleId, BigInteger exp) { byte[][] upgradableItem = new byte[5][]; BigInteger upgradableAmount = 0; int checkedIndex = 0; if (IsUpgradableItem(id1)) { upgradableItem[checkedIndex] = id1; checkedIndex++; upgradableAmount = BigInteger.Add(upgradableAmount, 1); } if (IsUpgradableItem(id2)) { upgradableItem[checkedIndex] = id2; checkedIndex++; upgradableAmount = BigInteger.Add(upgradableAmount, 1); } if (IsUpgradableItem(id3)) { upgradableItem[checkedIndex] = id3; checkedIndex++; upgradableAmount = BigInteger.Add(upgradableAmount, 1); } if (IsUpgradableItem(id4)) { upgradableItem[checkedIndex] = id4; checkedIndex++; upgradableAmount = BigInteger.Add(upgradableAmount, 1); } if (IsUpgradableItem(id5)) { upgradableItem[checkedIndex] = id5; checkedIndex++; upgradableAmount = BigInteger.Add(upgradableAmount, 1); } if (upgradableAmount == 0) { return; } BigInteger randomUpgradableIndex = GeneralContract.GetRandomNumber(0, (ulong)upgradableAmount); byte[] itemId = Helper.GetIdByIndex(upgradableItem, upgradableAmount, randomUpgradableIndex); if (itemId.Length <= 0) { Runtime.Log("Random generated is 0"); return; } string key = GeneralContract.ITEM_MAP + itemId; Item item = (Item)Neo.SmartContract.Framework.Helper.Deserialize(Storage.Get(Storage.CurrentContext, key)); // Increase XP that represents on how many items the Item was involved item.XP = BigInteger.Add(item.XP, exp); // Increase Level if (item.LEVEL == 0 && item.XP >= 2 || item.LEVEL == 1 && item.XP >= 6 || item.LEVEL == 2 && item.XP >= 20 || item.LEVEL == 3 && item.XP >= 48 || item.LEVEL == 4 && item.XP >= 92 || item.LEVEL == 5 && item.XP >= 152 || item.LEVEL == 6 && item.XP >= 228 || item.LEVEL == 7 && item.XP >= 318 || item.LEVEL == 8 && item.XP >= 434 || item.LEVEL == 9 && item.XP >= 580 ) { item.LEVEL = item.LEVEL + 1; item.STAT_VALUE = item.STAT_VALUE + 1; } // Put back On Storage the Item with increased values byte[] bytes = Neo.SmartContract.Framework.Helper.Serialize(item); Storage.Put(Storage.CurrentContext, key, bytes); Runtime.Log("Item exp increased"); Runtime.Notify(7019, itemId, battleId, exp, item.LEVEL, item.STAT_VALUE, item.XP); }
/** * Function records item drop * * Function drops item in every 120 blocks. Usually called by Server Side of Blocklords. * * Has 0 argument */ public static void SimpleDropItem(byte[] itemId, object strongholdAmountObj, object dropIntervalObj) { if (!Runtime.CheckWitness(GeneralContract.GameOwner)) { Runtime.Notify(16); throw new System.Exception(); } DropData lastDrop = new DropData(); lastDrop.Block = 0; lastDrop.StrongholdId = 0; byte[] lastDropBytes = Storage.Get(Storage.CurrentContext, GeneralContract.LAST_ITEM_DROP); if (lastDropBytes.Length > 0) { lastDrop = (DropData)Neo.SmartContract.Framework.Helper.Deserialize(lastDropBytes); } byte[] dropIntervalSettingBytes = Storage.Get(Storage.CurrentContext, GeneralContract.INTERVAL_DROP); byte[] dropIntervalBytes = (byte[])dropIntervalObj; if (dropIntervalSettingBytes.Length > 0) { if (!dropIntervalSettingBytes.Equals(dropIntervalBytes)) { Runtime.Notify(7); throw new System.Exception(); } } BigInteger dropInterval = (BigInteger)dropIntervalObj; if (Blockchain.GetHeight() <= dropInterval + lastDrop.Block) { Runtime.Notify(5001); throw new System.Exception(); } byte[] strongholdsAmountSettingBytes = Storage.Get(Storage.CurrentContext, GeneralContract.AMOUNT_STRONGHOLDS); byte[] strongholdsAmountBytes = (byte[])strongholdAmountObj; if (!strongholdsAmountSettingBytes.Equals(strongholdsAmountBytes)) { Runtime.Notify(8); throw new System.Exception(); } BigInteger strongholdsAmount = (BigInteger)strongholdAmountObj; string key; Stronghold stronghold; byte[] bytes; // Check that Item has no owner and that is is on stronghold reward batch string itemKey = GeneralContract.ITEM_MAP + itemId; bytes = Storage.Get(Storage.CurrentContext, itemKey); if (bytes.Length <= 0) { Runtime.Notify(1005); throw new System.Exception(); } Item item = (Item)Neo.SmartContract.Framework.Helper.Deserialize(bytes); if (item.BATCH != GeneralContract.STRONGHOLD_REWARD_BATCH) { Runtime.Notify(5002); throw new System.Exception(); } // returned an index on list of available strongholds ids BigInteger random = GeneralContract.GetRandomNumber(0, strongholdsAmount); random = BigInteger.Add(random, 1); key = GeneralContract.STRONGHOLD_MAP + random.ToByteArray(); bytes = Storage.Get(Storage.CurrentContext, key); if (bytes.Length <= 0) { // Delete Item //Storage.Delete(Storage.CurrentContext, itemKey); Runtime.Notify(5003);//, itemId, random, 0, Blockchain.GetHeight()); throw new System.Exception(); } else { stronghold = (Stronghold)Neo.SmartContract.Framework.Helper.Deserialize(bytes); BigInteger lordId = stronghold.Hero; if (lordId <= 0) { // Delete Item Storage.Delete(Storage.CurrentContext, itemKey); // Record the match lastDrop.Block = Blockchain.GetHeight(); lastDrop.HeroId = 0; lastDrop.ItemId = itemId; lastDrop.StrongholdId = random; lastDropBytes = Neo.SmartContract.Framework.Helper.Serialize(lastDrop); Storage.Put(Storage.CurrentContext, GeneralContract.LAST_ITEM_DROP, lastDropBytes); Runtime.Notify(5004, itemId, random, 0, Blockchain.GetHeight()); } else { string heroKey = GeneralContract.HERO_MAP + lordId.ToByteArray(); Hero hero = (Hero)Neo.SmartContract.Framework.Helper.Deserialize(Storage.Get(Storage.CurrentContext, heroKey)); // Change owner of Item. item.HERO = hero.ID; item.BATCH = GeneralContract.NO_BATCH; byte[] itemBytes = Neo.SmartContract.Framework.Helper.Serialize(item); // Save Item after change of ownership Storage.Put(Storage.CurrentContext, itemKey, itemBytes); // Kick out a lord from stronghold. stronghold.Hero = 0; stronghold.CreatedBlock = Blockchain.GetHeight(); byte[] strongholdBytes = Neo.SmartContract.Framework.Helper.Serialize(stronghold); Storage.Put(Storage.CurrentContext, key, strongholdBytes); lastDrop.Block = Blockchain.GetHeight(); lastDrop.HeroId = hero.ID; lastDrop.ItemId = itemId; lastDrop.StrongholdId = random; lastDropBytes = Neo.SmartContract.Framework.Helper.Serialize(lastDrop); Storage.Put(Storage.CurrentContext, GeneralContract.LAST_ITEM_DROP, lastDropBytes); // Save hero with the mark that he lost his stronghold hero.StrongholdsAmount = BigInteger.Subtract(hero.StrongholdsAmount, 1); byte[] heroBytes = Neo.SmartContract.Framework.Helper.Serialize(hero); Storage.Put(heroKey, heroBytes); Runtime.Notify(5000, itemId, lastDrop.StrongholdId, lastDrop.HeroId, lastDrop.Block); } } }