Всем известно что вновь испеченная рыбалка в 1.06 немного кривая
Ловится только скумбрия
Причина - неверный результат проверки поверхности в месте рыбалки
Но - скумбрия водится только в соленой воде, а карп только в пресной
Приступим к фиксу
За экшн рыбалки отвечает файл 4_World\Classes\UserActionsComponent\Actions\Continuous\ActionFishingNew.c
Почему ловится только скумбрия
смотрим код
результат рыбалки генерится в функции HandleFishingResultSuccess() в классе ActionFishingNewCB : ActionContinuousBaseCB
class ActionFishingNewCB : ActionContinuousBaseCB
{
....
float rnd = Math.RandomFloatInclusive(0.0,1.0);
if (rnd > m_ActionDataFishing.FISHING_GARBAGE_CHANCE)
{
if (m_ActionDataFishing.m_IsSurfaceSea)
fish = ItemBase.Cast(GetGame().CreateObject("Mackerel",m_ActionDataFishing.m_Player.GetPosition(), false));
else
fish = ItemBase.Cast(GetGame().CreateObject("Carp",m_ActionDataFishing.m_Player.GetPosition(), false));
}
else
{
string junk_type = m_JunkTypes.Get(Math.RandomInt(0,m_JunkTypes.Count()));
fish = ItemBase.Cast(GetGame().CreateObject(junk_type,m_ActionDataFishing.m_Player.GetPosition(), false));
fish.SetHealth("","Health",fish.GetMaxHealth("","Health") * 0.1);
}
...
}
Согласно условию if (rnd > m_ActionDataFishing.FISHING_GARBAGE_CHANCE)
есть шанс (если rnd < m_ActionDataFishing.FISHING_GARBAGE_CHANCE), что вместо рыбки будет мусор из массива m_JunkTypes
Но нас интерисует условие
if (m_ActionDataFishing.m_IsSurfaceSea)
но! m_ActionDataFishing.m_IsSurfaceSea всегда true
Эта переменная в классе m_ActionDataFishing устанавливается таким макаром в SetupAction
vector pos_cursor = action_data.m_Target.GetCursorHitPos();
if (GetGame().SurfaceIsSea(pos_cursor[0],pos_cursor[2]))
{
FishingActionData.Cast(action_data).m_IsSurfaceSea = true;
}
однако на стороне сервера GetCursorHitPos() всегда вернет 0 0 0 - а там что? Море
потому m_IsSurfaceSea всегда true
Вобщем косяк разработчикив
Мы же организуем свою проверку и переустановим значение m_IsSurfaceSea, что бы оно соответствовало действительности, заодно поправим количество рыбки - не может же ловиться частично съеденная рыба +
уменьшим дамаг для крючка, удочки
Ну не может оно так дамажится как сейчас
Вобщем такой вот код - дебаг и тп не убираю сознательно
//FIX 12.12.2019
//AUTHOR: BORIZZ.K
modded class FishingActionData : ActionData
{
const float FISHING_DAMAGE = 1.0; //Fix hook damage
const bool MyFishingActionDebug = true;
bool m_IsSurfaceSea = false;
}
modded class ActionFishingNewCB : ActionContinuousBaseCB
{
override void HandleFishingResultSuccess()
{
if (!GetGame().IsMultiplayer() || GetGame().IsServer())
{
ItemBase fish;
if (!m_ActionDataFishing.m_Bait)
m_ActionDataFishing.InitBait(ItemBase.Cast(m_ActionDataFishing.m_MainItem.FindAttachmentBySlotName("Hook")));
if (!m_ActionDataFishing.IsBaitEmptyHook())
{
m_ActionDataFishing.m_Bait.AddHealth(-m_ActionDataFishing.FISHING_DAMAGE);
MiscGameplayFunctions.TurnItemIntoItem(m_ActionDataFishing.m_Bait,m_ActionDataFishing.m_Bait.ConfigGetString("hookType"),m_ActionDataFishing.m_Player);
}
else
{
m_ActionDataFishing.m_Bait.AddHealth(-m_ActionDataFishing.FISHING_DAMAGE * 2);
}
//Mod
m_ActionDataFishing.m_IsSurfaceSea = IsFishingOnSea(m_ActionDataFishing.m_Player)
if (m_ActionDataFishing.MyFishingActionDebug) CheckIsFishingOn(m_ActionDataFishing.m_Player);
float rnd = Math.RandomFloatInclusive(0.0,1.0);
if (rnd > m_ActionDataFishing.FISHING_GARBAGE_CHANCE)
{
//if (m_ActionDataFishing.m_IsSurfaceSea)
if (IsFishingOnSea(m_ActionDataFishing.m_Player)) //Call function with surface check
{
fish = ItemBase.Cast(GetGame().CreateObject("Mackerel",m_ActionDataFishing.m_Player.GetPosition(), false));
if (m_ActionDataFishing.MyFishingActionDebug) Print("::: SERVER: [ActionFishingNewCB]: HandleFishingResultSuccess(): Player: " + m_ActionDataFishing.m_Player.ToString() + ", Name: " + m_ActionDataFishing.m_Player.GetIdentity().GetName() + ", pos = " + m_ActionDataFishing.m_Player.GetPosition() + ", fish = Mackerel = " + fish);
}
else
{
fish = ItemBase.Cast(GetGame().CreateObject("Carp",m_ActionDataFishing.m_Player.GetPosition(), false));
if (m_ActionDataFishing.MyFishingActionDebug) Print("::: SERVER: [ActionFishingNewCB]: HandleFishingResultSuccess(): Player: " + m_ActionDataFishing.m_Player.ToString() + ", Name: " + m_ActionDataFishing.m_Player.GetIdentity().GetName() + ", pos = " + m_ActionDataFishing.m_Player.GetPosition() + ", fish = Carp = " + fish);
}
}
else
{
string junk_type = m_JunkTypes.Get(Math.RandomInt(0,m_JunkTypes.Count()));
fish = ItemBase.Cast(GetGame().CreateObject(junk_type,m_ActionDataFishing.m_Player.GetPosition(), false));
fish.SetHealth("","Health",fish.GetMaxHealth("","Health") * 0.1);
}
//Mod
if (fish)
{
fish.SetWet(0.3);
fish.PlaceOnSurface();
fish.SetOrientation(fish.GetOrientation());
if (fish.HasQuantity())
{
//Mod
if (fish.GetHealth() > (fish.GetMaxHealth() / 2)) //Fix fish quantity //If fish health > 1/2
{
fish.SetQuantity( fish.GetQuantityMax() );
}
else
{
//native
float coef = Math.RandomFloatInclusive(0.5, 1.0);
float item_quantity = fish.GetQuantityMax() * coef;
item_quantity = Math.Round(item_quantity);
fish.SetQuantity( item_quantity );
}
//Mod
}
fish.SetSynchDirty(); //Mod
}
m_ActionDataFishing.m_MainItem.AddHealth(-m_ActionDataFishing.FISHING_DAMAGE / 2);
}
}
bool IsFishingOnSea(PlayerBase player)
{
vector pos = player.GetPosition() + (player.GetDirection() * 5);
return GetGame().SurfaceIsSea(pos[0], pos[2]); //return true if sea
}
bool IsFishingOnPond(PlayerBase player) //Not used but let it be here
{
vector pos = player.GetPosition() + (player.GetDirection() * 5);
return GetGame().SurfaceIsPond(pos[0], pos[2]);
}
void CheckIsFishingOn(PlayerBase player)
{
vector pos = player.GetPosition() + (player.GetDirection() * 5);
bool s_sea = GetGame().SurfaceIsSea(pos[0], pos[2]);
bool s_pond = GetGame().SurfaceIsPond(pos[0], pos[2]);
string surface_type;
GetGame().SurfaceGetType(pos[0], pos[2], surface_type);
Print("::: SERVER: [ActionFishingNewCB]: CheckIsFishingOn: Player: " + player + ", Name: " + player.GetIdentity().GetName() + ", pos = " + pos + ": SurfaceIsSea = " + s_sea + " : SurfaceIsPond = " + s_pond + " >>> surface_type = " + surface_type + " >>> m_ActionDataFishing.m_IsSurfaceSea = " + m_ActionDataFishing.m_IsSurfaceSea);
}
}