Mercurial > hg > early-roguelike
view srogue/daemon.c @ 296:000b1c5b8d63
UltraRogue: fix inventory collision after save and restore.
Inventory letters are based on "identifiers" stored in objects' o_ident
field. Identifiers are allocated by get_ident(), which keeps a list of
objects that have them, to avoid giving the same identifier to multiple
objects.
The list is not stored in the savefile, so after restore, get_ident()
was not aware of existing identifiers. This resulted in picked-up
objects having the same inventory letters as objects restored from the
file.
The restore code now adds all objects with identifiers to the list.
author | John "Elwin" Edwards |
---|---|
date | Mon, 15 Jan 2018 20:20:35 -0500 |
parents | b67b99f6c92b |
children |
line wrap: on
line source
/* * Contains functions for dealing with things that * happen in the future. * * @(#)daemon.c 9.0 (rdk) 7/17/84 * * Super-Rogue * Copyright (C) 1984 Robert D. Kindelberger * All rights reserved. * * Based on "Rogue: Exploring the Dungeons of Doom" * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include "rogue.h" #include "rogue.ext" #define EMPTY 0 #define DAEMON -1 #define _X_ { 0, 0, 0, 0 } struct delayed_action d_list[MAXDAEMONS] = { _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, }; /* * d_insert: * Insert a function in the daemon list. */ struct delayed_action * d_insert(void (*func)(), int arg, int type, int time) { reg struct delayed_action *dev; if (demoncnt < MAXDAEMONS) { dev = &d_list[demoncnt]; dev->d_type = type; dev->d_time = time; dev->d_func = func; dev->d_arg = arg; demoncnt += 1; return dev; } return NULL; } void d_delete(struct delayed_action *wire) { reg struct delayed_action *d1, *d2; for (d1 = d_list; d1 < &d_list[demoncnt]; d1++) { if (wire == d1) { for (d2 = d1 + 1; d2 < &d_list[demoncnt]; d2++) *d1++ = *d2; demoncnt -= 1; d1 = &d_list[demoncnt]; d1->d_type = EMPTY; d1->d_func = EMPTY; return; } } } /* * find_slot: * Find a particular slot in the table */ struct delayed_action * find_slot(void (*func)()) { reg struct delayed_action *dev; for (dev = d_list; dev < &d_list[demoncnt]; dev++) if (dev->d_type != EMPTY && func == dev->d_func) return dev; return NULL; } /* * start_daemon: * Start a daemon, takes a function. */ void start_daemon(void (*func)(), int arg, int type) { d_insert(func, arg, type, DAEMON); } /* * do_daemons: * Run all the daemons that are active with the current * flag, passing the argument to the function. */ void do_daemons(int flag) { reg struct delayed_action *dev; for (dev = d_list; dev < &d_list[demoncnt]; dev++) if (dev->d_type == flag && dev->d_time == DAEMON) (*dev->d_func)(dev->d_arg); } /* * fuse: * Start a fuse to go off in a certain number of turns */ void fuse(void (*func)(), int arg, int time) { d_insert(func, arg, AFTER, time); } /* * lengthen: * Increase the time until a fuse goes off */ void lengthen(void (*func)(), int xtime) { reg struct delayed_action *wire; for (wire = d_list; wire < &d_list[demoncnt]; wire++) if (wire->d_type != EMPTY && func == wire->d_func) wire->d_time += xtime; } /* * extinguish: * Put out a fuse. Find all such fuses and kill them. */ void extinguish(void (*func)()) { reg struct delayed_action *dev; for (dev = d_list; dev < &d_list[demoncnt]; dev++) if (dev->d_type != EMPTY && func == dev->d_func) d_delete(dev); } /* * do_fuses: * Decrement counters and start needed fuses */ void do_fuses(void) { reg struct delayed_action *dev; for (dev = d_list; dev < &d_list[demoncnt]; dev++) { if (dev->d_type == AFTER && dev->d_time > DAEMON) { if (--dev->d_time == 0) { (*dev->d_func)(dev->d_arg); d_delete(dev); } } } } /* * activity: * Show wizard number of demaons and memory blocks used */ void activity(void) { msg("Daemons = %d : Memory Items = %d : Memory Used = %d", demoncnt,total,md_memused()); }