コード例 #1
0
        /// <summary>
        /// This will be called at server to order character to unequip equipments
        /// </summary>
        /// <param name="fromEquipPosition"></param>
        protected virtual void NetFuncUnEquipItem(byte byteInventoryType, short index)
        {
            if (!CanDoActions())
            {
                return;
            }

            EquipWeapons  tempEquipWeapons = EquipWeapons;
            CharacterItem unEquipItem      = CharacterItem.Empty;

            switch ((InventoryType)byteInventoryType)
            {
            case InventoryType.EquipWeaponRight:
                unEquipItem = tempEquipWeapons.rightHand;
                tempEquipWeapons.rightHand = CharacterItem.Empty;
                EquipWeapons = tempEquipWeapons;
                break;

            case InventoryType.EquipWeaponLeft:
                unEquipItem = tempEquipWeapons.leftHand;
                tempEquipWeapons.leftHand = CharacterItem.Empty;
                EquipWeapons = tempEquipWeapons;
                break;

            case InventoryType.EquipItems:
                unEquipItem = equipItems[index];
                equipItems.RemoveAt(index);
                UpdateEquipItemIndexes();
                break;
            }
            if (unEquipItem.NotEmptySlot())
            {
                nonEquipItems.Add(unEquipItem);
            }
        }
コード例 #2
0
        protected virtual void NetFuncSellItem(short index, short amount)
        {
            if (IsDead() ||
                index >= nonEquipItems.Count)
            {
                return;
            }

            if (currentNpcDialog == null || currentNpcDialog.type != NpcDialogType.Shop)
            {
                return;
            }

            CharacterItem nonEquipItem = nonEquipItems[index];

            if (!nonEquipItem.NotEmptySlot() || amount > nonEquipItem.amount)
            {
                return;
            }

            Item item = nonEquipItem.GetItem();

            if (this.DecreaseItemsByIndex(index, amount))
            {
                gameplayRule.IncreaseCurrenciesWhenSellItem(this, item, amount);
            }
        }
コード例 #3
0
        protected virtual void NetFuncSwapOrMergeNonEquipItems(short index1, short index2)
        {
            if (!CanDoActions() ||
                index1 >= nonEquipItems.Count ||
                index2 >= nonEquipItems.Count)
            {
                return;
            }

            CharacterItem nonEquipItem1 = nonEquipItems[index1];
            CharacterItem nonEquipItem2 = nonEquipItems[index2];

            if (nonEquipItem1.dataId == nonEquipItem2.dataId &&
                nonEquipItem1.NotEmptySlot() && nonEquipItem2.NotEmptySlot())
            {
                // Merge or swap
                if (nonEquipItem1.IsFull() || nonEquipItem2.IsFull())
                {
                    // Swap
                    NetFuncSwapNonEquipItems(index1, index2);
                }
                else
                {
                    // Merge
                    NetFuncMergeNonEquipItems(index1, index2);
                }
            }
            else
            {
                // Swap
                NetFuncSwapNonEquipItems(index1, index2);
            }
        }
コード例 #4
0
        private static void RepairItem(IPlayerCharacterData character, CharacterItem repairingItem, System.Action <CharacterItem> onRepaired, out GameMessage.Type gameMessageType)
        {
            gameMessageType = GameMessage.Type.CannotRepair;
            if (!repairingItem.NotEmptySlot())
            {
                // Cannot refine because character item is empty
                return;
            }
            Item equipmentItem = repairingItem.GetEquipmentItem();

            if (equipmentItem == null)
            {
                // Cannot refine because it's not equipment item
                return;
            }
            ItemRepairPrice repairPrice;

            if (equipmentItem.CanRepair(character, repairingItem.durability, out repairPrice, out gameMessageType))
            {
                gameMessageType = GameMessage.Type.RepairSuccess;
                // Repair item
                repairingItem.durability = equipmentItem.maxDurability;
                onRepaired.Invoke(repairingItem);
                // Decrease required gold
                GameInstance.Singleton.GameplayRule.DecreaseCurrenciesWhenRepairItem(character, repairPrice);
            }
        }
コード例 #5
0
        protected virtual void NetFuncSwapOrMergeItem(short fromIndex, short toIndex)
        {
            if (!CanDoActions() ||
                fromIndex >= NonEquipItems.Count ||
                toIndex >= NonEquipItems.Count)
            {
                return;
            }

            CharacterItem fromItem = NonEquipItems[fromIndex];
            CharacterItem toItem   = NonEquipItems[toIndex];

            if (!fromItem.NotEmptySlot() || !toItem.NotEmptySlot())
            {
                return;
            }

            if (fromItem.dataId.Equals(toItem.dataId) && !fromItem.IsFull() && !toItem.IsFull())
            {
                // Merge if same id and not full
                short maxStack = toItem.GetMaxStack();
                if (toItem.amount + fromItem.amount <= maxStack)
                {
                    toItem.amount           += fromItem.amount;
                    NonEquipItems[fromIndex] = CharacterItem.Empty;
                    NonEquipItems[toIndex]   = toItem;
                }
                else
                {
                    short remains = (short)(toItem.amount + fromItem.amount - maxStack);
                    toItem.amount            = maxStack;
                    fromItem.amount          = remains;
                    NonEquipItems[fromIndex] = fromItem;
                    NonEquipItems[toIndex]   = toItem;
                }
            }
            else
            {
                // Swap
                NonEquipItems[fromIndex] = toItem;
                NonEquipItems[toIndex]   = fromItem;
            }
        }
コード例 #6
0
        private static void EnhanceSocketItem(IPlayerCharacterData character, CharacterItem enhancingItem, int enhancerId, System.Action <CharacterItem> onEnhanceSocket, out GameMessage.Type gameMessageType)
        {
            gameMessageType = GameMessage.Type.CannotEnhanceSocket;
            if (!enhancingItem.NotEmptySlot())
            {
                // Cannot enhance socket because character item is empty
                return;
            }
            Item equipmentItem = enhancingItem.GetEquipmentItem();

            if (equipmentItem == null)
            {
                // Cannot enhance socket because it's not equipment item
                return;
            }
            if (equipmentItem.maxSocket <= 0)
            {
                // Cannot enhance socket because equipment has no socket(s)
                return;
            }
            if (enhancingItem.Sockets.Count >= equipmentItem.maxSocket)
            {
                // Cannot enhance socket because socket is full
                return;
            }
            Item enhancerItem;

            if (!GameInstance.Items.TryGetValue(enhancerId, out enhancerItem) || !enhancerItem.IsSocketEnhancer())
            {
                // Cannot enhance socket because enhancer id is invalid
                return;
            }
            if (!character.DecreaseItems(enhancerItem.DataId, 1))
            {
                // Cannot enhance socket because there is no item
                gameMessageType = GameMessage.Type.NotEnoughSocketEnchaner;
                return;
            }
            enhancingItem.Sockets.Add(enhancerId);
            onEnhanceSocket.Invoke(enhancingItem);
        }
コード例 #7
0
        /// <summary>
        /// This will be called at server to order character to pickup items
        /// </summary>
        /// <param name="objectId"></param>
        protected virtual void NetFuncPickupItem(PackedUInt objectId)
        {
            if (!CanDoActions())
            {
                return;
            }

            ItemDropEntity itemDropEntity = null;

            if (!TryGetEntityByObjectId(objectId, out itemDropEntity))
            {
                return;
            }

            if (Vector3.Distance(CacheTransform.position, itemDropEntity.CacheTransform.position) > gameInstance.pickUpItemDistance + 5f)
            {
                return;
            }

            if (!itemDropEntity.IsAbleToLoot(this))
            {
                gameManager.SendServerGameMessage(ConnectionId, GameMessage.Type.NotAbleToLoot);
                return;
            }

            CharacterItem itemDropData = itemDropEntity.dropData;

            if (!itemDropData.NotEmptySlot())
            {
                // Destroy item drop entity without item add because this is not valid
                itemDropEntity.MarkAsPickedUp();
                itemDropEntity.NetworkDestroy();
                return;
            }
            if (!this.IncreasingItemsWillOverwhelming(itemDropData.dataId, itemDropData.amount) && this.IncreaseItems(itemDropData))
            {
                itemDropEntity.MarkAsPickedUp();
                itemDropEntity.NetworkDestroy();
            }
        }
コード例 #8
0
        protected virtual void NetFuncBuild(short itemIndex, Vector3 position, Quaternion rotation, PackedUInt parentObjectId)
        {
            if (!CanDoActions() ||
                itemIndex >= NonEquipItems.Count)
            {
                return;
            }

            BuildingEntity buildingEntity;
            CharacterItem  nonEquipItem = NonEquipItems[itemIndex];

            if (!nonEquipItem.NotEmptySlot() ||
                nonEquipItem.GetBuildingItem() == null ||
                nonEquipItem.GetBuildingItem().buildingEntity == null ||
                !GameInstance.BuildingEntities.TryGetValue(nonEquipItem.GetBuildingItem().buildingEntity.DataId, out buildingEntity) ||
                !this.DecreaseItemsByIndex(itemIndex, 1))
            {
                return;
            }

            BuildingSaveData buildingSaveData = new BuildingSaveData();

            buildingSaveData.Id       = GenericUtils.GetUniqueId();
            buildingSaveData.ParentId = string.Empty;
            BuildingEntity parentBuildingEntity;

            if (TryGetEntityByObjectId(parentObjectId, out parentBuildingEntity))
            {
                buildingSaveData.ParentId = parentBuildingEntity.Id;
            }
            buildingSaveData.DataId      = buildingEntity.DataId;
            buildingSaveData.CurrentHp   = buildingEntity.maxHp;
            buildingSaveData.Position    = position;
            buildingSaveData.Rotation    = rotation;
            buildingSaveData.CreatorId   = Id;
            buildingSaveData.CreatorName = CharacterName;
            gameManager.CreateBuildingEntity(buildingSaveData, false);
        }
コード例 #9
0
    public static bool DecreaseItemsByIndex(IList <CharacterItem> itemList, int index, short amount)
    {
        if (index < 0 || index >= itemList.Count)
        {
            return(false);
        }
        CharacterItem nonEquipItem = itemList[index];

        if (!nonEquipItem.NotEmptySlot() || amount > nonEquipItem.amount)
        {
            return(false);
        }
        if (nonEquipItem.amount - amount == 0)
        {
            itemList.RemoveAt(index);
        }
        else
        {
            nonEquipItem.amount -= amount;
            itemList[index]      = nonEquipItem;
        }
        return(true);
    }
コード例 #10
0
        /// <summary>
        /// This will be called at server to order character to drop items
        /// </summary>
        /// <param name="index"></param>
        /// <param name="amount"></param>
        protected virtual void NetFuncDropItem(short index, short amount)
        {
            if (!CanDoActions() ||
                index >= nonEquipItems.Count)
            {
                return;
            }

            CharacterItem nonEquipItem = nonEquipItems[index];

            if (!nonEquipItem.NotEmptySlot() || amount > nonEquipItem.amount)
            {
                return;
            }

            if (this.DecreaseItemsByIndex(index, amount))
            {
                // Drop item to the ground
                CharacterItem dropData = nonEquipItem.Clone();
                dropData.amount = amount;
                ItemDropEntity.DropItem(this, dropData, new uint[] { ObjectId });
            }
        }
コード例 #11
0
    public static bool IncreaseItems(IList <CharacterItem> itemList, CharacterItem addingItem)
    {
        // If item not valid
        if (!addingItem.NotEmptySlot())
        {
            return(false);
        }

        Item  itemData = addingItem.GetItem();
        short amount   = addingItem.amount;

        short maxStack = itemData.maxStack;
        Dictionary <int, CharacterItem> emptySlots = new Dictionary <int, CharacterItem>();
        Dictionary <int, CharacterItem> changes    = new Dictionary <int, CharacterItem>();
        // Loop to all slots to add amount to any slots that item amount not max in stack
        CharacterItem tempNonEquipItem;

        for (int i = 0; i < itemList.Count; ++i)
        {
            tempNonEquipItem = itemList[i];
            if (!tempNonEquipItem.NotEmptySlot())
            {
                // If current entry is not valid, add it to empty list, going to replacing it later
                emptySlots[i] = tempNonEquipItem;
            }
            else if (tempNonEquipItem.dataId == addingItem.dataId)
            {
                // If same item id, increase its amount
                if (tempNonEquipItem.amount + amount <= maxStack)
                {
                    tempNonEquipItem.amount += amount;
                    changes[i] = tempNonEquipItem;
                    amount     = 0;
                    break;
                }
                else if (maxStack - tempNonEquipItem.amount >= 0)
                {
                    amount -= (short)(maxStack - tempNonEquipItem.amount);
                    tempNonEquipItem.amount = maxStack;
                    changes[i] = tempNonEquipItem;
                }
            }
        }

        // Adding item to new slots or empty slots if needed
        CharacterItem tempNewItem;

        if (changes.Count == 0 && emptySlots.Count > 0)
        {
            // If there are no changes and there are an empty entries, fill them
            foreach (int emptySlotIndex in emptySlots.Keys)
            {
                tempNewItem = addingItem.Clone();
                short addAmount = 0;
                if (amount - maxStack >= 0)
                {
                    addAmount = maxStack;
                    amount   -= maxStack;
                }
                else
                {
                    addAmount = amount;
                    amount    = 0;
                }
                tempNewItem.amount      = addAmount;
                changes[emptySlotIndex] = tempNewItem;
                if (amount == 0)
                {
                    break;
                }
            }
        }

        // Apply all changes
        foreach (KeyValuePair <int, CharacterItem> change in changes)
        {
            itemList[change.Key] = change.Value;
        }

        // Add new items to new slots
        while (amount > 0)
        {
            tempNewItem = addingItem.Clone();
            short addAmount = 0;
            if (amount - maxStack >= 0)
            {
                addAmount = maxStack;
                amount   -= maxStack;
            }
            else
            {
                addAmount = amount;
                amount    = 0;
            }
            tempNewItem.amount = addAmount;
            itemList.Add(tempNewItem);
            if (amount == 0)
            {
                break;
            }
        }
        return(true);
    }
コード例 #12
0
        private static void RefineItem(IPlayerCharacterData character, CharacterItem refiningItem, System.Action <CharacterItem> onRefine, System.Action onDestroy, out GameMessage.Type gameMessageType)
        {
            gameMessageType = GameMessage.Type.CannotRefine;
            if (!refiningItem.NotEmptySlot())
            {
                // Cannot refine because character item is empty
                return;
            }
            Item equipmentItem = refiningItem.GetEquipmentItem();

            if (equipmentItem == null)
            {
                // Cannot refine because it's not equipment item
                return;
            }
            if (!equipmentItem.CanRefine(character, refiningItem.level, out gameMessageType))
            {
                // Cannot refine because of some reasons
                return;
            }
            ItemRefineLevel refineLevel = equipmentItem.itemRefine.levels[refiningItem.level - 1];

            if (Random.value <= refineLevel.SuccessRate)
            {
                // If success, increase item level
                gameMessageType = GameMessage.Type.RefineSuccess;
                ++refiningItem.level;
                onRefine.Invoke(refiningItem);
            }
            else
            {
                // Fail
                gameMessageType = GameMessage.Type.RefineFail;
                if (refineLevel.RefineFailDestroyItem)
                {
                    // If condition when fail is it has to be destroyed
                    onDestroy.Invoke();
                }
                else
                {
                    // If condition when fail is reduce its level
                    refiningItem.level -= refineLevel.RefineFailDecreaseLevels;
                    if (refiningItem.level < 1)
                    {
                        refiningItem.level = 1;
                    }
                    onRefine.Invoke(refiningItem);
                }
            }
            if (refineLevel.RequireItems != null)
            {
                // Decrease required items
                foreach (ItemAmount requireItem in refineLevel.RequireItems)
                {
                    if (requireItem.item != null && requireItem.amount > 0)
                    {
                        character.DecreaseItems(requireItem.item.DataId, requireItem.amount);
                    }
                }
            }
            // Decrease required gold
            GameInstance.Singleton.GameplayRule.DecreaseCurrenciesWhenRefineItem(character, refineLevel);
        }
コード例 #13
0
    public static T ValidateCharacterData <T>(this T character) where T : IPlayerCharacterData
    {
        GameInstance    gameInstance = GameInstance.Singleton;
        PlayerCharacter database;

        if (!GameInstance.PlayerCharacters.TryGetValue(character.DataId, out database))
        {
            return(character);
        }
        // Validating character attributes
        short         returningStatPoint = 0;
        HashSet <int> validAttributeIds  = new HashSet <int>();
        IList <CharacterAttribute> characterAttributes = character.Attributes;

        for (int i = characterAttributes.Count - 1; i >= 0; --i)
        {
            CharacterAttribute characterAttribute = characterAttributes[i];
            int attributeDataId = characterAttribute.dataId;
            // If attribute is invalid
            if (characterAttribute.GetAttribute() == null ||
                validAttributeIds.Contains(attributeDataId))
            {
                returningStatPoint += characterAttribute.amount;
                character.Attributes.RemoveAt(i);
            }
            else
            {
                validAttributeIds.Add(attributeDataId);
            }
        }
        character.StatPoint += returningStatPoint;
        // Add character's attributes
        foreach (Attribute attribute in GameInstance.Attributes.Values)
        {
            // This attribute is valid, so not have to add it
            if (validAttributeIds.Contains(attribute.DataId))
            {
                continue;
            }
            CharacterAttribute characterAttribute = new CharacterAttribute();
            characterAttribute.dataId = attribute.DataId;
            characterAttribute.amount = 0;
            character.Attributes.Add(characterAttribute);
        }
        // Validating character skills
        short                  returningSkillPoint = 0;
        HashSet <int>          validSkillIds       = new HashSet <int>();
        IList <CharacterSkill> characterSkills     = character.Skills;

        for (int i = characterSkills.Count - 1; i >= 0; --i)
        {
            CharacterSkill characterSkill = characterSkills[i];
            Skill          skill          = characterSkill.GetSkill();
            // If skill is invalid or this character database does not have skill
            if (characterSkill.GetSkill() == null ||
                !database.CacheSkillLevels.ContainsKey(skill) ||
                validSkillIds.Contains(skill.DataId))
            {
                returningSkillPoint += characterSkill.level;
                character.Skills.RemoveAt(i);
            }
            else
            {
                validSkillIds.Add(skill.DataId);
            }
        }
        character.SkillPoint += returningSkillPoint;
        // Add character's skills
        Dictionary <Skill, short> skillLevels = database.CacheSkillLevels;

        foreach (KeyValuePair <Skill, short> skillLevel in skillLevels)
        {
            Skill skill = skillLevel.Key;
            // This skill is valid, so not have to add it
            if (validSkillIds.Contains(skill.DataId))
            {
                continue;
            }
            CharacterSkill characterSkill = new CharacterSkill();
            characterSkill.dataId = skill.DataId;
            characterSkill.level  = skillLevel.Value;
            character.Skills.Add(characterSkill);
        }
        // Validating character equip weapons
        List <CharacterItem> returningItems = new List <CharacterItem>();
        EquipWeapons         equipWeapons   = character.EquipWeapons;
        CharacterItem        rightHand      = equipWeapons.rightHand;
        CharacterItem        leftHand       = equipWeapons.leftHand;

        if (rightHand.GetEquipmentItem() == null)
        {
            if (rightHand.NotEmptySlot())
            {
                returningItems.Add(rightHand);
            }
            equipWeapons.rightHand = CharacterItem.Empty;
        }
        if (leftHand.GetEquipmentItem() == null)
        {
            if (leftHand.NotEmptySlot())
            {
                returningItems.Add(leftHand);
            }
            equipWeapons.leftHand = CharacterItem.Empty;
        }
        // Validating character equip items
        IList <CharacterItem> equipItems = character.EquipItems;

        for (int i = equipItems.Count - 1; i >= 0; --i)
        {
            CharacterItem equipItem = equipItems[i];
            // If equipment is invalid
            if (equipItem.GetEquipmentItem() == null)
            {
                if (equipItem.NotEmptySlot())
                {
                    returningItems.Add(equipItem);
                }
                character.EquipItems.RemoveAt(i);
            }
        }
        // Return items to non equip items
        foreach (CharacterItem returningItem in returningItems)
        {
            character.NonEquipItems.Add(returningItem);
        }
        character.FillEmptySlots();
        DevExtUtils.InvokeStaticDevExtMethods(ClassType, "ValidateCharacterData", character);
        return(character);
    }