/
area/ril/
help/olc/
src/
src/current_project/
src/docs/
src/documents/
/**************************************************************************/ 
// 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(); 
} 
/**************************************************************************/ 
/**************************************************************************/ 
/**************************************************************************/ 
/**************************************************************************/