package affectors; import main.Node; import main.Globals; /** An artificial Affector which sets nodes to specific values. See DefinedValuesAff for more information. This one only operates according to a second "indicator" node. If the indicator is > 0.5 in a cell, then this affector will change the value of its target node in that cell. If the indicator is < 0.5, this affector does nothing.

Formula
dnodex/dt = 0 | before first_time
dnodex/dt = (second_value - initial_value) / (second_time - first_time) | between first and second times
dnodex/dt = 0 | between second and third times
dnodex/dt = (third_value - second_value) / (fourth_time - third_time) | between third and fourth times
dnodex/dt = 0 | after fourth_time

Parameters
Target [nodex] The Node which this Affector is acting on
Indicator node [nodex] The Node which this Affector is acting on
First time [first_t] See formula above
Second time [second_t] See formula above
Third time [third_t] See formula above
Fourth time [fourth_t] See formula above
Second value [second_v] See formula above
Third value [third_v] See formula above

Usage
&nodex

&DefinedValuesAff nodex indicator_node first_t second_t third_t fourth_t second_v third_v
&endnodex */ public class DefinedValuesIndicatorAff extends Affector { int firstTime, secondTime, thirdTime, fourthTime, secondValue, thirdValue; float initValue; static final String desc = "Rises and/or falls to defined values at given speeds"; static final String [] nodeDescriptions = {"Target", "IndicatorNode"}; static final String [] paramDescriptions = {"First time", "Second time", "Third time", "Fourth time", "Second value", "Third value"}; static final int [] whichSides = { -1, -1 }; public DefinedValuesIndicatorAff() {} protected void setLabelsAndTypes() { setDescriptions(this.desc, nodeDescriptions, paramDescriptions); setSided(true, whichSides); setContainsTarget(true); this.Type[GUI_CAPABLE] = 1; this.Type[CERTIFICATION] = Affector.RETURNS_DERIV; this.Type[MATHTYPE] = Affector.CC; this.Type[TERMTYPE] = Affector.DEGRADATION; } public void setParameterNumbers(int [] param_nums) { firstTime = param_nums[0]; secondTime = param_nums[1]; thirdTime = param_nums[2]; fourthTime = param_nums[3]; secondValue = param_nums[4]; thirdValue = param_nums[5]; } public float getValue(Node which_node) { float val; // Get the initial value - not totally clean, but should work if(Globals.time == 0) { initValue = Nodes[0].getValue(side); } // If the indicator node is < 0.5, leave things alone if(Nodes[1].getIntegrationValue() < 0.5) { val = 0; } else if(Globals.time < params[firstTime]) { val = 0.0f; } else if(Globals.time >= params[firstTime] && Globals.time < params[secondTime]) { val = Globals.characteristicTime * (params[secondValue] - initValue) / (params[secondTime] - params[firstTime]); } else if(Globals.time >= params[secondTime] && Globals.time < params[thirdTime]) { val = 0f; } else if(Globals.time >= params[thirdTime] && Globals.time < params[fourthTime]) { val = Globals.characteristicTime * (params[thirdValue] - params[secondValue]) / (params[fourthTime] - params[thirdTime]); } else { val = Globals.characteristicTime * (params[thirdValue] - Nodes[0].getIntegrationValue(side)); } return val; } }