/* * $Id: map.dynamic.c,v 1.1.1.1 2005/01/11 21:18:08 kstevens Exp $ * * Author: Markus Stenberg <fingon@iki.fi> * * Copyright (c) 1996 Markus Stenberg * Copyright (c) 1998-2002 Thomas Wouters * Copyright (c) 2000-2002 Cord Awtry * All rights reserved * * Created: Sun Oct 13 19:38:31 1996 fingon * Last modified: Sun Jun 14 14:54:11 1998 fingon * */ #include <stdio.h> #include "create.h" #include "mech.h" #include "autopilot.h" #include "p.econ_cmds.h" #include "p.mech.restrict.h" #include "p.mech.utils.h" #include "p.map.conditions.h" #define DYNAMIC_MAGIC 42 /* Code for saving / loading / setting / unsetting the dynamic pieces of map structure: - mechsOnMap - LOSinfo - mechflags */ #define CHELO(a,b,c,d) if (!(ugly_kludge++)) { \ if ((tmp=fread(a,b,c,d)) != c) { fprintf (stderr, "Error loading mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); return; } } else { if ((tmp=fread(a,b,c,d)) != c) { fprintf (stderr, "Error loading mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); fflush(stderr); exit(1); } } #define CHESA(a,b,c,d) if ((tmp=fwrite(a,b,c,d)) != c) { fprintf (stderr, "Error writing mapdynamic for #%d - couldn't find enough entries! (found: %d, should: %d)\n", map->mynum, tmp, c); fflush(stderr); exit(1); } static int ugly_kludge = 0; /* Nonfatal for _first_ */ void load_mapdynamic(FILE * f, MAP * map) { int count = map->first_free; int i, tmp; unsigned char tmpb; if (count > 0) { Create(map->mechsOnMap, dbref, count); CHELO(map->mechsOnMap, sizeof(map->mechsOnMap[0]), count, f); Create(map->mechflags, char, count); CHELO(map->mechflags, sizeof(map->mechflags[0]), count, f); Create(map->LOSinfo, unsigned short *, count); for (i = 0; i < count; i++) { Create(map->LOSinfo[i], unsigned short, count); CHELO(map->LOSinfo[i], sizeof(map->LOSinfo[i][0]), count, f); } } else { map->mechsOnMap = NULL; map->mechflags = NULL; map->LOSinfo = NULL; } CHELO(&tmpb, 1, 1, f); if (tmpb != DYNAMIC_MAGIC) { fprintf(stderr, "Error reading data for obj #%d (%d != %d)!\n", map->mynum, tmpb, DYNAMIC_MAGIC); fflush(stderr); exit(1); } } #define outbyte(a) tmpb=(a);CHESA(&tmpb, 1, 1, f); void save_mapdynamic(FILE * f, MAP * map) { int count = map->first_free; int i, tmp; unsigned char tmpb; if (count > 0) { CHESA(map->mechsOnMap, sizeof(map->mechsOnMap[0]), count, f); CHESA(map->mechflags, sizeof(map->mechflags[0]), count, f); for (i = 0; i < count; i++) CHESA(map->LOSinfo[i], sizeof(map->LOSinfo[i][0]), count, f); } outbyte(DYNAMIC_MAGIC); } void mech_map_consistency_check(MECH * mech) { MAP *map = getMap(mech->mapindex); if (!map) { if (mech->mapindex > 0) { mech->mapindex = -1; fprintf(stderr, "#%d on nonexistent map - removing..\n", mech->mynum); } return; } if (map->first_free <= mech->mapnumber) { /* Invalid: possible corruption of data, therefore un-hosing it */ mech->mapindex = -1; mech_remove_from_all_maps(mech); fprintf(stderr, "#%d on invalid map - removing.. (#1)\n", mech->mynum); return; } if (map->mechsOnMap[mech->mapnumber] != mech->mynum) { mech->mapindex = -1; mech_remove_from_all_maps(mech); fprintf(stderr, "#%d on invalid map - removing.. (#2)\n", mech->mynum); return; } mech_remove_from_all_maps_except(mech, map->mynum); } void eliminate_empties(MAP * map) { int i; int j; int count, oldcount; char tempbuf[SBUF_SIZE]; if (!map) return; for (i = map->first_free - 1; i >= 0; i--) if (map->mechsOnMap[i] > 0) break; count = i + 1; if (count == (oldcount = map->first_free)) return; fprintf(stderr, "Map #%d contains empty entries ; removing %d (%d->%d)\n", map->mynum, oldcount - count, oldcount, count); if (i < 0) return; for (j = count; j < oldcount; j++) free((void *) map->LOSinfo[j]); ReCreate(map->LOSinfo, unsigned short *, count); ReCreate(map->mechsOnMap, dbref, count); ReCreate(map->mechflags, char, count); map->first_free = count; sprintf(tempbuf, "%d", map->mynum); mech_Rfixstuff(GOD, NULL, tempbuf); } void remove_mech_from_map(MAP * map, MECH * mech) { int loop = map->first_free; clear_mech_from_LOS(mech); mech->mapindex = -1; if (map->first_free <= mech->mapnumber || map->mechsOnMap[mech->mapnumber] != mech->mynum) { SendError(tprintf ("Map indexing error for mech #%d: Map index %d contains data for #%d instead.", mech->mynum, mech->mapnumber, map->mechsOnMap ? map->mechsOnMap[mech->mapnumber] : -1)); if (map->mechsOnMap) for (loop = 0; (loop < map->first_free) && (map->mechsOnMap[loop] != mech->mynum); loop++); } else loop = mech->mapnumber; mech->mapnumber = 0; if (loop != (map->first_free)) { map->mechsOnMap[loop] = -1; /* clear it */ map->mechflags[loop] = 0; #if 0 for (i = 0; i < map->first_free; i++) if (map->mechsOnMap[i] > 0 && i != loop) if ((t = getMech(map->mechsOnMap[i]))) if (MechTeam(t) != MechTeam(mech) && (map->LOSinfo[i][loop] & MECHLOSFLAG_SEEN)) { MechNumSeen(t) = MAX(0, MechNumSeen(t) - 1); } #endif if (loop == (map->first_free - 1)) map->first_free--; /* Who cares about some lost memory? In realloc we'll gain it back anyway */ } if (Towed(mech)) { /* Check that the towing guy isn't left on the map */ int i; MECH *t; for (i = 0; i < map->first_free; i++) /* Release from towing if tow-guy ain't on same map already */ if ((t = FindObjectsData(map->mechsOnMap[i]))) if (MechCarrying(t) == mech->mynum) { SetCarrying(t, -1); MechStatus(mech) &= ~TOWED; /* Reset the Towed flag */ break; } } MechNumSeen(mech) = 0; if (IsDS(mech)) SendDSInfo(tprintf("DS #%d has left map #%d", mech->mynum, map->mynum)); } void add_mech_to_map(MAP * newmap, MECH * mech) { int loop, count, i; for (loop = 0; loop < newmap->first_free; loop++) if (newmap->mechsOnMap[loop] == mech->mynum) break; if (loop != newmap->first_free) return; for (loop = 0; loop < newmap->first_free; loop++) if (newmap->mechsOnMap[loop] < 0) break; if (loop == newmap->first_free) { newmap->first_free++; count = newmap->first_free; ReCreate(newmap->mechsOnMap, dbref, count); ReCreate(newmap->mechflags, char, count); ReCreate(newmap->LOSinfo, unsigned short *, count); newmap->LOSinfo[count - 1] = NULL; for (i = 0; i < count; i++) { ReCreate(newmap->LOSinfo[i], unsigned short, count); newmap->LOSinfo[i][loop] = 0; } for (i = 0; i < count; i++) newmap->LOSinfo[loop][i] = 0; } mech->mapindex = newmap->mynum; mech->mapnumber = loop; newmap->mechsOnMap[loop] = mech->mynum; newmap->mechflags[loop] = 0; /* Is there an autopilot */ if (MechAuto(mech) > 0) { AUTO *a = FindObjectsData(MechAuto(mech)); /* Reset the AI's comtitle */ if (a) auto_set_comtitle(a, mech); } if (Towed(mech)) { int i; MECH *t; for (i = 0; i < newmap->first_free; i++) /* Release from towing if tow-guy ain't on same map already */ if ((t = FindObjectsData(newmap->mechsOnMap[i]))) if (MechCarrying(t) == mech->mynum) break; if (i == newmap->first_free) MechStatus(mech) &= ~TOWED; /* Reset the Towed flag */ } MarkForLOSUpdate(mech); UnZombifyMech(mech); UpdateConditions(mech, newmap); if (IsDS(mech)) SendDSInfo(tprintf("DS #%d has entered map #%d", mech->mynum, newmap->mynum)); } int mech_size(MAP * map) { return map->first_free * (sizeof(dbref) + sizeof(char) + sizeof(unsigned short *) + map->first_free * sizeof(unsigned short)); }