示例#1
0
std::string Room::get_description_with_doors()
{
	std::string direction_names[] = {"North", "East", "South", "West", "Up", "Down", "Secret0", "Secret1", "Secret2", "Invalid"};
	std::string retval = description;
	for (std::size_t i = 0; i < static_cast<std::size_t>(Exit::INVALID); ++i)
	{
		//if we have a door description, add it in
		if (door_descriptions[i] != "")
		{
			std::string c = "green>open";
			if (get_exit(static_cast<Exit>(i)) == Exit_Status::Locked)
			{
				c = "red>locked";
			}
			#ifdef DEBUG
			else if (get_exit(static_cast<Exit>(i)) == Exit_Status::Wall)
			{
				Log::write("Warning: The room '" + StringUtils::to_string(static_cast<int>(my_handle)) + "' has a door but the door is neither locked nor open. Just counting it as 'open'.");
			}
			#endif
			
			retval += "<fg=white><bg=black>\nTo the " + direction_names[i] + " is " + door_descriptions[i] + "<fg=white><bg=black>. It is <fg=" + c + "<fg=white>.";
		}
		//if there is no door description but the way is still locked, just say there's a generic door
		else if (exits[i] == Exit_Status::Locked)
		{
			retval += "<fg=white><bg=black>\nTo the " + direction_names[i] + " is an unremarkable door. It is <fg=red>locked<fg=white>.";
		}
	}
	
	return retval;
}
示例#2
0
void hunt_victim( CHAR_DATA * ch )
{
    bool found;
    CHAR_DATA *tmp;
    EXIT_DATA *pexit;
    short ret;

    if( !ch || !ch->hunting || ch->position < 5 )
        return;

    /*
     * make sure the char still exists
     */
    for( found = FALSE, tmp = first_char; tmp && !found; tmp = tmp->next )
        if( ch->hunting->who == tmp )
            found = TRUE;

    if( !found )
    {
        do_say( ch, "Damn!  My prey is gone!!" );
        stop_hunting( ch );
        return;
    }

    if( ch->in_room == ch->hunting->who->in_room )
    {
        if( ch->fighting )
            return;
        found_prey( ch, ch->hunting->who );
        return;
    }

    ret = find_first_step( ch->in_room, ch->hunting->who->in_room, 500 + ch->level * 25 );
    if( ret < 0 )
    {
        do_say( ch, "Damn!  Lost my prey!" );
        stop_hunting( ch );
        return;
    }
    else
    {
        if( ( pexit = get_exit( ch->in_room, ret ) ) == NULL )
        {
            bug( "%s", "Hunt_victim: lost exit?" );
            return;
        }
        move_char( ch, pexit, FALSE );

        /*
         * Crash bug fix by Shaddai
         */
        if( char_died( ch ) )
            return;

        if( !ch->hunting )
        {
            if( !ch->in_room )
            {
                bug( "Hunt_victim: no ch->in_room!  Mob #%d, name: %s.  Placing mob in limbo.", ch->pIndexData->vnum, ch->name );
                char_to_room( ch, get_room_index( ROOM_VNUM_LIMBO ) );
                return;
            }
            do_say( ch, "Damn!  Lost my prey!" );
            return;
        }
        if( ch->in_room == ch->hunting->who->in_room )
            found_prey( ch, ch->hunting->who );
        else
        {
            CHAR_DATA *vch;

            /*
             * perform a ranged attack if possible
             */
            /*
             * Changed who to name as scan_for_victim expects the name and
             * * Not the char struct. --Shaddai
             */
            if( ( vch = scan_for_victim( ch, pexit, ch->hunting->name ) ) != NULL )
            {
                if( !mob_fire( ch, ch->hunting->who->name ) )
                {
                    /*
                     * ranged spell attacks go here
                     */
                }
            }
        }
        return;
    }
}
示例#3
0
SPEC_RET spec_mayor( CHAR_DATA *ch )
{
	static const char  open_path[]  = "W3a3003b33000c111d0d111Oe333333Oe22c222112212111a1S.";
	static const char  close_path[] = "W3a3003b33000c111d0d111CE333333CE22c222112212111a1S.";
	static const char *path;
	static int		   pos;
	static bool		   move;

	if ( !move )
	{
		if ( calendar.hour == 6 )
		{
			path = open_path;
			move = TRUE;
			pos  = 0;
		}

		if ( calendar.hour == 20 )
		{
			path = close_path;
			move = TRUE;
			pos  = 0;
		}
	}

	if ( ch->fighting )
		return spec_cast_cleric( ch );

	if ( !move || ch->position < POSITION_SLEEP )
		return FALSE;

	/* (TR) */
	switch ( path[pos] )
	{
	  case '0':
	  case '1':
	  case '2':
	  case '3':
		move_char( ch, get_exit(ch->in_room, path[pos] - '0'), 0, FALSE );
		break;

	  case 'W':
		ch->position = POSITION_STAND;
		act( AT_ACTION, "$n awakens and groans loudly.", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'S':
		ch->position = POSITION_SLEEP;
		act( AT_ACTION, "$n lies down and falls asleep.", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'a':
		act( AT_SAY, "$n says 'Hello Honey!'", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'b':
		act( AT_SAY, "$n says 'What a view!  I must do something about that dump!'", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'c':
		act( AT_SAY, "$n says 'Vandals!  Youngsters have no respect for anything!'", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'd':
		act( AT_SAY, "$n says 'Good day, citizens!'", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'e':
		act( AT_SAY, "$n says 'I hereby declare the town of Darkhaven open!'", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'E':
		act( AT_SAY, "$n says 'I hereby declare the town of Darkhaven closed!'", ch, NULL, NULL, TO_ROOM );
		break;

	  case 'O':
	  	send_command( ch, "unlock gate", CO );
		send_command( ch, "open gate", CO );
		break;

	  case 'C':
	  	send_command( ch, "close gate", CO );
	  	send_command( ch, "lock gate", CO );
		break;

	  case '.' :
		move = FALSE;
		break;
	}

	pos++;
	return FALSE;
}
示例#4
0
/* This function is recursive, ie it calls itself */
void map_exits( CHAR_DATA * ch, ROOM_INDEX_DATA * pRoom, int x, int y, int depth )
{
	static char map_chars[11] = "|-|-UD/\\\\/";
	int door;
	int exitx = 0, exity = 0;
	int roomx = 0, roomy = 0;
	EXIT_DATA *pExit;

	/*
	 * Setup this coord as a room - Change any symbols that can't be displayed here 
	 */
	dmap[x][y].sector = pRoom->sector_type;
	switch ( pRoom->sector_type )
	{
		case SECT_INSIDE:
			dmap[x][y].tegn = 'O';
			dmap[x][y].sector = -1;
			break;

		case SECT_CITY:
			dmap[x][y].tegn = ':';
			break;

		case SECT_FIELD:
		case SECT_FOREST:
		case SECT_HILLS:
			dmap[x][y].tegn = '*';
			break;

		case SECT_MOUNTAIN:
			dmap[x][y].tegn = '@';
			break;

		case SECT_WATER_SWIM:
		case SECT_WATER_NOSWIM:
			dmap[x][y].tegn = '=';
			break;

		case SECT_AIR:
			dmap[x][y].tegn = '~';
			break;

		case SECT_DESERT:
			dmap[x][y].tegn = '+';
			break;

		default:
			dmap[x][y].tegn = 'O';
			dmap[x][y].sector = -1;
			bug( "%s: Bad sector type (%d) in room %d.", __FUNCTION__, pRoom->sector_type, pRoom->vnum );
			break;
	}

	dmap[x][y].vnum = pRoom->vnum;
	dmap[x][y].depth = depth;
//   dmap[x][y].info = pRoom->room_flags;
	dmap[x][y].can_see = room_is_dark( pRoom );

	/*
	 * Limit recursion 
	 */
	if ( depth > MAXDEPTH )
		return;

	/*
	 * This room is done, deal with it's exits 
	 */
	for ( door = 0; door < 10; ++door )
	{
		/*
		 * Skip if there is no exit in this direction 
		 */
		if ( !( pExit = get_exit( pRoom, door ) ) )
			continue;

		/*
		 * Skip up and down until I can figure out a good way to display it 
		 */
		if ( door == 4 || door == 5 )
			continue;

		/*
		 * Get the coords for the next exit and room in this direction 
		 */
		get_exit_dir( door, &exitx, &exity, x, y );
		get_exit_dir( door, &roomx, &roomy, exitx, exity );

		/*
		 * Skip if coords fall outside map 
		 */
		if ( BOUNDARY( exitx, exity ) || BOUNDARY( roomx, roomy ) )
			continue;

		/*
		 * Skip if there is no room beyond this exit 
		 */
		if ( !pExit->to_room )
			continue;

		/*
		 * Ensure there are no clashes with previously defined rooms 
		 */
		if ( ( dmap[roomx][roomy].vnum != 0 ) && ( dmap[roomx][roomy].vnum != pExit->to_room->vnum ) )
		{
			/*
			 * Use the new room if the depth is higher 
			 */
			if ( dmap[roomx][roomy].depth <= depth )
				continue;

			/*
			 * It is so clear the old room 
			 */
			clear_room( roomx, roomy );
		}

		/*
		 * No exits at MAXDEPTH 
		 */
		if ( depth == MAXDEPTH )
			continue;

		/*
		 * No need for exits that are already mapped 
		 */
		if ( dmap[exitx][exity].depth > 0 )
			continue;

		/*
		 * Fill in exit 
		 */
		dmap[exitx][exity].depth = depth;
		dmap[exitx][exity].vnum = pExit->to_room->vnum;
//      dmap[exitx][exity].info = pExit->exit_info;
		dmap[exitx][exity].tegn = map_chars[door];
		dmap[exitx][exity].sector = -1;

		/*
		 * More to do? If so we recurse 
		 */
		if ( depth < MAXDEPTH && ( ( dmap[roomx][roomy].vnum == pExit->to_room->vnum ) || ( dmap[roomx][roomy].vnum == 0 ) ) )
		{
			/*
			 * Depth increases by one each time 
			 */
			map_exits( ch, pExit->to_room, roomx, roomy, depth + 1 );
		}
	}
}
示例#5
0
char *sprint_reset( RESET_DATA * pReset, short *num )
{
	RESET_DATA *tReset, *gReset;
	static char buf[MAX_STRING_LENGTH];
	char mobname[MAX_STRING_LENGTH], roomname[MAX_STRING_LENGTH], objname[MAX_STRING_LENGTH];
	static ROOM_INDEX_DATA *room;
	static OBJ_INDEX_DATA *obj, *obj2;
	static MOB_INDEX_DATA *mob;

	switch ( pReset->command )
	{
		default:
			snprintf( buf, MAX_STRING_LENGTH, "%2d) *** BAD RESET: %c %d %d %d %d ***\r\n", *num, pReset->command, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3 );
			break;

		case 'M':
			mob = get_mob_index( pReset->arg1 );
			room = get_room_index( pReset->arg3 );
			if ( mob )
				strncpy( mobname, mob->player_name, MAX_STRING_LENGTH );
			else
				strncpy( mobname, "Mobile: *BAD VNUM*", MAX_STRING_LENGTH );
			if ( room )
				strncpy( roomname, room->name, MAX_STRING_LENGTH );
			else
				strncpy( roomname, "Room: *BAD VNUM*", MAX_STRING_LENGTH );
			snprintf( buf, MAX_STRING_LENGTH, "%2d) %s (%d) -> %s Room: %d [%d] %s\r\n", *num, mobname, pReset->arg1,
				roomname, pReset->arg3, pReset->arg2, pReset->sreset ? "[Not Reset]" : "[Reset]" );

			for ( tReset = pReset->first_reset; tReset; tReset = tReset->next_reset )
			{
				( *num )++;
				switch ( tReset->command )
				{
					case 'E':
						if ( !mob )
							strncpy( mobname, "* ERROR: NO MOBILE! *", MAX_STRING_LENGTH );
						if ( !( obj = get_obj_index( tReset->arg1 ) ) )
							strncpy( objname, "Object: *BAD VNUM*", MAX_STRING_LENGTH );
						else
							strncpy( objname, obj->name, MAX_STRING_LENGTH );
						snprintf( buf + strlen( buf ), MAX_STRING_LENGTH - strlen( buf ),
							"%2d) (equip) %s (%d) -> %s (%s) [%d]\r\n", *num, objname, tReset->arg1, mobname, wear_locs[tReset->arg3], tReset->arg2 );
						break;

					case 'G':
						if ( !mob )
							strncpy( mobname, "* ERROR: NO MOBILE! *", MAX_STRING_LENGTH );
						if ( !( obj = get_obj_index( tReset->arg1 ) ) )
							strncpy( objname, "Object: *BAD VNUM*", MAX_STRING_LENGTH );
						else
							strncpy( objname, obj->name, MAX_STRING_LENGTH );
						snprintf( buf + strlen( buf ), MAX_STRING_LENGTH - strlen( buf ), "%2d) (carry) %s (%d) -> %s [%d]\r\n", *num, objname, tReset->arg1, mobname, tReset->arg2 );
						break;
				}
				if ( tReset->first_reset )
				{
					for ( gReset = tReset->first_reset; gReset; gReset = gReset->next_reset )
					{
						( *num )++;
						switch ( gReset->command )
						{
							case 'P':
								if ( !( obj2 = get_obj_index( gReset->arg1 ) ) )
									strncpy( objname, "Object1: *BAD VNUM*", MAX_STRING_LENGTH );
								else
									strncpy( objname, obj2->name, MAX_STRING_LENGTH );
								if ( gReset->arg3 > 0 && ( obj = get_obj_index( gReset->arg3 ) ) == NULL )
									strncpy( roomname, "Object2: *BAD VNUM*", MAX_STRING_LENGTH );
								else if ( !obj )
									strncpy( roomname, "Object2: *NULL obj*", MAX_STRING_LENGTH );
								else
									strncpy( roomname, obj->name, MAX_STRING_LENGTH );
								snprintf( buf + strlen( buf ), MAX_STRING_LENGTH - strlen( buf ),
									"%2d) (put) %s (%d) -> %s (%d) [%d]\r\n", *num, objname, gReset->arg1, roomname, obj ? obj->vnum : gReset->arg3, gReset->arg2 );
								break;
						}
					}
				}
			}
			break;

		case 'O':
			if ( !( obj = get_obj_index( pReset->arg1 ) ) )
				strncpy( objname, "Object: *BAD VNUM*", MAX_STRING_LENGTH );
			else
				strncpy( objname, obj->name, MAX_STRING_LENGTH );
			room = get_room_index( pReset->arg3 );
			if ( !room )
				strncpy( roomname, "Room: *BAD VNUM*", MAX_STRING_LENGTH );
			else
				strncpy( roomname, room->name, MAX_STRING_LENGTH );
			snprintf( buf, MAX_STRING_LENGTH, "%2d) (object) %s (%d) -> %s Room: %d [%d]\r\n", *num, objname, pReset->arg1, roomname, pReset->arg3, pReset->arg2 );

			for ( tReset = pReset->first_reset; tReset; tReset = tReset->next_reset )
			{
				( *num )++;
				switch ( tReset->command )
				{
					case 'P':
						if ( !( obj2 = get_obj_index( tReset->arg1 ) ) )
							strncpy( objname, "Object1: *BAD VNUM*", MAX_STRING_LENGTH );
						else
							strncpy( objname, obj2->name, MAX_STRING_LENGTH );
						if ( tReset->arg3 > 0 && ( obj = get_obj_index( tReset->arg3 ) ) == NULL )
							strncpy( roomname, "Object2: *BAD VNUM*", MAX_STRING_LENGTH );
						else if ( !obj )
							strncpy( roomname, "Object2: *NULL obj*", MAX_STRING_LENGTH );
						else
							strncpy( roomname, obj->name, MAX_STRING_LENGTH );
						snprintf( buf + strlen( buf ), MAX_STRING_LENGTH - strlen( buf ), "%2d) (put) %s (%d) -> %s (%d) [%d]\r\n",
							*num, objname, tReset->arg1, roomname, obj ? obj->vnum : tReset->arg3, tReset->arg2 );
						break;

					case 'T':
						snprintf( buf + strlen( buf ), MAX_STRING_LENGTH - strlen( buf ),
							"%2d) (trap) %d %d %d %d (%s) -> %s (%d)\r\n", *num, tReset->extra, tReset->arg1, tReset->arg2,
							tReset->arg3, flag_string( tReset->extra, trap_flags ), objname, obj ? obj->vnum : 0 );
						break;

					case 'H':
						snprintf( buf + strlen( buf ), MAX_STRING_LENGTH - strlen( buf ), "%2d) (hide) -> %s\r\n", *num, objname );
						break;
				}
			}
			break;

		case 'D':
			if ( pReset->arg2 < 0 || pReset->arg2 > MAX_DIR + 1 )
				pReset->arg2 = 0;
			if ( !( room = get_room_index( pReset->arg1 ) ) )
			{
				strncpy( roomname, "Room: *BAD VNUM*", MAX_STRING_LENGTH );
				snprintf( objname, MAX_STRING_LENGTH, "%s (no exit)", dir_name[pReset->arg2] );
			}
			else
			{
				strncpy( roomname, room->name, MAX_STRING_LENGTH );
				snprintf( objname, MAX_STRING_LENGTH, "%s%s", dir_name[pReset->arg2], get_exit( room, pReset->arg2 ) ? "" : " (NO EXIT!)" );
			}
			switch ( pReset->arg3 )
			{
				default:
					strncpy( mobname, "(* ERROR *)", MAX_STRING_LENGTH );
					break;
				case 0:
					strncpy( mobname, "Open", MAX_STRING_LENGTH );
					break;
				case 1:
					strncpy( mobname, "Close", MAX_STRING_LENGTH );
					break;
				case 2:
					strncpy( mobname, "Close and lock", MAX_STRING_LENGTH );
					break;
			}
			snprintf( buf, MAX_STRING_LENGTH, "%2d) %s [%d] the %s [%d] door %s (%d)\r\n", *num, mobname, pReset->arg3, objname, pReset->arg2, roomname, pReset->arg1 );
			break;

		case 'R':
			if ( !( room = get_room_index( pReset->arg1 ) ) )
				strncpy( roomname, "Room: *BAD VNUM*", MAX_STRING_LENGTH );
			else
				strncpy( roomname, room->name, MAX_STRING_LENGTH );
			snprintf( buf, MAX_STRING_LENGTH, "%2d) Randomize exits 0 to %d -> %s (%d)\r\n", *num, pReset->arg2, roomname, pReset->arg1 );
			break;

		case 'T':
			if ( !( room = get_room_index( pReset->arg3 ) ) )
				strncpy( roomname, "Room: *BAD VNUM*", MAX_STRING_LENGTH );
			else
				strncpy( roomname, room->name, MAX_STRING_LENGTH );
			snprintf( buf, MAX_STRING_LENGTH, "%2d) Trap: %d %d %d %d (%s) -> %s (%d)\r\n",
				*num, pReset->extra, pReset->arg1, pReset->arg2, pReset->arg3, flag_string( pReset->extra, trap_flags ), roomname, room ? room->vnum : 0 );
			break;
	}
	return buf;
}
示例#6
0
/*
 * Reset one room.
 */
void reset_room( ROOM_INDEX_DATA * room )
{
	RESET_DATA *pReset, *tReset, *gReset;
	OBJ_DATA *nestmap[MAX_NEST];
	CHAR_DATA *mob;
	OBJ_DATA *obj, *lastobj, *to_obj;
	ROOM_INDEX_DATA *pRoomIndex = NULL;
	MOB_INDEX_DATA *pMobIndex = NULL;
	OBJ_INDEX_DATA *pObjIndex = NULL, *pObjToIndex;
	EXIT_DATA *pexit;
	const char *filename = room->area->filename;
	int level = 0, n, num = 0, lastnest, onreset = 0;

	mob = NULL;
	obj = NULL;
	lastobj = NULL;
	if ( !room->first_reset )
		return;
	level = 0;
	for ( pReset = room->first_reset; pReset; pReset = pReset->next )
	{
		++onreset;
		switch ( pReset->command )
		{
			default:
				bug( "%s: %s: bad command %c.", __FUNCTION__, filename, pReset->command );
				break;

			case 'M':
				if ( !( pMobIndex = get_mob_index( pReset->arg1 ) ) )
				{
					bug( "%s: %s: 'M': bad mob vnum %d.", __FUNCTION__, filename, pReset->arg1 );
					continue;
				}
				if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
				{
					bug( "%s: %s: 'M': bad room vnum %d.", __FUNCTION__, filename, pReset->arg3 );
					continue;
				}
				if ( !pReset->sreset )
				{
					mob = NULL;
					break;
				}
				mob = create_mobile( pMobIndex );
				{
					ROOM_INDEX_DATA *pRoomPrev = get_room_index( pReset->arg3 - 1 );

					if ( pRoomPrev && xIS_SET( pRoomPrev->room_flags, ROOM_PET_SHOP ) )
						xSET_BIT( mob->act, ACT_PET );
				}
				if ( room_is_dark( pRoomIndex ) )
					xSET_BIT( mob->affected_by, AFF_INFRARED );
				mob->resetvnum = pRoomIndex->vnum;
				mob->resetnum = onreset;
				pReset->sreset = false;
				char_to_room( mob, pRoomIndex );
				level = URANGE( 0, mob->level - 2, LEVEL_AVATAR );

				if ( pReset->first_reset )
				{
					for ( tReset = pReset->first_reset; tReset; tReset = tReset->next_reset )
					{
						++onreset;
						switch ( tReset->command )
						{
							case 'G':
							case 'E':
								if ( !( pObjIndex = get_obj_index( tReset->arg1 ) ) )
								{
									bug( "%s: %s: 'E' or 'G': bad obj vnum %d.", __FUNCTION__, filename, tReset->arg1 );
									continue;
								}
								if ( !mob )
								{
									lastobj = NULL;
									break;
								}

								if ( mob->pIndexData->pShop )
								{
									int olevel = generate_itemlevel( room->area, pObjIndex );

									obj = create_object( pObjIndex, olevel );
									xSET_BIT( obj->extra_flags, ITEM_INVENTORY );
								}
								else
									obj = create_object( pObjIndex, number_fuzzy( level ) );
								obj->level = URANGE( 0, obj->level, LEVEL_AVATAR );
								obj = obj_to_char( obj, mob );
								if ( tReset->command == 'E' )
								{
									if ( obj->carried_by != mob )
									{
										bug( "'E' reset: can't give object %d to mob %d.", obj->pIndexData->vnum, mob->pIndexData->vnum );
										break;
									}
									equip_char( mob, obj, tReset->arg3 );
								}
								for ( n = 0; n < MAX_NEST; n++ )
									nestmap[n] = NULL;
								nestmap[0] = obj;
								lastobj = nestmap[0];
								lastnest = 0;

								if ( tReset->first_reset )
								{
									for ( gReset = tReset->first_reset; gReset; gReset = gReset->next_reset )
									{
										int iNest;

										to_obj = lastobj;

										++onreset;
										switch ( gReset->command )
										{
											case 'H':
												if ( !lastobj )
													break;
												xSET_BIT( lastobj->extra_flags, ITEM_HIDDEN );
												break;

											case 'P':
												if ( !( pObjIndex = get_obj_index( gReset->arg1 ) ) )
												{
													bug( "%s: %s: 'P': bad obj vnum %d.", __FUNCTION__, filename, gReset->arg1 );
													continue;
												}
												iNest = gReset->extra;

												if ( !( pObjToIndex = get_obj_index( gReset->arg3 ) ) )
												{
													bug( "%s: %s: 'P': bad objto vnum %d.", __FUNCTION__, filename, gReset->arg3 );
													continue;
												}
												if ( iNest >= MAX_NEST )
												{
													bug( "%s: %s: 'P': Exceeded nesting limit of %d", __FUNCTION__, filename, MAX_NEST );
													obj = NULL;
													break;
												}
												if ( count_obj_list( pObjIndex, to_obj->first_content ) > 0 )
												{
													obj = NULL;
													break;
												}

												if ( iNest < lastnest )
													to_obj = nestmap[iNest];
												else if ( iNest == lastnest )
													to_obj = nestmap[lastnest];
												else
													to_obj = lastobj;

												obj = create_object( pObjIndex, number_fuzzy( UMAX( generate_itemlevel( room->area, pObjIndex ), to_obj->level ) ) );
												if ( num > 1 )
													pObjIndex->count += ( num - 1 );
												obj->count = gReset->arg2;
												obj->level = UMIN( obj->level, LEVEL_AVATAR );
												obj->count = gReset->arg2;
												obj_to_obj( obj, to_obj );
												if ( iNest > lastnest )
												{
													nestmap[iNest] = to_obj;
													lastnest = iNest;
												}
												lastobj = obj;
												/*
												 * Hackish fix for nested puts 
												 */
												if ( gReset->arg3 == OBJ_VNUM_MONEY_ONE )
													gReset->arg3 = to_obj->pIndexData->vnum;
												break;
										}
									}
								}
								break;
						}
					}
				}
				break;

			case 'O':
				if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
				{
					bug( "%s: %s: 'O': bad obj vnum %d.", __FUNCTION__, filename, pReset->arg1 );
					continue;
				}
				if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
				{
					bug( "%s: %s: 'O': bad room vnum %d.", __FUNCTION__, filename, pReset->arg3 );
					continue;
				}

				if ( count_obj_list( pObjIndex, pRoomIndex->first_content ) < 1 )
				{
					obj = create_object( pObjIndex, number_fuzzy( generate_itemlevel( room->area, pObjIndex ) ) );
					if ( num > 1 )
						pObjIndex->count += ( num - 1 );
					obj->count = pReset->arg2;
					obj->level = UMIN( obj->level, LEVEL_AVATAR );
					obj->cost = 0;
					obj_to_room( obj, pRoomIndex );
				}
				else
				{
					int x;

					if ( !( obj = get_obj_room( pObjIndex, pRoomIndex ) ) )
					{
						obj = NULL;
						lastobj = NULL;
						break;
					}
					obj->extra_flags = pObjIndex->extra_flags;
					for ( x = 0; x < 6; ++x )
						obj->value[x] = pObjIndex->value[x];
				}
				for ( n = 0; n < MAX_NEST; n++ )
					nestmap[n] = NULL;
				nestmap[0] = obj;
				lastobj = nestmap[0];
				lastnest = 0;
				if ( pReset->first_reset )
				{
					for ( tReset = pReset->first_reset; tReset; tReset = tReset->next_reset )
					{
						int iNest;

						to_obj = lastobj;
						++onreset;

						switch ( tReset->command )
						{
							case 'H':
								if ( !lastobj )
									break;
								xSET_BIT( lastobj->extra_flags, ITEM_HIDDEN );
								break;

							case 'T':
								if ( !IS_SET( tReset->extra, TRAP_OBJ ) )
								{
									bug( "%s: Room reset found on object reset list", __FUNCTION__ );
									break;
								}
								else
								{
									/*
									 * We need to preserve obj for future 'T' checks 
									 */
									OBJ_DATA *pobj;

									if ( tReset->arg3 > 0 )
									{
										if ( !( pObjToIndex = get_obj_index( tReset->arg3 ) ) )
										{
											bug( "%s: %s: 'T': bad objto vnum %d.", __FUNCTION__, filename, tReset->arg3 );
											continue;
										}
										if ( room->area->nplayer > 0 || !( to_obj = get_obj_type( pObjToIndex ) ) ||
											( to_obj->carried_by && !IS_NPC( to_obj->carried_by ) ) || is_trapped( to_obj ) )
											break;
									}
									else
									{
										if ( !lastobj || !obj )
											break;
										to_obj = obj;
									}
									pobj = make_trap( tReset->arg2, tReset->arg1, number_fuzzy( to_obj->level ), tReset->extra );
									obj_to_obj( pobj, to_obj );
								}
								break;

							case 'P':
								if ( !( pObjIndex = get_obj_index( tReset->arg1 ) ) )
								{
									bug( "%s: %s: 'P': bad obj vnum %d.", __FUNCTION__, filename, tReset->arg1 );
									continue;
								}
								iNest = tReset->extra;

								if ( !( pObjToIndex = get_obj_index( tReset->arg3 ) ) )
								{
									bug( "%s: %s: 'P': bad objto vnum %d.", __FUNCTION__, filename, tReset->arg3 );
									continue;
								}

								if ( iNest >= MAX_NEST )
								{
									bug( "%s: %s: 'P': Exceeded nesting limit of %d. Room %d.", __FUNCTION__, filename, MAX_NEST, room->vnum );
									obj = NULL;
									break;
								}

								if ( count_obj_list( pObjIndex, to_obj->first_content ) > 0 )
								{
									obj = NULL;
									break;
								}
								if ( iNest < lastnest )
									to_obj = nestmap[iNest];
								else if ( iNest == lastnest )
									to_obj = nestmap[lastnest];
								else
									to_obj = lastobj;

								obj = create_object( pObjIndex, number_fuzzy( UMAX( generate_itemlevel( room->area, pObjIndex ), to_obj->level ) ) );
								if ( num > 1 )
									pObjIndex->count += ( num - 1 );
								obj->count = tReset->arg2;
								obj->level = UMIN( obj->level, LEVEL_AVATAR );
								obj->count = tReset->arg2;
								obj_to_obj( obj, to_obj );
								if ( iNest > lastnest )
								{
									nestmap[iNest] = to_obj;
									lastnest = iNest;
								}
								lastobj = obj;
								/*
								 * Hackish fix for nested puts 
								 */
								if ( tReset->arg3 == OBJ_VNUM_MONEY_ONE )
									tReset->arg3 = to_obj->pIndexData->vnum;
								break;
						}
					}
				}
				break;

			case 'T':
				if ( IS_SET( pReset->extra, TRAP_OBJ ) )
				{
					bug( "%s: Object trap found in room %d reset list", __FUNCTION__, room->vnum );
					break;
				}
				else
				{
					if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
					{
						bug( "%s: %s: 'T': bad room %d.", __FUNCTION__, filename, pReset->arg3 );
						continue;
					}
					if ( room->area->nplayer > 0 || count_obj_list( get_obj_index( OBJ_VNUM_TRAP ), pRoomIndex->first_content ) > 0 )
						break;
					to_obj = make_trap( pReset->arg1, pReset->arg1, 10, pReset->extra );
					obj_to_room( to_obj, pRoomIndex );
				}
				break;

			case 'D':
				if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
				{
					bug( "%s: %s: 'D': bad room vnum %d.", __FUNCTION__, filename, pReset->arg1 );
					continue;
				}
				if ( !( pexit = get_exit( pRoomIndex, pReset->arg2 ) ) )
					break;
				switch ( pReset->arg3 )
				{
					case 0:
						REMOVE_BIT( pexit->exit_info, EX_CLOSED );
						REMOVE_BIT( pexit->exit_info, EX_LOCKED );
						break;
					case 1:
						SET_BIT( pexit->exit_info, EX_CLOSED );
						REMOVE_BIT( pexit->exit_info, EX_LOCKED );
						if ( IS_SET( pexit->exit_info, EX_xSEARCHABLE ) )
							SET_BIT( pexit->exit_info, EX_SECRET );
						break;
					case 2:
						SET_BIT( pexit->exit_info, EX_CLOSED );
						SET_BIT( pexit->exit_info, EX_LOCKED );
						if ( IS_SET( pexit->exit_info, EX_xSEARCHABLE ) )
							SET_BIT( pexit->exit_info, EX_SECRET );
						break;
				}
				break;

			case 'R':
				if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
				{
					bug( "%s: %s: 'R': bad room vnum %d.", __FUNCTION__, filename, pReset->arg1 );
					continue;
				}
				randomize_exits( pRoomIndex, pReset->arg2 - 1 );
				break;
		}
	}
}
示例#7
0
void redit_parse( DESCRIPTOR_DATA *d , char *arg )
{
	ROOM_DATA		 *room  = d->character->dest_buf;
	ROOM_DATA		 *tmp;
	EXIT_DATA		 *pexit = d->character->spare_ptr;
	EXTRA_DESCR_DATA *ed	  = d->character->spare_ptr;
	char			  arg1[MIL];
	char			  buf[MSL];
	int				  number = 0;

	switch ( OLC_MODE(d) )
	{
	  case REDIT_CONFIRM_SAVESTRING:
		switch ( *arg )
		{
		  case 'y':
		  case 'Y':
			/* redit_save_internally(d); */
			send_log( NULL, LOG_OLC, "OLC: %s edits room %d", d->character->name, OLC_NUM(d) );
			cleanup_olc( d );
			send_to_char( d->character, "Room saved to memory.\r\n" );
			break;
		  case 'n':
		  case 'N':
			cleanup_olc( d );
			break;
		  default:
			send_to_char( d->character, "Invalid choice!\r\n" );
			send_to_char( d->character, "Do you wish to save this room internally? : " );
			break;
		}
		return;

	  case REDIT_MAIN_MENU:
		switch ( *arg )
		{
		  case 'q':
		  case 'Q':
/*			if ( OLC_CHANGE(d) )
			{ *. Something has been modified .*
				send_to_char( d->character, "Do you wish to save this room internally? : " );
				OLC_MODE(d) = REDIT_CONFIRM_SAVESTRING;
			}
			else */
			cleanup_olc( d );
			return;
		  case '1':
			send_to_char( d->character, "Enter room name:-\r\n| " );
			OLC_MODE(d) = REDIT_NAME;
			break;
		  case '2':
			OLC_MODE(d) = REDIT_DESC;
			d->character->substate = SUB_ROOM_DESCR;
			d->character->last_cmd = do_redit_reset;

			send_to_char( d->character, "Enter room description:-\r\n" );
			if ( !room->description )
				room->description = str_dup( "" );
			start_editing( d->character, room->description );
			break;
		  case '3':
			redit_disp_flag_menu(d);
			break;
		  case '4':
			redit_disp_sector_menu(d);
			break;
		  case '5':
			send_to_char( d->character, "How many people can fit in the room? " );
			OLC_MODE(d) = REDIT_TUNNEL;
			break;
		  case '6':
			send_to_char( d->character, "How long before people are teleported out? " );
			OLC_MODE(d) = REDIT_TELEDELAY;
			break;
		  case '7':
			send_to_char( d->character, "Where are they teleported to? " );
			OLC_MODE(d) = REDIT_TELEVNUM;
			break;
		  case 'a':
		  case 'A':
			redit_disp_exit_menu(d);
			break;
		  case 'b':
		  case 'B':
			redit_disp_extradesc_menu(d);
			break;

		  default:
			send_to_char( d->character, "Invalid choice!" );
			redit_disp_menu(d);
			break;
		}
		return;

	  case REDIT_NAME:
		DISPOSE( room->name );
		room->name = str_dup( arg );
		olc_log( d, "Changed name to %s", room->name );
		break;

	  case REDIT_DESC:
		/* we will NEVER get here */
		send_log( NULL, LOG_OLC, "redit_parse: reached REDIT_DESC case in redit_parse" );
		break;

	  case REDIT_FLAGS:
		if ( is_number(arg) )
		{
			number = atoi( arg );
			if ( number == 0 )
				break;
			else if ( number < 0 || number >= MAX_ROOM )
			{
				send_to_char( d->character, "Invalid flag, try again: " );
				return;
			}
			else
			{
				number--;	/* Offset for 0 */
				TOGGLE_BIT( room->flags, number );
				olc_log( d, "%s the room flag %s",
				HAS_BIT( room->flags, number ) ? "Added" : "Removed",
				code_name(NULL, number, CODE_ROOM) );
			}
		}
		else
		{
			while ( VALID_STR(arg) )
			{
				arg = one_argument( arg, arg1 );
				number = code_num( NULL, arg1, CODE_ROOM );
				if ( number > 0 )
				{
					TOGGLE_BIT( room->flags, number );
					olc_log( d, "%s the room flag %s",
						HAS_BIT( room->flags, number ) ? "Added" : "Removed",
						code_name( NULL, number, CODE_ROOM) );
				}
			}
		}
		redit_disp_flag_menu(d);
		return;

	  case REDIT_SECTOR:
		number = atoi( arg );
		if ( number < 0 || number >= MAX_SECTOR )
		{
			send_to_char( d->character, "Invalid choice!" );
			redit_disp_sector_menu(d);
			return;
		}
		else
			room->sector = number;

		olc_log( d, "Changed sector to %s", code_name(NULL, number, CODE_SECTOR) );
		break;

	  case REDIT_TUNNEL:
		number = atoi( arg );
		room->tunnel = URANGE( 0, number, 1000 );
		olc_log( d, "Changed tunnel amount to %d", room->tunnel );
		break;

	  case REDIT_TELEDELAY:
		number = atoi( arg );
		room->tele_delay = number;
		olc_log( d, "Changed teleportation delay to %d", room->tele_delay );
		break;

	  case REDIT_TELEVNUM:
		number = atoi( arg );
		room->tele_vnum = URANGE( 1, number, MAX_VNUM-1 );
		olc_log( d, "Changed teleportation vnum to %d", room->tele_vnum );
		break;

	  case REDIT_EXIT_MENU:
		switch ( toupper(arg[0]) )
		{
		  default:
			if ( is_number(arg) )
			{
				number = atoi( arg );
				pexit = get_exit_num( room, number );
				d->character->spare_ptr = pexit;
				redit_disp_exit_edit(d);
				return;
			}
			redit_disp_exit_menu( d );
			return;
		  case 'A':
			OLC_MODE(d) = REDIT_EXIT_ADD;
			redit_disp_exit_dirs( d );
			return;
		  case 'R':
			OLC_MODE(d) = REDIT_EXIT_DELETE;
			send_to_char( d->character, "Delete which exit? " );
			return;
		  case 'Q':
			d->character->spare_ptr = NULL;
			break;
		}
		break;

	  case REDIT_EXIT_EDIT:
		switch ( toupper(arg[0]) )
		{
		  case 'Q':
			d->character->spare_ptr = NULL;
			redit_disp_exit_menu(d);
			return;
		  case '1':
			/* OLC_MODE(d) = REDIT_EXIT_DIR;
			redit_disp_exit_dirs(d); */
			send_to_char( d->character, "This option can only be changed by remaking the exit.\r\n" );
			break;
		  case '2':
			OLC_MODE(d) = REDIT_EXIT_VNUM;
			send_to_char( d->character, "Which room does this exit go to? " );
			return;
		  case '3':
			OLC_MODE(d) = REDIT_EXIT_KEY;
			send_to_char( d->character, "What is the vnum of the key to this exit? " );
			return;
		  case '4':
			OLC_MODE(d) = REDIT_EXIT_KEYWORD;
			send_to_char( d->character, "What is the keyword to this exit? " );
			return;
		  case '5':
			OLC_MODE(d) = REDIT_EXIT_FLAGS;
			redit_disp_exit_flag_menu(d);
			return;
		  case '6':
			OLC_MODE(d) = REDIT_EXIT_DESC;
			send_to_char( d->character, "Description:\r\n] " );
			return;
		}
		redit_disp_exit_edit(d);
		return;

	  case REDIT_EXIT_DESC:
		if ( !VALID_STR(arg) )
		{
			DISPOSE( pexit->description );
			pexit->description = str_dup( "" );
		}
		else
		{
			sprintf( buf, "%s\r\n", arg );
			DISPOSE( pexit->description );
			pexit->description = str_dup( buf );
		}
		olc_log( d, "Changed %s description to %s", code_name( NULL, pexit->vdir, CODE_DIR), arg  ?  arg  :  "none" );
		redit_disp_exit_edit(d);
		return;

	  case REDIT_EXIT_ADD:
		if ( is_number( arg ) )
		{
			number = atoi( arg );
			if ( number < 0 || number >= MAX_DIR )
			{
				send_to_char( d->character, "Invalid direction, try again: " );
				return;
			}
			d->character->tempnum = number;
		}
		else
		{
			number = get_dir(arg);
			pexit = get_exit( room, number );
			if ( pexit )
			{
				send_to_char( d->character, "An exit in that direction already exists.\r\n" );
				redit_disp_exit_menu(d);
				return;
			}
			d->character->tempnum = number;
		}
		OLC_MODE(d) = REDIT_EXIT_ADD_VNUM;
		send_to_char( d->character, "Which room does this exit go to? " );
		return;

	  case REDIT_EXIT_ADD_VNUM:
		number = atoi( arg );
		if ( (tmp = get_room_index(NULL, number)) == NULL )
		{
			send_to_char( d->character, "Non-existant room.\r\n" );
			OLC_MODE(d) = REDIT_EXIT_MENU;
			redit_disp_exit_menu(d);
			return;
		}
		pexit = make_exit( room, tmp, d->character->tempnum );
		DISPOSE( pexit->keyword );
		DISPOSE( pexit->description );
		pexit->keyword		= str_dup( "" );
		pexit->description	= str_dup( "" );
		pexit->key			= -1;
		pexit->flags	= 0;
		act( AT_ADMIN, "$n reveals a hidden passage!", d->character, NULL, NULL, TO_ROOM );
		d->character->spare_ptr = pexit;

		olc_log( d, "Added %s exit to %d", code_name( NULL, pexit->vdir, CODE_DIR), pexit->vnum );

		OLC_MODE(d) = REDIT_EXIT_EDIT;
		redit_disp_exit_edit(d);
		return;

	  case REDIT_EXIT_DELETE:
		if ( !is_number( arg ) )
		{
			send_to_char( d->character, "Exit must be specified in a number.\r\n" );
			redit_disp_exit_menu(d);
		}
		number = atoi( arg );
		pexit = get_exit_num( room, number );

		if ( !pexit )
		{
			send_to_char( d->character, "That exit does not exist.\r\n" );
			redit_disp_exit_menu(d);
		}
		olc_log( d, "Removed %s exit", code_name( NULL, pexit->vdir, CODE_DIR) );
		extract_exit( room, pexit );
		redit_disp_exit_menu( d );
		return;

	  case REDIT_EXIT_VNUM:
		number = atoi( arg );
		if ( number < 1 || number >= MAX_VNUM )
		{
			send_to_char( d->character, "Invalid room number, try again : " );
			return;
		}

		if ( get_room_index(NULL, number) == NULL )
		{
			send_to_char( d->character, "That room does not exist, try again: " );
			return;
		}
		pexit->vnum = number;
		olc_log( d, "%s exit vnum changed to %d", code_name( NULL, pexit->vdir, CODE_DIR), pexit->vnum );
		redit_disp_exit_menu( d );
		return;

	  case REDIT_EXIT_KEYWORD:
		DISPOSE( pexit->keyword );
		pexit->keyword = str_dup( arg );
		olc_log( d, "Changed %s keyword to %s", code_name( NULL, pexit->vdir, CODE_DIR), pexit->keyword );
		redit_disp_exit_edit( d );
		return;

	  case REDIT_EXIT_KEY:
		number = atoi( arg );
		if ( number < 1 || number >= MAX_VNUM )
			send_to_char( d->character, "Invalid vnum, try again: " );
		else
		{
			pexit->key = number;
			redit_disp_exit_edit( d );
		}
		olc_log( d, "%s key vnum is now %d", code_name( NULL, pexit->vdir, CODE_DIR), pexit->key );
		return;

	  case REDIT_EXIT_FLAGS:
		number = atoi( arg );
		if ( number == 0 )
		{
			redit_disp_exit_edit( d );
			return;
		}

		if ( number < 0 || number >= MAX_EXIT
		  || ((number-1) == EXIT_RES1)
		  || ((number-1) == EXIT_RES2)
		  || ((number-1) == EXIT_PORTAL) )
		{
			send_to_char( d->character, "That's not a valid choice!\r\n" );
			redit_disp_exit_flag_menu( d );
		}
		number -= 1;
		TOGGLE_BIT( pexit->flags, number );
		olc_log( d, "%s %s to %s exit",
			HAS_BIT(pexit->flags, number)  ?  "Added"  :  "Removed",
			code_name(NULL, number, CODE_EXIT),
			code_name(NULL, pexit->vdir, CODE_DIR) );
		redit_disp_exit_flag_menu( d );
		return;

	  case REDIT_EXTRADESC_DELETE:
		ed = redit_find_extradesc( room, atoi(arg) );
		if ( !ed )
		{
			send_to_char( d->character, "Not found, try again: " );
			return;
		}
		olc_log( d, "Deleted exdesc %s", ed->keyword );
		UNLINK( ed, room->first_extradescr, room->last_extradescr, next, prev );
		DISPOSE( ed->keyword );
		DISPOSE( ed->description );
		DISPOSE( ed );
		top_ed--;
		redit_disp_extradesc_menu(d);
		return;

	  case REDIT_EXTRADESC_CHOICE:
		switch ( toupper( arg[0] ) )
		{
		  case 'Q':
			if ( !ed->keyword || !ed->description )
			{
				send_to_char( d->character, "No keyword and/or description, junking..." );
				UNLINK( ed, room->first_extradescr, room->last_extradescr, next, prev );
				DISPOSE( ed->keyword );
				DISPOSE( ed->keyword );
				DISPOSE( ed );
				top_ed--;
			}
			d->character->spare_ptr = NULL;
			redit_disp_extradesc_menu(d);
			return;
		  case '1':
			OLC_MODE(d) = REDIT_EXTRADESC_KEY;
			send_to_char( d->character, "Keywords, seperated by spaces: " );
			return;
		  case '2':
			OLC_MODE(d) = REDIT_EXTRADESC_DESCRIPTION;
			d->character->substate = SUB_ROOM_EXTRA;
			d->character->last_cmd = do_redit_reset;
			send_to_char( d->character, "Enter new extradesc description: \r\n" );
			start_editing( d->character, ed->description );
			return;
		}
		break;

	  case REDIT_EXTRADESC_KEY:
/*		if ( SetRExtra( room, arg ) )
		{
			send_to_char( d->character, "A extradesc with that keyword already exists.\r\n" );
			redit_disp_extradesc_menu(d);
			return;
		} */
		olc_log( d, "Changed exkey %s to %s", ed->keyword, arg );
		DISPOSE( ed->keyword );
		ed->keyword = str_dup( arg );
		oedit_disp_extra_choice(d);
		OLC_MODE(d) = REDIT_EXTRADESC_CHOICE;
		return;

	  case REDIT_EXTRADESC_MENU:
		switch ( toupper( arg[0] ) )
		{
		  case 'Q':
			break;
		  case 'A':
			CREATE( ed, EXTRA_DESCR_DATA, 1 );
			LINK( ed, room->first_extradescr, room->last_extradescr, next, prev );
			ed->keyword = str_dup( "" );
			ed->description = str_dup( "" );
			top_ed++;
			d->character->spare_ptr = ed;
			olc_log( d, "Added new exdesc" );
			oedit_disp_extra_choice(d);
			OLC_MODE(d) = REDIT_EXTRADESC_CHOICE;
			return;
		  case 'R':
			OLC_MODE(d) = REDIT_EXTRADESC_DELETE;
			send_to_char( d->character, "Delete which extra description? " );
			return;
		  default:
			if ( is_number(arg) )
			{
				ed = redit_find_extradesc( room, atoi(arg) );
				if ( !ed )
				{
					send_to_char( d->character, "Not found, try again: " );
					return;
				}
				d->character->spare_ptr = ed;
				oedit_disp_extra_choice(d);
				OLC_MODE(d) = REDIT_EXTRADESC_CHOICE;
			}
			else
				redit_disp_extradesc_menu(d);

			return;
		}
		break;

	  default:
		/* we should never get here */
		send_log( NULL, LOG_OLC, "redit_parse: reached default case in parse_redit" );
		break;
	} /* chiude lo switch */
	/* Log the changes, so we can keep track of those sneaky bastards */
	/* Don't log on the flags cause it does that above */
/*	if ( OLC_MODE(d) != REDIT_FLAGS )
		olc_log( d, arg );
*/
	/*. If we get this far, something has be changed .*/
	OLC_CHANGE(d) = TRUE;
	redit_disp_menu(d);
}
示例#8
0
文件: special.c 项目: bkero/Smaug
bool spec_wanderer( CHAR_DATA *ch )
{
    OBJ_DATA *trash;
    OBJ_DATA *trash_next;
    OBJ_DATA *obj2;
    ROOM_INDEX_DATA *was_in_room;
    EXIT_DATA *pexit = NULL;
    CHAR_DATA *vch;
    int door;
    int chance=50;
    bool found = FALSE; /* Valid direction */
    bool thrown = FALSE;/* Whether to be thrown or not */
    bool noexit = TRUE; /* Assume there is no valid exits */
    
    
    was_in_room = ch->in_room;
    if ( !IS_AWAKE(ch) )
	return FALSE;

    if((pexit = ch->in_room->first_exit) !=NULL)
			noexit=FALSE;
    
    if(chance>number_percent()){
    /****
     * Look for objects on the ground and pick it up
     ****/
    
    for ( trash = ch->in_room->first_content; trash; trash = trash_next )
    {
	trash_next = trash->next_content;
	if ( !IS_SET( trash->wear_flags, ITEM_TAKE )
	||    IS_OBJ_STAT( trash, ITEM_BURIED ) )
	    continue;
	
	if ( trash->item_type == ITEM_WEAPON
	|| 	 trash->item_type == ITEM_ARMOR
	||   trash->item_type == ITEM_LIGHT ) {
	separate_obj( trash );  /* So there is no 'sword <6>' gets only one object off ground */
	act( AT_ACTION, "$n leans over and gets $p.", ch, trash, NULL, TO_ROOM );	
	obj_from_room( trash );
	trash = obj_to_char( trash, ch );
	
	/*****
	 * If object is too high a level throw it away.
	 *****/
    if ( ch->level < trash->level )
    {
	act( AT_ACTION, "$n tries to use $p, but is too inexperienced.",ch, trash, NULL, TO_ROOM );
        thrown = TRUE;
    }
    
	/*****
	 * Wear the object if it is not to be thrown. The FALSE is passed
	 * so that the mob wont remove a piece of armor already there
	 * if it is not worn it is assumed that they can't use it or 
	 * they already are wearing something.
	 *****/
	
	if(!thrown)
	wear_obj( ch, trash, FALSE, -1 );
	
	/*****
	 * Look for an object in the inventory that is not being worn
	 * then throw it away...
	 *****/
	found=FALSE;
	if(!thrown)
        for ( obj2 = ch->first_carrying; obj2; obj2 = obj2->next_content ){
			if (obj2->wear_loc == WEAR_NONE){
			do_say(ch,"Hmm, I can't use this.");			
			trash=obj2; 
			thrown=TRUE;
	 }
	}
	/*****
	 * Ugly bit of code..
	 * Checks if the object is to be thrown & there is a valid exit, 
	 * randomly pick a direction to throw it, and check to make sure no other
	 * spec_wanderer mobs are in that room.
	 *****/
	if(thrown && !noexit)
	  while(!found && !noexit){
		door=number_door();
		if((pexit = get_exit(ch->in_room,door) ) != NULL
		&&   pexit->to_room
		&&   !IS_SET(pexit->exit_info, EX_CLOSED)
		&&	!xIS_SET(pexit->to_room->room_flags, ROOM_NODROP)){
		  if( (vch = pexit->to_room->first_person) !=NULL)
			for( vch = pexit->to_room->first_person; vch; vch = vch->next_in_room){
			  if (!str_cmp(lookup_spec(vch->spec_fun), "spec_wanderer")){
			  noexit = TRUE;
			  /*act( AT_CYAN,"$n spec_wanderer inroom $T", ch, NULL,dir_name[pexit->vdir], TO_ROOM);*/
			  return FALSE;
			  }
			}
			found = TRUE;
		}
	  }
		if (!noexit && thrown){
		/*if (trash->value*/
		set_cur_obj( trash );
		if( damage_obj( trash ) != rOBJ_SCRAPPED){
		separate_obj(trash);
		act( AT_ACTION, "$n growls and throws $p $T.", ch, trash, dir_name[pexit->vdir], TO_ROOM );
		obj_from_char( trash );
		obj_to_room( trash, pexit->to_room );
		char_from_room(ch);
		char_to_room(ch, pexit->to_room);
		act( AT_CYAN,"$p thrown by $n lands in the room.",ch, trash, ch, TO_ROOM);
		char_from_room(ch);
		char_to_room(ch, was_in_room);
		}
		else{
		do_say(ch,"This thing is junk!");
		act( AT_ACTION, "$n growls and breaks $p.",ch, trash, NULL, TO_ROOM);
		}
	
	return TRUE;
	}
	return TRUE;
    }
   } /* get next obj */
    return FALSE; /* No objects :< */
   }
   return FALSE;
}
示例#9
0
struct commandResult execute_command(struct player * me, char * cmd_buffer, char * cmd_param) {
    World *w = me->world;
    struct commandResult result;
    int ret = 0;
    int moved = 0;

    if(strlen(cmd_buffer) == 0) {
        printf("What?\n");
    }
    else if(has_exit(me->currentRoom, cmd_buffer)) {
        printf("You go: %s\n", cmd_buffer);
        char room_file[30];
        memset(&room_file, '\0', sizeof(char)*30);
        get_exit(&room_file, me->currentRoom, cmd_buffer);
        //free currentRoom..

        struct room * nextRoom = cached_read_room(w, room_file);
        if(nextRoom != NULL) {
            // Also free links, items etc
            //free(me->currentRoom);
            me->currentRoom=NULL;
            me->currentRoom = nextRoom;
            moved = 1;
        } else {
            printf("You didn't move.\n");
        }
    }
    else if(strcmp(cmd_buffer, "examine") == 0) {
      if((me->currentRoom)->items == NULL) {
        printf("You do not notice anything.\n");
      } else {
        printf("You notice:-\n");
        struct item * itemPtr = (me->currentRoom)->items;
          do {
            printf("%s\n", itemPtr->name);
            itemPtr = itemPtr->link;
          } while(itemPtr != NULL);
      }
    }
    else if(strcmp(cmd_buffer, "look") == 0) {
        if(cmd_param != NULL && strlen(cmd_param) > 0) {
    //      printf("%s\n", cmd_param);
            if(strcmp(cmd_param, "me") == 0) {
                time_t now;
                time(&now);
                int seconds = (int)difftime(now, me->connectionTime);

                printf(
"================================================================================\n"
"Player: %s\n"
"================================================================================\n"
"Current room: %s\n"
"Connected for: %d seconds\n",
                me->name, (me->currentRoom)->name, seconds);
            } else {
                printf("You do not notice anything special about: '%s'.\n", cmd_param);
            }
        }
        else {
            look_player(me);
        }
    }
    else if(strcmp(cmd_buffer, "mem") == 0) {
      printf("World: %s\n\n", w->name);
      LoadedRoom *head = w->rooms;
      printf("Loaded rooms:\n");
      do {
        printf("- %s\n", (head->current)->fileName);
        head = head->next;
      } while(head != NULL);
        // && head->next!=NULL);

    }
    else if(strcmp(cmd_buffer, "help") == 0) {
        showHelp();
    }
    else if(strcmp(cmd_buffer, "quit")==0) {
        ret = 1;
    }
    else {
        char expanded[30];
        if(find_alias(&expanded, cmd_buffer, me)) {
            printf("Using alias %s.\n", expanded);
            struct commandResult childResult = execute_command(me, &expanded, cmd_param);
            ret = childResult.exit;
            moved = childResult.moved;

        } else {
            printf("I do not understand: '%s'.. ?\n", cmd_buffer);
        }
    }
    result.exit = ret;
    result.moved = moved;
    return result;
}
示例#10
0
文件: pathfind.c 项目: jlmjlm/atc-ai
void plot_course(struct plane *p, int row, int col, int alt) {
    const bool trace = (p->id == 'i' && frame_no == 575);

    struct frame *frstart = malloc(sizeof *frstart);
    struct frame *frend = frstart;
    frstart->prev = frstart->next = NULL;
    frstart->opc_start = NULL;
    struct op_courses *opc_end = NULL;

    assert(alt == 7 || alt == 0);
    int bearing = alt ? calc_bearing(row, col)
                      : get_airport_xy(row, col)->bearing;
    bool cleared_exit = false;
    struct xyz target;

    for (struct plane *pi = plstart; pi; pi = pi->next) {
        if (pi == p)
            continue;
        new_op_course(pi->current, &frstart->opc_start, &opc_end, pi->isjet);
    }
    incr_opc(frstart->opc_start);

    if (p->target_airport) {
        struct airport *a = get_airport(p->target_num);
        if (a == NULL) {
            errexit('u', "Plane '%c' headed to unknown airport %d.",
                    p->id, p->target_num);
        }
        target.alt = 1;
        target.row = a->trow;
        target.col = a->tcol;
    } else {
        struct exitspec *e = get_exit(p->target_num);
        if (e == NULL) {
            errexit('u', "Plane '%c' headed to unknown exit %d.",
                    p->id, p->target_num);
        }
        target.alt = 9;
        target.row = e->row;
        target.col = e->col;
    }
    tracelog(trace, "Tracing plane %c's course from %d:(%d, %d, %d)@%d to "
                    "(%d, %d, %d)\n",
             p->id, frame_no, row, col, alt, bearings[bearing].degree,
             target.row, target.col, target.alt);

    p->start = p->current = p->end = NULL;
    add_course_elem(p, row, col, alt, bearing, false, trace ? frame_no : 0);
    p->start_tm = p->current_tm = frame_no;
    int tick = frame_no+1;
    int steps = 0, moves = 0;

    /* Operation of the "plotting course" machine:
     *    (A) Get a frame for the current pos'n.
     *    (B) If frame has cands, step ahead to the best cand and return to (A).
     *    (C) If not, step back to parent frame and remove the cand and
     *        return to (B).
     */
    for (;;) {
        if (++steps > 200) {
            log_course(p);
            errexit('8', "Plane %c stuck in an infinite loop.", p->id);
        }

        // Plane doesn't move if it's a prop and the tick is odd...
        // ...except that a prop plane in an exit will pop out of it.
        if (!p->isjet && tick%2 == 1 && row != 0 && col != 0 &&
                row != board_height-1 && col != board_width-1) {
            add_course_elem(p, row, col, alt, bearing, cleared_exit,
                            trace ? tick : 0);
            tick++;
            frend->n_cand = -3;
            make_new_fr(&frend);
            continue;
        }

        moves++;
        calc_next_move(p, row, col, &alt, target, &bearing, cleared_exit,
                       frend);
        assert((alt < 0) == (frend->n_cand <= 0));
        while (frend->n_cand <= 0) {
            tracelog(trace, "Backtracking at step %d move %d tick %d\n",
                     steps, moves, tick);
            struct xyz bt_pos = backtrack(&tick, &cleared_exit, &p->end,
                                          &frend);
            moves--;

            // Check for a prop. plane's non-move.
            // TODO: Do we have to worry about the "pop out of an exit" move
            // that props get at their first tick?
            if (frend->n_cand == -3) {
                tracelog(trace,
                         "Backtracking over prop's non-move at tick %d\n",
                         tick);
                assert(!p->isjet);
                bt_pos = backtrack(&tick, &cleared_exit, &p->end, &frend);
                assert(frend->n_cand != -3);
            }

            row = bt_pos.row;  col = bt_pos.col;
            tracelog(trace, "After backtracking:  %d: pos(%d, %d, %d) and %d "
                            "remaining candidates\n", tick, bt_pos.row,
                     bt_pos.col, bt_pos.alt, frend->n_cand - 1);

            if (--frend->n_cand > 0) {
                // We've found a new candidate that's available after
                // backtracking, so stop backtracing and get on with it.
                alt = frend->cand[frend->n_cand-1].alt;
                bearing = frend->cand[frend->n_cand-1].bearing;
                break;
            }
            tracelog(trace, "No new candidates found at tick %d.  Backtracking "
                            "again.\n", tick);
        }
        if (alt) {
            row += bearings[bearing].drow;
            col += bearings[bearing].dcol;
        }

        add_course_elem(p, row, col, alt, bearing, cleared_exit,
                        trace ? tick : 0);
        tick++;

        if (row == target.row && col == target.col && alt == target.alt) {
            // We've reached the target.  Clean-up and return.
            if (p->target_airport) {
                if (!p->isjet) {
                    add_course_elem(p, row, col, alt, bearing, cleared_exit,
                                    trace ? tick : 0);
                    tick++;
                }
                add_course_elem(p, -1, -1, -2, -1, cleared_exit,
                                trace ? tick : 0);
                p->end_tm = tick;
            } else {
                // For an exit, the plane disappears at reaching it.
                p->end_tm = tick-1;
                p->end->at_exit = true;
            }

            free_framelist(frstart);

            if (!quiet) {
                struct record *rec = p->isjet ? &rec_jet : &rec_prop;
                if (steps > rec->steps || moves > rec->moves) {
                    if (steps > rec->steps)
                        rec->steps = steps;
                    if (moves > rec->moves)
                        rec->moves = moves;
                    fprintf(logff, "New record long route: plane '%c' at time "
                                   "%d in %d steps/%d moves.\n",
                            p->id, frame_no, steps, moves);
                    log_course(p);
                    log_all_courses();
                }
            }

            return;
        }

        if (!cleared_exit && alt > 1 && ((row > 2 && row < board_height-3 &&
                col > 2 && col < board_width-3) || alt < 6 || alt == 9)) {
            cleared_exit = true;
        }

        make_new_fr(&frend);
    }
}