/// <summary> /// Проверяет корректность покупки лицензии /// </summary> private bool CanBuyLicense(Client player, PlayerInfo playerInfo, int price) { var result = true; var messages = new List <string>(); if (playerInfo.Level < MIN_LEVEL_TO_LICENCE) { messages.Add($"Необходимо достигнуть {5}-го уровня"); result = false; } if (playerInfo.Wanted.WantedLevel > 0) { messages.Add("Вы находитесь в розыске"); result = false; } if (playerInfo.Balance < price) { messages.Add("Недостаточно средств"); result = false; } if (playerInfo.Inventory.Any(e => e.Type == InventoryType.WeaponLicense)) { messages.Add("У вас уже есть лицензия"); result = false; } foreach (var message in messages) { API.sendNotificationToPlayer(player, $"~r~{message}", true); } return(result); }
/// <summary> /// Обработывает успешную авторизацию игрока /// </summary> private void ProcessLogin(Client player, PlayerInfo playerInfo) { var appearance = _playersAppearanceProvider.Get(playerInfo.AccountId); playerInfo.Skin = (Skin)appearance.Skin; playerInfo.Appearance = appearance; API.triggerClientEvent(player, ServerEvent.SHOW_INTERFACE); _gtaCharacter.SetAppearance(player, appearance); _gtaCharacter.SetClothes(player, playerInfo.Clothes.Where(e => e.OnPlayer).ToList()); SetPosition(player, playerInfo); PlayerManager.SetPlayerName(player, playerInfo); player.resetSyncedData(DISABLE_HOTKEYS); if (_admins.Contains(player.socialClubName)) { player.setSyncedData("IsAdmin", true); } if (playerInfo.PhoneNumber != 0) { player.setSyncedData("HasPhone", true); } player.freeze(false); _playerInfoManager.RefreshUI(player, playerInfo); API.sendNativeToPlayer(player, Hash.DISPLAY_RADAR, true); API.sendChatMessageToAll($"~g~[Информация]: {playerInfo.Name} зашел на сервер. Онлайн: {ServerState.Players.Count}"); }
/// <summary> /// Сконвертировать данные игрока в модель /// </summary> public static PlayerInfo ConvertToModel(gta_mp_data.Entity.PlayerInfo playerInfo, PlayerAdditionalInfo additionalInfo, DriverInfo driverInfo, IEnumerable <PlayerWork> worksInfo, Wanted wantedInfo, Settings settings, IEnumerable <PlayerClothes> clothes) { var result = new PlayerInfo { AccountId = playerInfo.AccountId, Name = playerInfo.Name, Level = playerInfo.Level, Experience = playerInfo.Experience, Satiety = playerInfo.Satiety, Health = playerInfo.Health, LastPosition = playerInfo.LastPosition, Dimension = playerInfo.Dimension, Driver = DriverInfoConverter.ConvertToModel(driverInfo), Works = WorksInfoConverter.ConvertToModels(worksInfo), Wanted = wantedInfo, PhoneNumber = additionalInfo.PhoneNumber, PhoneBalance = additionalInfo.PhoneBalance, TagName = additionalInfo.TagName, TagColor = additionalInfo.TagColor, LastTeleportToHouse = additionalInfo.LastTeleportToHouse, Settings = settings, Clothes = PlayerClothesConverter.ConvertTModels(clothes) }; return(result); }
/// <summary> /// Заправить транспорт из канистры /// </summary> private void FillVehicle(Client player, PlayerInfo playerInfo, int liters) { if (player.isInVehicle) { API.sendNotificationToPlayer(player, "~r~Чтобы заправить транспорт, необходимо выйти из нее", true); return; } var vehicle = _vehicleManager.GetNearestVehicle(player, 3.5f); if (vehicle == null) { API.sendNotificationToPlayer(player, "~r~Подойдите ближе к транспорту", true); return; } if (!vehicle.hasData(VehicleManager.MAX_FUEL)) { API.sendNotificationToPlayer(player, "~r~Можно заправить только личный транспорт", true); return; } var maxFuel = (int)vehicle.getData(VehicleManager.MAX_FUEL); var newFuel = API.getVehicleFuelLevel(vehicle) + liters; if (maxFuel < newFuel) { API.sendNotificationToPlayer(player, "~r~Количество бензина превышает вместимость бака", true); return; } API.setVehicleFuelLevel(vehicle, newFuel); API.sendNotificationToPlayer(player, $"~b~Залито {liters} литров"); playerInfo.Inventory.First(e => e.Type == InventoryType.Canister).DecreaseCount(liters); }
/// <summary> /// Выход из клана /// </summary> public void LeftClan(Client player, PlayerInfo playerInfo) { API.sendNotificationToPlayer(player, $"Вы покинули банду ~b~\"{GetClanName(playerInfo.Clan.ClanId)}\""); _clanProvider.RemoveClanInfo(playerInfo.AccountId); playerInfo.Clan = null; playerInfo.TagName = string.Empty; PlayerManager.SetPlayerName(player, playerInfo); }
/// <summary> /// Использовать сухой паёк /// </summary> private static void UsePackedLunch(Client player, PlayerInfo playerInfo, int count) { const int satietyCount = 25; var newSatiety = playerInfo.Satiety + satietyCount * count; playerInfo.Satiety = newSatiety > PlayerInfo.MAX_VALUE ? PlayerInfo.MAX_VALUE : newSatiety; playerInfo.Inventory.First(e => e.Type == InventoryType.Food).DecreaseCount(count); PlayerHelper.PlayEatAnimation(player); }
/// <summary> /// Использовать аптечку /// </summary> private void UseMedicine(Client player, PlayerInfo playerInfo, int count) { const int healCount = 30; var health = player.health + healCount * count; API.setPlayerHealth(player, health); playerInfo.Health = health; playerInfo.Inventory.First(e => e.Type == InventoryType.Medicine).DecreaseCount(count); }
/// <summary> /// Проверяет, что у игрока достаточно денег /// </summary> private bool HasMoney(Client player, PlayerInfo playerInfo, int price) { if (playerInfo.Balance < price) { API.sendNotificationToPlayer(player, "~r~Недостаточно средств", true); return(false); } return(true); }
/// <summary> /// Сконвертировать дополнительные данные игрока в сущность /// </summary> public static PlayerAdditionalInfo ConvertToAdditionalEntity(PlayerInfo model) { return(new PlayerAdditionalInfo { AccountId = model.AccountId, TagName = model.TagName, TagColor = model.TagColor, PhoneNumber = model.PhoneNumber, PhoneBalance = model.PhoneBalance, LastTeleportToHouse = model.LastTeleportToHouse }); }
/// <summary> /// Проверяет наличие лицензии на покупку оружия /// </summary> private bool HasLicense(Client player, PlayerInfo playerInfo) { var license = playerInfo.Inventory.FirstOrDefault(e => e.Type == InventoryType.WeaponLicense); if (license == null) { API.sendNotificationToPlayer(player, "~r~У вас нет лицензии на покупку оружия", true); return(false); } return(true); }
/// <summary> /// Создает итем патронов /// </summary> private static InventoryItem CreateAmmoItem(PlayerInfo playerInfo, WeaponGood ammo, int count) { return(new InventoryItem { OwnerId = playerInfo.AccountId, Name = ammo.Name, Type = InventoryType.Ammo, Count = count, CountInHouse = 0, Model = ammo.Model }); }
/// <summary> /// Создает итем оружия /// </summary> private static InventoryItem CreateWeaponItem(PlayerInfo playerInfo, WeaponGood goodItem) { return(new InventoryItem { OwnerId = playerInfo.AccountId, Name = goodItem.Name, Type = InventoryType.Weapon, Count = 1, CountInHouse = 0, Model = goodItem.Model }); }
/// <summary> /// Устанавливает имя полицейского /// </summary> private void SetPolicemanName(Client player, PlayerInfo playerInfo) { var workLevel = WorkInfoManager.GetActiveWork(player).Level; var rankName = PoliceDataGetter.RankNames[workLevel]; API.setPlayerNametag(player, $"[{rankName}] {playerInfo.Name}"); if (string.IsNullOrEmpty(playerInfo.TagColor)) { API.resetPlayerNametagColor(player); API.setPlayerNametagColor(player, 99, 154, 242); } }
/// <summary> /// Положить в хранилище /// </summary> private static void PutItem(Client player, PlayerInfo playerInfo, long id, int count) { var item = playerInfo.Inventory.First(e => e.Id == id); if (item.Count < count) { API.shared.sendNotificationToPlayer(player, "~r~Попытка переместить неверное количество"); return; } item.Count -= count; item.CountInHouse += count; }
/// <summary> /// Применить рандомный скин /// </summary> private void SetRandomSkin(Client player, PlayerInfo playerInfo) { ActionHelper.CancelAction(player, SKIN_RESET_ACTION); var skins = Enum.GetValues(typeof(TemporarySkin)); var hash = (PedHash)skins.GetValue(ActionHelper.Random.Next(skins.Length)); API.setPlayerSkin(player, hash); ActionHelper.SetAction(player, 3600000, () => _playerInfoManager.SetPlayerClothes(player, true), SKIN_RESET_ACTION); playerInfo.Inventory.First(e => e.Type == InventoryType.TempoSkin).DecreaseCount(); EquipWeapon(player); API.sendColoredNotificationToPlayer(player, "Действие скина закончится через час", 0, 21); }
/// <summary> /// Сконвертировать основную информацию игроков в сущности /// </summary> public static gta_mp_data.Entity.PlayerInfo ConvertToEntity(PlayerInfo model) { return(new gta_mp_data.Entity.PlayerInfo { AccountId = model.AccountId, Level = model.Level, Experience = model.Experience, Dimension = model.Dimension, Name = model.Name, Satiety = model.Satiety, Health = model.Health, LastPosition = model.LastPosition }); }
/// <summary> /// Установить аренду дома /// </summary> private void SetRent(Client player, HouseInfo house, PlayerInfo playerInfo, int daysRent) { var endOfRenting = DateTime.Now.AddDays(daysRent); var isRentExt = Validator.IsValid(house.EndOfRenting); house.EndOfRenting = isRentExt ? house.EndOfRenting.AddDays(daysRent) : endOfRenting; house.OwnerId = playerInfo.AccountId; _houseManager.SetHouse(house); _houseManager.UpdateBlip(house, playerInfo.Name); var actionName = isRentExt ? "продлена" : "оплачена"; API.sendNotificationToPlayer(player, $"~g~Аренда {actionName} до {house.EndOfRenting:g}"); }
/// <summary> /// Поместить игрока на позицию до выхода /// </summary> private void SetPosition(Client player, PlayerInfo info) { var lastPosition = !string.IsNullOrEmpty(info.LastPosition) ? PositionConverter.ToVector3(info.LastPosition) : null; if (info.Wanted.JailTime > 0) { _jailManager.SetInJail(player, lastPosition); } else { API.setEntityPosition(player, lastPosition ?? MainPosition.StartSpawn); } API.setEntityDimension(player, info.Dimension); }
/// <summary> /// Вступление в клан /// </summary> public void JoinClan(Client player, PlayerInfo playerInfo, int clanId) { var clanInfo = new PlayerClanInfo { AccountId = playerInfo.AccountId, ClanId = clanId, Rank = ClanRank.Lowest, Reputation = 0 }; playerInfo.Clan = clanInfo; playerInfo.TagName = _clanTags[clanId]; PlayerManager.SetPlayerName(player, playerInfo); API.sendNotificationToPlayer(player, $"Вы присоединились к банде ~b~\"{GetClanName(clanId)}\""); }
/// <summary> /// Обновляет данные инвентаря /// </summary> private static void UpdateInventory(Database db, PlayerInfo playerInfo) { foreach (var entity in playerInfo.Inventory) { var exist = db.Inventory.Any(e => e.Id == entity.Id); if (exist) { db.Update(entity); } else { entity.Id = Convert.ToInt32(db.InsertWithIdentity(entity)); } } }
/// <summary> /// Проверяет корректность покупки /// </summary> private bool CanFillVehicle(Client player, PlayerInfo playerInfo, int maxFuel, float currentFuel, float fillingAmount) { if (!HasMoney(player, playerInfo.Balance, (int)fillingAmount)) { return(false); } var newFuelCount = currentFuel + fillingAmount; if (newFuelCount > maxFuel) { API.sendColoredNotificationToPlayer(player, "Количество топлива превышает вместимость бака", 0, 6); return(false); } return(true); }
/// <summary> /// Обновление информации об одеждах игрока /// </summary> private static void UpdatePhoneContacts(Database db, PlayerInfo playerInfo) { foreach (var entity in playerInfo.PhoneContacts) { var exist = db.PhoneContacts.Any(e => e.AccountId == entity.AccountId && e.Number == entity.Number); if (exist) { db.Update(entity); } else { db.Insert(entity); } } }
/// <summary> /// Забрать из хранилища /// </summary> private void TakeItem(Client player, PlayerInfo playerInfo, long id, int count) { var item = playerInfo.Inventory.First(e => e.Id == id); if (!_inventoryHelper.CanCarry(playerInfo.Inventory, item, count)) { API.sendColoredNotificationToPlayer(player, "Превышена грузоподъемность персонажа", 0, 6); return; } if (item.CountInHouse < count) { API.sendNotificationToPlayer(player, "~r~Попытка переместить неверное количество"); return; } item.CountInHouse -= count; item.Count += count; }
/// <summary> /// Обновляет данные о работах игрока /// </summary> private static void UpdateWorks(Database db, PlayerInfo playerInfo) { var worksEntities = WorksInfoConverter.ConvertToEntities(playerInfo.AccountId, playerInfo.Works.Values); foreach (var entity in worksEntities) { var exist = db.PlayerWorks.Any(e => e.AccountId == entity.AccountId && e.Type == entity.Type); if (exist) { db.Update(entity); } else { db.Insert(entity); } } }
/// <summary> /// Обновление информации об одеждах игрока /// </summary> private static void UpdateClothes(Database db, PlayerInfo playerInfo) { var clothesEntities = PlayerClothesConverter.ConvertToEntities(playerInfo.AccountId, playerInfo.Clothes); foreach (var entity in clothesEntities) { var exist = db.PlayerClothes.Any(e => e.AccountId == entity.AccountId && e.Slot == entity.Slot && e.Variation == entity.Variation); if (exist) { db.Update(entity); } else { db.Insert(entity); } } }
/// <summary> /// Добавляет покупку в инвентарь /// </summary> private bool AddItemToInventory(PlayerInfo playerInfo, InventoryType type, int count) { var item = playerInfo.Inventory.FirstOrDefault(e => e.Type == type) ?? CreateItem(playerInfo.AccountId, type, count); if (!_inventoryHelper.CanCarry(playerInfo.Inventory, item, count)) { return(false); } if (playerInfo.Inventory.Any(e => e.Type == type)) { item.Count += count; } else { playerInfo.Inventory.Add(item); } return(true); }
/// <summary> /// Обновить патроны игрока /// </summary> public void RefreshAmmo(Client player, PlayerInfo playerInfo = null) { if (playerInfo == null) { playerInfo = _playerInfoManager.GetInfo(player); } var weapons = API.getPlayerWeapons(player); foreach (var weapon in weapons) { var ammoCount = API.getPlayerWeaponAmmo(player, weapon); var ammoType = API.getWeaponAmmoType(weapon); var ammoItem = playerInfo.Inventory.FirstOrDefault(e => e.Type == InventoryType.Ammo && e.Model == (int)ammoType); if (ammoItem != null) { ammoItem.Count = ammoCount; } } }
/// <summary> /// Записать данные игрока /// todo: попробовать заюзать async /// </summary> public void SetInfo(PlayerInfo playerInfo) { var playerEntity = PlayerInfoConverter.ConvertToEntity(playerInfo); var additionalEntity = PlayerInfoConverter.ConvertToAdditionalEntity(playerInfo); var driverInfo = DriverInfoConverter.ConvertToEntity(playerInfo.AccountId, playerInfo.Driver); using (var db = new Database()) { db.Update(playerEntity); db.Update(additionalEntity); db.Update(driverInfo); db.Update(playerInfo.Wanted); db.Update(playerInfo.Settings); UpdateClanInfo(db, playerInfo.Clan); UpdateInventory(db, playerInfo); UpdateWorks(db, playerInfo); UpdateClothes(db, playerInfo); UpdatePhoneContacts(db, playerInfo); } }
/// <summary> /// Загрузить транспорт игрока /// </summary> private void LoadPlayerVehicles(Client player, PlayerInfo playerInfo) { var vehicles = _vehicleInfoManager.GetPlayerVehicles(playerInfo.AccountId); foreach (var vehicle in vehicles) { if (vehicle.IsSpawned) { var instance = _vehicleManager.GetInstanceById(vehicle.Id); if (instance != null) { vehicle.Instance = instance; } else { vehicle.IsSpawned = false; } } _vehicleInfoManager.SetInfo(player, vehicle); } }
/// <summary> /// Устанавливает ранг /// </summary> public void SetReputation(Client player, int value, PlayerInfo playerInfo = null) { if (playerInfo == null) { playerInfo = _playerInfoManager.GetInfo(player); } if (value > 0 && playerInfo.IsPremium()) { value += (int)(value * 0.3); } playerInfo.Clan.Reputation += value; var prefix = value > 0 ? "~b~Получено" : "~w~Потеряно"; API.sendNotificationToPlayer(player, $"{prefix} {Math.Abs(value)} очков репутации банды"); var rank = GetRank(playerInfo.Clan.Reputation); if (rank != playerInfo.Clan.Rank) { playerInfo.Clan.Rank = rank; API.sendNotificationToPlayer(player, $"~g~Изменение ранга. Новый ранг: {rank.GetDescription()}"); } }