154 lines
3.9 KiB
C#
154 lines
3.9 KiB
C#
using System;
|
|
|
|
public class SurvivalState
|
|
{
|
|
private const float HungerDrainPerSecond = 0.012f;
|
|
private const float ThirstDrainPerSecond = 0.018f;
|
|
private const float PassiveEnergyDrainPerSecond = 0.01f;
|
|
private const float AutoConsumeThreshold = 30f;
|
|
private const double GracePeriodSeconds = 900.0;
|
|
|
|
public float hunger = 100f;
|
|
public float thirst = 100f;
|
|
public float energy = 100f;
|
|
|
|
public float maxHunger = 100f;
|
|
public float maxThirst = 100f;
|
|
public float maxEnergy = 100f;
|
|
|
|
public bool isDead = false;
|
|
public string deathReason = "";
|
|
public string currentStatus = "";
|
|
public double elapsedSeconds = 0;
|
|
public bool gracePeriodEnabled = true;
|
|
|
|
public void Update(double delta)
|
|
{
|
|
if (isDead) return;
|
|
|
|
elapsedSeconds += delta;
|
|
float drainModifier = IsInGracePeriod() ? 0.35f : 1f;
|
|
|
|
hunger = Math.Clamp(hunger - HungerDrainPerSecond * drainModifier * (float)delta, 0f, maxHunger);
|
|
thirst = Math.Clamp(thirst - ThirstDrainPerSecond * drainModifier * (float)delta, 0f, maxThirst);
|
|
energy = Math.Clamp(energy - PassiveEnergyDrainPerSecond * drainModifier * (float)delta, 0f, maxEnergy);
|
|
|
|
TryAutoConsumeFood();
|
|
TryAutoConsumeWater();
|
|
TryAutoConsumeEnergy();
|
|
UpdateStatus();
|
|
CheckDeath();
|
|
}
|
|
|
|
public bool TryConsumeEnergy(float amount)
|
|
{
|
|
if (amount <= 0f) return true;
|
|
if (energy < amount) return false;
|
|
|
|
energy -= amount;
|
|
return true;
|
|
}
|
|
|
|
private void TryAutoConsumeFood()
|
|
{
|
|
if (hunger > AutoConsumeThreshold) return;
|
|
if (!GameData.inventory.TryRemoveItem("mushroom", 1)) return;
|
|
|
|
hunger = Math.Clamp(hunger + 45f, 0f, maxHunger);
|
|
}
|
|
|
|
private void TryAutoConsumeWater()
|
|
{
|
|
if (thirst > AutoConsumeThreshold) return;
|
|
if (!GameData.inventory.TryRemoveItem("water", 1)) return;
|
|
|
|
thirst = Math.Clamp(thirst + 50f, 0f, maxThirst);
|
|
}
|
|
|
|
private void TryAutoConsumeEnergy()
|
|
{
|
|
if (energy > AutoConsumeThreshold) return;
|
|
|
|
if (GameData.inventory.TryRemoveItem("battery_v2", 1))
|
|
{
|
|
energy = Math.Clamp(energy + 90f, 0f, maxEnergy);
|
|
return;
|
|
}
|
|
|
|
if (GameData.inventory.TryRemoveItem("battery_v1", 1))
|
|
{
|
|
energy = Math.Clamp(energy + 65f, 0f, maxEnergy);
|
|
return;
|
|
}
|
|
|
|
if (GameData.inventory.TryRemoveItem("steam", 1))
|
|
{
|
|
energy = Math.Clamp(energy + 40f, 0f, maxEnergy);
|
|
}
|
|
}
|
|
|
|
private void UpdateStatus()
|
|
{
|
|
if (hunger <= AutoConsumeThreshold)
|
|
{
|
|
currentStatus = "Food supply critical";
|
|
return;
|
|
}
|
|
|
|
if (thirst <= AutoConsumeThreshold)
|
|
{
|
|
currentStatus = "Water supply critical";
|
|
return;
|
|
}
|
|
|
|
if (energy <= AutoConsumeThreshold)
|
|
{
|
|
currentStatus = "Energy reserves critical";
|
|
return;
|
|
}
|
|
|
|
currentStatus = "Survival stable";
|
|
}
|
|
|
|
private void CheckDeath()
|
|
{
|
|
if (IsInGracePeriod())
|
|
{
|
|
hunger = Math.Max(hunger, 1f);
|
|
thirst = Math.Max(thirst, 1f);
|
|
energy = Math.Max(energy, 1f);
|
|
return;
|
|
}
|
|
|
|
if (hunger <= 0f)
|
|
{
|
|
KillPlayer("Starved");
|
|
return;
|
|
}
|
|
|
|
if (thirst <= 0f)
|
|
{
|
|
KillPlayer("Died of thirst");
|
|
return;
|
|
}
|
|
|
|
if (energy <= 0f)
|
|
{
|
|
KillPlayer("Life support lost power");
|
|
}
|
|
}
|
|
|
|
private void KillPlayer(string reason)
|
|
{
|
|
isDead = true;
|
|
deathReason = reason;
|
|
currentStatus = "Survival failed: " + reason;
|
|
GameData.canMove = false;
|
|
}
|
|
|
|
private bool IsInGracePeriod()
|
|
{
|
|
return gracePeriodEnabled && elapsedSeconds < GracePeriodSeconds;
|
|
}
|
|
}
|