/**************************************************************************/
// vehicle.cpp - Vehicle movement & Combat by Ixliam
/***************************************************************************
* Whispers of Times Lost (c)1998-2004 Brad Wilson (ixliam@wotl.org) *
* >> If you use this code you must give credit in your help file as well *
* as leaving this header intact. *
* >> To use this source code, you must fully comply with all the licenses *
* in licenses below. In particular, you may not remove this copyright *
* notice. *
***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with the dawn license *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
**************************************************************************/
#include "include.h"
#include "vehicle.h"
DECLARE_DO_FUN( do_look );
bool laston_find(char *argument);
/**************************************************************************/
// semilocalized globals
VEHICLE_DATA *vehicle_list;
/**************************************************************************/
// create vehicle GIO lookup table
GIO_START(VEHICLE_DATA)
GIO_INTH(reset, "Reset ")
GIO_INTH(vnum, "Vnum ")
GIO_FINISH_STRDUP_EMPTY
/**************************************************************************/
// loads in the vehicle database
void load_vehicle_db(void)
{
VEHICLE_DATA *node;
OBJ_DATA *obj;
room_index_data *room=NULL;
logf("===Loading vehicle database from %s...", VEHICLE_FILE);
GIOLOAD_LIST(vehicle_list, VEHICLE_DATA, VEHICLE_FILE);
for (node = vehicle_list; node; node= node->next)
{
room = get_room_index(node->reset);
if(room)
{
obj = create_object(get_obj_index(node->vnum));
obj_to_room(obj, room);
}
}
log_string ("load_vehicle_db(): finished");
}
/**************************************************************************/
// saves the vehicle database
void save_vehicle_db( void)
{
logf("===save_vehicle_db(): saving vehicle database to %s", VEHICLE_FILE);
GIOSAVE_LIST(vehicle_list, VEHICLE_DATA, VEHICLE_FILE, true);
}
/**************************************************************************/
// lists vehicles
void do_vehiclelist( char_data *ch, char *)
{
VEHICLE_DATA *node;
int count;
ch->titlebar("-=VEHICLE RESETS=-");
count=0;
for (node = vehicle_list; node; node= node->next)
{
ch->printlnf("`s%d> `MRoom: `m%d `MVnum: `m%d", ++count, node->reset, node->vnum);
}
return;
}
/**************************************************************************************/
void queue_vehicle(int reset, int vnum)
{
VEHICLE_DATA *node = new VEHICLE_DATA;
node->reset = reset;
node->vnum = vnum;
node->next = vehicle_list;
vehicle_list = node;
save_vehicle_db();
}
/**************************************************************************/
EXTRA_DESCR_DATA *ed_prefix(EXTRA_DESCR_DATA *ed, char *keyword, char *description);
/**************************************************************************/
/**************************************************************************/
void do_vehicle_add(char_data *ch, char *argument)
{
OBJ_DATA *obj = NULL;
char arg1[MIL];
argument = one_argument( argument, arg1 );
obj = get_obj_list( ch, arg1, ch->in_room->contents );
if (obj == NULL )
{
ch->println("No vehicle here to add to database.");
return;
}
if ( obj->item_type!=ITEM_VEHICLE)
{
ch->println("That is not a vehicle.");
return;
}
queue_vehicle(ch->in_room->vnum, obj->pIndexData->vnum);
ch->printlnf("%s `W[`S%d`W] `wadded in room %d.",obj->short_descr, obj->pIndexData->vnum, ch->in_room->vnum);
return;
}
/**************************************************************************/
int get_direction( char *arg )
{
if ( !str_cmp( arg, "n" ) || !str_cmp( arg, "north" ) ) return 0;
else if ( !str_cmp( arg, "e" ) || !str_cmp( arg, "east" ) ) return 1;
else if ( !str_cmp( arg, "s" ) || !str_cmp( arg, "south" ) ) return 2;
else if ( !str_cmp( arg, "w" ) || !str_cmp( arg, "west" ) ) return 3;
else if ( !str_cmp( arg, "u" ) || !str_cmp( arg, "up" ) ) return 4;
else if ( !str_cmp( arg, "d" ) || !str_cmp( arg, "down" ) ) return 5;
else if ( !str_cmp( arg, "ne" ) || !str_cmp( arg, "northeast" ) ) return 6;
else if ( !str_cmp( arg, "se" ) || !str_cmp( arg, "southeast" ) ) return 7;
else if ( !str_cmp( arg, "sw" ) || !str_cmp( arg, "southwest" ) ) return 8;
else if ( !str_cmp( arg, "nw" ) || !str_cmp( arg, "northwest" ) ) return 9;
return -1;
}
/**************************************************************************/
void travelecho( char_data *ch, OBJ_DATA *vehicle )
{
int chance = 0;
for(char_data *vch = player_list; vch; vch = vch->next_player)
{
if(vch==ch)
{
if(IS_IMMORTAL(vch) || IS_SET(ch->comm,COMM_BUILDING))
{
vch->print("`#`STravelEcho: `^");
}
vch->print(get_extra_descr("_TRAVEL", vehicle->pIndexData->extra_descr));
vch->println("`x");
continue;
}
if(ch->in_room->area==vch->in_room->area && vch->in_room->sector_type == SECT_VEHICLE)
{
chance = number_range(1,2);
if(vch!=ch && chance==1)
{
if(IS_IMMORTAL(vch) || IS_SET(vch->comm,COMM_BUILDING))
{
vch->print("`#`STravelEcho: `^");
}
vch->print(get_extra_descr("_TRAVEL", vehicle->pIndexData->extra_descr));
vch->println("`x");
}
}
}
return;
}
/**************************************************************************/
void do_drive( char_data *ch, char *argument )
{
char_data *vch;
ROOM_INDEX_DATA *in_room;
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
char arg1[MIL];
OBJ_DATA *controls;
OBJ_DATA *vehicle = NULL;
int direction;
int dir_name_2;
for ( controls = ch->in_room->contents; controls != NULL; controls = controls->next_content )
{
if ( controls->item_type == ITEM_VEHICLE_CONTROLS )
break;
}
if ( controls == NULL )
{
ch->println("Nothing to drive here.");
return;
}
if ( ( vehicle = get_obj_type( get_obj_index( controls->value[0] ) ) ) == NULL )
{
ch->println("Error, can't find vehicle for control panel." );
return;
}
if ( vehicle->item_type != ITEM_VEHICLE )
{
do_huh(ch, "");
return;
}
if ( vehicle->in_room == NULL )
{
ch->println("Error, vehicle room is null." );
return;
}
in_room = vehicle->in_room;
argument = one_argument( argument, arg1 );
direction = get_direction( arg1 );
if ( arg1[0] == '\0' )
direction = -1;
if ( direction == -1 )
{
ch->println("Drive where ?" );
return;
}
if ( ( pexit = in_room->exit[direction] ) == NULL
|| ( to_room = pexit->u1.to_room ) == NULL
|| !can_see_room(ch,pexit->u1.to_room))
{
ch->println("There is no way to travel in that direction." );
return;
}
if (IS_SET(pexit->exit_info, EX_ISDOOR) && to_room->sector_type!=SECT_CITY)
{
ch->println("You cannot drive through there." );
return;
}
if (IS_SET(to_room->room_flags, ROOM_INDOORS) && !IS_SET(vehicle->value[2], VEHICLE_CAVE))
{
ch->println("You cannot drive indoors." );
return;
}
if (IS_SET(pexit->exit_info, EX_LOCKED))
{
ch->println("That direction seems to be barred to you." );
return;
}
if( to_room->sector_type==SECT_LAVA && !IS_SET(vehicle->value[2], VEHICLE_LAVA))
{
ch->println("You would burn there.");
return;
}
if( to_room->sector_type==SECT_WATER_NOSWIM && !IS_SET(vehicle->value[2], VEHICLE_WATER))
{
ch->println("You are not in a boat.");
return;
}
if( to_room->sector_type==SECT_AIR && !IS_SET(vehicle->value[2], VEHICLE_AIR))
{
ch->println("This vehicle cannot fly.");
return;
}
if( to_room->sector_type==SECT_CAVE && !IS_SET(vehicle->value[2], VEHICLE_CAVE))
{
ch->println("This vehicle cannot travel underground.");
return;
}
if( to_room->sector_type==SECT_INSIDE)
{
ch->println("You cannot go there.");
return;
}
if ( to_room->sector_type==SECT_UNDERWATER ||IS_SET( to_room->affected_by, ROOMAFF_UNDERWATER ))
{
ch->println("This vehicle cannot go underwater.");
return;
}
if((to_room->sector_type==SECT_CITY || to_room->sector_type==SECT_FIELD ||
to_room->sector_type==SECT_FOREST || to_room->sector_type==SECT_HILLS ||
to_room->sector_type==SECT_MOUNTAIN || to_room->sector_type==SECT_SWAMP ||
to_room->sector_type==SECT_DESERT ||
to_room->sector_type==SECT_SNOW || to_room->sector_type==SECT_ICE ||
to_room->sector_type==SECT_TRAIL || to_room->sector_type==SECT_GATEWAY ) &&
!IS_SET(vehicle->value[2], VEHICLE_LAND))
{
ch->println("This vehicle cannot travel on land.");
return;
}
for ( vch = in_room->people; vch != NULL; vch = vch->next_in_room )
{
if ( can_see_obj( vch, vehicle ) )
vch->printlnf( "%s leaves %s.", capitalize(vehicle->short_descr), dir_name[direction] );
}
obj_from_room( vehicle );
obj_to_room( vehicle, to_room );
dir_name_2 = rev_dir[direction];
for ( vch = to_room->people; vch != NULL; vch = vch->next_in_room )
{
if ( can_see_obj( vch, vehicle ) )
vch->printlnf( "%s has arrived from %s.", capitalize(vehicle->short_descr), dir_name[dir_name_2] );
}
bool travel = false;
if( to_room->sector_type==SECT_AIR && IS_SET(vehicle->value[2], VEHICLE_AIR) && travel==false)
{
ch->printlnf( "You fly %s %s.", vehicle->short_descr, dir_name[direction] );
travel = true;
}
if (IS_SET(vehicle->value[2], VEHICLE_LAND) && to_room->sector_type==SECT_SNOW && travel==false)
{
ch->printlnf( "You drive %s %s through the snow.", vehicle->short_descr, dir_name[direction] );
travel = true;
}
if (IS_SET(vehicle->value[2], VEHICLE_LAND) && to_room->sector_type==SECT_SNOW && travel==false)
{
ch->printlnf( "You drive %s %s through the ice.", vehicle->short_descr, dir_name[direction] );
travel = true;
}
if (IS_SET(vehicle->value[2], VEHICLE_LAND) && to_room->sector_type!=SECT_WATER_NOSWIM && travel==false)
{
ch->printlnf( "You drive %s %s.", vehicle->short_descr, dir_name[direction] );
travel = true;
}
if (IS_SET(vehicle->value[2], VEHICLE_WATER) && to_room->sector_type==SECT_WATER_NOSWIM && travel==false)
{
ch->printlnf( "You sail %s %s.", vehicle->short_descr, dir_name[direction] );
travel = true;
}
if (IS_SET(vehicle->value[2], VEHICLE_WATER) && to_room->sector_type==SECT_WATER_SWIM && travel==false)
{
ch->printlnf( "You sail %s %s through the shallow water.", vehicle->short_descr, dir_name[direction] );
travel = true;
}
if (travel==false)
{
ch->printlnf( "You move %s %s.", vehicle->short_descr, dir_name[direction] );
travel = true;
}
travelecho(ch, controls);
in_room = ch->in_room;
char_from_room( ch );
char_to_room( ch, to_room );
do_look( ch, "" );
char_from_room( ch );
char_to_room( ch, in_room );
return;
}
/**************************************************************************/
void do_board( char_data *ch, char *argument )
{
char arg1[MIL];
ROOM_INDEX_DATA *to_room;
OBJ_DATA *building, *building_next = NULL;
OBJ_DATA *vehicle = NULL;
argument = one_argument( argument, arg1 );
if ( IS_NULLSTR(arg1))
{
for ( building = ch->in_room->contents; building != NULL; building = building_next )
{
building_next = building->next_content;
if ( building->item_type!=ITEM_VEHICLE_EXIT)
continue;
if ( building->item_type==ITEM_VEHICLE_EXIT)
{
if ( ( vehicle = get_obj_type( get_obj_index( building->value[0] ) ) ) == NULL )
{
ch->println("Error, can't find ship for vehicle exit." );
return;
}
act("You leave $p.", ch, vehicle, NULL, TO_CHAR );
act("$n leaves $p.", ch, vehicle, NULL, TO_ROOM );
char_from_room( ch );
char_to_room( ch, get_room_index(vehicle->in_room->vnum));
do_look( ch, "" );
act("$n has arrived from $p.", ch, vehicle, NULL, TO_ROOM);
return;
}
}
}
building = get_obj_list( ch, arg1, ch->in_room->contents );
if ( building == NULL )
{
ch->println("Nothing like that to board here.");
return;
}
if ( building->item_type==ITEM_VEHICLE_EXIT)
{
if ( ( vehicle = get_obj_type( get_obj_index( building->value[0] ) ) ) == NULL )
{
ch->println("Error, can't find vehicle for this exit." );
return;
}
act("You leave $p.", ch, vehicle, NULL, TO_CHAR );
act("$n leaves $p.", ch, vehicle, NULL, TO_ROOM );
char_from_room( ch );
char_to_room( ch, get_room_index(vehicle->in_room->vnum));
do_look( ch, "" );
act("$n has arrived from $p.", ch, vehicle, NULL, TO_ROOM);
return;
}
if ( building->item_type!=ITEM_VEHICLE)
{
ch->println("Nothing to board here." );
return;
}
if ( ( to_room = get_room_index( building->value[0] ) ) == NULL )
{
ch->println("Error, bad room pointed to by building object." );
return;
}
act("You board $p.", ch, building, NULL, TO_CHAR );
act("$n boards $p.", ch, building, NULL, TO_ROOM );
char_from_room( ch );
char_to_room( ch, to_room);
do_look( ch, "" );
act("$n has arrived from outside.", ch, NULL, NULL, TO_ROOM);
return;
}
/**************************************************************************/
void do_vehicle_delete( char_data *ch, char *argument )
{
VEHICLE_DATA *node;
VEHICLE_DATA *prevnode=NULL;
int target, count=1;
if(vehicle_list==NULL){
ch->println("There are no vehicles in the database.");
return;
}
if(IS_NULLSTR(argument)){
ch->println("syntax: vehicledelete <vehicle_number>");
return;
};
if(!is_number(argument)){
ch->print("Argument to vehicledelete must be a number.");
return;
}
target=atoi(argument);
for (node=vehicle_list;node;node=node->next, ++count){
if(count==target)
break;
prevnode = node;
}
if(node==NULL){
ch->printf(0, "Vehicle not found.");
return;
}
ch->printf(0, "Vehicle Vnum #%d has been deleted.\r\n", node->vnum);
if(!prevnode){ // delete the head
vehicle_list = vehicle_list->next;
}else{
prevnode->next=node->next;
}
delete node;
save_vehicle_db();
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/