/// <summary> /// Verify all conditions to pickup a dropped item. /// </summary> /// <param name="droppedItem">The dropped item.</param> private void PickUpDroppedItem(IItemEntity droppedItem) { // TODO: check if drop belongs to a party. if (droppedItem.Drop.HasOwner && droppedItem.Drop.Owner != _player) { _textPacketFactory.SendDefinedText(_player, DefineText.TID_GAME_PRIORITYITEMPER, $"\"{droppedItem.Object.Name}\""); return; } if (droppedItem.Drop.IsGold) { int droppedGoldAmount = droppedItem.Drop.Item.Quantity; if (_playerDataSystem.IncreaseGold(_player, droppedGoldAmount)) { _textPacketFactory.SendDefinedText(_player, DefineText.TID_GAME_REAPMONEY, droppedGoldAmount.ToString("###,###,###,###"), _player.PlayerData.Gold.ToString("###,###,###,###")); } } else { _inventorySystem.CreateItem(_player, droppedItem.Drop.Item, droppedItem.Drop.Item.Quantity); _textPacketFactory.SendDefinedText(_player, DefineText.TID_GAME_REAPITEM, $"\"{droppedItem.Object.Name}\""); } _moverPacketFactory.SendMotion(_player, ObjectMessageType.OBJMSG_PICKUP); droppedItem.Delete(); }
/// <summary> /// Process the walk algorithm. /// </summary> /// <param name="entity">Current entity</param> private void Walk(ILivingEntity entity) { if (entity.Object.Position.IsInCircle(entity.Moves.DestinationPosition, ArrivalRangeRadius)) { entity.Object.Position.Copy(entity.Moves.DestinationPosition); entity.Moves.DestinationPosition.Reset(); if (!entity.Battle.IsFighting) { entity.Object.MovingFlags &= ~ObjectState.OBJSTA_FMOVE; entity.Object.MovingFlags |= ObjectState.OBJSTA_STAND; _moverPacketFactory.SendMotion(entity, ObjectMessageType.OBJMSG_STAND); } entity.Behavior.OnArrived(); } else { entity.Object.Angle = Vector3.AngleBetween(entity.Object.Position, entity.Moves.DestinationPosition); float entitySpeed = GetEntitySpeed(entity); if (entity.Object.MotionFlags.HasFlag(StateFlags.OBJSTAF_WALK)) { entitySpeed /= 4f; } else if (entity.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_BMOVE)) { entitySpeed /= 5f; } float distanceX = entity.Moves.DestinationPosition.X - entity.Object.Position.X; float distanceZ = entity.Moves.DestinationPosition.Z - entity.Object.Position.Z; double distance = Math.Sqrt(distanceX * distanceX + distanceZ * distanceZ); // Normalize double offsetX = (distanceX / distance) * entitySpeed; double offsetZ = (distanceZ / distance) * entitySpeed; if (Math.Abs(offsetX) > Math.Abs(distanceX)) { offsetX = distanceX; } if (Math.Abs(offsetZ) > Math.Abs(distanceZ)) { offsetZ = distanceZ; } UpdatePosition(entity, (float)offsetX, (float)offsetZ); } }
/// <inheritdoc /> public void ResurectLodelight(IPlayerEntity player) { IMapRevivalRegion revivalRegion = player.Object.CurrentMap.GetNearRevivalRegion(player.Object.Position); if (revivalRegion == null) { _logger.LogError($"Cannot find any revival region for map '{player.Object.CurrentMap.Name}'."); return; } decimal recoveryRate = _gameResources.Penalities.GetRevivalPenality(player.Object.Level) / 100; var jobData = player.PlayerData.JobData; int strength = player.Attributes[DefineAttributes.STR]; int stamina = player.Attributes[DefineAttributes.STA]; int dexterity = player.Attributes[DefineAttributes.DEX]; int intelligence = player.Attributes[DefineAttributes.INT]; player.Attributes[DefineAttributes.HP] = (int)(HealthFormulas.GetMaxOriginHp(player.Object.Level, stamina, jobData.MaxHpFactor) * recoveryRate); player.Attributes[DefineAttributes.MP] = (int)(HealthFormulas.GetMaxOriginMp(player.Object.Level, intelligence, jobData.MaxMpFactor, true) * recoveryRate); player.Attributes[DefineAttributes.FP] = (int)(HealthFormulas.GetMaxOriginFp(player.Object.Level, stamina, dexterity, strength, jobData.MaxFpFactor, true) * recoveryRate); if (player.Object.MapId != revivalRegion.MapId) { IMapInstance revivalMap = _mapManager.GetMap(revivalRegion.MapId); if (revivalMap == null) { _logger.LogError($"Cannot find revival map with id '{revivalRegion.MapId}'."); // TODO: disconnect client //player.Connection.Server.DisconnectClient(player.Connection.Id); return; } revivalRegion = revivalMap.GetRevivalRegion(revivalRegion.Key); } _teleportSystem.Teleport(player, revivalRegion.MapId, revivalRegion.RevivalPosition.X, null, revivalRegion.RevivalPosition.Z); _moverPacketFactory.SendMotion(player, ObjectMessageType.OBJMSG_ACC_STOP | ObjectMessageType.OBJMSG_STOP_TURN | ObjectMessageType.OBJMSG_STAND); _playerPacketFactory.SendPlayerRevival(player); _moverPacketFactory.SendUpdateAttributes(player, DefineAttributes.HP, player.Attributes[DefineAttributes.HP]); _moverPacketFactory.SendUpdateAttributes(player, DefineAttributes.MP, player.Attributes[DefineAttributes.MP]); _moverPacketFactory.SendUpdateAttributes(player, DefineAttributes.FP, player.Attributes[DefineAttributes.FP]); ProcessDeathPenality(player); }