class CatchingContextFishingRodAction : CatchingContextFishingBase
{
protected PlayerBase m_Player;
//chances + modifiers
protected float m_BaitLossChanceMod;
protected float m_HookLossChanceMod;
//times
protected float m_SignalDurationMin; //seconds
protected float m_SignalDurationMax; //seconds
protected float m_SignalStartTimeMin; //seconds
protected float m_SignalStartTimeMax; //seconds
//signal targets
protected float m_SignalCycleTarget;
protected float m_SignalCycleEndTarget;
protected float m_SignalCycleTargetAdjustment;
protected float m_SignalCycleTargetEndAdjustment;
//signal targets - constant
protected float m_SignalTargetProbability;
protected float m_SignalTargetEndProbability;
//misc
protected int m_SignalCurrent;
//important items
protected EntityAI m_Hook;
protected EntityAI m_Bait;
protected EntityAI m_Rod;
override protected void Init(Param par)
{
super.Init(par);
m_Rod = m_MainItem; //only stable one, rest initialized on 'InitItemValues' periodically
m_Player = PlayerBase.Cast(m_MainItem.GetHierarchyRootPlayer());
}
override protected void InitCatchMethodMask()
{
m_MethodMask = AnimalCatchingConstants.MASK_METHOD_ROD;
}
override protected void InitCatchEnviroMask()
{
if (m_IsSea)
m_EnviroMask = AnimalCatchingConstants.MASK_ENVIRO_SEA;
else
m_EnviroMask = AnimalCatchingConstants.MASK_ENVIRO_POND;
}
override protected void CreateResultDataStructure()
{
m_Result = new CarchingResultFishingAction(m_MainItem);
super.CreateResultDataStructure();
}
//! only clear stuff you need to update
override protected void ClearCatchingItemData()
{
super.ClearCatchingItemData();
ResetSignalCounter();
m_HookLossChanceMod = 0.0;
m_BaitLossChanceMod = 0.0;
m_SignalDurationMin = -1;
m_SignalDurationMax = -1;
m_SignalStartTimeMin = -1;
m_SignalStartTimeMax = -1;
m_SignalCycleTarget = UAFishingConstants.SIGNAL_CYCLE_MEAN_DEFAULT - 1; //lowered by '1', configured value is count
m_SignalCycleEndTarget = UAFishingConstants.SIGNAL_CYCLE_HARD_TARGET_DEFAULT - 1; //lowered by '1', configured value is count
m_SignalTargetProbability = UAFishingConstants.SIGNAL_MEAN_CHANCE_DEFAULT;
m_SignalTargetEndProbability = UAFishingConstants.SIGNAL_HARD_TARGET_CHANCE_DEFAULT;
m_SignalCycleTargetAdjustment = 0.0;
m_SignalCycleTargetEndAdjustment = 0.0;
}
override void InitCatchingItemData()
{
super.InitCatchingItemData();
//sanitize fishing values
if (m_SignalDurationMin == -1) //if not set by any item
m_SignalDurationMin = UAFishingConstants.SIGNAL_DURATION_MIN_BASE;
else
m_SignalDurationMin = Math.Clamp(m_SignalDurationMin,UAFishingConstants.SIGNAL_DURATION_MIN_BASE,UAFishingConstants.SIGNAL_DURATION_MAX_BASE);
if (m_SignalDurationMax == -1) //if not set by any item
m_SignalDurationMax = UAFishingConstants.SIGNAL_DURATION_MAX_BASE;
else
m_SignalDurationMax = Math.Clamp(m_SignalDurationMax,UAFishingConstants.SIGNAL_DURATION_MIN_BASE,UAFishingConstants.SIGNAL_DURATION_MAX_BASE);
if (m_SignalStartTimeMin == -1) //if not set by any item (else already clamped)
m_SignalStartTimeMin = UAFishingConstants.SIGNAL_START_TIME_MIN_BASE;
if (m_SignalStartTimeMax == -1) //if not set by any item (else already clamped)
m_SignalStartTimeMax = UAFishingConstants.SIGNAL_START_TIME_MAX_BASE;
m_SignalCycleTarget = Math.Clamp((m_SignalCycleTarget + m_SignalCycleTargetAdjustment),0,float.MAX);
m_SignalCycleEndTarget = Math.Clamp((m_SignalCycleEndTarget + m_SignalCycleTargetEndAdjustment),(m_SignalCycleTarget + 1),float.MAX);
#ifdef DEVELOPER
if (IsCLIParam("fishingLogs"))
{
Debug.Log("---InitCatchingItemData---","Fishing");
Debug.Log("m_SignalCycleTarget (adjusted): " + m_SignalCycleTarget,"Fishing");
Debug.Log("m_SignalCycleTargetAdjustment: " + m_SignalCycleTargetAdjustment,"Fishing");
Debug.Log("m_SignalTargetProbability: " + m_SignalTargetProbability,"Fishing");
Debug.Log("m_SignalCycleEndTarget (adjusted): " + m_SignalCycleEndTarget,"Fishing");
Debug.Log("m_SignalCycleTargetEndAdjustment: " + m_SignalCycleTargetEndAdjustment,"Fishing");
Debug.Log("m_SignalTargetEndProbability: " + m_SignalTargetEndProbability,"Fishing");
Debug.Log("m_SignalDurationMin: " + m_SignalDurationMin,"Fishing");
Debug.Log("m_SignalDurationMax: " + m_SignalDurationMax,"Fishing");
Debug.Log("m_SignalStartTimeMin: " + m_SignalStartTimeMin,"Fishing");
Debug.Log("m_SignalStartTimeMax: " + m_SignalStartTimeMax,"Fishing");
}
#endif
}
override protected void InitItemValues(EntityAI item)
{
//skip ruined or deleted items entirely
if (item.IsRuined() || item.IsSetForDeletion())
return;
string path = "" + CFG_VEHICLESPATH + " " + item.GetType() + " Fishing";
if (g_Game.ConfigIsExisting(path))
{
if (g_Game.ConfigIsExisting(path + " resultQuantityBaseMod"))
m_QualityBaseMod += g_Game.ConfigGetFloat(path + " resultQuantityBaseMod");
if (g_Game.ConfigIsExisting(path + " resultQuantityDispersionMin"))
m_QualityDispersionMinMod += g_Game.ConfigGetFloat(path + " resultQuantityDispersionMin");
if (g_Game.ConfigIsExisting(path + " resultQuantityDispersionMax"))
m_QualityDispersionMaxMod += g_Game.ConfigGetFloat(path + " resultQuantityDispersionMax");
if (g_Game.ConfigIsExisting(path + " hookLossChanceMod"))
m_HookLossChanceMod += g_Game.ConfigGetFloat(path + " hookLossChanceMod");
if (g_Game.ConfigIsExisting(path + " baitLossChanceMod"))
m_BaitLossChanceMod += g_Game.ConfigGetFloat(path + " baitLossChanceMod");
if (g_Game.ConfigIsExisting(path + " signalDurationMin"))
{
if (m_SignalDurationMin == -1)
m_SignalDurationMin = 0;
m_SignalDurationMin += g_Game.ConfigGetFloat(path + " signalDurationMin");
}
if (g_Game.ConfigIsExisting(path + " signalDurationMax"))
{
if (m_SignalDurationMax == -1)
m_SignalDurationMax = 0;
m_SignalDurationMax += g_Game.ConfigGetFloat(path + " signalDurationMax");
}
if (g_Game.ConfigIsExisting(path + " signalCycleTargetAdjustment"))
m_SignalCycleTargetAdjustment += g_Game.ConfigGetFloat(path + " signalCycleTargetAdjustment");
if (g_Game.ConfigIsExisting(path + " signalCycleTargetEndAdjustment"))
m_SignalCycleTargetEndAdjustment += g_Game.ConfigGetFloat(path + " signalCycleTargetEndAdjustment");
int slotID;
string slotName;
if (item.GetInventory().GetCurrentAttachmentSlotInfo(slotID,slotName))
{
switch (slotName)
{
case "Bait":
m_Bait = item;
break;
case "Hook":
m_Hook = item;
break;
}
}
}
}
override bool ModifySignalProbability(inout float probability)
{
float easingTime;
if ((float)m_SignalCurrent < m_SignalCycleTarget)
{
easingTime = Math.InverseLerp(0,m_SignalCycleTarget,(float)m_SignalCurrent);
probability = Easing.EaseInExpo(easingTime) * m_SignalTargetProbability * GetChanceCoef();
}
else
{
easingTime = Math.InverseLerp(m_SignalCycleTarget,m_SignalCycleEndTarget,(float)m_SignalCurrent);
probability = (m_SignalTargetProbability + (Easing.EaseInExpo(easingTime) * (m_SignalTargetEndProbability - m_SignalTargetProbability))) * GetChanceCoef();
}
#ifdef DEVELOPER
// Needs to be revisited, won't work when the autotests run inside of workbench
if (IsCLIParam("autotest"))
probability = UAFishingConstants.DEBUG_FISHING_CHANCE_PROBABILITY;
if (IsCLIParam("fishingLogs"))
{
Debug.Log("---ModifySignalProbability---","Fishing");
Debug.Log("m_SignalCurrent: " + m_SignalCurrent,"Fishing");
Debug.Log("easingTime: " + easingTime,"Fishing");
Debug.Log("probability: " + probability,"Fishing");
}
#endif
return true;
}
float GetChanceCoef()
{
return UAFishingConstants.SIGNAL_FISHING_CHANCE_COEF;
}
override bool RollCatch()
{
bool ret = super.RollCatch();
m_SignalCurrent++;
return ret;
}
protected void ResetSignalCounter()
{
m_SignalCurrent = 0.0;
}
//! done locally on both sides, needs a synced random
override void GenerateResult()
{
YieldItemBase yItem;
int idx = m_Player.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAnimalCatching,0,m_ProbabilityArray.Count() - 1);
Class.CastTo(yItem,m_YieldsMapAll.Get(m_ProbabilityArray[idx]));
m_Result.SetYieldItem(yItem);
}
int GetResultParticleId()
{
if (m_Result)
return m_Result.GetYieldItemParticleId();
return ParticleList.INVALID;
}
override protected void RecalculateProcessingData()
{
m_Result.UpdateCatchChance(this);
}
float GetHookLossChanceModifierClamped()
{
return Math.Clamp(m_HookLossChanceMod,0.001,1);
}
float GetBaitLossChanceModifierClamped()
{
return Math.Clamp(m_BaitLossChanceMod,0,1);
}
float GetActionCycleTime()
{
return CarchingResultFishingAction.Cast(m_Result).GetCurrentCycleTime(this);
}
float RandomizeSignalDuration()
{
float res = m_Player.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAnimalCatching,m_SignalDurationMin,m_SignalDurationMax);
#ifdef DEVELOPER
if (IsCLIParam("fishingLogs"))
{
Debug.Log("---RandomizeSignalDuration---","Fishing");
Debug.Log("next signal duration: " + res,"Fishing");
}
#endif
return res;
}
float RandomizeSignalStartTime()
{
float res = m_Player.GetRandomGeneratorSyncManager().GetRandomInRange(RandomGeneratorSyncUsage.RGSAnimalCatching,m_SignalStartTimeMin,m_SignalStartTimeMax);
#ifdef DEVELOPER
if (IsCLIParam("fishingLogs"))
{
Debug.Log("---RandomizeSignalStartTime---","Fishing");
Debug.Log("next signal start time: " + res,"Fishing");
}
#endif
return res;
}
protected void TryHookLoss()
{
if (m_Hook && !m_Hook.IsSetForDeletion())
{
float lossChance = GetHookLossChanceModifierClamped();
if (lossChance <= 0)
return;
float roll = m_Player.GetRandomGeneratorSyncManager().GetRandom01(RandomGeneratorSyncUsage.RGSAnimalCatching);
if (lossChance >= 1 || roll < lossChance)
{
RemoveItemSafe(m_Hook);
}
}
}
protected void RemoveItemSafe(EntityAI item)
{
if (item && !m_Player.IsQuickFishing())
{
item.SetPrepareToDelete(); //should probably flag the bait too, but the action terminates anyway
item.DeleteSafe();
}
}
protected void TryBaitLoss()
{
if (m_Bait && !m_Bait.IsSetForDeletion())
{
float lossChance = GetBaitLossChanceModifierClamped();
if (lossChance <= 0)
return;
float roll = m_Player.GetRandomGeneratorSyncManager().GetRandom01(RandomGeneratorSyncUsage.RGSAnimalCatching);
if (lossChance >= 1 || roll < lossChance)
{
RemoveItemSafe(m_Bait);
}
}
}
protected void TryDamageItems()
{
if (!g_Game.IsMultiplayer() || g_Game.IsDedicatedServer())
{
if (m_Hook && !m_Hook.IsSetForDeletion())
m_Hook.AddHealth("","Health",-UAFishingConstants.DAMAGE_HOOK);
}
}
override EntityAI SpawnAndSetupCatch(out int yItemIdx, vector v = vector.Zero)
{
//hook check on catch
if (m_Hook && !m_Hook.IsSetForDeletion())
return super.SpawnAndSetupCatch(yItemIdx,v);
return null;
}
//events
void OnBeforeSpawnSignalHit()
{
TryHookLoss();
}
void OnAfterSpawnSignalHit()
{
RemoveItemSafe(m_Bait);
TryDamageItems();
}
//! release without signal
void OnSignalMiss()
{
TryHookLoss();
TryBaitLoss();
}
void OnSignalPass()
{
RemoveItemSafe(m_Bait);
TryDamageItems();
UpdateCatchingItemData();
}
///////////////////////////////
//Fish pen of deprecated code//
///////////////////////////////
protected float m_SignalPoissonMean = AnimalCatchingConstants.POISSON_CYCLE_MEAN_DEFAULT; //!Deprecated, left here due to inheritance change
float GetSignalPoissonMean() {return m_SignalPoissonMean;} //!Deprecated, left here due to inheritance change
int GetSignalMax() {return Math.Ceil(m_SignalPoissonMean) + Math.Ceil(m_SignalPoissonMean/5);} //!Deprecated, left here due to inheritance change
}