public override void ReceiveDamage(IAttackerEntity attacker, CharacterItem weapon, Dictionary <DamageElement, MinMaxFloat> allDamageAmounts, CharacterBuff debuff, uint hitEffectsId)
        {
            if (!IsServer || IsDead() || weapon == null)
            {
                return;
            }

            base.ReceiveDamage(attacker, weapon, allDamageAmounts, debuff, hitEffectsId);
            BaseCharacterEntity attackerCharacter = attacker as BaseCharacterEntity;

            // Play hit effect
            if (hitEffectsId == 0)
            {
                hitEffectsId = gameInstance.DefaultHitEffects.Id;
            }
            if (hitEffectsId > 0)
            {
                RequestPlayEffect(hitEffectsId);
            }
            // Apply damages
            int  totalDamage = 0;
            Item weaponItem  = weapon.GetWeaponItem();
            HarvestEffectiveness harvestEffectiveness;
            WeightedRandomizer <ItemDropByWeight> itemRandomizer;

            if (harvestable.CacheHarvestEffectivenesses.TryGetValue(weaponItem.weaponType, out harvestEffectiveness) &&
                harvestable.CacheHarvestItems.TryGetValue(weaponItem.weaponType, out itemRandomizer))
            {
                totalDamage = (int)(weaponItem.harvestDamageAmount.GetAmount(weapon.level).Random() * harvestEffectiveness.damageEffectiveness);
                ItemDropByWeight receivingItem = itemRandomizer.TakeOne();
                int   dataId           = receivingItem.item.DataId;
                short amount           = (short)(receivingItem.amountPerDamage * totalDamage);
                bool  droppingToGround = collectType == HarvestableCollectType.DropToGround;
                if (attackerCharacter.IncreasingItemsWillOverwhelming(dataId, amount))
                {
                    droppingToGround = true;
                }
                if (!droppingToGround)
                {
                    attackerCharacter.IncreaseItems(CharacterItem.Create(dataId, 1, amount));
                }
                else
                {
                    ItemDropEntity.DropItem(this, CharacterItem.Create(dataId, 1, amount), new uint[0]);
                }
            }
            CurrentHp -= totalDamage;
            ReceivedDamage(attackerCharacter, CombatAmountType.NormalDamage, totalDamage);

            if (IsDead())
            {
                CurrentHp = 0;
                CallNetFunction(NetFuncOnHarvestableDestroy, FunctionReceivers.All);
                DestroyAndRespawn();
            }
        }
Example #2
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(ushort index, short amount)
        {
            if (!CanMoveOrDoActions() ||
                index >= nonEquipItems.Count)
            {
                return;
            }

            var nonEquipItem = nonEquipItems[index];

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

            var itemDataId = nonEquipItem.dataId;
            var level      = nonEquipItem.level;

            if (this.DecreaseItemsByIndex(index, amount))
            {
                ItemDropEntity.DropItem(this, itemDataId, level, amount, new uint[] { ObjectId });
            }
        }
Example #3
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 });
            }
        }
        public override void Killed(BaseCharacterEntity lastAttacker)
        {
            base.Killed(lastAttacker);

            // If this summoned by someone, don't give reward to killer
            if (IsSummoned)
            {
                return;
            }

            var       randomedExp  = Random.Range(MonsterDatabase.randomExpMin, MonsterDatabase.randomExpMax);
            var       randomedGold = Random.Range(MonsterDatabase.randomGoldMin, MonsterDatabase.randomGoldMax);
            var       looters      = new HashSet <uint>();
            var       lastPlayer   = lastAttacker as BasePlayerCharacterEntity;
            GuildData tempGuildData;
            PartyData tempPartyData;
            BasePlayerCharacterEntity  tempPlayerCharacter;
            BaseMonsterCharacterEntity tempMonsterCharacter;

            if (receivedDamageRecords.Count > 0)
            {
                var tempHighRewardRate = 0f;
                foreach (var enemy in receivedDamageRecords.Keys)
                {
                    var receivedDamageRecord = receivedDamageRecords[enemy];
                    var rewardRate           = (float)receivedDamageRecord.totalReceivedDamage / (float)CacheMaxHp;
                    var rewardExp            = (int)(randomedExp * rewardRate);
                    var rewardGold           = (int)(randomedGold * rewardRate);
                    if (rewardRate > 1f)
                    {
                        rewardRate = 1f;
                    }
                    if (enemy is BasePlayerCharacterEntity)
                    {
                        var makeMostDamage = false;
                        tempPlayerCharacter = enemy as BasePlayerCharacterEntity;
                        // Clear looters list when it is found new player character who make most damages
                        if (rewardRate > tempHighRewardRate)
                        {
                            tempHighRewardRate = rewardRate;
                            looters.Clear();
                            makeMostDamage = true;
                        }
                        // Try find guild data from player character
                        if (tempPlayerCharacter.GuildId > 0 && GameManager.TryGetGuild(tempPlayerCharacter.GuildId, out tempGuildData))
                        {
                            // Calculation amount of Exp which will be shared to guild
                            int shareRewardExp = (int)(rewardExp * (float)tempGuildData.ShareExpPercentage(tempPlayerCharacter.Id) / 100f);
                            // Will share Exp to guild when sharing amount more than 0
                            if (shareRewardExp > 0)
                            {
                                GameManager.IncreaseGuildExp(tempPlayerCharacter, shareRewardExp);
                                rewardExp -= shareRewardExp;
                            }
                        }
                        // Try find party data from player character
                        if (tempPlayerCharacter.PartyId > 0 && GameManager.TryGetParty(tempPlayerCharacter.PartyId, out tempPartyData))
                        {
                            BasePlayerCharacterEntity partyPlayerCharacter;
                            // Loop party member to fill looter list / increase gold / increase exp
                            foreach (var member in tempPartyData.GetMembers())
                            {
                                if (GameManager.TryGetPlayerCharacterById(member.id, out partyPlayerCharacter))
                                {
                                    // If share exp, every party member will receive devided exp
                                    // If not share exp, character who make damage will receive non-devided exp
                                    if (tempPartyData.shareExp)
                                    {
                                        partyPlayerCharacter.RewardExp(rewardExp / tempPartyData.CountMember(), RewardGivenType.PartyShare);
                                    }

                                    // If share item, every party member will receive devided gold
                                    // If not share item, character who make damage will receive non-devided gold
                                    if (tempPartyData.shareItem)
                                    {
                                        if (makeMostDamage)
                                        {
                                            looters.Add(partyPlayerCharacter.ObjectId);
                                        }
                                        partyPlayerCharacter.RewardGold(rewardGold / tempPartyData.CountMember(), RewardGivenType.PartyShare);
                                    }
                                }
                            }
                            // Shared exp, has increased so do not increase it again
                            if (tempPartyData.shareExp)
                            {
                                rewardExp = 0;
                            }
                            // Shared gold, has increased so do not increase it again
                            if (tempPartyData.shareItem)
                            {
                                rewardGold = 0;
                            }
                        }
                        // Add reward to current character in damage record list
                        var petIndex = tempPlayerCharacter.IndexOfSummon(SummonType.Pet);
                        if (petIndex >= 0)
                        {
                            tempMonsterCharacter = tempPlayerCharacter.Summons[petIndex].CacheEntity;
                            if (tempMonsterCharacter != null)
                            {
                                // Share exp to pet
                                tempMonsterCharacter.RewardExp(rewardExp, RewardGivenType.KillMonster);
                            }
                        }
                        tempPlayerCharacter.RewardExp(rewardExp, RewardGivenType.KillMonster);
                        if (makeMostDamage)
                        {
                            looters.Add(tempPlayerCharacter.ObjectId);
                        }
                        tempPlayerCharacter.RewardGold(rewardGold, RewardGivenType.KillMonster);
                    }
                }
            }
            receivedDamageRecords.Clear();
            foreach (var randomItem in MonsterDatabase.randomItems)
            {
                if (Random.value <= randomItem.dropRate)
                {
                    var item   = randomItem.item;
                    var amount = randomItem.amount;
                    if (item != null && GameInstance.Items.ContainsKey(item.DataId))
                    {
                        var itemDataId = item.DataId;
                        if (amount > item.maxStack)
                        {
                            amount = item.maxStack;
                        }
                        ItemDropEntity.DropItem(this, itemDataId, 1, amount, looters);
                    }
                }
            }
            if (lastPlayer != null)
            {
                lastPlayer.OnKillMonster(this);
            }
        }
        public override sealed void Killed(BaseCharacterEntity lastAttacker)
        {
            base.Killed(lastAttacker);

            // If this summoned by someone, don't give reward to killer
            if (IsSummoned)
            {
                return;
            }

            Reward                    reward     = gameplayRule.MakeMonsterReward(monsterCharacter);
            HashSet <uint>            looters    = new HashSet <uint>();
            BasePlayerCharacterEntity lastPlayer = null;

            if (lastAttacker != null)
            {
                lastPlayer = lastAttacker as BasePlayerCharacterEntity;
            }
            GuildData tempGuildData;
            PartyData tempPartyData;
            BasePlayerCharacterEntity  tempPlayerCharacter;
            BaseMonsterCharacterEntity tempMonsterCharacter;
            bool  givenRewardExp;
            bool  givenRewardCurrency;
            float shareGuildExpRate;

            if (receivedDamageRecords.Count > 0)
            {
                float tempHighRewardRate = 0f;
                foreach (BaseCharacterEntity enemy in receivedDamageRecords.Keys)
                {
                    givenRewardExp      = false;
                    givenRewardCurrency = false;
                    shareGuildExpRate   = 0f;

                    ReceivedDamageRecord receivedDamageRecord = receivedDamageRecords[enemy];
                    float rewardRate = (float)receivedDamageRecord.totalReceivedDamage / (float)CacheMaxHp;
                    if (rewardRate > 1f)
                    {
                        rewardRate = 1f;
                    }

                    if (enemy is BasePlayerCharacterEntity)
                    {
                        bool makeMostDamage = false;
                        tempPlayerCharacter = enemy as BasePlayerCharacterEntity;
                        // Clear looters list when it is found new player character who make most damages
                        if (rewardRate > tempHighRewardRate)
                        {
                            tempHighRewardRate = rewardRate;
                            looters.Clear();
                            makeMostDamage = true;
                        }
                        // Try find guild data from player character
                        if (tempPlayerCharacter.GuildId > 0 && gameManager.TryGetGuild(tempPlayerCharacter.GuildId, out tempGuildData))
                        {
                            // Calculation amount of Exp which will be shared to guild
                            shareGuildExpRate = (float)tempGuildData.ShareExpPercentage(tempPlayerCharacter.Id) * 0.01f;
                            // Will share Exp to guild when sharing amount more than 0
                            if (shareGuildExpRate > 0)
                            {
                                // Increase guild exp
                                gameManager.IncreaseGuildExp(tempPlayerCharacter, (int)(reward.exp * shareGuildExpRate * rewardRate));
                            }
                        }
                        // Try find party data from player character
                        if (tempPlayerCharacter.PartyId > 0 && gameManager.TryGetParty(tempPlayerCharacter.PartyId, out tempPartyData))
                        {
                            BasePlayerCharacterEntity partyPlayerCharacter;
                            // Loop party member to fill looter list / increase gold / increase exp
                            foreach (SocialCharacterData member in tempPartyData.GetMembers())
                            {
                                if (gameManager.TryGetPlayerCharacterById(member.id, out partyPlayerCharacter))
                                {
                                    // If share exp, every party member will receive devided exp
                                    // If not share exp, character who make damage will receive non-devided exp
                                    if (tempPartyData.shareExp)
                                    {
                                        partyPlayerCharacter.RewardExp(reward, (1f - shareGuildExpRate) / (float)tempPartyData.CountMember() * rewardRate, RewardGivenType.PartyShare);
                                    }

                                    // If share item, every party member will receive devided gold
                                    // If not share item, character who make damage will receive non-devided gold
                                    if (tempPartyData.shareItem)
                                    {
                                        if (makeMostDamage)
                                        {
                                            // Make other member in party able to pickup items
                                            looters.Add(partyPlayerCharacter.ObjectId);
                                        }
                                        partyPlayerCharacter.RewardCurrencies(reward, 1f / (float)tempPartyData.CountMember() * rewardRate, RewardGivenType.PartyShare);
                                    }
                                }
                            }
                            // Shared exp has been given, so do not give it to character again
                            if (tempPartyData.shareExp)
                            {
                                givenRewardExp = true;
                            }
                            // Shared gold has been given, so do not give it to character again
                            if (tempPartyData.shareItem)
                            {
                                givenRewardCurrency = true;
                            }
                        }

                        // Add reward to current character in damage record list
                        if (!givenRewardExp)
                        {
                            // Will give reward when it was not given
                            int petIndex = tempPlayerCharacter.IndexOfSummon(SummonType.Pet);
                            if (petIndex >= 0)
                            {
                                tempMonsterCharacter = tempPlayerCharacter.Summons[petIndex].CacheEntity;
                                if (tempMonsterCharacter != null)
                                {
                                    // Share exp to pet, set multiplier to 0.5, because it will be shared to player
                                    tempMonsterCharacter.RewardExp(reward, (1f - shareGuildExpRate) * 0.5f * rewardRate, RewardGivenType.KillMonster);
                                }
                                // Set multiplier to 0.5, because it was shared to monster
                                tempPlayerCharacter.RewardExp(reward, (1f - shareGuildExpRate) * 0.5f * rewardRate, RewardGivenType.KillMonster);
                            }
                            else
                            {
                                // No pet, no share, so rate is 1f
                                tempPlayerCharacter.RewardExp(reward, (1f - shareGuildExpRate) * rewardRate, RewardGivenType.KillMonster);
                            }
                        }

                        if (!givenRewardCurrency)
                        {
                            // Will give reward when it was not given
                            tempPlayerCharacter.RewardCurrencies(reward, rewardRate, RewardGivenType.KillMonster);
                        }

                        if (makeMostDamage)
                        {
                            // Make current character able to pick up item because it made most damage
                            looters.Add(tempPlayerCharacter.ObjectId);
                        }
                    } // End is `BasePlayerCharacterEntity` condition
                }     // End for-loop
            }         // End count recived damage record count
            receivedDamageRecords.Clear();
            foreach (ItemDrop randomItem in monsterCharacter.randomItems)
            {
                if (Random.value <= randomItem.dropRate)
                {
                    Item  item   = randomItem.item;
                    short amount = randomItem.amount;
                    if (item != null && GameInstance.Items.ContainsKey(item.DataId))
                    {
                        // Drop item to the ground
                        if (amount > item.maxStack)
                        {
                            amount = item.maxStack;
                        }
                        CharacterItem dropData = CharacterItem.Create(item, 1);
                        dropData.amount = amount;
                        ItemDropEntity.DropItem(this, dropData, looters);
                    }
                }
            }

            if (lastPlayer != null)
            {
                // Increase kill progress
                lastPlayer.OnKillMonster(this);
            }

            if (!IsSummoned)
            {
                // If not summoned by someone, destroy and respawn it
                DestroyAndRespawn();
            }
        }