protected sealed override void ServerUpdate(ServerUpdateData data) { var character = data.GameObject; var privateState = data.PrivateState; var publicState = data.PublicState; if (publicState.IsDead) { // should never happen as the ServerCharacterDeathMechanic should properly destroy the character Logger.Error("(Should never happen) Destroying dead mob character: " + character); ServerWorld.DestroyObject(character); return; } this.ServerRebuildFinalCacheIfNeeded(character, privateState, publicState); ServerUpdateAgroState(privateState, data.DeltaTime); this.ServerUpdateMob(data); this.ServerUpdateMobDespawn(character, privateState, data.DeltaTime); // update weapon state (fires the weapon if needed) WeaponSystem.SharedUpdateCurrentWeapon( character, privateState.WeaponState, data.DeltaTime); }
public static CreateItemResult TryDropToCharacterOrGround( IReadOnlyDropItemsList dropItemsList, ICharacter toCharacter, Vector2Ushort tilePosition, bool sendNotificationWhenDropToGround, double probabilityMultiplier, DropItemContext context, out IItemsContainer groundContainer) { var containersProvider = new CharacterAndGroundContainersProvider(toCharacter, tilePosition); var result = dropItemsList.Execute( (protoItem, count) => Items.CreateItem(protoItem, containersProvider, count), context, probabilityMultiplier); groundContainer = containersProvider.GroundContainer; if (groundContainer is null) { return(result); } if (groundContainer.OccupiedSlotsCount == 0) { // nothing is spawned, the ground container should be destroyed World.DestroyObject(groundContainer.OwnerAsStaticObject); groundContainer = null; } else { if (sendNotificationWhenDropToGround && result.TotalCreatedCount > 0) { // notify player that there were not enough space in inventory so the items were dropped to the ground NotificationSystem.ServerSendNotificationNoSpaceInInventoryItemsDroppedToGround( toCharacter, protoItemForIcon: result.ItemAmounts .Keys .FirstOrDefault( k => k.Container == containersProvider.GroundContainer)? .ProtoItem); } WorldObjectClaimSystem.ServerTryClaim(groundContainer.OwnerAsStaticObject, toCharacter, WorldObjectClaimDuration.GroundItems); } return(result); }
public static void ServerRemoveAllStatusEffects(this ICharacter character, bool removeOnlyDebuffs = false) { var statusEffects = InternalServerGetStatusEffects(character); for (var index = 0; index < statusEffects.Count; index++) { var statusEffect = statusEffects[index]; if (removeOnlyDebuffs && ((IProtoStatusEffect)statusEffect.ProtoLogicObject).Kind == StatusEffectKind.Buff) { continue; } ServerWorld.DestroyObject(statusEffect); statusEffects.RemoveAt(index); index--; } Logger.Important("All status effects removed for " + character); }
private static void ServerLoadSystem() { var database = Server.Database; if (!database.TryGet(nameof(ChatSystem), DatabaseKeyGlobalChatRoomHolder, out sharedGlobalChatRoomHolder)) { sharedGlobalChatRoomHolder = ServerCreateChatRoom(new ChatRoomGlobal()); database.Set(nameof(ChatSystem), DatabaseKeyGlobalChatRoomHolder, sharedGlobalChatRoomHolder); } if (!database.TryGet(nameof(ChatSystem), DatabaseKeyLocalChatRoomHolder, out sharedLocalChatRoomHolder)) { sharedLocalChatRoomHolder = ServerCreateChatRoom(new ChatRoomLocal()); database.Set(nameof(ChatSystem), DatabaseKeyLocalChatRoomHolder, sharedLocalChatRoomHolder); } // right now it's not possible to enumerate all the existing chat rooms as this is a bootstrapper // schedule a delayed initialization ServerTimersSystem.AddAction( 0.1, () => { foreach (var chatRoomHolder in ServerWorld .GetGameObjectsOfProto <ILogicObject, ChatRoomHolder>() .ToList()) { if (!(SharedGetChatRoom(chatRoomHolder) is ChatRoomPrivate privateChatRoom)) { continue; } var characterA = Server.Characters.GetPlayerCharacter(privateChatRoom.CharacterA); var characterB = Server.Characters.GetPlayerCharacter(privateChatRoom.CharacterB); if (characterA == null || characterB == null) { // incorrect private chat room ServerWorld.DestroyObject(chatRoomHolder); continue; } ServerAddPrivateChatRoomToCharacterCache(characterA, chatRoomHolder); ServerAddPrivateChatRoomToCharacterCache(characterB, chatRoomHolder); }
public static void DestroyAllDecals( Vector2Ushort tilePosition, StaticObjectLayoutReadOnly layout) { Api.ValidateIsServer(); foreach (var tileOffset in layout.TileOffsets) { var tile = World.GetTile(tilePosition.X + tileOffset.X, tilePosition.Y + tileOffset.Y); if (!tile.IsValidTile) { continue; } var staticObjects = tile.StaticObjects; if (!HasFloorDecals(staticObjects)) { continue; } // remove floor decals using (var tempList = Api.Shared.WrapInTempList(staticObjects)) { foreach (var staticWorldObject in tempList) { if (staticWorldObject.ProtoStaticWorldObject.Kind == StaticObjectKind.FloorDecal) { World.DestroyObject(staticWorldObject); } } } } bool HasFloorDecals(ReadOnlyListWrapper <IStaticWorldObject> staticObjects) { foreach (var staticWorldObject in staticObjects) { if (staticWorldObject.ProtoStaticWorldObject.Kind == StaticObjectKind.FloorDecal) { return(true); } } return(false); } }
public virtual void ServerOnDeath(ICharacter character) { this.ServerSendDeathSoundEvent(character); ServerWorld.DestroyObject(character); var position = character.Position; var tilePosition = position.ToVector2Ushort(); var rotationAngleRad = character.GetPublicState <ICharacterPublicState>().AppliedInput.RotationAngleRad; var isLeftOrientation = ClientCharacterAnimationHelper.IsLeftHalfOfCircle( angleDeg: rotationAngleRad * MathConstants.RadToDeg); var isFlippedHorizontally = !isLeftOrientation; var objectCorpse = ServerWorld.CreateStaticWorldObject <ObjectCorpse>(tilePosition); ObjectCorpse.ServerSetupCorpse(objectCorpse, (IProtoCharacterMob)character.ProtoCharacter, (Vector2F)(position - tilePosition.ToVector2D()), isFlippedHorizontally: isFlippedHorizontally); }
private static void DropPlayerLoot(ICharacter character) { var containerEquipment = character.SharedGetPlayerContainerEquipment(); var containerHand = character.SharedGetPlayerContainerHand(); var containerHotbar = character.SharedGetPlayerContainerHotbar(); var containerInventory = character.SharedGetPlayerContainerInventory(); if (PveSystem.ServerIsPvE) { // don't drop player loot on death in PvE Api.Logger.Important("Player character is dead - reduce durability for the equipped items", character); // process items and drop loot ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: true, fromContainer: containerEquipment); ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: false, fromContainer: containerHand); ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: false, fromContainer: containerHotbar); ProcessContainerItemsOnDeathInPvE(isEquipmentContainer: false, fromContainer: containerInventory); return; } Api.Logger.Important("Player character is dead - drop loot", character); CraftingMechanics.ServerCancelCraftingQueue(character); var characterContainersOccupiedSlotsCount = containerEquipment.OccupiedSlotsCount + containerHand.OccupiedSlotsCount + containerHotbar.OccupiedSlotsCount + containerInventory.OccupiedSlotsCount; if (characterContainersOccupiedSlotsCount == 0) { Api.Logger.Important("No need to drop loot for dead character (no items to drop)", character); return; } var lootContainer = ObjectPlayerLootContainer.ServerTryCreateLootContainer(character); if (lootContainer is null) { Api.Logger.Error("Unable to drop loot for dead character", character); return; } // set slots count matching the total occupied slots count ServerItems.SetSlotsCount( lootContainer, (byte)characterContainersOccupiedSlotsCount); // process items and drop loot ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: true, fromContainer: containerEquipment, toContainer: lootContainer); ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: false, fromContainer: containerHand, toContainer: lootContainer); ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: false, fromContainer: containerHotbar, toContainer: lootContainer); ProcessContainerItemsOnDeathInPvP(isEquipmentContainer: false, fromContainer: containerInventory, toContainer: lootContainer); if (lootContainer.OccupiedSlotsCount <= 0) { // nothing dropped, destroy the just spawned loot container ServerWorld.DestroyObject((IWorldObject)lootContainer.Owner); return; } // set exact slots count ServerItems.SetSlotsCount( lootContainer, (byte)lootContainer.OccupiedSlotsCount); SharedLootDropNotifyHelper.ServerOnLootDropped(lootContainer); // please note - no need to notify player about the dropped loot, it's automatically done by ClientDroppedItemsNotificationsManager }