880 lines
16 KiB
C++
880 lines
16 KiB
C++
//
|
|
// Ingame save functions.
|
|
//
|
|
|
|
#include "game.h"
|
|
#include "memory.h"
|
|
#include "pcom.h"
|
|
#include "statedef.h"
|
|
#include "eway.h"
|
|
#include "animate.h"
|
|
#include "special.h"
|
|
#include "tracks.h"
|
|
|
|
#ifndef PSX
|
|
|
|
//
|
|
// Low level output functions.
|
|
//
|
|
|
|
#ifndef PSX
|
|
|
|
FILE *SAVE_handle;
|
|
|
|
SLONG SAVE_out_data(void *data, ULONG num_bytes)
|
|
{
|
|
if (fwrite(data, 1, num_bytes, SAVE_handle) != num_bytes)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
SLONG LOAD_in_data(void *data, ULONG num_bytes)
|
|
{
|
|
DebugText(" read <%d> \n",num_bytes);
|
|
if (fread(data, 1, num_bytes, SAVE_handle) != num_bytes)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
FILE *LOAD_open()
|
|
{
|
|
return MF_Fopen("ingame.sav", "rb");
|
|
}
|
|
FILE *SAVE_open()
|
|
{
|
|
return MF_Fopen("ingame.sav", "wb");
|
|
}
|
|
|
|
#else
|
|
|
|
int SAVE_handle;
|
|
|
|
SLONG SAVE_open()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
SLONG LOAD_open()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
SLONG SAVE_out_data(void *data,ULONG num_bytes)
|
|
{
|
|
// Compress_Compress(data,num_bytes);
|
|
}
|
|
|
|
SLONG LOAD_in_data(void *data,ULONG num_bytes)
|
|
{
|
|
// Compress_Decompress(data,num_bytes);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
//
|
|
// A compressed person.
|
|
//
|
|
|
|
#define SAVE_PERSON_TYPE_NORMAL 0 // The whole goddam lot is saved.
|
|
#define SAVE_PERSON_TYPE_WANDERING_DRIVER 1
|
|
#define SAVE_PERSON_TYPE_DEAD 2
|
|
#define SAVE_PERSON_TYPE_ARRESTED 3
|
|
#define SAVE_PERSON_TYPE_WANDERING_CIV 4
|
|
#define SAVE_PERSON_TYPE_FULL 5
|
|
|
|
#define SAVE_SPECIAL_TYPE_FULL 6
|
|
|
|
#define SAVE_VEHICLE_TYPE_FULL 7
|
|
#define SAVE_VEHICLE_TYPE_WANDERING 8
|
|
#define SAVE_SKIP 99
|
|
#define SAVE_SKIP_CLASS_NONE 100
|
|
|
|
|
|
#define SAVE_GAME_EWAY 101
|
|
|
|
UBYTE skip=SAVE_SKIP;
|
|
UBYTE skip_class_none=SAVE_SKIP_CLASS_NONE;
|
|
|
|
typedef struct
|
|
{
|
|
UBYTE type;
|
|
UBYTE yaw;
|
|
SBYTE health;
|
|
UBYTE looklike; // Top four bits is the PersonID, bottom four bits are PersonType
|
|
UWORD x;
|
|
SWORD y;
|
|
UWORD z;
|
|
UWORD other_a; // The car this person is driving
|
|
// The current anim for dead people
|
|
UWORD other_b; // The passenger for drivers
|
|
UBYTE ware;
|
|
UBYTE drop;
|
|
UWORD onface;
|
|
|
|
} SAVE_Person;
|
|
|
|
typedef struct
|
|
{
|
|
UBYTE Type;
|
|
UBYTE Person;
|
|
UWORD Thing;
|
|
UWORD DrawTween;
|
|
|
|
} SAVE_Person_extra;
|
|
|
|
typedef struct
|
|
{
|
|
UBYTE Type;
|
|
UBYTE Pad;
|
|
UWORD Thing;
|
|
UWORD Special;
|
|
UWORD DrawMesh;
|
|
|
|
} SAVE_Special_extra;
|
|
|
|
typedef struct
|
|
{
|
|
UBYTE Type;
|
|
UBYTE Yaw;
|
|
UWORD Thing;
|
|
UWORD x;
|
|
SWORD y;
|
|
UWORD z;
|
|
UWORD driver;
|
|
UWORD passenger;
|
|
|
|
} SAVE_just_vehicle;
|
|
|
|
typedef struct
|
|
{
|
|
UBYTE Type;
|
|
UBYTE Pad;
|
|
UWORD Thing;
|
|
UWORD Vehicle;
|
|
UWORD DrawMesh;
|
|
|
|
} SAVE_Vehicle_extra;
|
|
|
|
//
|
|
// Saves out a person thing structure. Returns FALSE on failure.
|
|
//
|
|
|
|
SLONG SAVE_special(Thing *p_special)
|
|
{
|
|
SLONG ret=1;
|
|
|
|
SAVE_Special_extra extra;
|
|
|
|
|
|
extra.Type = SAVE_SPECIAL_TYPE_FULL;
|
|
|
|
extra.Thing = THING_NUMBER(p_special);
|
|
|
|
extra.Special = SPECIAL_NUMBER(p_special->Genus.Special);
|
|
|
|
ret&=SAVE_out_data(&extra, sizeof(extra));
|
|
ret&=SAVE_out_data(p_special->Genus.Special, sizeof(Special));
|
|
ret&=SAVE_out_data(p_special->Draw.Mesh, sizeof(DrawMesh));
|
|
ret&=SAVE_out_data(p_special, sizeof(Thing));
|
|
|
|
return(ret);
|
|
}
|
|
|
|
SLONG SAVE_vehicle(Thing *p_vehicle)
|
|
{
|
|
Thing *p_driver;
|
|
SLONG ret=1;
|
|
SAVE_Vehicle_extra extra;
|
|
|
|
if(p_vehicle->Genus.Vehicle->Driver)
|
|
{
|
|
p_driver=TO_THING(p_vehicle->Genus.Vehicle->Driver);
|
|
if (p_driver->Genus.Person->pcom_ai == PCOM_AI_DRIVER &&
|
|
p_driver->Genus.Person->pcom_move == PCOM_MOVE_WANDER)
|
|
{
|
|
if (p_driver->Genus.Person->Flags & FLAG_PERSON_DRIVING)
|
|
{
|
|
if (p_driver->Genus.Person->pcom_ai_state == PCOM_AI_STATE_NORMAL)
|
|
{
|
|
SAVE_out_data(&skip, sizeof(skip));
|
|
return(1);
|
|
|
|
/*
|
|
SAVE_just_vehicle extrav;
|
|
|
|
//
|
|
// dont save info about wandering drivers
|
|
//
|
|
return(1);
|
|
|
|
extrav.Type=SAVE_VEHICLE_TYPE_HALF;
|
|
extrav.Yaw =(p_vehicle->Genus.Vehicle->Angle&2047)>>3;
|
|
extrav.Thing = THING_NUMBER(p_vehicle);
|
|
extrav.x=p_vehicle->WorldPos.X>>8;
|
|
extrav.y=p_vehicle->WorldPos.Y>>8;
|
|
extrav.z=p_vehicle->WorldPos.Z>>8;
|
|
extrav.driver=p_vehicle->Genus.Vehicle->Driver;
|
|
extrav.passenger=p_vehicle->Genus.Vehicle->Passenger;
|
|
|
|
return(SAVE_out_data(&extrav, sizeof(extrav)));
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
extra.Type = SAVE_VEHICLE_TYPE_FULL;
|
|
|
|
extra.Thing = THING_NUMBER(p_vehicle);
|
|
|
|
extra.Vehicle = VEHICLE_NUMBER(p_vehicle->Genus.Vehicle);
|
|
|
|
ret&=SAVE_out_data(&extra, sizeof(extra));
|
|
ret&=SAVE_out_data(p_vehicle->Genus.Vehicle, sizeof(Vehicle));
|
|
ret&=SAVE_out_data(p_vehicle, sizeof(Thing));
|
|
|
|
return(ret);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SLONG SAVE_person(Thing *p_person)
|
|
{
|
|
SAVE_Person sp;
|
|
SLONG ret;
|
|
|
|
ASSERT(p_person->Class == CLASS_PERSON);
|
|
|
|
memset(&sp, 0, sizeof(sp));
|
|
|
|
//
|
|
// If this person is a wandering civ or a wandering civ driver, then
|
|
// we don't have to save much state for him.
|
|
//
|
|
|
|
sp.type = SAVE_PERSON_TYPE_NORMAL;
|
|
|
|
if (p_person->Genus.Person->pcom_ai == PCOM_AI_CIV &&
|
|
p_person->Genus.Person->pcom_move == PCOM_MOVE_WANDER)
|
|
{
|
|
//
|
|
// Wandering civs are regenerated when we load the waypoints for the level.
|
|
//
|
|
|
|
SAVE_out_data(&skip, sizeof(skip));
|
|
return(1);
|
|
sp.type = SAVE_PERSON_TYPE_WANDERING_CIV;
|
|
|
|
return SAVE_out_data(&sp.type, sizeof(UBYTE));
|
|
}
|
|
|
|
|
|
if (p_person->Genus.Person->pcom_ai == PCOM_AI_DRIVER &&
|
|
p_person->Genus.Person->pcom_move == PCOM_MOVE_WANDER)
|
|
{
|
|
if (p_person->Genus.Person->Flags & FLAG_PERSON_DRIVING)
|
|
{
|
|
if (p_person->Genus.Person->pcom_ai_state == PCOM_AI_STATE_NORMAL)
|
|
{
|
|
SAVE_out_data(&skip, sizeof(skip));
|
|
return(1);
|
|
|
|
sp.type = SAVE_PERSON_TYPE_WANDERING_DRIVER;
|
|
sp.other_a = p_person->Genus.Person->InCar;
|
|
sp.other_b = p_person->Genus.Person->Passenger;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (p_person->State == STATE_DEAD)
|
|
{
|
|
if (p_person->Genus.Person->Flags & FLAG_PERSON_ARRESTED)
|
|
{
|
|
sp.type = SAVE_PERSON_TYPE_ARRESTED;
|
|
sp.other_b = p_person->SubState;
|
|
}
|
|
else
|
|
{
|
|
sp.type = SAVE_PERSON_TYPE_DEAD;
|
|
}
|
|
sp.other_a = p_person->Draw.Tweened->CurrentAnim;
|
|
}
|
|
|
|
if(sp.type)
|
|
{
|
|
//
|
|
// Fill in the person structure
|
|
//
|
|
|
|
sp.x = p_person->WorldPos.X >> 8;
|
|
sp.y = p_person->WorldPos.Y >> 8;
|
|
sp.z = p_person->WorldPos.Z >> 8;
|
|
sp.yaw = p_person->Draw.Tweened->Angle >> 3;
|
|
sp.health = p_person->Genus.Person->Health;
|
|
// sp.looklike = 0;
|
|
// sp.looklike |= p_person->Genus.Person->PersonType & 0xf;
|
|
// sp.looklike |= p_person->Draw.Tweened->PersonID << 4;
|
|
sp.ware = p_person->Genus.Person->Ware;
|
|
sp.drop = p_person->Genus.Person->drop;
|
|
sp.onface = p_person->OnFace;
|
|
|
|
|
|
if (!SAVE_out_data(&sp, sizeof(SAVE_Person)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SAVE_Person_extra extra;
|
|
|
|
ret=1;
|
|
|
|
extra.Type = SAVE_PERSON_TYPE_FULL;
|
|
|
|
extra.Thing = THING_NUMBER(p_person);
|
|
|
|
extra.Person = PERSON_NUMBER(p_person->Genus.Person);
|
|
extra.DrawTween = DRAW_TWEEN_NUMBER(p_person->Draw.Tweened);
|
|
|
|
ret&=SAVE_out_data(&extra, sizeof(SAVE_Person_extra));
|
|
ret&=SAVE_out_data(p_person->Draw.Tweened, sizeof(DrawTween));
|
|
ret&=SAVE_out_data(p_person->Genus.Person, sizeof(Person));
|
|
ret&=SAVE_out_data(p_person, sizeof(Thing));
|
|
if(ret==0)
|
|
return(FALSE);
|
|
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
SLONG SAVE_things(void)
|
|
{
|
|
SLONG index;
|
|
Thing *p_thing;
|
|
|
|
for(index=0;index<MAX_THINGS;index++)
|
|
{
|
|
p_thing=TO_THING(index);
|
|
|
|
switch(p_thing->Class)
|
|
{
|
|
case CLASS_PERSON:
|
|
if(!SAVE_person(p_thing))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
break;
|
|
case CLASS_SPECIAL:
|
|
if(!SAVE_special(p_thing))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
break;
|
|
case CLASS_VEHICLE:
|
|
if(!SAVE_vehicle(p_thing))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
break;
|
|
case CLASS_NONE:
|
|
SAVE_out_data(&skip_class_none, sizeof(skip_class_none));
|
|
break;
|
|
|
|
default:
|
|
SAVE_out_data(&skip, sizeof(skip));
|
|
|
|
break;
|
|
}
|
|
|
|
// index=p_thing->LinkChild;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
SLONG SAVE_eways(void)
|
|
{
|
|
UBYTE marker=SAVE_GAME_EWAY;
|
|
SLONG c0,res=1;
|
|
EWAY_Way *ew;
|
|
|
|
if (!SAVE_out_data(&marker, sizeof(marker)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
for(c0=0;c0<EWAY_way_upto;c0++)
|
|
{
|
|
ew = &EWAY_way[c0];
|
|
|
|
if(ew->flag & EWAY_FLAG_COUNTDOWN)
|
|
{
|
|
|
|
res&=SAVE_out_data(&ew->flag, sizeof(ew->flag));
|
|
res&=SAVE_out_data(&ew->timer, sizeof(ew->timer));
|
|
}
|
|
else
|
|
{
|
|
res&=SAVE_out_data(&ew->flag, sizeof(ew->flag));
|
|
}
|
|
|
|
if(!res)
|
|
return(FALSE);
|
|
}
|
|
res&=SAVE_out_data(EWAY_timer, sizeof(UWORD)*EWAY_MAX_TIMERS);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
SLONG SAVE_ingame(CBYTE *fname)
|
|
{
|
|
SLONG ret=1;
|
|
|
|
#ifndef PSX
|
|
SAVE_handle = MF_Fopen("ingame.sav", "wb");
|
|
#else
|
|
SAVE_handle = SAVE_open();
|
|
#endif
|
|
|
|
ret&=SAVE_things();
|
|
ret&=SAVE_eways();
|
|
|
|
MF_Fclose(SAVE_handle);
|
|
// SAVE_VALID=1;
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
//*******************************************************************************************************
|
|
//* *
|
|
//* Load Equivalent *
|
|
//* *
|
|
//* *
|
|
//*******************************************************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SLONG LOAD_eways(void)
|
|
{
|
|
SLONG c0,res=1;
|
|
EWAY_Way *ew;
|
|
|
|
|
|
for(c0=0;c0<EWAY_way_upto;c0++)
|
|
{
|
|
ew = &EWAY_way[c0];
|
|
|
|
res&=LOAD_in_data(&ew->flag, sizeof(ew->flag));
|
|
if(ew->flag & EWAY_FLAG_COUNTDOWN)
|
|
{
|
|
|
|
res&=LOAD_in_data(&ew->timer, sizeof(ew->timer));
|
|
}
|
|
if(!res)
|
|
return(FALSE);
|
|
}
|
|
res&=LOAD_in_data(EWAY_timer, sizeof(UWORD)*EWAY_MAX_TIMERS);
|
|
return(res);
|
|
}
|
|
|
|
void set_person_default_data(Thing *p_person,SAVE_Person *sp)
|
|
{
|
|
p_person->WorldPos.X=sp->x<<8;
|
|
p_person->WorldPos.Y=sp->y<<8;
|
|
p_person->WorldPos.Z=sp->z<<8;
|
|
p_person->Draw.Tweened->Angle=sp->yaw<<3;
|
|
p_person->Genus.Person->Health=sp->health;
|
|
p_person->Genus.Person->Ware=sp->ware;
|
|
p_person->Genus.Person->drop=sp->drop;
|
|
p_person->OnFace=sp->onface;
|
|
|
|
}
|
|
|
|
void LOAD_person_dead(Thing *p_person)
|
|
{
|
|
SAVE_Person sp;
|
|
|
|
ASSERT(p_person->Class==CLASS_PERSON);
|
|
|
|
if (p_person->Flags&FLAGS_ON_MAPWHO) // Does thing currently exist on map?
|
|
remove_thing_from_map(p_person);
|
|
|
|
DebugText(" load person %d ",THING_NUMBER(p_person));
|
|
LOAD_in_data(&sp.yaw, sizeof(SAVE_Person)-1);
|
|
|
|
set_person_default_data(p_person,&sp);
|
|
|
|
|
|
|
|
//
|
|
// recreate what it's like to be dead
|
|
//
|
|
|
|
set_anim(p_person,sp.other_a);
|
|
set_generic_person_state_function(p_person,STATE_DEAD);
|
|
p_person->Genus.Person->Action = ACTION_DEAD;
|
|
p_person->Genus.Person->Timer1 = 0;
|
|
p_person->SubState=0;
|
|
TRACKS_Bloodpool(p_person);
|
|
TRACKS_Bloodpool(p_person);
|
|
|
|
p_person->Flags&=~FLAGS_ON_MAPWHO;
|
|
add_thing_to_map(p_person);
|
|
|
|
}
|
|
|
|
void LOAD_person_arrested(Thing *p_person)
|
|
{
|
|
SAVE_Person sp;
|
|
|
|
ASSERT(p_person->Class==CLASS_PERSON);
|
|
|
|
if (p_person->Flags&FLAGS_ON_MAPWHO) // Does thing currently exist on map?
|
|
remove_thing_from_map(p_person);
|
|
|
|
DebugText(" load person arrest%d ",THING_NUMBER(p_person));
|
|
LOAD_in_data((&sp.yaw), sizeof(SAVE_Person)-1);
|
|
|
|
set_person_default_data(p_person,&sp);
|
|
|
|
|
|
|
|
//
|
|
// recreate what it's like to be dead
|
|
//
|
|
|
|
set_anim(p_person,sp.other_a);
|
|
set_generic_person_state_function(p_person,STATE_DEAD);
|
|
p_person->Genus.Person->Action = ACTION_DEAD;
|
|
p_person->Genus.Person->Timer1 = 0;
|
|
p_person->SubState=sp.other_b;
|
|
TRACKS_Bloodpool(p_person);
|
|
TRACKS_Bloodpool(p_person);
|
|
|
|
p_person->Flags&=~FLAGS_ON_MAPWHO;
|
|
add_thing_to_map(p_person);
|
|
}
|
|
|
|
void LOAD_person_full(Thing *p_person)
|
|
{
|
|
SAVE_Person_extra extra;
|
|
|
|
ASSERT(p_person->Class==CLASS_PERSON);
|
|
|
|
if (p_person->Flags&FLAGS_ON_MAPWHO) // Does thing currently exist on map?
|
|
remove_thing_from_map(p_person);
|
|
|
|
DebugText(" load person full %d ",THING_NUMBER(p_person));
|
|
LOAD_in_data((&extra.Person),sizeof(extra)-1);
|
|
|
|
ASSERT(extra.Thing==THING_NUMBER(p_person));
|
|
ASSERT(extra.Person==PERSON_NUMBER(p_person->Genus.Person));
|
|
ASSERT(extra.DrawTween==DRAW_TWEEN_NUMBER(p_person->Draw.Tweened));
|
|
|
|
LOAD_in_data(p_person->Draw.Tweened,sizeof(DrawTween));
|
|
LOAD_in_data(p_person->Genus.Person,sizeof(Person));
|
|
LOAD_in_data(p_person,sizeof(Thing));
|
|
|
|
if (p_person->Flags&FLAGS_ON_MAPWHO)
|
|
{
|
|
p_person->Flags&=~FLAGS_ON_MAPWHO;
|
|
add_thing_to_map(p_person);
|
|
}
|
|
else
|
|
{
|
|
// Wasn't on mapwho when we saved so don't add it now
|
|
}
|
|
}
|
|
|
|
void LOAD_special_full(Thing *p_special)
|
|
{
|
|
DrawMesh *draw_mesh;
|
|
Special *special;
|
|
|
|
if (p_special->Flags&FLAGS_ON_MAPWHO) // Does thing currently exist on map?
|
|
remove_thing_from_map(p_special);
|
|
|
|
SAVE_Special_extra extra;
|
|
DebugText(" loadspecialfull %d ",THING_NUMBER(p_special));
|
|
LOAD_in_data((&extra.Pad),sizeof(extra)-1);
|
|
// ASSERT(extra.Special==SPECIAL_NUMBER(p_special->Genus.Special));
|
|
// ASSERT(extra.Thing==THING_NUMBER(p_special));
|
|
|
|
// ASSERT(p_special->Class==CLASS_SPECIAL);
|
|
|
|
if(p_special->Class!=CLASS_SPECIAL)
|
|
{
|
|
SLONG index;
|
|
DrawMesh *dm;
|
|
|
|
extern SLONG find_empty_special(void);
|
|
index=find_empty_special();
|
|
|
|
p_special->Genus.Special=TO_SPECIAL(index);
|
|
|
|
dm = alloc_draw_mesh();
|
|
|
|
ASSERT(dm);
|
|
p_special->Draw.Mesh = dm;
|
|
}
|
|
|
|
LOAD_in_data(p_special->Genus.Special,sizeof(Special));
|
|
LOAD_in_data(p_special->Draw.Mesh,sizeof(DrawMesh));
|
|
special =p_special->Genus.Special;
|
|
draw_mesh=p_special->Draw.Mesh;
|
|
|
|
|
|
LOAD_in_data(p_special,sizeof(Thing));
|
|
p_special->Genus.Special=special;
|
|
p_special->Draw.Mesh=draw_mesh;
|
|
|
|
if (p_special->Flags&FLAGS_ON_MAPWHO)
|
|
{
|
|
p_special->Flags&=~FLAGS_ON_MAPWHO;
|
|
add_thing_to_map(p_special);
|
|
}
|
|
else
|
|
{
|
|
// Wasn't on mapwho when we saved so don't add it now
|
|
}
|
|
}
|
|
|
|
void LOAD_vehicle_full(Thing *p_vehicle)
|
|
{
|
|
SAVE_Vehicle_extra extra;
|
|
|
|
ASSERT(p_vehicle->Class==CLASS_VEHICLE);
|
|
|
|
if (p_vehicle->Flags&FLAGS_ON_MAPWHO) // Does thing currently exist on map?
|
|
remove_thing_from_map(p_vehicle);
|
|
|
|
DebugText(" loadvehiclefull %d ",THING_NUMBER(p_vehicle));
|
|
LOAD_in_data((&extra.Pad),sizeof(extra)-1);
|
|
|
|
ASSERT(extra.Thing==THING_NUMBER(p_vehicle));
|
|
ASSERT(extra.Vehicle==VEHICLE_NUMBER(p_vehicle->Genus.Vehicle));
|
|
|
|
LOAD_in_data(p_vehicle->Genus.Vehicle,sizeof(Vehicle));
|
|
LOAD_in_data(p_vehicle,sizeof(Thing));
|
|
|
|
if (p_vehicle->Flags&FLAGS_ON_MAPWHO)
|
|
{
|
|
p_vehicle->Flags&=~FLAGS_ON_MAPWHO;
|
|
add_thing_to_map(p_vehicle);
|
|
}
|
|
else
|
|
{
|
|
// Wasn't on mapwho when we saved so don't add it now
|
|
}
|
|
}
|
|
|
|
SLONG LOAD_types(void)
|
|
{
|
|
UBYTE type;
|
|
UWORD thing=0;
|
|
Thing *p_thing;
|
|
|
|
SLONG special=0,person=0,car=0;
|
|
|
|
|
|
|
|
p_thing=TO_THING(0);
|
|
while(LOAD_in_data(&type,1))
|
|
{
|
|
switch(type)
|
|
{
|
|
case SAVE_PERSON_TYPE_NORMAL:
|
|
ASSERT(0);
|
|
break;
|
|
case SAVE_PERSON_TYPE_WANDERING_DRIVER:
|
|
ASSERT(0);
|
|
break;
|
|
case SAVE_PERSON_TYPE_DEAD:
|
|
LOAD_person_dead(p_thing);
|
|
break;
|
|
case SAVE_PERSON_TYPE_ARRESTED:
|
|
LOAD_person_arrested(p_thing);
|
|
break;
|
|
case SAVE_PERSON_TYPE_WANDERING_CIV:
|
|
ASSERT(0);
|
|
// LOAD_person_wandering(p_thing);
|
|
break;
|
|
case SAVE_PERSON_TYPE_FULL:
|
|
LOAD_person_full(p_thing);
|
|
person++;
|
|
break;
|
|
|
|
case SAVE_SPECIAL_TYPE_FULL:
|
|
LOAD_special_full(p_thing);
|
|
special++;
|
|
break;
|
|
|
|
case SAVE_VEHICLE_TYPE_FULL:
|
|
LOAD_vehicle_full(p_thing);
|
|
car++;
|
|
break;
|
|
|
|
case SAVE_GAME_EWAY:
|
|
LOAD_eways();
|
|
|
|
case SAVE_SKIP:
|
|
switch(p_thing->Class)
|
|
{
|
|
case CLASS_SPECIAL:
|
|
remove_thing_from_map(p_thing);
|
|
p_thing->Class=CLASS_NONE;
|
|
// ASSERT(0);
|
|
break;
|
|
|
|
}
|
|
break;
|
|
case SAVE_SKIP_CLASS_NONE:
|
|
remove_thing_from_map(p_thing);
|
|
switch(p_thing->Class)
|
|
{
|
|
case CLASS_NONE:
|
|
break;
|
|
|
|
case CLASS_SPECIAL:
|
|
void free_special(Thing *special_thing);
|
|
free_special(p_thing);
|
|
break;
|
|
case CLASS_TRACK:
|
|
break;
|
|
default:
|
|
ASSERT(0);
|
|
break;
|
|
|
|
|
|
}
|
|
p_thing->Class=CLASS_NONE;
|
|
|
|
break;
|
|
default:
|
|
|
|
ASSERT(0);
|
|
break;
|
|
}
|
|
p_thing++;
|
|
thing++;
|
|
}
|
|
|
|
DebugText(" special %d people %d car %d \n",special,person,car);
|
|
|
|
return 0;
|
|
}
|
|
|
|
extern UWORD *thing_class_head;
|
|
|
|
|
|
void fix_thing_lists(void)
|
|
{
|
|
SLONG c0;
|
|
Thing *p_thing;
|
|
|
|
PRIMARY_USED = 0;
|
|
PRIMARY_UNUSED = 0;
|
|
PRIMARY_COUNT = 0;
|
|
|
|
for(c0=0;c0<MAX_THINGS;c0++)
|
|
{
|
|
p_thing=TO_THING(c0);
|
|
|
|
if(p_thing->Class!=CLASS_NONE)
|
|
{
|
|
//
|
|
// thing is used
|
|
//
|
|
|
|
p_thing->LinkParent=0;
|
|
p_thing->LinkChild=PRIMARY_USED;
|
|
PRIMARY_USED=c0;
|
|
PRIMARY_COUNT++;
|
|
|
|
thing_class_head[p_thing->Class]=c0;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// thing is unused
|
|
//
|
|
|
|
p_thing->LinkParent=0;
|
|
p_thing->LinkChild=PRIMARY_UNUSED;
|
|
PRIMARY_UNUSED=c0;
|
|
|
|
}
|
|
}
|
|
}
|
|
extern void free_special(Thing *s_thing);
|
|
|
|
void remove_specials(void)
|
|
{
|
|
SLONG index,next;
|
|
Thing *p_special;
|
|
|
|
index=thing_class_head[CLASS_SPECIAL];
|
|
|
|
while(index)
|
|
{
|
|
p_special=TO_THING(index);
|
|
next=p_special->NextLink;
|
|
free_special(p_special);
|
|
index=next;
|
|
}
|
|
|
|
}
|
|
SLONG LOAD_ingame(CBYTE *fname)
|
|
{
|
|
SLONG ret=1;
|
|
|
|
TRACKS_Reset();
|
|
|
|
remove_specials();
|
|
|
|
|
|
void reload_level(void);
|
|
reload_level();
|
|
|
|
DebugText("\nLoadInGame \n\n");
|
|
SAVE_handle = LOAD_open();
|
|
|
|
SAVE_handle = LOAD_open();
|
|
LOAD_types();
|
|
MF_Fclose(SAVE_handle);
|
|
|
|
fix_thing_lists();
|
|
// SAVE_VALID=1;
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
#endif |