short good_attack_room(struct Thing *thing)
{
    // Debug code to find incorrect states
    if (!is_hero_thing(thing))
    {
        ERRORLOG("Non hero %s index %d owner %d - reset",thing_model_name(thing),(int)thing->index,(int)thing->owner);
        set_start_state(thing);
        return 0;
    }
    //return _DK_good_attack_room(thing);
    MapSlabCoord base_slb_x,base_slb_y;
    base_slb_x = subtile_slab_fast(thing->mappos.x.stl.num);
    base_slb_y = subtile_slab_fast(thing->mappos.y.stl.num);
    struct Room *room;
    room = slab_room_get(base_slb_x, base_slb_y);
    // If the current tile can be destroyed
    if (room_exists(room) && (room->owner != thing->owner) && !room_cannot_vandalise(room->kind))
    {
        struct CreatureControl *cctrl;
        cctrl = creature_control_get_from_thing(thing);
        if (cctrl->instance_id == CrInst_NULL)
        {
            set_creature_instance(thing, CrInst_ATTACK_ROOM_SLAB, 1, 0, 0);
            MapCoord ev_coord_x,ev_coord_y;
            ev_coord_x = subtile_coord_center(room->central_stl_x);
            ev_coord_y = subtile_coord_center(room->central_stl_y);
            event_create_event_or_update_nearby_existing_event(ev_coord_x, ev_coord_y, EvKind_RoomUnderAttack, room->owner, 0);
            if (is_my_player_number(room->owner))
                output_message(SMsg_EnemyDestroyRooms, MESSAGE_DELAY_FIGHT, true);
        }
        return 1;
    }
    // Otherwise, search around for a tile to destroy
    long m,n;
    m = ACTION_RANDOM(SMALL_AROUND_SLAB_LENGTH);
    for (n=0; n < SMALL_AROUND_SLAB_LENGTH; n++)
    {
        MapSlabCoord slb_x,slb_y;
        slb_x = base_slb_x + (long)small_around[m].delta_x;
        slb_y = base_slb_y + (long)small_around[m].delta_y;
        room = slab_room_get(slb_x, slb_y);
        if (room_exists(room) && (room->owner != thing->owner))
        {
            if (setup_person_move_to_position(thing, slb_x, slb_y, NavRtF_Default))
            {
                thing->continue_state = CrSt_GoodAttackRoom1;
                return 1;
            }
        }
        m = (m+1) % SMALL_AROUND_SLAB_LENGTH;
    }
    set_start_state(thing);
    return 0;
}
TbBool remove_workshop_object_from_player(PlayerNumber owner, ThingModel objmodel)
{
    struct Thing *cratetng;
    struct Room *room;
    cratetng = get_workshop_box_thing(owner, objmodel);
    if (thing_is_invalid(cratetng)) {
        WARNLOG("Crate %s could not be found",object_code_name(objmodel));
        return false;
    }
    room = get_room_thing_is_on(cratetng);
    if (room_exists(room)) {
        remove_workshop_object_from_workshop(room,cratetng);
    } else {
        WARNLOG("Crate thing index %d isn't placed existing room; removing anyway",(int)cratetng->index);
    }
    create_effect(&cratetng->mappos, imp_spangle_effects[cratetng->owner], cratetng->owner);
    destroy_object(cratetng);
    return true;
}
short good_arrived_at_attack_room(struct Thing *thing)
{
    struct Room *room;
    room = get_room_thing_is_on(thing);
    // If the current tile can be destroyed
    if (room_exists(room) && (room->owner != thing->owner) && !room_cannot_vandalise(room->kind))
    {
        internal_set_thing_state(thing, CrSt_GoodAttackRoom1);
        MapCoord ev_coord_x,ev_coord_y;
        ev_coord_x = subtile_coord_center(room->central_stl_x);
        ev_coord_y = subtile_coord_center(room->central_stl_y);
        event_create_event_or_update_nearby_existing_event(ev_coord_x, ev_coord_y, EvKind_RoomUnderAttack, room->owner, 0);
        if (is_my_player_number(room->owner))
          output_message(SMsg_EnemyDestroyRooms, MESSAGE_DELAY_FIGHT, true);
        return 1;
    }
    set_start_state(thing);
    return 0;
}
示例#4
0
struct Room *get_opponent_room(struct Computer2 *comp, PlayerNumber plyr_idx)
{
    static const RoomKind opponent_room_kinds[] = {RoK_DUNGHEART, RoK_PRISON, RoK_LIBRARY, RoK_TREASURE};
    struct Dungeon *dungeon;
    struct Room *room;
    dungeon = get_players_num_dungeon(plyr_idx);
    if (dungeon_invalid(dungeon) || (slab_conf.room_types_count < 1)) {
        return INVALID_ROOM;
    }
    int i,n;
    n = opponent_room_kinds[ACTION_RANDOM(sizeof(opponent_room_kinds)/sizeof(opponent_room_kinds[0]))];
    for (i=0; i < slab_conf.room_types_count; i++)
    {
        room = room_get(dungeon->room_kind[n]);
        if (room_exists(room)) {
            return room;
        }
        n = (n + 1) % slab_conf.room_types_count;
    }
    return INVALID_ROOM;
}
void room_manager::read_rooms()
{
	if (!filename_.empty() && file_exists(filename_)) {
		LOG_LOBBY << "Reading rooms from " <<  filename_ << "\n";
		config cfg;
		scoped_istream file = istream_file(filename_);
		if (compress_stored_rooms_) {
			read_gz(cfg, *file);
		} else {
			detect_format_and_read(cfg, *file);
		}

		foreach (const config &c, cfg.child_range("room")) {
			room* r(new room(c));
			if (room_exists(r->name())) {
				ERR_LOBBY << "Duplicate room ignored in stored rooms: "
					<< r->name() << "\n";
				delete r;
			} else {
				rooms_by_name_.insert(std::make_pair(r->name(), r));
			}
		}
	}
示例#6
0
struct Thing *find_prisoner_for_thing(struct Thing *creatng)
{
    struct CreatureControl *cctrl;
    struct Thing *thing;
    unsigned long k;
    long i;
    TRACE_THING(creatng);
    struct Room *room;
    room = INVALID_ROOM;
    if (!is_neutral_thing(creatng)) {
        room = find_nearest_room_for_thing_with_used_capacity(creatng, creatng->owner, RoK_PRISON, NavRtF_Default, 1);
    }
    if (room_exists(room)) {
        i = room->creatures_list;
    } else {
        i = 0;
    }
    struct Thing *out_creatng;
    long out_delay;
    out_creatng = INVALID_THING;
    out_delay = LONG_MAX;
    k = 0;
    while (i != 0)
    {
        thing = thing_get(i);
        TRACE_THING(thing);
        cctrl = creature_control_get_from_thing(thing);
        if (!creature_control_exists(cctrl))
        {
            ERRORLOG("Jump to invalid creature %ld detected",i);
            break;
        }
        i = cctrl->next_in_room;
        // Per creature code
        long dist, durt;
        dist = get_2d_box_distance(&creatng->mappos, &thing->mappos);
        if (out_delay < 0)
        {
            // If we have a victim which isn't frozen, accept only other unfrozen creatures
            if ((dist <= LONG_MAX) && !creature_affected_by_spell(thing, SplK_Freeze)) {
                out_creatng = thing;
                out_delay = -1;
            }
        } else
        if (creature_affected_by_spell(thing, SplK_Freeze))
        {
            // If the victim is frozen, select one which will unfreeze sooner
            durt = get_spell_duration_left_on_thing(thing, SplK_Freeze);
            if ((durt > 0) && (out_delay > durt)) {
                out_creatng = thing;
                out_delay = durt;
            }
        } else
        {
            // Found first unfrozen victim - change out_delay to mark thet we no longer want frozen ones
            out_creatng = thing;
            out_delay = -1;
        }
        // Per creature code ends
        k++;
        if (k > THINGS_COUNT)
        {
          ERRORLOG("Infinite loop detected when sweeping creatures list");
          break;
        }
    }
    return out_creatng;
}