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