/***************************************************************************\ [*] ___ ____ ____ __ __ ____ [*] ROGUE: ROM With Attitude [*] [*] /#/ ) /#/ ) /#/ ) /#/ /#/ /#/ [*] All rights reserved [*] [*] /#/ < /#/ / /#/ _ /#/ /#/ /#/-- [*] Copyright(C) 2000-2001 [*] [*] /#/ \(#(__/ (#(__/ (#(__/#/ (#(___ [*] Kenneth Conley (Mendanbar) [*] [*] Expression of Digital Creativity.. [*] scmud@mad.scientist.com [*] [-]---------------------------------------+-+-----------------------------[-] [*] File: vehicles.cpp [*] [*] Usage: Vehicle Functions [*] \***************************************************************************/ #include "merc.h" #include "interp.h" #include "lookup.h" void vehicle_move(OBJ_DATA *vehicle, ROOM_INDEX_DATA *to); extern char * dirs[]; extern char * dir_text[MAX_DIR]; #define VEHICLE_FLAGGED(vehicle, flag) (IS_SET((vehicle)->value[1], (flag))) #define NOWHERE -1 #define DRIVE_NOT 0 #define DRIVE_CONTROL 1 #define DRIVE_MOUNT 2 #define ROOM_SECT(room) (room->sector_type) CHAR_DATA *get_char_on_obj(OBJ_DATA *obj); OBJ_DATA *find_vehicle_by_vnum(int vnum) { OBJ_DATA *obj = NULL; for (obj = object_list; obj != NULL; obj = obj->next) { if (obj->pIndexData->vnum == vnum) break; } return obj; } ACMD(do_mount) { CHAR_DATA *tch; OBJ_DATA *vehicle; char arg[MAX_INPUT_LENGTH]; one_argument(argument, arg); if (!*arg) ch->Send("Mount what?\n\r"); else if (!(vehicle = get_obj_list(ch, arg, IN_ROOM(ch)->contents))) ch->Send("You do not see that here.\n\r"); else if ((tch = get_char_on_obj(vehicle))) act("$N is already mounted on $p.", ch, vehicle, tch, TO_CHAR); else if (!IS_MOUNTABLE(vehicle)) act("You can't mount $p.", ch, vehicle, 0, TO_CHAR); else { act("You mount $p.", ch, vehicle, 0, TO_CHAR); act("$n mounts $p.", ch, vehicle, 0, TO_ROOM); GET_POS(ch) = POS_SITTING; ch->on = vehicle; } } ACMD(do_unmount) { if (!ch->on) ch->Send("You aren't sitting on anything.\n\r"); else if (!IS_MOUNTABLE(ch->on)) ch->Send("You aren't sitting on a vehicle.\n\r"); else { GET_POS(ch) = POS_STANDING; act("You get off $p.", ch, ch->on, 0, TO_CHAR); act("$n gets off $p.", ch, ch->on, 0, TO_ROOM); ch->on = NULL; } } ACMD(do_drive) { int dir, drive_mode = DRIVE_NOT, i; OBJ_DATA *vehicle, *controls = NULL, *vehicle_in_out; char arg[MAX_INPUT_LENGTH]; if (ch->on && IS_MOUNTABLE(ch->on)) drive_mode = DRIVE_MOUNT; else { drive_mode = DRIVE_CONTROL; if (!(controls = get_obj_list_type(ITEM_V_CONTROLS, IN_ROOM(ch)->contents))) if (!(controls = get_obj_list_type(ITEM_V_CONTROLS, ch->carrying))) for (i = 0; i < MAX_WEAR; i++) { if ((controls = get_eq_char(ch, i)) && (controls->item_type == ITEM_V_CONTROLS)) break; } if (!controls) { ch->Send("You can't do that here.\n\r"); return; } if (!ch->CanUse(controls)) { ch->Send("You can't figure out the controls.\n\r"); return; } if (ch->position > POS_SITTING) { ch->Send("You must be sitting to drive.\n\r"); return; } } if (drive_mode == DRIVE_CONTROL) { vehicle = find_vehicle_by_vnum(controls->value[0]); if (!vehicle || vehicle->item_type != ITEM_VEHICLE) { ch->Send("The controls seem to be broken.\n\r"); return; } } else if (!(vehicle = (ch->on)) || (IN_ROOM(vehicle) == NULL)) { ch->Send("The vehicle exists yet it doesn't. Sorry, you're screwed...\r\n"); return; } if (AFF_FLAGGED(ch, AFF_BLIND)) { ch->Send("You can't see the controls!\n\r"); return; } argument = one_argument(argument, arg); if (!*arg) ch->Send("Drive which direction?\n\r"); else if (is_abbrev(arg, "into")) { ROOM_INDEX_DATA *is_going_to; one_argument(argument, arg); if (!*arg) ch->Send("Drive into what?\n\r"); else if (!(vehicle_in_out = get_obj_list(ch, arg, IN_ROOM(vehicle)->contents))) ch->Send("There is nothing here by that name.\n\r"); else if (vehicle_in_out->item_type != ITEM_VEHICLE) ch->Send("That is not a vehicle.\n\r"); else if (vehicle == vehicle_in_out) ch->Send("The laws of physics do not work that way.\n\r"); else if (IS_MOUNTABLE(vehicle_in_out)) ch->Send("Thats a mountable vehicle, not one you can drive into!\n\r"); else if (vehicle_in_out->value[0] == NOWHERE) ch->Send("That is not a vehicle.\n\r"); else if ((vehicle_in_out->value[4] / 2) < vehicle->value[4]) act("$p is too large to drive into $P.", ch, vehicle, vehicle_in_out, TO_CHAR); else if (!(is_going_to = get_room_index(vehicle_in_out->value[0])) || !ROOM_FLAGGED(is_going_to, ROOM_VEHICLE)) ch->Send("That vehicle can't carry other vehicles.\n\r"); else if (drive_mode == DRIVE_MOUNT) { act("$n drives $p into $P.", ch, vehicle, vehicle_in_out, TO_ROOM); act("You drive $p into $P.", ch, vehicle, vehicle_in_out, TO_CHAR); vehicle_move(vehicle, is_going_to); act("$n drives $p in.", ch, vehicle, 0, TO_ROOM); look_at_room(ch, 0); } else { act("You drive into $P", ch, 0, vehicle_in_out, TO_CHAR); act("$n drives into $P.", ch, 0, vehicle_in_out, TO_ROOM); act("$p enters $P.", 0, vehicle, vehicle_in_out, TO_ROOM); vehicle_move(vehicle, is_going_to); act("$p enters.", 0, vehicle, 0, TO_ROOM); look_at_rnum(ch, IN_ROOM(vehicle), FALSE); } } else if (is_abbrev(arg, "out")) { OBJ_DATA *hatch; if (!(hatch = get_obj_list_type(ITEM_V_HATCH, IN_ROOM(vehicle)->contents))) ch->Send("Nowhere to drive out of.\n\r"); else if (!(vehicle_in_out = find_vehicle_by_vnum(hatch->value[0])) || (IN_ROOM(vehicle_in_out) == NULL)) ch->Send("ERROR! Vehicle to drive out of does not exist!\n\r"); else if (drive_mode == DRIVE_MOUNT) { act("$n drives $p out.", ch, vehicle, 0, TO_ROOM); act("You drive $p out of $P.", ch, vehicle, vehicle_in_out, TO_CHAR); vehicle_move(vehicle, IN_ROOM(vehicle_in_out)); act("$n drives $p out of $P.", ch, vehicle, vehicle_in_out, TO_ROOM); look_at_room(ch, 0); } else { act("$p exits $P.", 0, vehicle, vehicle_in_out, TO_ROOM); vehicle_move(vehicle, IN_ROOM(vehicle_in_out)); act("$p drives out of $P.", 0, vehicle, vehicle_in_out, TO_ROOM); act("$n drives out of $P.", ch, 0, vehicle_in_out, TO_ROOM); act("You drive $p out of $P.", ch, vehicle, vehicle_in_out, TO_CHAR); look_at_rnum(ch, IN_ROOM(vehicle), FALSE); } } else if ((dir = search_block(arg, dir_name, FALSE)) >= 0) { if (!ch || (dir < 0) || (dir >= MAX_DIR) || (IN_ROOM(vehicle) == NULL)) ch->Send("Sorry, an internal error has occurred.\n\r"); else if (!CAN_GO(vehicle, dir)) ch->Send("Alas, you cannot go that way...\n\r"); else if (EXIT_FLAGGED(EXIT(vehicle, dir), EX_CLOSED)) { if (EXIT(vehicle, dir)->keyword) act("The $d seems to be closed.", ch, 0, (EXIT(vehicle, dir)->keyword), TO_CHAR); else act("It seems to be closed.", ch, 0, 0, TO_CHAR); } else if (!ROOM_FLAGGED(EXIT(vehicle, dir)->u1.to_room, ROOM_VEHICLE) || EXIT_FLAGGED(EXIT(vehicle, dir), EX_NOVEHICLES)) ch->Send("The vehicle can't manage that terrain.\n\r"); else if (ROOM_SECT(EXIT(vehicle, dir)->u1.to_room) == SECT_AIR && !VEHICLE_FLAGGED(vehicle, VEHICLE_AIR)) act("The $o can't fly.", ch, vehicle, 0, TO_CHAR); else if ((ROOM_SECT(EXIT(vehicle, dir)->u1.to_room) == SECT_WATER_NOSWIM) && !VEHICLE_FLAGGED(vehicle, VEHICLE_WATER | VEHICLE_SUBMERGE)) act("The $o can't go in such deep water!", ch, vehicle, 0, TO_CHAR); else if ((ROOM_SECT(EXIT(vehicle, dir)->u1.to_room) == SECT_UNDERWATER) && !VEHICLE_FLAGGED(vehicle, VEHICLE_SUBMERGE)) act("The $o can't go underwater!", ch, vehicle, 0, TO_CHAR); else if ((ROOM_SECT(EXIT(vehicle, dir)->u1.to_room) == SECT_SPACE) && !VEHICLE_FLAGGED(vehicle, VEHICLE_SPACE)) act("The $o cannot handle space travel.", ch, vehicle, 0, TO_CHAR); else if ((ROOM_SECT(EXIT(vehicle, dir)->u1.to_room) > SECT_FIELD) && (ROOM_SECT(EXIT(vehicle, dir)->u1.to_room) <= SECT_MOUNTAIN) && !VEHICLE_FLAGGED(vehicle, VEHICLE_GROUND)) act("The $o cannot land on that terrain.", ch, vehicle, 0, TO_CHAR); else { // But nothing! Let's go that way! if (drive_mode == DRIVE_MOUNT) act("$n drives $p $T.", ch, vehicle, dirs[dir], TO_ROOM); else act("$p leaves $T.", 0, vehicle, dirs[dir], TO_ROOM); vehicle_move(vehicle, EXIT(vehicle, dir)->u1.to_room); if (drive_mode == DRIVE_MOUNT) { act("You drive $p $T.", ch, vehicle, dirs[dir], TO_CHAR); act("$n enters from $T on $p.", ch, vehicle, dir_text[rev_dir[dir]], TO_ROOM); if (ch->desc != NULL) look_at_room(ch, 0); } else { act("$p enters from $T.", 0, vehicle, dir_text[rev_dir[dir]], TO_ROOM); act("$n drives $T.", ch, 0, dirs[dir], TO_ROOM); act("You drive $T.", ch, 0, dirs[dir], TO_CHAR); if (ch->desc != NULL) look_at_rnum(ch, IN_ROOM(vehicle), FALSE); } } } else ch->Send("That is not a valid direction.\n\r"); return; } void vehicle_move(OBJ_DATA *vehicle, ROOM_INDEX_DATA *to) { CHAR_DATA *tch; ROOM_INDEX_DATA *prev_in = IN_ROOM(vehicle); for (tch = prev_in->people; tch != NULL; tch = tch->next_in_room) { if (tch->on == vehicle) { char_from_room(tch); char_to_room(tch, to); tch->on = vehicle; } } obj_from_room(vehicle); obj_to_room(vehicle, to); }