/*
* file: vedit.cc
* author: Dunkelzahn
* (c)2001 The AwakeMUD Consortium, Daniel Gelinske
* purpose: vedit, vehicle editor addon
* to AwakeOLC, a component of AwakeMUD
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "structs.h"
#include "awake.h"
#include "constants.h"
#include "interpreter.h"
#include "comm.h"
#include "utils.h"
#include "db.h"
#include "dblist.h"
#include "screen.h"
#include "olc.h"
#include "memory.h"
#define VEH d->edit_veh
extern class memoryClass *Mem;
void write_vehs_to_disk(int zone);
// extern funcs
extern char *cleanup(char *dest, const char *src);
/* display main menu */
void vedit_disp_menu(struct descriptor_data * d)
{
CLS(CH);
send_to_char(CH, "Vehicle number: %s%d%s\r\n", CCCYN(CH, C_CMP), d->edit_number,
CCNRM(CH, C_CMP));
send_to_char(CH, "1) Vechile namelist: %s%s%s\r\n", CCCYN(CH, C_CMP),
d->edit_veh->name, CCNRM(CH, C_CMP));
send_to_char(CH, "2) Vehicle shortdesc: %s%s%s\r\n", CCCYN(CH, C_CMP),
d->edit_veh->short_description, CCNRM(CH, C_CMP));
send_to_char(CH, "3) Vehicle descript (Stationary): %s%s%s\r\n", CCCYN(CH, C_CMP),
d->edit_veh->description, CCNRM(CH, C_CMP));
send_to_char(CH, "4) Vehicle longdesc: \r\n%s\r\n",
d->edit_veh->long_description ? d->edit_veh->long_description :
"(not set)");
send_to_char(CH, "5) Vehicle Inside Descript: \r\n%s\r\n",
d->edit_veh->inside_description ? d->edit_veh->inside_description : "(not set)");
send_to_char(CH, "6) Vehicle Inside Rear Descript: \r\n%s\r\n",
d->edit_veh->rear_description ? d->edit_veh->rear_description : "(not set)");
send_to_char(CH, "7) Arrive text: ^c%s^n, 8) Leave text: ^c%s^n\r\n",
d->edit_veh->arrive, d->edit_veh->leave);
d->edit_veh->flags.PrintBits(buf1, MAX_STRING_LENGTH, veh_flag, NUM_VFLAGS);
send_to_char(CH, "9) Flags: ^c%s^n\r\n", buf1);
send_to_char(CH, "a) H(^c%d^n) Sp(^c%d^n) Acc(^c%d^n) B(^c%d^n) Ar(^c%d^n)\r\n",
d->edit_veh->handling, d->edit_veh->speed, d->edit_veh->accel, d->edit_veh->body,
d->edit_veh->armor);
send_to_char(CH, " Sig(^c%d^n) Au(^c%d^n) P(^c%d^n) Seat(^c%d/%d^n) Load(^c%d^n) Cost(^c%d^n)\r\n",
d->edit_veh->sig, d->edit_veh->autonav, d->edit_veh->pilot, d->edit_veh->seating[1], d->edit_veh->seating[0],
(int)d->edit_veh->load, d->edit_veh->cost);
send_to_char(CH, "b) Type: ^C%s^n\r\n", veh_type[d->edit_veh->type]);
send_to_char(CH, "c) Stock Engine: ^C%s^n\r\n", engine_type[d->edit_veh->engine]);
send_to_char("q) Quit and save\r\n"
"x) Exit and abort\r\n"
"Enter your choice:\r\n", CH);
d->edit_mode = VEDIT_MAIN_MENU;
}
/***************************************************************************
main loop (of sorts).. basically interpreter throws all input to here
***************************************************************************/
void vedit_disp_att(struct descriptor_data * d)
{
CLS(CH);
send_to_char(CH, "1) Handling: ^c%d^n\r\n", d->edit_veh->handling);
send_to_char(CH, "2) Speed: ^c%d^n\r\n", d->edit_veh->speed);
send_to_char(CH, "3) Acceleration: ^c%d^n\r\n", d->edit_veh->accel);
send_to_char(CH, "4) Body: ^c%d^n\r\n", d->edit_veh->body);
send_to_char(CH, "5) Armor: ^c%d^n\r\n", d->edit_veh->armor);
send_to_char(CH, "6) Signature: ^c%d^n\r\n", d->edit_veh->sig);
send_to_char(CH, "7) AutoNav: ^c%d^n\r\n", d->edit_veh->autonav);
send_to_char(CH, "8) Pilot: ^c%d^n\r\n", d->edit_veh->pilot);
send_to_char(CH, "9) Seating: ^c%d/%d^n\r\n", d->edit_veh->seating[1], d->edit_veh->seating[0]);
send_to_char(CH, "0) Load: ^c%d^n\r\n", (int)d->edit_veh->load);
send_to_char(CH, "a) Cost: ^c%d^n\r\n", d->edit_veh->cost);
send_to_char(CH, "q) Quit\r\n");
send_to_char(CH, "\r\nEnter your choice:\r\n");
d->edit_mode = VEDIT_ATT;
}
void vedit_disp_type(struct descriptor_data * d)
{
CLS(CH);
send_to_char(CH, "0) Drone\r\n");
send_to_char(CH, "1) Car\r\n");
send_to_char(CH, "2) Bike\r\n");
send_to_char(CH, "3) Truck\r\n");
send_to_char(CH, "4) Fixed Wing\r\n");
send_to_char(CH, "5) Rotorcraft\r\n");
send_to_char(CH, "6) Vector Thrust\r\n");
send_to_char(CH, "7) Hovercraft\r\n");
send_to_char(CH, "8) MotorBoat\r\n");
send_to_char(CH, "9) Ship\r\n");
send_to_char(CH, "a) Lighter Than Air\r\n");
send_to_char(CH, "Enter your choice:\r\n");
d->edit_mode = VEDIT_TYPE;
}
void vedit_disp_flag_menu(struct descriptor_data *d)
{
CLS(CH);
for (int x = 1; x < NUM_VFLAGS; x++)
send_to_char(CH, "%d) %s\r\n", x, veh_flag[x]);
d->edit_veh->flags.PrintBits(buf1, MAX_STRING_LENGTH,
veh_flag, NUM_VFLAGS);
send_to_char(CH, "Vehicle Flags: ^c%s^n\r\nSelect Flag (q to quit): ", buf1);
d->edit_mode = VEDIT_FLAGS;
}
void vedit_parse(struct descriptor_data * d, char *arg)
{
int number;
int veh_number; /* the RNUM */
switch (d->edit_mode)
{
case VEDIT_CONFIRM_EDIT:
/* if player hits 'Y' then edit veh */
switch (*arg) {
case 'y':
case 'Y':
vedit_disp_menu(d);
break;
case 'n':
case 'N':
STATE(d) = CON_PLAYING;
/* free up the editing vehicle */
if (d->edit_veh)
Mem->DeleteVehicle(d->edit_veh);
d->edit_veh = NULL;
d->edit_number = 0;
PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
break;
default:
send_to_char("That's not a valid choice!\r\n", d->character);
send_to_char("Do you wish to edit it?\r\n", d->character);
break;
}
break; /* end of VEDIT_CONFIRM_EDIT */
case VEDIT_CONFIRM_SAVESTRING:
switch (*arg) {
case 'y':
case 'Y': {
/* write to internal tables */
veh_number = real_vehicle(d->edit_number);
if (veh_number > 0) {
/* we need to run through each and every vehicle currently in the
* game to see which ones are pointing to this prototype */
struct veh_data *i;
struct veh_data *temp;
/* if vehicle is pointing to this prototype, then we need to replace
* with the new one */
for (i = veh_list; i; i = i->next) {
if (veh_number == i->veh_number) {
temp = Mem->GetVehicle();
*temp = *i;
*i = *d->edit_veh;
/* copy game-time dependent vars over */
i->in_room = temp->in_room;
i->veh_number = veh_number;
i->next_veh = temp->next_veh;
i->contents = temp->contents;
i->people = temp->people;
i->damage = temp->damage;
i->cspeed = temp->cspeed;
i->seating[0] = temp->seating[0];
i->seating[1] = temp->seating[1];
for (int c = 0; c < NUM_MODS; c++)
i->mod[c] = temp->mod[c];
i->owner = temp->owner;
Mem->ClearVehicle(temp);
}
}
// this function updates pointers to the active list of vehicles
// in the mud
/* now safe to free old proto and write over */
if (veh_proto[veh_number].name)
delete [] veh_proto[veh_number].name;
if (veh_proto[veh_number].description)
delete [] veh_proto[veh_number].description;
if (veh_proto[veh_number].short_description)
delete [] veh_proto[veh_number].short_description;
if (veh_proto[veh_number].long_description)
delete [] veh_proto[veh_number].long_description;
if (veh_proto[veh_number].inside_description)
delete [] veh_proto[veh_number].inside_description;
veh_proto[veh_number] = *d->edit_veh;
} else {
/* uhoh.. need to make a new place in the vehicle prototype table */
int found = FALSE;
struct veh_data *new_veh_proto;
struct index_data *new_veh_index;
struct veh_data *temp_veh;
/* + 2.. strange but true */
new_veh_index = new struct index_data[top_of_veht + 2];
new_veh_proto = new struct veh_data[top_of_veht + 2];
/* start counting through both tables */
int counter = 0;
for (counter = 0; counter < top_of_veht + 1; counter++) {
/* if we haven't found it */
if (!found) {
/* check if current virtual is bigger than our virtual */
if (veh_index[counter].vnum > d->edit_number) {
/* eureka. insert now */
/*---------*/
new_veh_index[counter].vnum = d->edit_number;
new_veh_index[counter].number = 0;
new_veh_index[counter].func = NULL;
/*---------*/
new_veh_proto[counter] = *(d->edit_veh);
new_veh_proto[counter].in_room = NOWHERE;
/* it is now safe (and necessary!) to assign real number to
* the edit_veh, which has been -1 all this time */
d->edit_veh->veh_number = counter;
/* and assign to prototype as well */
new_veh_proto[counter].veh_number = counter;
found = TRUE;
/* insert the other proto at this point */
new_veh_index[counter + 1] = veh_index[counter];
new_veh_proto[counter + 1] = veh_proto[counter];
new_veh_proto[counter + 1].veh_number = counter + 1;
} else {
/* just copy from old to new, no num change */
new_veh_proto[counter] = veh_proto[counter];
new_veh_index[counter] = veh_index[counter];
}
} else {
/* we HAVE already found it.. therefore copy to vehicle + 1 */
new_veh_index[counter + 1] = veh_index[counter];
new_veh_proto[counter + 1] = veh_proto[counter];
new_veh_proto[counter + 1].veh_number = counter + 1;
}
}
/* if we STILL haven't found it, means the vehicle was > than all
* the other vehicles.. so insert at end */
if (!found) {
new_veh_index[top_of_veht + 1].vnum = d->edit_number;
new_veh_index[top_of_veht + 1].number = 0;
new_veh_index[top_of_veht + 1].func = NULL;
clear_vehicle(new_veh_proto + top_of_veht + 1);
new_veh_proto[top_of_veht + 1] = *(d->edit_veh);
new_veh_proto[top_of_veht + 1].in_room = NOWHERE;
new_veh_proto[top_of_veht + 1].veh_number = top_of_veht + 1;
/* it is now safe (and necessary!) to assign real number to
* the edit_veh, which has been -1 all this time */
d->edit_veh->veh_number = top_of_veht + 1;
}
top_of_veht++;
/* we also have to renumber all the vehicles currently
existing in the world. This is because when I start
extracting vehicles, bad things will happen! */
for (temp_veh = veh_list; temp_veh; temp_veh = temp_veh->next)
if (temp_veh->veh_number >= d->edit_veh->veh_number)
temp_veh->veh_number++;
/* free and replace old tables */
delete [] veh_proto;
delete [] veh_index;
veh_proto = new_veh_proto;
veh_index = new_veh_index;
}
send_to_char("Writing vehicle to disk..", d->character);
write_vehs_to_disk(d->character->player_specials->saved.zonenum);
// don't wanna nuke the strings, so we use ClearVehicle
if (d->edit_veh)
Mem->ClearVehicle(d->edit_veh);
d->edit_veh = NULL;
STATE(d) = CON_PLAYING;
PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
send_to_char("Done.\r\n", d->character);
}
break;
case 'n':
case 'N':
send_to_char("Vehicle not saved, aborting.\r\n", d->character);
STATE(d) = CON_PLAYING;
/* free up the editing vehicle. free_veh *is* safe since
it checks against prototype table */
if (d->edit_veh)
Mem->DeleteVehicle(d->edit_veh);
d->edit_veh = NULL;
d->edit_number = 0;
PLR_FLAGS(d->character).RemoveBit(PLR_EDITING);
break;
default:
send_to_char("Invalid choice!\r\n", d->character);
send_to_char("Do you wish to save this vehicle internally?\r\n", d->character);
break;
}
break; /* end of VEDIT_CONFIRM_SAVESTRING */
case VEDIT_MAIN_MENU:
/* throw us out to whichever edit mode based on user input */
switch (*arg) {
case 'q':
case 'Q':
d->edit_mode = VEDIT_CONFIRM_SAVESTRING;
vedit_parse(d, "y");
break;
case 'x':
case 'X':
d->edit_mode = VEDIT_CONFIRM_SAVESTRING;
vedit_parse(d, "n");
break;
case '1':
send_to_char("Enter namelist:", d->character);
d->edit_mode = VEDIT_EDIT_NAMELIST;
break;
case '2':
send_to_char("Enter short desc:", d->character);
d->edit_mode = VEDIT_SHORTDESC;
break;
case '3':
send_to_char("Enter normal desc (Stationary):\r\n", d->character);
d->edit_mode = VEDIT_DESC;
break;
case '4':
/* let's go out to modify.c */
send_to_char("Enter long desc:\r\n", d->character);
d->edit_mode = VEDIT_LONGDESC;
d->str = new (char *);
if (!d->str) {
mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
shutdown();
}
*(d->str) = NULL;
d->max_str = MAX_MESSAGE_LENGTH;
d->mail_to = 0;
break;
case '5':
send_to_char("Enter inside desc:\r\n", d->character);
d->edit_mode = VEDIT_INSDESC;
d->str = new (char *);
if (!d->str) {
mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
shutdown();
}
*(d->str) = NULL;
d->max_str = MAX_MESSAGE_LENGTH;
d->mail_to = 0;
break;
case '6':
send_to_char("Enter inside rear desc:\r\n", d->character);
d->edit_mode = VEDIT_REARDESC;
d->str = new (char *);
if (!d->str) {
mudlog("Malloc failed!", NULL, LOG_SYSLOG, TRUE);
shutdown();
}
*(d->str) = NULL;
d->max_str = MAX_MESSAGE_LENGTH;
d->mail_to = 0;
break;
case '7':
send_to_char("Enter arrive text:", d->character);
d->edit_mode = VEDIT_ARRIVE;
break;
case '8':
send_to_char("Enter leave text:", d->character);
d->edit_mode = VEDIT_LEAVE;
break;
case '9':
vedit_disp_flag_menu(d);
break;
case 'a':
vedit_disp_att(d);
d->edit_mode = VEDIT_ATT;
break;
case 'b':
vedit_disp_type(d);
d->edit_mode = VEDIT_TYPE;
break;
case 'c':
for (number = 1; number <= ENGINE_DIESEL; number ++)
send_to_char(CH, " %d) %s\r\n", number, engine_type[number]);
send_to_char("Enter default engine type: ", CH);
d->edit_mode = VEDIT_ENGINE;
break;
default:
send_to_char("That's not a valid choice!\r\n", d->character);
vedit_disp_menu(d);
break;
}
break; /* end of IEDIT_MAIN_MENU */
case VEDIT_TYPE:
switch(*arg) {
case '1':
d->edit_veh->type = VEH_CAR;
vedit_disp_menu(d);
break;
case '2':
d->edit_veh->type = VEH_BIKE;
vedit_disp_menu(d);
break;
case '3':
d->edit_veh->type = VEH_TRUCK;
vedit_disp_menu(d);
break;
case '4':
d->edit_veh->type = VEH_FIXEDWING;
vedit_disp_menu(d);
break;
case '5':
d->edit_veh->type = VEH_ROTORCRAFT;
vedit_disp_menu(d);
break;
case '6':
d->edit_veh->type = VEH_VECTORTHRUST;
vedit_disp_menu(d);
break;
case '7':
d->edit_veh->type = VEH_HOVERCRAFT;
vedit_disp_menu(d);
break;
case '8':
d->edit_veh->type = VEH_MOTORBOAT;
vedit_disp_menu(d);
break;
case '9':
d->edit_veh->type = VEH_SHIP;
vedit_disp_menu(d);
break;
case 'a':
d->edit_veh->type = VEH_LTA;
vedit_disp_menu(d);
break;
case '0':
default:
d->edit_veh->type = VEH_DRONE;
vedit_disp_menu(d);
break;
}
break;
case VEDIT_ATT:
switch(*arg) {
case '1':
send_to_char(CH, "Enter Handling Attribute: ");
d->edit_mode = VEDIT_HAND;
break;
case '2':
send_to_char(CH, "Enter Speed Attribute: ");
d->edit_mode = VEDIT_SP;
break;
case '3':
send_to_char(CH, "Enter Acceleration Attribute: ");
d->edit_mode = VEDIT_ACC;
break;
case '4':
send_to_char(CH, "Enter Body Attribute: ");
d->edit_mode = VEDIT_BOD;
break;
case '5':
send_to_char(CH, "Enter Armor Attribute: ");
d->edit_mode = VEDIT_ARMOR;
break;
case '6':
send_to_char(CH, "Enter Signature Attribute: ");
d->edit_mode = VEDIT_SIG;
break;
case '7':
send_to_char(CH, "Enter Autonav Attribute: ");
d->edit_mode = VEDIT_AUTO;
break;
case '8':
send_to_char(CH, "Enter Pilot Attribute: ");
d->edit_mode = VEDIT_PILOT;
break;
case '9':
send_to_char(CH, "Enter Seating (Front) Attribute: ");
d->edit_mode = VEDIT_SEAT;
break;
case '0':
send_to_char(CH, "Enter Load Attribute: ");
d->edit_mode = VEDIT_LOAD;
break;
case 'a':
send_to_char(CH, "Enter Cost: ");
d->edit_mode = VEDIT_COST;
break;
case 'q':
case 'Q':
vedit_disp_menu(d);
break;
default:
vedit_disp_att(d);
break;
}
break;
case VEDIT_HAND:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Handling attribute: ", CH);
} else {
d->edit_veh->handling = number;
vedit_disp_att(d);
}
break;
case VEDIT_SP:
number = atoi(arg);
if ((number < 0) || (number > 1500)) {
send_to_char("Value must range between 0 and 1500.\r\n", CH);
send_to_char("Enter Speed attribute: ", CH);
} else {
d->edit_veh->speed = number;
vedit_disp_att(d);
}
break;
case VEDIT_ACC:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Acceleration attribute: ", CH);
} else {
d->edit_veh->accel = number;
vedit_disp_att(d);
}
break;
case VEDIT_BOD:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Body attribute: ", CH);
} else {
d->edit_veh->body = number;
vedit_disp_att(d);
}
break;
case VEDIT_ARMOR:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Armor attribute: ", CH);
} else {
d->edit_veh->armor = number;
vedit_disp_att(d);
}
break;
case VEDIT_SIG:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Signature attribute: ", CH);
} else {
d->edit_veh->sig = number;
vedit_disp_att(d);
}
break;
case VEDIT_AUTO:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter AutoNav attribute: ", CH);
} else {
d->edit_veh->autonav = number;
vedit_disp_att(d);
}
break;
case VEDIT_PILOT:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Pilot attribute: ", CH);
} else {
d->edit_veh->pilot = number;
vedit_disp_att(d);
}
break;
case VEDIT_LOAD:
number = atoi(arg);
if ((number < 1) || (number > 15000)) {
send_to_char("Value must range between 1 and 15000.\r\n", CH);
send_to_char("Enter Load attribute: ", CH);
} else {
d->edit_veh->load = number;
vedit_disp_att(d);
}
break;
case VEDIT_SEAT:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Seating (Front) attribute: ", CH);
} else {
d->edit_veh->seating[1] = number;
send_to_char("Enter Seating (Rear) attribute: ", CH);
d->edit_mode = VEDIT_SEAT2;
}
break;
case VEDIT_SEAT2:
number = atoi(arg);
if ((number < 0) || (number > 50)) {
send_to_char("Value must range between 0 and 50.\r\n", CH);
send_to_char("Enter Seating (Rear) attribute: ", CH);
} else {
d->edit_veh->seating[0] = number;
vedit_disp_att(d);
}
break;
case VEDIT_COST:
number = atoi(arg);
d->edit_veh->cost = number;
vedit_disp_att(d);
break;
case VEDIT_EDIT_NAMELIST:
if (d->edit_veh->name)
delete [] d->edit_veh->name;
d->edit_veh->name = str_dup(arg);
vedit_disp_menu(d);
break;
case VEDIT_SHORTDESC:
if (d->edit_veh->short_description)
delete [] d->edit_veh->short_description;
d->edit_veh->short_description = str_dup(arg);
vedit_disp_menu(d);
break;
case VEDIT_DESC:
if (d->edit_veh->description)
delete [] d->edit_veh->description;
d->edit_veh->description = str_dup(arg);
vedit_disp_menu(d);
break;
case VEDIT_ARRIVE:
if (d->edit_veh->arrive)
delete [] d->edit_veh->arrive;
d->edit_veh->arrive = str_dup(arg);
vedit_disp_menu(d);
break;
case VEDIT_LEAVE:
if (d->edit_veh->leave)
delete [] d->edit_veh->leave;
d->edit_veh->leave = str_dup(arg);
vedit_disp_menu(d);
break;
case VEDIT_FLAGS:
number = atoi(arg);
if (number < 0 || number > NUM_VFLAGS)
send_to_char(CH, "Invalid choice. Choose Flag (0 to quit):");
else if (number == 0)
vedit_disp_menu(d);
else {
d->edit_veh->flags.ToggleBit(number);
vedit_disp_flag_menu(d);
}
break;
case VEDIT_ENGINE:
number = atoi(arg);
if (number < 1 || number > ENGINE_DIESEL)
send_to_char("Invalid Engine Type. Select Type : ", CH);
else {
d->edit_veh->engine = number;
vedit_disp_menu(d);
}
default:
break;
}
}
#undef VEH
void write_vehs_to_disk(int zone)
{
long counter, realcounter;
FILE *fp;
struct veh_data *veh;
zone = real_zone(zone);
veh = Mem->GetVehicle();
sprintf(buf, "%s/%d.veh", VEH_PREFIX, zone_table[zone].number);
fp = fopen(buf, "w+");
/* start running through all vehicles in this zone */
for (counter = zone_table[zone].number * 100; counter <= zone_table[zone].top; counter++) {
/* write vehicle to disk */
realcounter = real_vehicle(counter);
if (realcounter >= 0) {
*veh = veh_proto[realcounter];
if (!strcmp("an unfinished object", veh->name))
continue;
fprintf(fp, "#%ld\n", veh_index[veh->veh_number].vnum);
fprintf(fp, "Name:\t%s\n", veh->name ? veh->name : "unnamed");
fprintf(fp, "ShortDesc:\t%s\n", veh->short_description ? veh->short_description : "an unnamed vehicle");
fprintf(fp, "RoomDesc:\t%s\n", veh->description ? veh->description : "An unnamed vehicle sits here");
fprintf(fp, "LongDesc:$\n%s~\n", cleanup(buf2, veh->long_description ? veh->long_description : "You see an uncreative vehicle."));
fprintf(fp, "Inside:$\n%s~\n", cleanup(buf2, veh->inside_description ? veh->inside_description: "You see an uncreative vehicle."));
fprintf(fp, "InsideRear:$\n%s~\n", cleanup(buf2, veh->rear_description ? veh->rear_description: "You see an uncreative vehicle."));
fprintf(fp, "Leaving:\t%s\n", cleanup(buf2, veh->leave ? veh->leave : "leaves"));
fprintf(fp, "Arriving:\t%s\n", cleanup(buf2, veh->arrive ? veh->arrive : "arrives"));
fprintf(fp, "Handling:\t%d\n"
"Speed:\t%d\n"
"Accel:\t%d\n"
"Body:\t%d\n"
"Armour:\t%d\n"
"Pilot:\t%d\n",
veh->handling, veh->speed, veh->accel, veh->body, veh->armor, veh->pilot);
fprintf(fp, "Sig:\t%d\n"
"Autonav:\t%d\n"
"Seating:\t%d\n"
"SeatingBack:\t%d\n"
"Load:\t%d\n"
"Cost:\t%d\n"
"Type:\t%d\n"
"Flags:\t%s\n"
"Engine:\t%d\n",
veh->sig, veh->autonav, veh->seating[1], veh->seating[0], (int)veh->load, veh->cost, veh->type,
veh->flags.ToString(), veh->engine);
fprintf(fp, "BREAK\n");
}
}
/* write final line, close */
fprintf(fp, "END\n");
fclose(fp);
/* nuke temp vehicle, but not the strings */
Mem->ClearVehicle(veh);
write_index_file("veh");
}