예제 #1
0
        private void ResponseUnrenderItemEnhancement(ActionBase.ActionEvaluation <ItemEnhancement5> eval)
        {
            var agentAddress  = eval.Signer;
            var avatarAddress = eval.Action.avatarAddress;
            var slot          = eval.OutputStates.GetCombinationSlotState(avatarAddress, eval.Action.slotIndex);
            var result        = (ItemEnhancement.ResultModel)slot.Result;
            var itemUsable    = result.itemUsable;
            var avatarState   = eval.OutputStates.GetAvatarState(avatarAddress);

            // NOTE: 사용한 자원에 대한 레이어 다시 추가하기.
            LocalLayerModifier.ModifyAgentGold(agentAddress, -result.gold);
            LocalLayerModifier.RemoveItem(avatarAddress, itemUsable.ItemId);
            foreach (var itemId in result.materialItemIdList)
            {
                // NOTE: 최종적으로 UpdateCurrentAvatarState()를 호출한다면, 그곳에서 상태를 새로 설정할 것이다.
                LocalLayerModifier.RemoveItem(avatarAddress, itemId);
            }

            // NOTE: 메일 레이어 다시 없애기.
            LocalLayerModifier.AddItem(avatarAddress, itemUsable.ItemId, false);
            LocalLayerModifier.RemoveNewAttachmentMail(avatarAddress, result.id);

            // NOTE: 워크샵 슬롯의 모든 휘발성 상태 변경자를 다시 추가하기.
            var otherItemId = result.materialItemIdList.First();

            LocalLayerModifier.ModifyCombinationSlotItemEnhancement(
                itemUsable.ItemId,
                otherItemId,
                eval.Action.slotIndex);

            UpdateAgentState(eval);
            UpdateCurrentAvatarState(eval);
            UpdateCombinationSlotState(slot);
            UnrenderQuest(avatarAddress, avatarState.questList.completedQuestIds);
        }
예제 #2
0
        private bool ContainsAddressToBroadcast(ActionBase.ActionEvaluation <ActionBase> ev)
        {
            var updatedAddresses =
                ev.OutputStates.UpdatedAddresses.Union(ev.OutputStates.UpdatedFungibleAssets.Keys);

            return(_context.AddressesToSubscribe.Any(address =>
                                                     ev.Signer.Equals(address) || updatedAddresses.Contains(address)));
        }
예제 #3
0
        private void ResponseItemEnhancement(ActionBase.ActionEvaluation <ItemEnhancement> eval)
        {
            if (eval.Exception is null)
            {
                var agentAddress  = eval.Signer;
                var avatarAddress = eval.Action.avatarAddress;
                var slot          = eval.OutputStates.GetCombinationSlotState(avatarAddress, eval.Action.slotIndex);
                var result        = (ItemEnhancement.ResultModel)slot.Result;
                var itemUsable    = result.itemUsable;
                var avatarState   = eval.OutputStates.GetAvatarState(avatarAddress);

                // NOTE: 사용한 자원에 대한 레이어 벗기기.
                LocalLayerModifier.ModifyAgentGold(agentAddress, result.gold);
                LocalLayerModifier.AddItem(avatarAddress, itemUsable.ItemId, false);
                foreach (var itemId in result.materialItemIdList)
                {
                    // NOTE: 최종적으로 UpdateCurrentAvatarState()를 호출한다면, 그곳에서 상태를 새로 설정할 것이다.
                    LocalLayerModifier.AddItem(avatarAddress, itemId, false);
                }

                // NOTE: 메일 레이어 씌우기.
                LocalLayerModifier.RemoveItem(avatarAddress, itemUsable.ItemId);
                LocalLayerModifier.AddNewAttachmentMail(avatarAddress, result.id);

                // NOTE: 워크샵 슬롯의 모든 휘발성 상태 변경자를 제거하기.
                LocalLayerModifier.ResetCombinationSlot(slot);

                // NOTE: 노티 예약 걸기.
                var format = L10nManager.Localize("NOTIFICATION_ITEM_ENHANCEMENT_COMPLETE");
                UI.Notification.Reserve(
                    MailType.Workshop,
                    string.Format(format, result.itemUsable.GetLocalizedName()),
                    slot.UnlockBlockIndex,
                    result.itemUsable.ItemId);

                //[TentuPlay] 장비강화, 골드사용
                //Local에서 변경하는 States.Instance 보다는 블락에서 꺼내온 eval.OutputStates를 사용
                if (eval.OutputStates.TryGetGoldBalance(agentAddress, GoldCurrency, out var outAgentBalance))
                {
                    var total = outAgentBalance -
                                new FungibleAssetValue(outAgentBalance.Currency, result.gold, 0);
                    new TPStashEvent().CharacterCurrencyUse(
                        player_uuid: agentAddress.ToHex(),
                        character_uuid: States.Instance.CurrentAvatarState.address.ToHex().Substring(0, 4),
                        currency_slug: "gold",
                        currency_quantity: (float)result.gold,
                        currency_total_quantity: float.Parse(total.GetQuantityString()),
                        reference_entity: entity.Items, //강화가 가능하므로 장비
                        reference_category_slug: "item_enhancement",
                        reference_slug: itemUsable.Id.ToString());
                }

                UpdateAgentState(eval);
                UpdateCurrentAvatarState(eval);
                UpdateCombinationSlotState(slot);
                RenderQuest(avatarAddress, avatarState.questList.completedQuestIds);
            }
        }
예제 #4
0
        private void ResponseMimisbrunnr(ActionBase.ActionEvaluation <MimisbrunnrBattle> eval)
        {
            if (eval.Exception is null)
            {
                _disposableForBattleEnd?.Dispose();
                _disposableForBattleEnd =
                    Game.Game.instance.Stage.onEnterToStageEnd
                    .First()
                    .Subscribe(_ =>
                {
                    UpdateCurrentAvatarState(eval);
                    UpdateWeeklyArenaState(eval);
                    var avatarState =
                        eval.OutputStates.GetAvatarState(eval.Action.avatarAddress);
                    RenderQuest(eval.Action.avatarAddress,
                                avatarState.questList.completedQuestIds);
                    _disposableForBattleEnd = null;
                });

                var actionFailPopup = Widget.Find <ActionFailPopup>();
                actionFailPopup.CloseCallback = null;
                actionFailPopup.Close();

                if (Widget.Find <LoadingScreen>().IsActive())
                {
                    if (Widget.Find <MimisbrunnrPreparation>().IsActive())
                    {
                        Widget.Find <MimisbrunnrPreparation>().GoToStage(eval.Action.Result);
                    }
                    else if (Widget.Find <Menu>().IsActive())
                    {
                        Widget.Find <Menu>().GoToStage(eval.Action.Result);
                    }
                }
                else if (Widget.Find <StageLoadingScreen>().IsActive() &&
                         Widget.Find <BattleResult>().IsActive())
                {
                    Widget.Find <BattleResult>().NextMimisbrunnrStage(eval);
                }
            }
            else
            {
                var showLoadingScreen = false;
                if (Widget.Find <StageLoadingScreen>().IsActive())
                {
                    Widget.Find <StageLoadingScreen>().Close();
                }
                if (Widget.Find <BattleResult>().IsActive())
                {
                    showLoadingScreen = true;
                    Widget.Find <BattleResult>().Close();
                }

                var exc = eval.Exception.InnerException;
                BackToMain(showLoadingScreen, exc);
            }
        }
예제 #5
0
        protected bool HasUpdatedAssetsForCurrentAgent <T>(ActionBase.ActionEvaluation <T> evaluation)
            where T : ActionBase
        {
            if (States.Instance.AgentState is null)
            {
                return(false);
            }

            return(evaluation.OutputStates.UpdatedFungibleAssets.ContainsKey(States.Instance.AgentState.address));
        }
예제 #6
0
        protected bool ValidateEvaluationForAgentState <T>(ActionBase.ActionEvaluation <T> evaluation)
            where T : ActionBase
        {
            if (States.Instance.AgentState is null)
            {
                return(false);
            }

            return(evaluation.OutputStates.UpdatedAddresses.Contains(States.Instance.AgentState.address));
        }
예제 #7
0
        private void NotifyAction(ActionBase.ActionEvaluation <ActionBase> eval)
        {
            if (StandaloneContext.NineChroniclesNodeService is null)
            {
                throw new InvalidOperationException(
                          $"{nameof(StandaloneContext.NineChroniclesNodeService)} is null.");
            }

            if (StandaloneContext.NineChroniclesNodeService.MinerPrivateKey is null)
            {
                Log.Information("PrivateKey is not set. please call SetPrivateKey() first.");
                return;
            }
            Address address = StandaloneContext.NineChroniclesNodeService.MinerPrivateKey.PublicKey.ToAddress();

            if (eval.OutputStates.UpdatedAddresses.Contains(address) || eval.Signer == address)
            {
                if (eval.Signer == address)
                {
                    var type = NotificationEnum.Refill;
                    var msg  = string.Empty;
                    switch (eval.Action)
                    {
                    case HackAndSlash4 has:
                        type = NotificationEnum.HAS;
                        msg  = has.stageId.ToString(CultureInfo.InvariantCulture);
                        break;

                    case CombinationConsumable3 _:
                        type = NotificationEnum.CombinationConsumable;
                        break;

                    case CombinationEquipment4 _:
                        type = NotificationEnum.CombinationEquipment;
                        break;

                    case Buy4 _:
                        type = NotificationEnum.Buyer;
                        break;
                    }
                    Log.Information("NotifyAction: Type: {Type} MSG: {Msg}", type, msg);
                    var notification = new Notification(type, msg);
                    StandaloneContext.NotificationSubject.OnNext(notification);
                }
                else
                {
                    if (eval.Action is Buy4 buy && buy.sellerAgentAddress == address)
                    {
                        var notification = new Notification(NotificationEnum.Seller);
                        StandaloneContext.NotificationSubject.OnNext(notification);
                    }
                }
            }
        }
예제 #8
0
        private void ResponseCombinationConsumable(ActionBase.ActionEvaluation <CombinationConsumable> eval)
        {
            if (eval.Exception is null)
            {
                var agentAddress  = eval.Signer;
                var avatarAddress = eval.Action.AvatarAddress;
                var slot          = eval.OutputStates.GetCombinationSlotState(avatarAddress, eval.Action.slotIndex);
                var result        = (CombinationConsumable.ResultModel)slot.Result;
                var itemUsable    = result.itemUsable;
                var avatarState   = eval.OutputStates.GetAvatarState(avatarAddress);

                LocalLayerModifier.ModifyAgentGold(agentAddress, result.gold);
                LocalLayerModifier.ModifyAvatarActionPoint(avatarAddress, result.actionPoint);
                foreach (var pair in result.materials)
                {
                    // NOTE: 최종적으로 UpdateCurrentAvatarState()를 호출한다면, 그곳에서 상태를 새로 설정할 것이다.
                    LocalLayerModifier.AddItem(avatarAddress, pair.Key.ItemId, pair.Value, false);
                }

                LocalLayerModifier.RemoveItem(avatarAddress, itemUsable.ItemId);
                LocalLayerModifier.AddNewAttachmentMail(avatarAddress, result.id);
                LocalLayerModifier.ResetCombinationSlot(slot);

                var format = L10nManager.Localize("NOTIFICATION_COMBINATION_COMPLETE");
                UI.Notification.Reserve(
                    MailType.Workshop,
                    string.Format(format, result.itemUsable.GetLocalizedName()),
                    slot.UnlockBlockIndex,
                    result.itemUsable.ItemId
                    );
                AnalyticsManager.Instance.OnEvent(AnalyticsManager.EventName.ActionCombinationSuccess);

                //[TentuPlay] Consumable 합성에 사용한 골드 기록
                //Local에서 변경하는 States.Instance 보다는 블락에서 꺼내온 eval.OutputStates를 사용
                if (eval.OutputStates.TryGetGoldBalance(agentAddress, GoldCurrency, out var balance))
                {
                    var total = balance - new FungibleAssetValue(balance.Currency, result.gold, 0);
                    new TPStashEvent().CharacterCurrencyUse(
                        player_uuid: agentAddress.ToHex(),
                        character_uuid: States.Instance.CurrentAvatarState.address.ToHex().Substring(0, 4),
                        currency_slug: "gold",
                        currency_quantity: (float)result.gold,
                        currency_total_quantity: float.Parse(total.GetQuantityString()),
                        reference_entity: entity.Items,
                        reference_category_slug: "consumables_combination",
                        reference_slug: result.itemUsable.Id.ToString());
                }

                UpdateAgentState(eval);
                UpdateCurrentAvatarState(eval);
                UpdateCombinationSlotState(slot);
                RenderQuest(avatarAddress, avatarState.questList.completedQuestIds);
            }
        }
예제 #9
0
 private void ResponseChargeActionPoint(ActionBase.ActionEvaluation <ChargeActionPoint> eval)
 {
     if (eval.Exception is null)
     {
         var avatarAddress = eval.Action.avatarAddress;
         LocalLayerModifier.ModifyAvatarActionPoint(avatarAddress, -States.Instance.GameConfigState.ActionPointMax);
         var row = Game.Game.instance.TableSheets.MaterialItemSheet.Values.First(r =>
                                                                                 r.ItemSubType == ItemSubType.ApStone);
         LocalLayerModifier.AddItem(avatarAddress, row.ItemId, 1);
         UpdateCurrentAvatarState(eval);
     }
 }
예제 #10
0
        private void ResponseSell(ActionBase.ActionEvaluation <Sell3> eval)
        {
            if (!(eval.Exception is null))
            {
                return;
            }

            var avatarAddress = eval.Action.sellerAvatarAddress;
            var itemId        = eval.Action.itemId;

            LocalLayerModifier.RemoveItem(avatarAddress, itemId);
            UpdateCurrentAvatarState(eval);
        }
예제 #11
0
        private IEnumerator CoGoToNextMimisbrunnrStageClose(ActionBase.ActionEvaluation <MimisbrunnrBattle2> eval)
        {
            if (Find <Menu>().IsActive())
            {
                yield break;
            }

            yield return(StartCoroutine(Find <StageLoadingScreen>().CoClose()));

            yield return(StartCoroutine(CoFadeOut()));

            Game.Event.OnStageStart.Invoke(eval.Action.Result);
            Close();
        }
예제 #12
0
        private void ResponseSellCancellation(ActionBase.ActionEvaluation <SellCancellation4> eval)
        {
            if (!(eval.Exception is null))
            {
                return;
            }

            var result          = eval.Action.result;
            var nonFungibleItem = result.itemUsable ?? (INonFungibleItem)result.costume;
            var avatarAddress   = eval.Action.sellerAvatarAddress;
            var itemId          = nonFungibleItem.ItemId;

            LocalLayerModifier.AddItem(avatarAddress, itemId);
            UpdateCurrentAvatarState(eval);
        }
예제 #13
0
        private void ResponseSellCancellation(ActionBase.ActionEvaluation <SellCancellation4> eval)
        {
            if (eval.Exception is null)
            {
                var avatarAddress   = eval.Action.sellerAvatarAddress;
                var result          = eval.Action.result;
                var nonFungibleItem = result.itemUsable ?? (INonFungibleItem)result.costume;
                var itemBase        = result.itemUsable ?? (ItemBase)result.costume;

                LocalLayerModifier.RemoveItem(avatarAddress, nonFungibleItem.ItemId);
                LocalLayerModifier.AddNewAttachmentMail(avatarAddress, result.id);
                var format = L10nManager.Localize("NOTIFICATION_SELL_CANCEL_COMPLETE");
                UI.Notification.Push(MailType.Auction, string.Format(format, itemBase.GetLocalizedName()));
                UpdateCurrentAvatarState(eval);
            }
        }
예제 #14
0
        private void ResponseDailyReward(ActionBase.ActionEvaluation <DailyReward> eval)
        {
            if (!(eval.Exception is null))
            {
                return;
            }

            var avatarAddress = eval.Action.avatarAddress;
            var itemId        = eval.Action.dailyRewardResult.materials.First().Key.ItemId;
            var itemCount     = eval.Action.dailyRewardResult.materials.First().Value;

            LocalLayerModifier.AddItem(avatarAddress, itemId, itemCount);
            UpdateCurrentAvatarState(eval);

            WidgetHandler.Instance.Menu.SetActiveActionPointLoading(true);
        }
예제 #15
0
        private void ResponseBuy(ActionBase.ActionEvaluation <Buy4> eval)
        {
            if (!(eval.Exception is null))
            {
                return;
            }

            var        buyerAvatarAddress = eval.Action.buyerAvatarAddress;
            var        price = eval.Action.sellerResult.shopItem.Price;
            Address    renderQuestAvatarAddress;
            List <int> renderQuestCompletedQuestIds;

            if (buyerAvatarAddress == States.Instance.CurrentAvatarState.address)
            {
                var buyerAgentAddress = States.Instance.AgentState.address;
                var result            = eval.Action.buyerResult;

                var itemId      = result.itemUsable?.ItemId ?? result.costume.ItemId;
                var buyerAvatar = eval.OutputStates.GetAvatarState(buyerAvatarAddress);

                LocalLayerModifier.ModifyAgentGold(buyerAgentAddress, -price);
                LocalLayerModifier.AddItem(buyerAvatarAddress, itemId);
                LocalLayerModifier.RemoveNewAttachmentMail(buyerAvatarAddress, result.id);

                renderQuestAvatarAddress     = buyerAvatarAddress;
                renderQuestCompletedQuestIds = buyerAvatar.questList.completedQuestIds;
            }
            else
            {
                var sellerAvatarAddress = eval.Action.sellerAvatarAddress;
                var sellerAgentAddress  = eval.Action.sellerAgentAddress;
                var result       = eval.Action.sellerResult;
                var gold         = result.gold;
                var sellerAvatar = eval.OutputStates.GetAvatarState(sellerAvatarAddress);

                LocalLayerModifier.ModifyAgentGold(sellerAgentAddress, gold);
                LocalLayerModifier.RemoveNewAttachmentMail(sellerAvatarAddress, result.id);

                renderQuestAvatarAddress     = sellerAvatarAddress;
                renderQuestCompletedQuestIds = sellerAvatar.questList.completedQuestIds;
            }

            UpdateAgentState(eval);
            UpdateCurrentAvatarState(eval);
            UnrenderQuest(renderQuestAvatarAddress, renderQuestCompletedQuestIds);
        }
        private void NotifyAction(ActionBase.ActionEvaluation <ActionBase> eval)
        {
            if (eval.OutputStates.UpdatedAddresses.Contains(_address))
            {
                if (eval.Signer == _address)
                {
                    var type = NotificationEnum.Refill;
                    var msg  = string.Empty;
                    switch (eval.Action)
                    {
                    case HackAndSlash3 has:
                        type = NotificationEnum.HAS;
                        msg  = has.stageId.ToString(CultureInfo.InvariantCulture);
                        break;

                    case CombinationConsumable2 _:
                        type = NotificationEnum.CombinationConsumable;
                        break;

                    case CombinationEquipment3 _:
                        type = NotificationEnum.CombinationEquipment;
                        break;

                    case Buy3 _:
                        type = NotificationEnum.Buyer;
                        break;
                    }
                    var notification = new Notification(type, msg);
                    StandaloneContext.NotificationSubject.OnNext(notification);
                }
                else
                {
                    if (eval.Action is Buy3 buy && buy.sellerAgentAddress == _address)
                    {
                        var notification = new Notification(NotificationEnum.Seller);
                        StandaloneContext.NotificationSubject.OnNext(notification);
                    }
                }
            }
        }
예제 #17
0
        private void ResponseRapidCombination(ActionBase.ActionEvaluation <RapidCombination2> eval)
        {
            var avatarAddress = eval.Action.avatarAddress;
            var slot          =
                eval.OutputStates.GetCombinationSlotState(avatarAddress, eval.Action.slotIndex);
            var result = (RapidCombination.ResultModel)slot.Result;

            foreach (var pair in result.cost)
            {
                // NOTE: 최종적으로 UpdateCurrentAvatarState()를 호출한다면, 그곳에서 상태를 새로 설정할 것이다.
                LocalLayerModifier.AddItem(avatarAddress, pair.Key.ItemId, pair.Value, false);
            }
            LocalLayerModifier.RemoveAvatarItemRequiredIndex(avatarAddress, result.itemUsable.ItemId);
            LocalLayerModifier.ResetCombinationSlot(slot);

            AnalyticsManager.Instance.OnEvent(AnalyticsManager.EventName.ActionCombinationSuccess);

            //[TentuPlay] RapidCombinationConsumable 합성에 사용한 골드 기록
            //Local에서 변경하는 States.Instance 보다는 블락에서 꺼내온 eval.OutputStates를 사용
            var agentAddress = eval.Signer;
            var qty          = eval.OutputStates.GetAvatarState(avatarAddress).inventory.Materials
                               .Count(i => i.ItemSubType == ItemSubType.Hourglass);
            var prevQty = eval.PreviousStates.GetAvatarState(avatarAddress).inventory.Materials
                          .Count(i => i.ItemSubType == ItemSubType.Hourglass);

            new TPStashEvent().CharacterItemUse(
                player_uuid: agentAddress.ToHex(),
                character_uuid: States.Instance.CurrentAvatarState.address.ToHex().Substring(0, 4),
                item_category: itemCategory.Consumable,
                item_slug: "hourglass",
                item_quantity: (float)(prevQty - qty),
                reference_entity: entity.Items,
                reference_category_slug: "consumables_rapid_combination",
                reference_slug: slot.Result.itemUsable.Id.ToString()
                );

            UpdateAgentState(eval);
            UpdateCurrentAvatarState(eval);
            UpdateCombinationSlotState(slot);
        }
예제 #18
0
        private void ResponseRedeemCode(ActionBase.ActionEvaluation <Action.RedeemCode> eval)
        {
            var key = "UI_REDEEM_CODE_INVALID_CODE";

            if (eval.Exception is null)
            {
                Widget.Find <CodeReward>().Show(eval.OutputStates.GetRedeemCodeState());
                key = "UI_REDEEM_CODE_SUCCESS";
                UpdateCurrentAvatarState(eval);
            }
            else
            {
                if (eval.Exception.InnerException is DuplicateRedeemException)
                {
                    key = "UI_REDEEM_CODE_ALREADY_USE";
                }
            }

            var msg = L10nManager.Localize(key);

            UI.Notification.Push(MailType.System, msg);
        }
예제 #19
0
        private void ResponseSell(ActionBase.ActionEvaluation <Sell> eval)
        {
            if (eval.Exception is null)
            {
                var avatarAddress = eval.Action.sellerAvatarAddress;
                var itemId        = eval.Action.itemId;

                // NOTE: 최종적으로 UpdateCurrentAvatarState()를 호출한다면, 그곳에서 상태를 새로 설정할 것이다.
                LocalLayerModifier.AddItem(avatarAddress, itemId, false);
                var format    = L10nManager.Localize("NOTIFICATION_SELL_COMPLETE");
                var shopState = new ShopState((Dictionary)eval.OutputStates.GetState(ShopState.Address));

                var shopItem = shopState.Products.Values.First(r =>
                {
                    var nonFungibleItem = r.ItemUsable ?? (INonFungibleItem)r.Costume;
                    return(nonFungibleItem.ItemId == itemId);
                });

                var itemBase = shopItem.ItemUsable ?? (ItemBase)shopItem.Costume;
                UI.Notification.Push(MailType.Auction, string.Format(format, itemBase.GetLocalizedName()));
                UpdateCurrentAvatarState(eval);
            }
        }
예제 #20
0
        private void ResponseBuy(ActionBase.ActionEvaluation <Buy> eval)
        {
            if (eval.Exception is null)
            {
                var        buyerAvatarAddress = eval.Action.buyerAvatarAddress;
                var        price = eval.Action.sellerResult.shopItem.Price;
                Address    renderQuestAvatarAddress;
                List <int> renderQuestCompletedQuestIds = null;

                if (buyerAvatarAddress == States.Instance.CurrentAvatarState.address)
                {
                    var buyerAgentAddress = States.Instance.AgentState.address;
                    var result            = eval.Action.buyerResult;
                    var nonFungibleItem   = result.itemUsable ?? (INonFungibleItem)result.costume;
                    var itemBase          = result.itemUsable ?? (ItemBase)result.costume;
                    var buyerAvatar       = eval.OutputStates.GetAvatarState(buyerAvatarAddress);

                    // 골드 처리.
                    LocalLayerModifier.ModifyAgentGold(buyerAgentAddress, price);

                    // 메일 처리.
                    LocalLayerModifier.RemoveItem(buyerAvatarAddress, nonFungibleItem.ItemId);
                    LocalLayerModifier.AddNewAttachmentMail(buyerAvatarAddress, result.id);

                    var format = L10nManager.Localize("NOTIFICATION_BUY_BUYER_COMPLETE");
                    UI.Notification.Push(MailType.Auction, string.Format(format, itemBase.GetLocalizedName()));

                    //[TentuPlay] 아이템 구입, 골드 사용
                    //Local에서 변경하는 States.Instance 보다는 블락에서 꺼내온 eval.OutputStates를 사용
                    if (eval.OutputStates.TryGetGoldBalance(buyerAgentAddress, GoldCurrency, out var buyerAgentBalance))
                    {
                        var total = buyerAgentBalance - price;
                        new TPStashEvent().CharacterCurrencyUse(
                            player_uuid: States.Instance.AgentState.address.ToHex(),
                            character_uuid: States.Instance.CurrentAvatarState.address.ToHex().Substring(0, 4),
                            currency_slug: "gold",
                            currency_quantity: float.Parse(price.GetQuantityString()),
                            currency_total_quantity: float.Parse(total.GetQuantityString()),
                            reference_entity: entity.Trades,
                            reference_category_slug: "buy",
                            reference_slug: itemBase.Id.ToString() //아이템 품번
                            );
                    }

                    renderQuestAvatarAddress     = buyerAvatarAddress;
                    renderQuestCompletedQuestIds = buyerAvatar.questList.completedQuestIds;
                }
                else
                {
                    var sellerAvatarAddress = eval.Action.sellerAvatarAddress;
                    var sellerAgentAddress  = eval.Action.sellerAgentAddress;
                    var result       = eval.Action.sellerResult;
                    var itemBase     = result.itemUsable ?? (ItemBase)result.costume;
                    var gold         = result.gold;
                    var sellerAvatar = eval.OutputStates.GetAvatarState(sellerAvatarAddress);

                    LocalLayerModifier.ModifyAgentGold(sellerAgentAddress, -gold);
                    LocalLayerModifier.AddNewAttachmentMail(sellerAvatarAddress, result.id);

                    var format    = L10nManager.Localize("NOTIFICATION_BUY_SELLER_COMPLETE");
                    var buyerName =
                        new AvatarState(
                            (Bencodex.Types.Dictionary)eval.OutputStates.GetState(eval.Action.buyerAvatarAddress))
                        .NameWithHash;
                    UI.Notification.Push(MailType.Auction, string.Format(format, buyerName, itemBase.GetLocalizedName()));

                    //[TentuPlay] 아이템 판매완료, 골드 증가
                    //Local에서 변경하는 States.Instance 보다는 블락에서 꺼내온 eval.OutputStates를 사용
                    var sellerAgentBalance = eval.OutputStates.GetBalance(sellerAgentAddress, GoldCurrency);
                    var total = sellerAgentBalance + gold;
                    new TPStashEvent().CharacterCurrencyGet(
                        player_uuid: sellerAgentAddress.ToHex(), // seller == 본인인지 확인필요
                        character_uuid: States.Instance.CurrentAvatarState.address.ToHex().Substring(0, 4),
                        currency_slug: "gold",
                        currency_quantity: float.Parse(gold.GetQuantityString()),
                        currency_total_quantity: float.Parse(total.GetQuantityString()),
                        reference_entity: entity.Trades,
                        reference_category_slug: "sell",
                        reference_slug: itemBase.Id.ToString() //아이템 품번
                        );

                    renderQuestAvatarAddress     = sellerAvatarAddress;
                    renderQuestCompletedQuestIds = sellerAvatar.questList.completedQuestIds;
                }

                UpdateAgentState(eval);
                UpdateCurrentAvatarState(eval);
                RenderQuest(renderQuestAvatarAddress, renderQuestCompletedQuestIds);
            }
        }
예제 #21
0
 private static void UpdateActivationSet(ActionBase.ActionEvaluation <ActionBase> evaluation)
 {
     UpdateActivationSet(evaluation.OutputStates.GetState(ActivatedAccountsState.Address));
 }
예제 #22
0
        private void ResponseRankingBattle(ActionBase.ActionEvaluation <RankingBattle> eval)
        {
            if (eval.Exception is null)
            {
                var weeklyArenaAddress = eval.Action.WeeklyArenaAddress;
                var avatarAddress      = eval.Action.AvatarAddress;

                LocalLayerModifier.RemoveWeeklyArenaInfoActivator(weeklyArenaAddress, avatarAddress);

                //[TentuPlay] RankingBattle 참가비 사용 기록 // 위의 fixme 내용과 어떻게 연결되는지?
                //Local에서 변경하는 States.Instance 보다는 블락에서 꺼내온 eval.OutputStates를 사용
                Address agentAddress = States.Instance.AgentState.address;
                if (eval.OutputStates.TryGetGoldBalance(agentAddress, GoldCurrency, out var balance))
                {
                    var total = balance - new FungibleAssetValue(balance.Currency,
                                                                 Nekoyume.GameConfig.ArenaActivationCostNCG, 0);
                    new TPStashEvent().CharacterCurrencyUse(
                        player_uuid: agentAddress.ToHex(),
                        character_uuid: States.Instance.CurrentAvatarState.address.ToHex().Substring(0, 4),
                        currency_slug: "gold",
                        currency_quantity: (float)Nekoyume.GameConfig.ArenaActivationCostNCG,
                        currency_total_quantity: float.Parse(total.GetQuantityString()),
                        reference_entity: entity.Quests,
                        reference_category_slug: "arena",
                        reference_slug: "WeeklyArenaEntryFee"
                        );
                }

                _disposableForBattleEnd?.Dispose();
                _disposableForBattleEnd =
                    Game.Game.instance.Stage.onEnterToStageEnd
                    .First()
                    .Subscribe(_ =>
                {
                    UpdateAgentState(eval);
                    UpdateCurrentAvatarState(eval);
                    UpdateWeeklyArenaState(eval);
                    _disposableForBattleEnd = null;
                });

                var actionFailPopup = Widget.Find <ActionFailPopup>();
                actionFailPopup.CloseCallback = null;
                actionFailPopup.Close();

                if (Widget.Find <ArenaBattleLoadingScreen>().IsActive())
                {
                    Widget.Find <RankingBoard>().GoToStage(eval);
                }
            }
            else
            {
                var showLoadingScreen = false;
                if (Widget.Find <ArenaBattleLoadingScreen>().IsActive())
                {
                    Widget.Find <ArenaBattleLoadingScreen>().Close();
                }
                if (Widget.Find <RankingBattleResult>().IsActive())
                {
                    showLoadingScreen = true;
                    Widget.Find <RankingBattleResult>().Close();
                }

                BackToMain(showLoadingScreen, eval.Exception.InnerException);
            }
        }
예제 #23
0
 protected bool ValidateEvaluationForCurrentAvatarState <T>(ActionBase.ActionEvaluation <T> evaluation)
     where T : ActionBase =>
 !(States.Instance.CurrentAvatarState is null) &&
예제 #24
0
 public void NextMimisbrunnrStage(ActionBase.ActionEvaluation <MimisbrunnrBattle2> eval)
 {
     Debug.Log("NextStage From ResponseHackAndSlash");
     StartCoroutine(CoGoToNextMimisbrunnrStageClose(eval));
 }
예제 #25
0
        private void ResponseCombinationEquipment(ActionBase.ActionEvaluation <CombinationEquipment> eval)
        {
            if (eval.Exception is null)
            {
                var agentAddress  = eval.Signer;
                var avatarAddress = eval.Action.AvatarAddress;
                var slot          = eval.OutputStates.GetCombinationSlotState(avatarAddress, eval.Action.SlotIndex);
                var result        = (CombinationConsumable.ResultModel)slot.Result;
                var avatarState   = eval.OutputStates.GetAvatarState(avatarAddress);

                // NOTE: 사용한 자원에 대한 레이어 벗기기.
                LocalLayerModifier.ModifyAgentGold(agentAddress, result.gold);
                LocalLayerModifier.ModifyAvatarActionPoint(avatarAddress, result.actionPoint);
                foreach (var pair in result.materials)
                {
                    // NOTE: 최종적으로 UpdateCurrentAvatarState()를 호출한다면, 그곳에서 상태를 새로 설정할 것이다.
                    LocalLayerModifier.AddItem(avatarAddress, pair.Key.ItemId, pair.Value, false);
                }

                // NOTE: 메일 레이어 씌우기.
                LocalLayerModifier.RemoveItem(avatarAddress, result.itemUsable.ItemId);
                LocalLayerModifier.AddNewAttachmentMail(avatarAddress, result.id);
                LocalLayerModifier.ResetCombinationSlot(slot);

                // NOTE: 노티 예약 걸기.
                var format = L10nManager.Localize("NOTIFICATION_COMBINATION_COMPLETE");
                UI.Notification.Reserve(
                    MailType.Workshop,
                    string.Format(format, result.itemUsable.GetLocalizedName()),
                    slot.UnlockBlockIndex,
                    result.itemUsable.ItemId);

                AnalyticsManager.Instance.OnEvent(AnalyticsManager.EventName.ActionCombinationSuccess);

                //[TentuPlay] Equipment 합성에 사용한 골드 기록
                //Local에서 변경하는 States.Instance 보다는 블락에서 꺼내온 eval.OutputStates를 사용
                if (eval.OutputStates.TryGetGoldBalance(agentAddress, GoldCurrency, out var balance))
                {
                    var total = balance - new FungibleAssetValue(balance.Currency, result.gold, 0);
                    new TPStashEvent().CharacterCurrencyUse(
                        player_uuid: agentAddress.ToHex(),
                        character_uuid: States.Instance.CurrentAvatarState.address.ToHex().Substring(0, 4),
                        currency_slug: "gold",
                        currency_quantity: (float)result.gold,
                        currency_total_quantity: float.Parse(total.GetQuantityString()),
                        reference_entity: entity.Items,
                        reference_category_slug: "equipments_combination",
                        reference_slug: result.itemUsable.Id.ToString());
                }

                var gameInstance = Game.Game.instance;

                var nextQuest = gameInstance.States.CurrentAvatarState.questList?
                                .OfType <CombinationEquipmentQuest>()
                                .Where(x => !x.Complete)
                                .OrderBy(x => x.StageId)
                                .FirstOrDefault(x =>
                                                gameInstance.TableSheets.EquipmentItemRecipeSheet.TryGetValue(x.RecipeId, out _));

                UpdateAgentState(eval);
                UpdateCurrentAvatarState(eval);
                RenderQuest(avatarAddress, avatarState.questList.completedQuestIds);
                UpdateCombinationSlotState(slot);

                if (!(nextQuest is null))
                {
                    var isRecipeMatch = nextQuest.RecipeId == eval.Action.RecipeId;

                    if (isRecipeMatch)
                    {
                        var celebratesPopup = Widget.Find <CelebratesPopup>();
                        celebratesPopup.Show(nextQuest);
                        celebratesPopup.OnDisableObservable
                        .First()
                        .Subscribe(_ =>
                        {
                            var menu = Widget.Find <Menu>();
                            if (menu.isActiveAndEnabled)
                            {
                                menu.UpdateGuideQuest(avatarState);
                            }

                            var combination = Widget.Find <Combination>();
                            if (combination.isActiveAndEnabled)
                            {
                                combination.UpdateRecipe();
                            }
                        });
                    }
                }
            }
        }