[DGD]reset() and other banana peels...
Ludger Merkens
balduin at uni-paderborn.de
Wed Aug 23 15:17:50 CEST 2000
On Wed, 23 Aug 2000, Imo Wright wrote:
> >Sure, but it would probably help if you also told us what your >previous
> attempts have been like, idea, background, >implementation and their
> respective problems? :-)
>
> Hmm...I've tried implementing a counter that started ticking over as soon as
> the state of the object changed, as well as what you suggested about
> reset()-ing every time a user got near the object.
>
> What would be ideal would be to combine these approaches, because I don't
> want everything resetting immediately because of balance (60 odd people with
> the same hugely valuable weapon, for instance). It would probably save some
> CPU if I made it that everything had a standard heart_beat(), but it would
> still need to be called out x number of times for almost everything.
>
> What I am really looking for is a way to call reset() so that I could have a
> variable time without getting into a state where I have 1k counters running
> at the same time, which would be enough to crash even the most patient of
> dedicated machines. I'm probably missing some crucial function or
> flow-control principle that would make this possible, but some pointing in
> the right direction would help :).
>
> Thanks,
Well I will try to pict an approach that will work without call_outs at
all. I will call it lazy calculation or calculate on demand. To make it
work I have to make one assumtion. Reset is not used to message anything
to the player. If you really need messages thrown from reset_code, and
need the messages in time, you will have to go back to call_out.
Following scenario, you have a variable (say hitpoints), you have a
regeneration rate (say 20 per minute), and you need to every time the
current value of variable.
The approach is as follows, store a timestamp (time()) with the variable,
and when checking the variable recalculate it according
time-difference. Adding and Subtracting from the variable can be done
without changing the timestamp. (e.g. taking hit-points doesn't influence
your regeneration rate/time)
This approach also works fine for objects that regenerate also, you just
have to clone e.g. the gold-coin or your monster the moment the user
"contacts" them. (In this case sight would mean to "contact" them)
The basic hit-point example would look like:
int hp, hp_time;
int regeneration_rate; /* use float or second int for non integer values*/
int query_hp() {
int running;
int t;
t = time();
running = t - hp_time;
hp += running * regeneration_rate;
hp_time = t;
return hp
}
int heal_hp(int amount) {
hp += amount; /* add checks for range */
}
int take_hp(int amount) {
hp = query_hp();
hp -= amount();
/* probably add check_death_code(); */
}
When using this approch with inventories (e.g. the monster, coins example)
You need to find a clever mechanism to detect somebody touching the
inventory. A solution might be to register dynamic objects with call_back
functions in the container (e.g. the room) wich had to modify the
inventory before you return it's value.
e.g.
mapping dynamic_inv;
mixed inv; /* object * */
register_dynamic_object(string function)
{
if (!dynamic_inv) /* make this type save */
dynamic_inv = ([]);
dynamic_inv [ function ] = 1; /* call everythin only once */
}
mixed inventory()
{
mixed fun_table;
int i;
fun_table = m_indices(dynamic_inv);
for (i=0;i<sizeof(fun_table);i++)
call_other(this_object(), dynamic_inv[fun_table[i]]);
return inv;
}
a registered function would look much like the query_hp() function above,
but had to clone the monsters, coins etc. depending on the
regeneration-rate. enter_inv and leave_inv will just manipulate the inv
variable only.
Ok I quicktyped the functions, so there will be bugs and typos, all I did
was just to give you an idea what I mean.
There are lots of possibilities to optimize the code. Notice this approach
does not work, if you ever send a message from reset_code. Because it
would be send with improper timing. (Monsters given birth just when you
enter the room or look at it)
Ludger Merkens
(grumbel at xyllomer)
List config page: http://list.imaginary.com/mailman/listinfo/dgd
More information about the DGD
mailing list