package org.nusco.narjillos.core.things;

import org.nusco.narjillos.core.configuration.Configuration;
import org.nusco.narjillos.core.utilities.NumberFormatter;

public class LifeFormEnergy implements Energy {

	private final double initialValue;

	private double value;

	private double maxForAge;

	private final double decay;

	// for deserialization only
	public LifeFormEnergy() {
		initialValue = decay = 0;
	}

	public LifeFormEnergy(double initialValue, double lifespan) {
		this.initialValue = initialValue;
		this.value = this.initialValue;
		this.maxForAge = this.initialValue * Configuration.CREATURE_MAX_ENERGY_TO_INITIAL_ENERGY;
		this.decay = maxForAge / lifespan;
	}

	@Override
	public double getValue() {
		return value;
	}

	@Override
	public double getMaximumValue() {
		return maxForAge;
	}

	@Override
	public boolean isZero() {
		return value <= 0;
	}

	@Override
	public void tick(double additionalEnergy) {
		if (maxForAge >= 0)
			maxForAge -= decay;

		increaseBy(additionalEnergy);
	}

	@Override
	public void increaseBy(double amount) {
		if (isZero())
			return; // once it's gone, it's gone

		value += amount;
		value = Math.max(0, Math.min(maxForAge, Math.max(0, value)));
	}

	@Override
	public void absorb(Energy other) {
		increaseBy(other.getValue());
		other.dropToZero();
	}

	@Override
	public void dropToZero() {
		value = 0;
	}

	@Override
	public void damage() {
		if (value < 10)
			increaseBy(-1);
		else
			value = value * 0.9;
	}

	@Override
	public int hashCode() {
		return (int) initialValue;
	}

	@Override
	public boolean equals(Object obj) {
		LifeFormEnergy other = (LifeFormEnergy) obj;
		return Double.doubleToLongBits(decay) == Double.doubleToLongBits(other.decay)
			&& Double.doubleToLongBits(initialValue) == Double.doubleToLongBits(other.initialValue)
			&& Double.doubleToLongBits(maxForAge) == Double.doubleToLongBits(other.maxForAge)
			&& Double.doubleToLongBits(value) == Double.doubleToLongBits(other.value);
	}

	@Override
	public String toString() {
		return NumberFormatter.format(getValue()) + " of " + NumberFormatter.format(getMaximumValue());
	}
}

@@ -689,32 +689,45 @@
 verride%0A%09public 
+synchronized 
 double getValue(
@@ -769,16 +769,29 @@
 %09public 
+synchronized 
 double g
@@ -844,32 +844,45 @@
 verride%0A%09public 
+synchronized 
 boolean isZero()
@@ -924,24 +924,37 @@
 ide%0A%09public 
+synchronized 
 void tick(do
@@ -1075,24 +1075,37 @@
 ide%0A%09public 
+synchronized 
 void increas
@@ -1284,24 +1284,37 @@
 ide%0A%09public 
+synchronized 
 void absorb(
@@ -1402,24 +1402,37 @@
 ide%0A%09public 
+synchronized 
 void dropToZ
@@ -1475,16 +1475,29 @@
 %09public 
+synchronized 
 void dam

Synchronize Energy