/** * Remove a player from the game that has been disconnected by logging * out, the socket connection was interrupted, etc. * @param pl The player to remove. */ void remove_ns_dead_player(player *pl) { if (pl == NULL || pl->ob->type == DEAD_OBJECT) { return; } if (pl->state == ST_PLAYING) { /* Trigger the global LOGOUT event */ trigger_global_event(GEVENT_LOGOUT, pl->ob, pl->socket.host); if (!pl->dm_stealth) { new_draw_info_format(NDI_UNIQUE | NDI_ALL | NDI_DK_ORANGE, NULL, "%s left the game.", query_name(pl->ob, NULL)); } /* If this player is in a party, leave the party */ if (pl->party) { command_party(pl->ob, "leave"); } strncpy(pl->killer, "left", MAX_BUF - 1); hiscore_check(pl->ob, 1); /* Be sure we have closed container when we leave */ container_unlink(pl, NULL); save_player(pl->ob, 0); if (!QUERY_FLAG(pl->ob, FLAG_REMOVED)) { leave_map(pl->ob); } if (pl->ob->map) { if (pl->ob->map->in_memory == MAP_IN_MEMORY) { pl->ob->map->timeout = MAP_TIMEOUT(pl->ob->map); } pl->ob->map = NULL; } } LOG(llevInfo, "LOGOUT: >%s< from IP %s\n", pl->ob->name, pl->socket.host); /* To avoid problems with inventory window */ pl->ob->type = DEAD_OBJECT; free_player(pl); }
/* Cheap hack of process_exit from overland.c for ships */ ch_ret process_shipexit( char_data * ch, short map, short x, short y, int dir ) { int sector = get_terrain( map, x, y ), move; room_index *from_room; ship_data *ship = ch->on_ship; ch_ret retcode; short fx, fy, fmap; from_room = ch->in_room; fx = ch->mx; fy = ch->my; fmap = ch->cmap; retcode = rNONE; if( ch->has_pcflag( PCFLAG_MAPEDIT ) ) { ch->print( "Get off the ship before you start editing.\r\n" ); return rSTOP; } if( sector == SECT_EXIT ) { mapexit_data *mexit; room_index *toroom = NULL; mexit = check_mapexit( map, x, y ); if( mexit != NULL ) { if( mexit->tomap != -1 ) /* Means exit goes to another map */ { if( !can_move_ship( ch, get_terrain( mexit->tomap, mexit->therex, mexit->therey ) ) ) return rSTOP; enter_map( ch, NULL, mexit->therex, mexit->therey, mexit->tomap ); if( ch->mount ) enter_map( ch->mount, NULL, mexit->therex, mexit->therey, mexit->tomap ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) && fch->mx == fx && fch->my == fy && fch->cmap == fmap ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_exit( fch, fch->cmap, x, y, dir, false ); } else enter_map( fch, NULL, mexit->therex, mexit->therey, mexit->tomap ); } } return rSTOP; } if( !( toroom = get_room_index( mexit->vnum ) ) ) { bug( "%s: Target vnum %d for map exit does not exist!", __FUNCTION__, mexit->vnum ); ch->print( "Ooops. Something bad happened. Contact the immortals ASAP.\r\n" ); return rSTOP; } if( !can_move_ship( ch, toroom->sector_type ) ) return rSTOP; if( !str_cmp( ch->name, ship->owner ) ) act_printf( AT_ACTION, ch, NULL, dir_name[dir], TO_ROOM, "%s sails off to the $T.", ship->name.c_str( ) ); ch->on_ship->room = toroom->vnum; leave_map( ch, NULL, toroom ); list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && fch->position == POS_STANDING && fch->mx == fx && fch->my == fy && fch->cmap == fmap ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_shipexit( fch, fch->cmap, x, y, dir ); } else leave_map( fch, ch, toroom ); } } return rSTOP; } } switch ( dir ) { default: ch->print( "Alas, you cannot go that way...\r\n" ); return rSTOP; case DIR_NORTH: if( y == -1 ) { ch->print( "You cannot sail any further north!\r\n" ); return rSTOP; } break; case DIR_EAST: if( x == MAX_X ) { ch->print( "You cannot sail any further east!\r\n" ); return rSTOP; } break; case DIR_SOUTH: if( y == MAX_Y ) { ch->print( "You cannot sail any further south!\r\n" ); return rSTOP; } break; case DIR_WEST: if( x == -1 ) { ch->print( "You cannot sail any further west!\r\n" ); return rSTOP; } break; case DIR_NORTHEAST: if( x == MAX_X || y == -1 ) { ch->print( "You cannot sail any further northeast!\r\n" ); return rSTOP; } break; case DIR_NORTHWEST: if( x == -1 || y == -1 ) { ch->print( "You cannot sail any further northwest!\r\n" ); return rSTOP; } break; case DIR_SOUTHEAST: if( x == MAX_X || y == MAX_Y ) { ch->print( "You cannot sail any further southeast!\r\n" ); return rSTOP; } break; case DIR_SOUTHWEST: if( x == -1 || y == MAX_Y ) { ch->print( "You cannot sail any further southwest!\r\n" ); return rSTOP; } break; } if( !can_move_ship( ch, sector ) ) return rSTOP; move = sect_show[sector].move; if( ship->fuel < move && !ch->is_immortal( ) ) { ch->print( "Your ship is too low on magical energy to sail further ahead.\r\n" ); return rSTOP; } if( !ch->is_immortal( ) && !str_cmp( ch->name, ship->owner ) ) ship->fuel -= move; if( !str_cmp( ch->name, ship->owner ) ) act_printf( AT_ACTION, ch, NULL, dir_name[dir], TO_ROOM, "%s sails off to the $T.", ship->name.c_str( ) ); ch->mx = x; ch->my = y; ship->mx = x; ship->my = y; if( !str_cmp( ch->name, ship->owner ) ) { const char *txt = rev_exit( dir ); act_printf( AT_ACTION, ch, NULL, NULL, TO_ROOM, "%s sails in from the %s.", ship->name.c_str( ), txt ); } list < char_data * >::iterator ich; size_t chars = from_room->people.size( ); size_t count = 0; for( ich = from_room->people.begin( ); ich != from_room->people.end( ), ( count < chars ); ) { char_data *fch = *ich; ++ich; ++count; if( fch != ch /* loop room bug fix here by Thoric */ && fch->master == ch && ( fch->position == POS_STANDING || fch->position == POS_MOUNTED ) && fch->mx == fx && fch->my == fy ) { if( !fch->isnpc( ) ) { act( AT_ACTION, "The ship sails $T.", fch, NULL, dir_name[dir], TO_CHAR ); process_exit( fch, fch->cmap, x, y, dir, false ); } else { fch->mx = x; fch->my = y; } } } interpret( ch, "look" ); return retcode; }