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(); } }
/// <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 }); } }
/// <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(); } }