/*
* heatable.c - a first attempt at a transient object that reacts to heat
*/
inherit "/obj/reagents/transient";
// phase is a two-element array. Each element is of the form:
// ({ (int) temp, (string) final, (string) result,
// (string) result_alias, (float) result_amt, (mixed) progress_msg })
// where tempi is the temp at which the change occurs; the other parameters
// are the same as for a normal transient.
// The first element is for the lower temp, and the second is for the
// higher temp.
//
// Currently, progress messages aren't supported.
mixed phase;
float tau = 100.0;
int last_T, last_time = 0, last_idx = -1;
int tot_heat;
void set_phase(mixed p) { phase = p; }
mixed query_phase() { return phase; }
void set_tau(float t) { tau = t; }
float query_tau() { return tau; }
int query_tot_heat() { return tot_heat; }
void start_reaction() {
// This does nothing if called from outside
return;
}
void init_heat(int h) {
last_T = h;
last_time = time();
tell_object(find_player("jeremy"), file_name(this_object()) +
": in init_heat("+h+","+last_time+")...\n");
}
object morph() {
object ob;
int idx;
idx = last_idx;
ob = ::morph();
ob->init_heat(phase[idx][0]);
ob->apply_heat(0);
return ob;
}
void apply_heat(int heat) {
int T0, T1, dt, idx;
// This is the best way I could think of to initialize it...
// It implies that the phase-change temp of the "parent" object
// should be between the extremes of this one.
tell_object(find_player("jeremy"), file_name(this_object()) +
": last_time = " + last_time + "\n");
// if (!last_time) {
// tell_object(find_player("jeremy"), file_name(this_object()) +
// ": initializing to "+heat+"...\n");
// tot_heat = heat;
// last_T = heat;
// last_time = time();
// return;
// }
//if (!heat) return;
tot_heat += heat;
if (phase[0] && (tot_heat <= phase[0][0]))
idx = 0;
else if (phase[1] && (tot_heat >= phase[1][0]))
idx = 1;
else
idx = -1;
stop_reaction();
printf("lt-t()=%d,nth=%d,lT=%d\n", last_time-time(), tot_heat,
last_T);
T0 = to_int((1.0 - exp((last_time-time())/tau))
* (tot_heat - heat - last_T) + last_T);
if (idx >= 0 ) {
T1 = phase[idx][0];
dt = to_int(tau * log((to_float(tot_heat) - T0)
/ (to_float(tot_heat) - T1)) + 0.5);
if (idx != last_idx) {
set_final(phase[idx][1]);
set_result(phase[idx][2]);
set_result_alias(phase[idx][3]);
set_result_amt(phase[idx][4]);
set_progress_msg(phase[idx][5]);
}
set_duration(dt);
restart_reaction();
}
printf("dt = %d, T0 = %d, T1 = %d, tau = %f, phase_idx = %O\n",
dt, T0, T1, tau, idx);
last_T = T0;
last_time = time();
last_idx = idx;
}
mapping int_query_static_auto_load() {
return ([
"::": ::int_query_static_auto_load(),
]);
} /* int_query_static_auto_load() */
mapping query_static_auto_load() {
if ( file_name( this_object() )[ 0 .. 21 ] == "/obj/reagents/heatable" )
return int_query_static_auto_load();
return 0;
} /* query_static_auto_load() */
void init_static_arg( mapping map ) {
if ( map[ "::" ] )
::init_static_arg( map[ "::" ] );
} /* init_static_arg() */