private bool RemoveEntity(GameObject other)
        {
            BasePlayerCharacterEntity  player  = null;
            BaseMonsterCharacterEntity monster = null;
            NpcEntity      npc      = null;
            ItemDropEntity itemDrop = null;
            BuildingEntity building = null;

            FindEntity(other, out player, out monster, out npc, out itemDrop, out building, false);

            if (player != null)
            {
                return(characters.Remove(player) && players.Remove(player));
            }
            if (monster != null)
            {
                return(characters.Remove(monster) && monsters.Remove(monster));
            }
            if (npc != null)
            {
                return(npcs.Remove(npc));
            }
            if (itemDrop != null)
            {
                return(itemDrops.Remove(itemDrop));
            }
            if (building != null)
            {
                return(buildings.Remove(building));
            }
            return(false);
        }
        private bool AddEntity(GameObject other)
        {
            BasePlayerCharacterEntity  player  = null;
            BaseMonsterCharacterEntity monster = null;
            NpcEntity      npc      = null;
            ItemDropEntity itemDrop = null;
            BuildingEntity building = null;

            FindEntity(other, out player, out monster, out npc, out itemDrop, out building);

            if (player != null)
            {
                if (!characters.Contains(player))
                {
                    characters.Add(player);
                }
                if (!players.Contains(player))
                {
                    players.Add(player);
                }
                return(true);
            }
            if (monster != null)
            {
                if (!characters.Contains(monster))
                {
                    characters.Add(monster);
                }
                if (!monsters.Contains(monster))
                {
                    monsters.Add(monster);
                }
                return(true);
            }
            if (npc != null)
            {
                if (!npcs.Contains(npc))
                {
                    npcs.Add(npc);
                }
                return(true);
            }
            if (building != null)
            {
                if (!buildings.Contains(building))
                {
                    buildings.Add(building);
                }
                return(true);
            }
            if (itemDrop != null)
            {
                if (!itemDrops.Contains(itemDrop))
                {
                    itemDrops.Add(itemDrop);
                }
                return(true);
            }
            return(false);
        }
        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();
            }
        }
        protected void SetTargetItemDrop(ItemDropEntity itemDrop)
        {
            if (uiTargetItemDrop == null)
            {
                return;
            }

            if (itemDrop == null)
            {
                uiTargetItemDrop.Hide();
                return;
            }

            uiTargetItemDrop.Data = itemDrop;
            uiTargetItemDrop.Show();
        }
Example #5
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 (!CanMoveOrDoActions())
            {
                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;
            }

            var itemDropData = itemDropEntity.dropData;

            if (!itemDropData.IsValid())
            {
                // Destroy item drop entity without item add because this is not valid
                itemDropEntity.NetworkDestroy();
                return;
            }
            var itemDataId = itemDropData.dataId;
            var level      = itemDropData.level;
            var amount     = itemDropData.amount;

            if (!IncreasingItemsWillOverwhelming(itemDataId, amount) && this.IncreaseItems(itemDataId, level, amount))
            {
                itemDropEntity.NetworkDestroy();
            }
        }
Example #6
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();
            }
        }
Example #7
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 #8
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 });
            }
        }
Example #9
0
        protected void UpdateInput()
        {
            if (GenericUtils.IsFocusInputField())
            {
                return;
            }

            if (PlayerCharacterEntity.IsDead())
            {
                return;
            }

            // If it's building something, don't allow to activate NPC/Warp/Pickup Item
            if (!ConstructingBuildingEntity)
            {
                // Activate nearby npcs / players / activable buildings
                if (InputManager.GetButtonDown("Activate"))
                {
                    targetPlayer = null;
                    if (ActivatableEntityDetector.players.Count > 0)
                    {
                        targetPlayer = ActivatableEntityDetector.players[0];
                    }
                    targetNpc = null;
                    if (ActivatableEntityDetector.npcs.Count > 0)
                    {
                        targetNpc = ActivatableEntityDetector.npcs[0];
                    }
                    targetBuilding = null;
                    if (ActivatableEntityDetector.buildings.Count > 0)
                    {
                        targetBuilding = ActivatableEntityDetector.buildings[0];
                    }
                    targetVehicle = null;
                    if (ActivatableEntityDetector.vehicles.Count > 0)
                    {
                        targetVehicle = ActivatableEntityDetector.vehicles[0];
                    }
                    // Priority Player -> Npc -> Buildings
                    if (targetPlayer && CacheUISceneGameplay)
                    {
                        // Show dealing, invitation menu
                        SelectedEntity = targetPlayer;
                        CacheUISceneGameplay.SetActivePlayerCharacter(targetPlayer);
                    }
                    else if (targetNpc)
                    {
                        // Talk to NPC
                        SelectedEntity = targetNpc;
                        PlayerCharacterEntity.RequestNpcActivate(targetNpc.ObjectId);
                    }
                    else if (targetBuilding)
                    {
                        // Use building
                        SelectedEntity = targetBuilding;
                        ActivateBuilding(targetBuilding);
                    }
                    else if (targetVehicle)
                    {
                        // Enter vehicle
                        PlayerCharacterEntity.RequestEnterVehicle(targetVehicle.ObjectId);
                    }
                    else
                    {
                        // Enter warp, For some warp portals that `warpImmediatelyWhenEnter` is FALSE
                        PlayerCharacterEntity.RequestEnterWarp();
                    }
                }
                // Pick up nearby items
                if (InputManager.GetButtonDown("PickUpItem"))
                {
                    targetItemDrop = null;
                    if (ItemDropEntityDetector.itemDrops.Count > 0)
                    {
                        targetItemDrop = ItemDropEntityDetector.itemDrops[0];
                    }
                    if (targetItemDrop != null)
                    {
                        PlayerCharacterEntity.RequestPickupItem(targetItemDrop.ObjectId);
                    }
                }
                // Reload
                if (InputManager.GetButtonDown("Reload"))
                {
                    // Reload ammo when press the button
                    ReloadAmmo();
                }
                if (InputManager.GetButtonDown("ExitVehicle"))
                {
                    // Exit vehicle
                    PlayerCharacterEntity.RequestExitVehicle();
                }
                if (InputManager.GetButtonDown("SwitchEquipWeaponSet"))
                {
                    // Switch equip weapon set
                    PlayerCharacterEntity.RequestSwitchEquipWeaponSet((byte)(PlayerCharacterEntity.EquipWeaponSet + 1));
                }
                if (InputManager.GetButtonDown("Sprint"))
                {
                    // Toggles sprint state
                    isSprinting = !isSprinting;
                }
                // Auto reload
                if (PlayerCharacterEntity.EquipWeapons.rightHand.IsAmmoEmpty() ||
                    PlayerCharacterEntity.EquipWeapons.leftHand.IsAmmoEmpty())
                {
                    // Reload ammo when empty and not press any keys
                    ReloadAmmo();
                }
            }
            // Update inputs
            UpdateLookInput();
            UpdateWASDInput();
            // Set sprinting state
            PlayerCharacterEntity.SetExtraMovement(isSprinting ? ExtraMovementState.IsSprinting : ExtraMovementState.None);
        }
        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);
            }
        }
        private void FindEntity(GameObject other,
                                out BasePlayerCharacterEntity player,
                                out BaseMonsterCharacterEntity monster,
                                out NpcEntity npc,
                                out ItemDropEntity itemDrop,
                                out BuildingEntity building,
                                bool findWithAdvanceOptions = true)
        {
            player = null;
            if (findPlayer)
            {
                player = other.GetComponent <BasePlayerCharacterEntity>();
                if (player == BasePlayerCharacterController.OwningCharacter)
                {
                    player = null;
                }
                if (findWithAdvanceOptions)
                {
                    if (findOnlyAlivePlayers && player != null && player.IsDead())
                    {
                        player = null;
                    }
                    if (findPlayerToAttack && player != null && player.IsAlly(BasePlayerCharacterController.OwningCharacter))
                    {
                        player = null;
                    }
                }
            }

            monster = null;
            if (findMonster)
            {
                monster = other.GetComponent <BaseMonsterCharacterEntity>();
                if (findWithAdvanceOptions)
                {
                    if (findOnlyAliveMonsters && monster != null && monster.IsDead())
                    {
                        monster = null;
                    }
                    if (findMonsterToAttack && monster != null && monster.IsAlly(BasePlayerCharacterController.OwningCharacter))
                    {
                        monster = null;
                    }
                }
            }

            npc = null;
            if (findNpc)
            {
                npc = other.GetComponent <NpcEntity>();
            }

            itemDrop = null;
            if (findItemDrop)
            {
                itemDrop = other.GetComponent <ItemDropEntity>();
            }

            building = null;
            if (findBuilding)
            {
                BuildingMaterial buildingMaterial = other.GetComponent <BuildingMaterial>();
                if (buildingMaterial != null)
                {
                    building = buildingMaterial.buildingEntity;
                }
                if (findWithAdvanceOptions)
                {
                    if (findOnlyAliveBuildings && building != null && building.IsDead())
                    {
                        building = null;
                    }
                    if (findOnlyActivatableBuildings && building != null && !building.Activatable)
                    {
                        building = null;
                    }
                }
            }
        }
        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();
            }
        }
        public static ItemDropEntity DropItem(BaseGameEntity dropper, CharacterItem dropData, IEnumerable <uint> looters)
        {
            GameInstance gameInstance = GameInstance.Singleton;

            if (gameInstance.itemDropEntityPrefab == null)
            {
                return(null);
            }

            Vector3    dropPosition = dropper.CacheTransform.position;
            Quaternion dropRotation = Quaternion.identity;

            if (gameInstance.DimensionType == DimensionType.Dimension2D)
            {
                // If 2d, just random position around character
                dropPosition = dropper.CacheTransform.position + new Vector3(Random.Range(-1f, 1f) * gameInstance.dropDistance, Random.Range(-1f, 1f) * gameInstance.dropDistance);
            }
            else
            {
                // Random drop position around character
                dropPosition = dropper.CacheTransform.position + new Vector3(Random.Range(-1f, 1f) * gameInstance.dropDistance, 0, Random.Range(-1f, 1f) * gameInstance.dropDistance);
                // Raycast to find hit floor
                Vector3?   aboveHitPoint    = null;
                Vector3?   underHitPoint    = null;
                int        raycastLayerMask = gameInstance.GetItemDropGroundDetectionLayerMask();
                RaycastHit tempHit;
                if (Physics.Raycast(dropPosition, Vector3.up, out tempHit, GROUND_DETECTION_DISTANCE, raycastLayerMask))
                {
                    aboveHitPoint = tempHit.point;
                }
                if (Physics.Raycast(dropPosition, Vector3.down, out tempHit, GROUND_DETECTION_DISTANCE, raycastLayerMask))
                {
                    underHitPoint = tempHit.point;
                }
                // Set drop position to nearest hit point
                if (aboveHitPoint.HasValue && underHitPoint.HasValue)
                {
                    if (Vector3.Distance(dropPosition, aboveHitPoint.Value) < Vector3.Distance(dropPosition, underHitPoint.Value))
                    {
                        dropPosition = aboveHitPoint.Value;
                    }
                    else
                    {
                        dropPosition = underHitPoint.Value;
                    }
                }
                else if (aboveHitPoint.HasValue)
                {
                    dropPosition = aboveHitPoint.Value;
                }
                else if (underHitPoint.HasValue)
                {
                    dropPosition = underHitPoint.Value;
                }
                // Random rotation
                dropRotation = Quaternion.Euler(Vector3.up * Random.Range(0, 360));
            }
            GameObject     spawnObj       = Instantiate(gameInstance.itemDropEntityPrefab.gameObject, dropPosition, dropRotation);
            ItemDropEntity itemDropEntity = spawnObj.GetComponent <ItemDropEntity>();

            itemDropEntity.dropData = dropData;
            itemDropEntity.looters  = new HashSet <uint>(looters);
            BaseGameNetworkManager.Singleton.Assets.NetworkSpawn(spawnObj);
            return(itemDropEntity);
        }