Files

154 lines
4.4 KiB
C#

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class Plant : MonoBehaviour
{
private float health;
public float growthRate;
public float nutrientsConsumed;
public float maxSize;
public float size;
public float reproductionChance;
public bool isAlive;
public bool isReproducing;
public GameObject visualPrefab;
public GameObject visual;
public float availNutrients;
public void SetVisual(GameObject visualPrefab)
{
this.visualPrefab = visualPrefab;
}
public void SetValues(float growthRate, float maxSize, float reproductionChance)
{
health = 10;
this.growthRate = growthRate;
this.maxSize = maxSize;
this.reproductionChance = reproductionChance;
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
private void Start()
{
visual = Instantiate(visualPrefab, transform);
nutrientsConsumed = 0;
isAlive = true;
size = 1f;
}
// Update is called once per frame
void Update()
{
}
public void Step(float dTime)
{
Terrain terrain = Core.instance.ground;
float xPosition = transform.position.x / terrain.terrainData.size.x;
float zPosition = transform.position.z / terrain.terrainData.size.z;
NutrientController nutrientCont = Core.instance.nutrientCont;
if (size >= maxSize)
{
TryReproduce(dTime, nutrientCont, xPosition, zPosition);
}
else
{
if(size > maxSize * 0.67f && Random.value > 0.5f)
{
TryReproduce(dTime, nutrientCont, xPosition, zPosition);
}
else
{
Grow(dTime, nutrientCont, xPosition, zPosition);
}
}
if (health <= 0)
{
isAlive = false;
nutrientCont.AddNutrients(xPosition, zPosition, nutrientsConsumed * 0.9f, size);
}
}
private void TryReproduce(float dTime, NutrientController nutrientCont, float xPosition, float zPosition)
{
if(reproductionChance >= 1)
{
ReproduceSuccess(dTime, nutrientCont, xPosition, zPosition);
}
else
{
float stepChance = reproductionChance * dTime;
if(Random.value < stepChance)
{
ReproduceSuccess(dTime, nutrientCont, xPosition, zPosition);
}
}
}
private void ReproduceSuccess(float dTime, NutrientController nutrientCont, float xPosition, float zPosition)
{
float stepGrowthRate = maxSize - Mathf.Pow(size, 2);
stepGrowthRate *= growthRate;
stepGrowthRate *= dTime;
float stepNutrientCost = (stepGrowthRate / 2) + 0.5f;
float nutrientDeficit = nutrientCont.PlantNutrientUse(xPosition, zPosition, size, stepNutrientCost);
// Take damage if there aren't enough nutrients to reproduce
if(nutrientDeficit > 0)
{
health -= nutrientDeficit;
}
isReproducing = true;
}
private void Grow(float dTime, NutrientController nutrientCont, float xPosition, float zPosition)
{
float stepGrowthRate = maxSize - Mathf.Pow(size, 2);
stepGrowthRate *= growthRate;
stepGrowthRate *= dTime;
float stepNutrientCost = (stepGrowthRate / 2) + 0.5f;
float nutrientDeficit = nutrientCont.PlantNutrientUse(xPosition, zPosition, size, stepNutrientCost);
if (nutrientDeficit > 0)
{
health -= nutrientDeficit * dTime;
nutrientsConsumed += stepNutrientCost - nutrientDeficit;
}
else
{
nutrientsConsumed += stepNutrientCost;
size += stepGrowthRate;
GrowVisual(stepGrowthRate);
}
}
private void OnDrawGizmos()
{
Vector3 camPos = SceneView.currentDrawingSceneView.camera.transform.position;
if(Vector3.Distance(camPos, this.transform.position) > 15 * visual.transform.localScale.x)
{
return;
}
GUIStyle big = new GUIStyle();
big.fontSize = 50;
big.normal.textColor = Color.purple;
Handles.Label(transform.position, $"Health: {health}", big);
}
void GrowVisual(float growthAmount)
{
visual.transform.localScale += visual.transform.localScale * growthAmount;
}
}