- Регистрация
- 12 Янв 2024
- Сообщения
- 74
- Реакции
- 10
- Баллы
- 8
Броня для Vip игрока
Для начала так поправим ServerPerks, чтобы у вип игрока
1. при появлении было 150 брони (пока решил не делать этот пункт, подробности ниже)
2. в магазине закупка брони была до 150 (при этом 150 всё равно будет 100%, просто 100 брони будет считаться 66%)
3. при подъёме брони с земли она пополнялась бы до 150
4. правильно отображалась полосочка брони в HUD
Рассмотрим подробнее эти исправления
0. Создадим класс утилит - Utilities.
Там будем складировать полезные static функции, которые вызываются из разных кусков кода.
Пока добавим одну только функцию HasItem, которая проверяет есть ли у игрока P в инвентаре что-то под именем ItemName.
Появление с бронёй
Решил опустить этот пункт. Во-первых, этот бонус выбивается из общей концепции, где мы правим ёмкость брони - задание конкретного значения это дело настроек каждого перка.
Во-вторых, у меня сходу не получилось придумать изящное решение, а громоздить некрасивый код я не хочу)
2. Покупка брони
Отображение в магазине:
Правим класс SRKFBuyMenuInvList, функцию UpdateMyBuyables
Добавляем переменную ShieldItemAmmoMax и в зависимости от того вип или нет присваиваем этой переменной значения 150 или 100.
И в дальнейшем в стандартном коде этой функции заменяем 100 на ShieldItemAmmoMax в кусочке относящимся к броне.
Фактическая реализация покупки:
Правим класс SRHumanPawn, функцию ServerBuyKevlar
Как и в прошлом случае создаём переменную, которая будет хранить 100 или 150. Пусть она называется cShield.
И в стандартном коде заменяем 100 на cShield.
Подбор брони с земли
Прежде всего хотелось бы заменить, что в броне (KFMod.Vest) уже прописано сколько брони добавлять игроку - 100
И если мы хотим это изменить, то надо добавить в какой-то мутатор такую строку в ту же функцию PostBeginPlay, например
class'KFMod.Vest'.default.ShieldAmount=150;
Если хотите можете добавить эту строчку в VipItemMut, хотя как по мне так это неправильно. Должен быть порядок на сервере и должен быть какой-то отдельный мутатор для того, чтобы заменять стандартные значения у классов.
Теперь правим класс SRHumanPawn, функцию AddShieldStrength
Идея всё та же. Создаём переменную и заполняем её значением 100 или 150 в зависимости от того есть ли у игрока VipItem.
После этого меняем стандартную функцию, заменяя 100 на cShield.
Отображение брони в HUD. Точнее заполненность полоски брони игрока с точки зрения других игроков.
Правим класс SRHUDKillingFloor, функцию DrawPlayerInfo
Идея всё та же. Переменная cShield со значениями 100 или 150 и замена стандартного кода.
Сварка брони.
Тут уже надо глядеть код сварочного аппарата. Если там тупо добавляется бронь - сами глядите, есть ли там ограничение до 100 и где его заменить на 150. Если же используется функция AddShieldStrength, то достаточно реализовать пункт 3
Изменённые файлы в SP 7.50
Ссылка Ссылка 2
Не так давно пришло в голову - нет никакой необходимости увеличивать количество брони
Можно просто улучшить её качество)
Броня в 150 единиц = обычной броне, которая в 1.5 раза сильнее стандартных настроек
Это резко уменьшает количество кода и мороки с бронёй
Нам достаточно в каждый SRVet* класс (или в класс SRVeterancyTypes) добавить изменённую функцию GetBodyArmorDamageModifier
Что-нибудь такое:
И мы получим по сути ровно тот же эффект)
Автор Flame.
Для начала так поправим ServerPerks, чтобы у вип игрока
1. при появлении было 150 брони (пока решил не делать этот пункт, подробности ниже)
2. в магазине закупка брони была до 150 (при этом 150 всё равно будет 100%, просто 100 брони будет считаться 66%)
3. при подъёме брони с земли она пополнялась бы до 150
4. правильно отображалась полосочка брони в HUD
Рассмотрим подробнее эти исправления
0. Создадим класс утилит - Utilities.
Там будем складировать полезные static функции, которые вызываются из разных кусков кода.
Пока добавим одну только функцию HasItem, которая проверяет есть ли у игрока P в инвентаре что-то под именем ItemName.
Код:
class Utilities extends Actor
abstract;
//Проверка есть ли у игрока P в инвентаре что-то под именем ItemName
static function bool HasItem(Pawn P, Name ItemName)
{
local Inventory Inv;
for(Inv=P.Inventory;Inv!=None;Inv=Inv.Inventory)
{
if(Inv.Name==ItemName)
return true;
}
return false;
}
Решил опустить этот пункт. Во-первых, этот бонус выбивается из общей концепции, где мы правим ёмкость брони - задание конкретного значения это дело настроек каждого перка.
Во-вторых, у меня сходу не получилось придумать изящное решение, а громоздить некрасивый код я не хочу)
2. Покупка брони
Отображение в магазине:
Правим класс SRKFBuyMenuInvList, функцию UpdateMyBuyables
Добавляем переменную ShieldItemAmmoMax и в зависимости от того вип или нет присваиваем этой переменной значения 150 или 100.
И в дальнейшем в стандартном коде этой функции заменяем 100 на ShieldItemAmmoMax в кусочке относящимся к броне.
Код:
function UpdateMyBuyables()
{
...
local float ShieldItemAmmoMax;
...
...
if (
PlayerOwner()!=none
&& class'Utilities'.static.HasItem(PlayerOwner().Pawn,'VipItem')
)
{
ShieldItemAmmoMax=150.0;
}
else
ShieldItemAmmoMax=100.0;
MyBuyable.ItemName = class'BuyableVest'.default.ItemName;
MyBuyable.ItemDescription = class'BuyableVest'.default.ItemDescription;
MyBuyable.ItemCategorie = "";
MyBuyable.ItemImage = class'BuyableVest'.default.ItemImage;
MyBuyable.ItemAmmoCurrent = PlayerOwner().Pawn.ShieldStrength;
MyBuyable.ItemAmmoMax = ShieldItemAmmoMax;
MyBuyable.ItemCost = int(class'BuyableVest'.default.ItemCost * KFV.static.GetCostScaling(PRI, class'Vest'));
MyBuyable.ItemAmmoCost = MyBuyable.ItemCost / ShieldItemAmmoMax;
MyBuyable.ItemFillAmmoCost = int((ShieldItemAmmoMax - MyBuyable.ItemAmmoCurrent) * MyBuyable.ItemAmmoCost);
MyBuyable.bIsVest = true;
MyBuyable.bMelee = false;
MyBuyable.bSaleList = false;
MyBuyable.bSellable = false;
MyBuyable.ItemPerkIndex = class'BuyableVest'.default.CorrespondingPerkIndex;
...
}
Правим класс SRHumanPawn, функцию ServerBuyKevlar
Как и в прошлом случае создаём переменную, которая будет хранить 100 или 150. Пусть она называется cShield.
И в стандартном коде заменяем 100 на cShield.
Код:
переменную, которая будет хранить 100 или 150. Пусть она называется cShield.
И в стандартном коде заменяем 100 на cShield.
Спойлер
Код:
function ServerBuyKevlar()
{
local float Cost;
local int UnitsAffordable;
local float cShield;
if(class'Utilities'.static.HasItem(self,'VipItem'))
cShield=150.0;
else
cShield=100.0;
Cost = class'Vest'.default.ItemCost * ((cShield - ShieldStrength) / cShield);
if ( KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none)
{
Cost *= KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.GetCostScaling(KFPlayerReplicationInfo(PlayerReplicationInfo), class'Vest');
}
if ( !CanBuyNow() || ShieldStrength==cShield )
{
SetTraderUpdate();
Return;
}
if ( PlayerReplicationInfo.Score >= Cost )
{
PlayerReplicationInfo.Score -= Cost;
ShieldStrength = cShield;
}
else if ( ShieldStrength > 0 )
{
Cost = class'Vest'.default.ItemCost;
if ( KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill != none)
{
Cost *= KFPlayerReplicationInfo(PlayerReplicationInfo).ClientVeteranSkill.static.GetCostScaling(KFPlayerReplicationInfo(PlayerReplicationInfo), class'Vest');
}
Cost /= cShield;
UnitsAffordable = int(PlayerReplicationInfo.Score / Cost);
PlayerReplicationInfo.Score -= int(Cost * UnitsAffordable);
ShieldStrength += UnitsAffordable;
}
SetTraderUpdate();
}
Прежде всего хотелось бы заменить, что в броне (KFMod.Vest) уже прописано сколько брони добавлять игроку - 100
И если мы хотим это изменить, то надо добавить в какой-то мутатор такую строку в ту же функцию PostBeginPlay, например
class'KFMod.Vest'.default.ShieldAmount=150;
Если хотите можете добавить эту строчку в VipItemMut, хотя как по мне так это неправильно. Должен быть порядок на сервере и должен быть какой-то отдельный мутатор для того, чтобы заменять стандартные значения у классов.
Теперь правим класс SRHumanPawn, функцию AddShieldStrength
Идея всё та же. Создаём переменную и заполняем её значением 100 или 150 в зависимости от того есть ли у игрока VipItem.
После этого меняем стандартную функцию, заменяя 100 на cShield.
Код:
function bool AddShieldStrength(int ShieldAmount)
{
local float cShield;
if(class'Utilities'.static.HasItem(self,'VipItem'))
cShield=150.0;
else
cShield=100.0;
if(ShieldStrength >= cShield)
return false;
ShieldStrength+=ShieldAmount;
if(ShieldStrength > cShield)
ShieldStrength = cShield;
return true ;
}
Правим класс SRHUDKillingFloor, функцию DrawPlayerInfo
Идея всё та же. Переменная cShield со значениями 100 или 150 и замена стандартного кода.
Код:
function DrawPlayerInfo(Canvas C, Pawn P, float ScreenLocX, float ScreenLocY)
{
...
local float cShield;
...
if(P!=none && class'Utilities'.static.HasItem(P,'VipItem'))
cShield=150.0;
else
cShield=100.0;
if ( P.ShieldStrength > 0 )
DrawKFBar(C, ScreenLocX - OffsetX, (ScreenLocY - YL) - 1.5 * BarHeight, FClamp(P.ShieldStrength / cShield, 0, 1), BeaconAlpha, true);
...
}
Тут уже надо глядеть код сварочного аппарата. Если там тупо добавляется бронь - сами глядите, есть ли там ограничение до 100 и где его заменить на 150. Если же используется функция AddShieldStrength, то достаточно реализовать пункт 3
Изменённые файлы в SP 7.50
Ссылка Ссылка 2
p.s. Как вы заметили раз за разом мы пишем число 150 в коде. Было бы неплохо не писать конкретное число. Можно это количество брони хранить в VipItem в какой-нибудь переменной, а в мутаторе расширить структуру и прописывать там количество брони для каждого игрока.
Есть много способов расширить возможности VipItem с формального информирования до каких-то практических плюшек.
Это вы сами пытайтесь)
Возможно будут статьи на эту тему.
p.p.s Ещё неплохой способ хранить информацию о том является ли игрок випом или нет - переменная в LinkedReplicationInfo.
Экземпляр LinkedReplicationInfo цепляется к обычному PlayerReplicationInfo, но это так же тема отдельной статьи.
p.p.p.s Ну и совсем адский способ - цепляемся к редко используемым переменным Pawn, Contoller или PlayerReplicationInfo и их детей.
Есть много способов расширить возможности VipItem с формального информирования до каких-то практических плюшек.
Это вы сами пытайтесь)
Возможно будут статьи на эту тему.
p.p.s Ещё неплохой способ хранить информацию о том является ли игрок випом или нет - переменная в LinkedReplicationInfo.
Экземпляр LinkedReplicationInfo цепляется к обычному PlayerReplicationInfo, но это так же тема отдельной статьи.
p.p.p.s Ну и совсем адский способ - цепляемся к редко используемым переменным Pawn, Contoller или PlayerReplicationInfo и их детей.
Не так давно пришло в голову - нет никакой необходимости увеличивать количество брони
Можно просто улучшить её качество)
Броня в 150 единиц = обычной броне, которая в 1.5 раза сильнее стандартных настроек
Это резко уменьшает количество кода и мороки с бронёй
Нам достаточно в каждый SRVet* класс (или в класс SRVeterancyTypes) добавить изменённую функцию GetBodyArmorDamageModifier
Что-нибудь такое:
Код:
static function float GetBodyArmorDamageModifier(KFPlayerReplicationInfo KFPRI)
{
if(class'Utilities'.static.HasItem(PlayerController(KFPRI.Owner).Pawn,'VipItem'))
}
Автор Flame.
Последнее редактирование: