btmux/autom4te.cache/
btmux/doc/.svn/
btmux/event/.svn/
btmux/game/.svn/
btmux/game/bin/.svn/
btmux/game/data/.svn/
btmux/game/logs/.svn/
btmux/game/maps/
btmux/game/maps/.svn/
btmux/game/maps/.svn/prop-base/
btmux/game/maps/.svn/props/
btmux/game/maps/.svn/text-base/
btmux/game/maps/.svn/wcprops/
btmux/game/mechs/
btmux/game/mechs/.svn/
btmux/game/mechs/.svn/prop-base/
btmux/game/mechs/.svn/props/
btmux/game/mechs/.svn/text-base/
btmux/game/mechs/.svn/wcprops/
btmux/game/text/.svn/
btmux/include/.svn/
btmux/misc/
btmux/misc/.svn/
btmux/misc/.svn/prop-base/
btmux/misc/.svn/props/
btmux/misc/.svn/text-base/
btmux/misc/.svn/wcprops/
btmux/python/
btmux/python/.svn/
btmux/python/.svn/prop-base/
btmux/python/.svn/props/
btmux/python/.svn/text-base/
btmux/python/.svn/wcprops/
btmux/src/.svn/prop-base/
btmux/src/.svn/props/
btmux/src/.svn/text-base/
btmux/src/.svn/wcprops/
btmux/src/hcode/.svn/
btmux/src/hcode/btech/
btmux/src/hcode/btech/.svn/
btmux/src/hcode/btech/.svn/prop-base/
btmux/src/hcode/btech/.svn/props/
btmux/src/hcode/btech/.svn/text-base/
btmux/src/hcode/btech/.svn/wcprops/
btmux/src/hcode/include/.svn/
/*
 * $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));
}