Пример #1
0
long instf_damage_wall(struct Thing *creatng, long *param)
{
    SYNCDBG(16,"Starting");
    TRACE_THING(creatng);
    //return _DK_instf_damage_wall(creatng, param);
    MapSubtlCoord stl_x, stl_y;
    {
        struct CreatureControl *cctrl;
        cctrl = creature_control_get_from_thing(creatng);
        stl_x = stl_num_decode_x(cctrl->field_284);
        stl_y = stl_num_decode_y(cctrl->field_284);
    }
    struct SlabMap *slb;
    slb = get_slabmap_for_subtile(stl_x, stl_y);
    if (slb->health > 2)
    {
        slb->health -= 2;
    } else
    {
        place_slab_type_on_map(2, stl_x, stl_y, creatng->owner, 0);
        do_slab_efficiency_alteration(subtile_slab_fast(stl_x), subtile_slab_fast(stl_y));
    }
    thing_play_sample(creatng, 63+UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
    return 1;
}
Пример #2
0
TbBool can_place_trap_on(PlayerNumber plyr_idx, MapSubtlCoord stl_x, MapSubtlCoord stl_y)
{
    MapSlabCoord slb_x, slb_y;
    slb_x = subtile_slab_fast(stl_x);
    slb_y = subtile_slab_fast(stl_y);
    struct SlabMap *slb;
    slb = get_slabmap_block(slb_x, slb_y);
    struct SlabAttr *slbattr;
    slbattr = get_slab_attrs(slb);
    if (!subtile_revealed(stl_x, stl_y, plyr_idx)) {
        return false;
    }
    if (((slbattr->block_flags & (SlbAtFlg_Filled|SlbAtFlg_Digable|SlbAtFlg_Valuable)) != 0)) {
        return false;
    }
    if (slab_kind_is_liquid(slb->kind)) {
        return false;
    }
    if ((slabmap_owner(slb) == plyr_idx) && (slb->kind == SlbT_CLAIMED))
    {
        if (!slab_has_trap_on(slb_x, slb_y) && !subtile_has_door_thing_on(stl_x, stl_y))
        {
            return true;
        }
    }
    return false;
}
Пример #3
0
/**
 * Finds a safe and unused, adjacent position in room for a creature.
 *
 * @param pos Position of the creature to be moved.
 * @param owner Room owner to keep.
 * @return Coded subtiles of the new position, or 0 on failure.
 * @see person_get_somewhere_adjacent_in_room()
 */
SubtlCodedCoords find_unused_adjacent_position_in_workshop(const struct Coord3d *pos, long owner)
{
    static const struct Around corners[] = { {1,2}, {0,1}, {1,0}, {2,1} };
    long i;
    for (i=0; i < SMALL_AROUND_LENGTH; i++)
    {
        MapSlabCoord slb_x, slb_y;
        slb_x = subtile_slab_fast(pos->x.stl.num) + (long)small_around[i].delta_x;
        slb_y = subtile_slab_fast(pos->y.stl.num) + (long)small_around[i].delta_y;
        struct SlabMap *slb;
        slb = get_slabmap_block(slb_x, slb_y);
        if ((slb->kind == SlbT_WORKSHOP) && (slabmap_owner(slb) == owner))
        {
            struct Thing *mnfc_creatng;
            MapSubtlCoord stl_x, stl_y;
            stl_x = slab_subtile(slb_x, corners[i].delta_x);
            stl_y = slab_subtile(slb_y, corners[i].delta_y);
            mnfc_creatng = get_other_creature_manufacturing_on_subtile(owner, stl_x, stl_y, INVALID_THING);
            if (!thing_is_invalid(mnfc_creatng)) {
                // Position used by another manufacturer
                continue;
            }
            struct Thing *objtng;
            objtng = get_workshop_equipment_to_work_with_on_subtile(owner, slab_subtile_center(slb_x), slab_subtile_center(slb_y));
            if (thing_is_invalid(objtng)) {
                // Position has no work equipment nearby
                continue;
            }
            // Found an acceptable position
            return get_subtile_number(stl_x, stl_y);
        }
    }
    return 0;
}
Пример #4
0
TbBool update_trap_trigger_pressure(struct Thing *traptng)
{
    MapSlabCoord slb_x, slb_y;
    slb_x = subtile_slab_fast(traptng->mappos.x.stl.num);
    slb_y = subtile_slab_fast(traptng->mappos.y.stl.num);
    MapSubtlCoord stl_x, stl_y;
    MapSubtlCoord end_stl_x, end_stl_y;
    end_stl_x = slab_subtile(slb_x,2);
    end_stl_y = slab_subtile(slb_y,2);
    for (stl_y=slab_subtile(slb_y,0); stl_y <= end_stl_y; stl_y++)
    {
        for (stl_x=slab_subtile(slb_x,0); stl_x <= end_stl_x; stl_x++)
        {
            struct Thing *creatng;
            creatng = INVALID_THING;
            if (find_pressure_trigger_trap_target_passing_by_subtile(traptng, stl_x, stl_y, &creatng))
            {
                activate_trap(traptng, creatng);
                return true;
            }

        }
    }
    return false;
}
Пример #5
0
long instf_destroy(struct Thing *creatng, long *param)
{
    struct Dungeon *dungeon;
    struct Room *room;
    struct SlabMap *slb;
    MapSlabCoord slb_x,slb_y;
    long prev_owner;

    TRACE_THING(creatng);
    slb_x = subtile_slab_fast(creatng->mappos.x.stl.num);
    slb_y = subtile_slab_fast(creatng->mappos.y.stl.num);
    dungeon = get_dungeon(creatng->owner);
    slb = get_slabmap_block(slb_x, slb_y);
    room = room_get(slb->room_index);
    prev_owner = slabmap_owner(slb);

    if ( !room_is_invalid(room) && (prev_owner != creatng->owner) )
    {
        if (room->health > 1)
        {
            room->health--;
            return 0;
        }
        clear_dig_on_room_slabs(room, creatng->owner);
        if (room->owner == game.neutral_player_num)
        {
            claim_room(room, creatng);
        } else
        {
            MapCoord ccor_x,ccor_y;
            ccor_x = subtile_coord_center(room->central_stl_x);
            ccor_y = subtile_coord_center(room->central_stl_y);
            event_create_event_or_update_nearby_existing_event(ccor_x, ccor_y, EvKind_RoomLost, room->owner, 0);
            claim_enemy_room(room, creatng);
        }
        thing_play_sample(creatng, 76, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
        create_effects_on_room_slabs(room, imp_spangle_effects[creatng->owner], 0, creatng->owner);
        return 0;
    }
    if (slb->health > 1)
    {
        slb->health--;
        return 0;
    }
    if (prev_owner != game.neutral_player_num) {
        struct Dungeon *prev_dungeon;
        prev_dungeon = get_dungeon(prev_owner);
        prev_dungeon->lvstats.territory_lost++;
    }
    decrease_dungeon_area(prev_owner, 1);
    neutralise_enemy_block(creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, creatng->owner);
    remove_traps_around_subtile(slab_subtile_center(slb_x), slab_subtile_center(slb_y), NULL);
    switch_owned_objects_on_destoyed_slab_to_neutral(slb_x, slb_y, prev_owner);
    dungeon->lvstats.territory_destroyed++;
    return 1;
}
Пример #6
0
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;
}
Пример #7
0
void activate_trap_slab_change(struct Thing *traptng, struct Thing *creatng)
{
    MapSubtlCoord stl_x, stl_y;
    stl_x = traptng->mappos.x.stl.num;
    stl_y = traptng->mappos.y.stl.num;
    if (subtile_is_room(stl_x, stl_y)) {
        delete_room_slab(subtile_slab_fast(stl_x), subtile_slab_fast(stl_y), true);
    }
    place_slab_type_on_map(trap_stats[traptng->model].field_1A, stl_x, stl_y, game.neutral_player_num, 0);
    do_slab_efficiency_alteration(subtile_slab_fast(stl_x), subtile_slab_fast(stl_y));
}
Пример #8
0
long instf_reinforce(struct Thing *creatng, long *param)
{
    struct CreatureControl *cctrl;
    SYNCDBG(16,"Starting");
    TRACE_THING(creatng);
    //return _DK_instf_reinforce(creatng, param);
    cctrl = creature_control_get_from_thing(creatng);
    MapSubtlCoord stl_x,stl_y;
    MapSlabCoord slb_x,slb_y;
    stl_x = stl_num_decode_x(cctrl->digger.working_stl);
    stl_y = stl_num_decode_y(cctrl->digger.working_stl);
    slb_x = subtile_slab_fast(stl_x);
    slb_y = subtile_slab_fast(stl_y);
    if (check_place_to_reinforce(creatng, slb_x, slb_y) <= 0) {
        return 0;
    }
    if (cctrl->digger.byte_93 <= 25)
    {
        cctrl->digger.byte_93++;
        if (!S3DEmitterIsPlayingSample(creatng->snd_emitter_id, 172, 0)) {
            thing_play_sample(creatng, 172, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
        }
        return 0;
    }
    cctrl->digger.byte_93 = 0;
    place_and_process_pretty_wall_slab(creatng, slb_x, slb_y);
    struct Coord3d pos;
    pos.x.stl.pos = 128;
    pos.y.stl.pos = 128;
    pos.z.stl.pos = 128;
    long n;
    for (n=0; n < SMALL_AROUND_LENGTH; n++)
    {
        pos.x.stl.num = stl_x + 2 * small_around[n].delta_x;
        pos.y.stl.num = stl_y + 2 * small_around[n].delta_y;
        struct Map *mapblk;
        mapblk = get_map_block_at(pos.x.stl.num, pos.y.stl.num);
        if (map_block_revealed(mapblk, creatng->owner) && ((mapblk->flags & MapFlg_IsTall) == 0))
        {
            pos.z.val = get_floor_height_at(&pos);
            create_effect(&pos, imp_spangle_effects[creatng->owner], creatng->owner);
        }
    }
    thing_play_sample(creatng, 41, NORMAL_PITCH, 0, 3, 0, 3, FULL_LOUDNESS);
    return 0;
}
Пример #9
0
long instf_first_person_do_imp_task(struct Thing *creatng, long *param)
{
    MapSlabCoord slb_x,slb_y;
    long locparam;
    TRACE_THING(creatng);
    //return _DK_instf_first_person_do_imp_task(thing, param);
    slb_x = subtile_slab_fast(creatng->mappos.x.stl.num);
    slb_y = subtile_slab_fast(creatng->mappos.y.stl.num);
    if ( check_place_to_pretty_excluding(creatng, slb_x, slb_y) )
    {
        instf_pretty_path(creatng, NULL);
    } else
    {
        locparam = 23;
        instf_creature_fire_shot(creatng, &locparam);
    }
    return 1;
}
Пример #10
0
void setup_workshop_search_for_post(struct Thing *creatng)
{
    struct Room *room;
    struct Thing *postng;
    postng = INVALID_THING;
    room = get_room_thing_is_on(creatng);
    // Find a random slab in the room to be used as our starting point
    long i;
    unsigned long n;
    i = ACTION_RANDOM(room->slabs_count);
    n = room->slabs_list;
    while (i > 0)
    {
        n = get_next_slab_number_in_room(n);
        i--;
    }
    i = room->slabs_count;
    while (i > 0)
    {
        // Loop the slabs list
        if (n <= 0) {
            n = room->slabs_list;
        }
        MapSlabCoord slb_x, slb_y;
        slb_x = subtile_slab_fast(stl_num_decode_x(n));
        slb_y = subtile_slab_fast(stl_num_decode_y(n));
        struct Thing *objtng;
        objtng = get_workshop_equipment_to_work_with_on_subtile(creatng->owner, slab_subtile_center(slb_x), slab_subtile_center(slb_y));
        if (!thing_is_invalid(objtng)) {
            postng = objtng;
        }
        n = get_next_slab_number_in_room(n);
        i--;
    }
    if (thing_is_invalid(postng))
    {
        SYNCDBG(9,"Work in %s, the %s moves to new pos",room_code_name(room->kind),thing_model_name(creatng));
        setup_move_to_new_workshop_position(creatng, room, 1);
    } else
    {
        SYNCDBG(9,"Work in %s, the %s found a post",room_code_name(room->kind),thing_model_name(creatng));
        setup_workshop_move(creatng, get_subtile_number(postng->mappos.x.stl.num, postng->mappos.y.stl.num));
    }
}
Пример #11
0
long instf_pretty_path(struct Thing *creatng, long *param)
{
    struct Dungeon *dungeon;
    TRACE_THING(creatng);
    SYNCDBG(16,"Starting");
    dungeon = get_dungeon(creatng->owner);
    MapSlabCoord slb_x,slb_y;
    slb_x = subtile_slab_fast(creatng->mappos.x.stl.num);
    slb_y = subtile_slab_fast(creatng->mappos.y.stl.num);
    create_effect(&creatng->mappos, imp_spangle_effects[creatng->owner], creatng->owner);
    thing_play_sample(creatng, 76, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
    place_slab_type_on_map(SlbT_CLAIMED, slab_subtile_center(slb_x), slab_subtile_center(slb_y), creatng->owner, 1);
    do_unprettying(creatng->owner, slb_x, slb_y);
    do_slab_efficiency_alteration(slb_x, slb_y);
    increase_dungeon_area(creatng->owner, 1);
    dungeon->lvstats.area_claimed++;
    remove_traps_around_subtile(slab_subtile_center(slb_x), slab_subtile_center(slb_y), NULL);
    return 1;
}
Пример #12
0
TbBool tag_cursor_blocks_place_trap(PlayerNumber plyr_idx, MapSubtlCoord stl_x, MapSubtlCoord stl_y)
{
    SYNCDBG(7,"Starting");
    int floor_height;
    TbBool can_place;
    MapSlabCoord slb_x, slb_y;
    slb_x = subtile_slab_fast(stl_x);
    slb_y = subtile_slab_fast(stl_y);
    can_place = can_place_trap_on(plyr_idx, stl_x, stl_y);
    floor_height = floor_height_for_volume_box(plyr_idx, slb_x, slb_y);
    if (is_my_player_number(plyr_idx))
    {
        if (!game_is_busy_doing_gui() && (game.small_map_state != 2)) {
            // Move to first subtile on a slab
            stl_x = slab_subtile(slb_x,0);
            stl_y = slab_subtile(slb_y,0);
            draw_map_volume_box(subtile_coord(stl_x,0), subtile_coord(stl_y,0),
                subtile_coord(stl_x+STL_PER_SLB,0), subtile_coord(stl_y+STL_PER_SLB,0), floor_height, can_place);
        }
    }
    return can_place;
}
Пример #13
0
void make_safe(struct PlayerInfo *player)
{
    //_DK_make_safe(player);
    unsigned char *areamap;
    areamap = (unsigned char *)scratch;
    MapSlabCoord slb_x, slb_y;
    // Prepare the array to remember which slabs were already taken care of
    for (slb_y=0; slb_y < map_tiles_y; slb_y++)
    {
        for (slb_x=0; slb_x < map_tiles_x; slb_x++)
        {
            SlabCodedCoords slb_num;
            struct SlabMap *slb;
            slb_num = get_slab_number(slb_x, slb_y);
            slb = get_slabmap_direct(slb_num);
            struct SlabAttr *slbattr;
            slbattr = get_slab_attrs(slb);
            if ((slbattr->block_flags & (SlbAtFlg_Filled|SlbAtFlg_Digable|SlbAtFlg_Valuable)) != 0)
                areamap[slb_num] = 0x01;
            else
                areamap[slb_num] = 0x00;
        }
    }
    {
        const struct Coord3d *center_pos;
        center_pos = dungeon_get_essential_pos(player->id_number);
        slb_x = subtile_slab_fast(center_pos->x.stl.num);
        slb_y = subtile_slab_fast(center_pos->y.stl.num);
        SlabCodedCoords slb_num;
        slb_num = get_slab_number(slb_x, slb_y);
        areamap[slb_num] |= 0x02;
    }

    unsigned int list_cur, list_len;
    PlayerNumber plyr_idx;
    plyr_idx = player->id_number;
    SlabCodedCoords *slblist;
    slblist = (SlabCodedCoords *)(scratch + map_tiles_x*map_tiles_y);
    list_len = 0;
    list_cur = 0;
    while (list_cur <= list_len)
    {
        SlabCodedCoords slb_num;

        if (slb_x > 0)
        {
            slb_num = get_slab_number(slb_x-1, slb_y);
            if ((areamap[slb_num] & 0x01) != 0)
            {
                areamap[slb_num] |= 0x02;
                struct SlabMap *slb;
                slb = get_slabmap_direct(slb_num);
                struct SlabAttr *slbattr;
                slbattr = get_slab_attrs(slb);
                if ((slbattr->category == SlbAtCtg_FriableDirt) && slab_by_players_land(plyr_idx, slb_x-1, slb_y))
                {
                    unsigned char pretty_type;
                    pretty_type = choose_pretty_type(plyr_idx, slb_x-1, slb_y);
                    place_slab_type_on_map(pretty_type, slab_subtile(slb_x-1,0), slab_subtile(slb_y,0), plyr_idx, 1);
                    do_slab_efficiency_alteration(slb_x-1, slb_y);
                    fill_in_reinforced_corners(plyr_idx, slb_x-1, slb_y);
                }
            } else
            if ((areamap[slb_num] & 0x02) == 0)
            {
                areamap[slb_num] |= 0x02;
                slblist[list_len] = slb_num;
                list_len++;
            }
        }
        if (slb_x < map_tiles_x-1)
        {
            slb_num = get_slab_number(slb_x+1, slb_y);
            if ((areamap[slb_num] & 0x01) != 0)
            {
                areamap[slb_num] |= 0x02;
                struct SlabMap *slb;
                slb = get_slabmap_direct(slb_num);
                struct SlabAttr *slbattr;
                slbattr = get_slab_attrs(slb);
                if ((slbattr->category == SlbAtCtg_FriableDirt) &&  slab_by_players_land(plyr_idx, slb_x+1, slb_y))
                {
                    unsigned char pretty_type;
                    pretty_type = choose_pretty_type(plyr_idx, slb_x+1, slb_y);
                    place_slab_type_on_map(pretty_type, slab_subtile(slb_x+1,0), slab_subtile(slb_y,0), plyr_idx, 1u);
                    do_slab_efficiency_alteration(slb_x+1, slb_y);
                    fill_in_reinforced_corners(plyr_idx, slb_x+1, slb_y);
                }
            } else
            if ((areamap[slb_num] & 0x02) == 0)
            {
                areamap[slb_num] |= 0x02;
                slblist[list_len] = slb_num;
                list_len++;
            }
        }
        if (slb_y > 0)
        {
            slb_num = get_slab_number(slb_x, slb_y-1);
            if ((areamap[slb_num] & 0x01) != 0)
            {
                areamap[slb_num] |= 0x02;
                struct SlabMap *slb;
                slb = get_slabmap_direct(slb_num);
                struct SlabAttr *slbattr;
                slbattr = get_slab_attrs(slb);
                if ((slbattr->category == SlbAtCtg_FriableDirt) && slab_by_players_land(plyr_idx, slb_x, slb_y-1))
                {
                    unsigned char pretty_type;
                    pretty_type = choose_pretty_type(plyr_idx, slb_x, slb_y-1);
                    place_slab_type_on_map(pretty_type, slab_subtile(slb_x,0), slab_subtile(slb_y-1,0), plyr_idx, 1u);
                    do_slab_efficiency_alteration(slb_x, slb_y-1);
                    fill_in_reinforced_corners(plyr_idx, slb_x, slb_y-1);
                }
            } else
            if ((areamap[slb_num] & 0x02) == 0)
            {
                areamap[slb_num] |= 0x02;
                slblist[list_len] = slb_num;
                list_len++;
            }
        }
        if (slb_y < map_tiles_y-1)
        {
            slb_num = get_slab_number(slb_x, slb_y+1);
            if ((areamap[slb_num] & 0x01) != 0)
            {
                areamap[slb_num] |= 0x02;
                struct SlabMap *slb;
                slb = get_slabmap_direct(slb_num);
                struct SlabAttr *slbattr;
                slbattr = get_slab_attrs(slb);
                if ((slbattr->category == SlbAtCtg_FriableDirt) && slab_by_players_land(plyr_idx, slb_x, slb_y+1))
                {
                    unsigned char pretty_type;
                    pretty_type = choose_pretty_type(plyr_idx, slb_x, slb_y+1);
                    place_slab_type_on_map(pretty_type, slab_subtile(slb_x,0), slab_subtile(slb_y+1,0), plyr_idx, 1u);
                    do_slab_efficiency_alteration(slb_x, slb_y+1);
                    fill_in_reinforced_corners(plyr_idx, slb_x, slb_y+1);
                }
            } else
            if ((areamap[slb_num] & 0x02) == 0)
            {
                areamap[slb_num] |= 0x02;
                slblist[list_len] = slb_num;
                list_len++;
            }
        }

        slb_x = slb_num_decode_x(slblist[list_cur]);
        slb_y = slb_num_decode_y(slblist[list_cur]);
        list_cur++;
    }
    pannel_map_update(0, 0, map_subtiles_x+1, map_subtiles_y+1);
}
Пример #14
0
void update_horizonal_explored_flags_for_power_sight(struct PlayerInfo *player, struct Coord3d *soe_pos)
{
    struct Dungeon *dungeon;
    long stl_x,stl_y;
    long soe_x,soe_y;
    long boundstl_y;
    long slb_x,slb_y;
    long delta;
    long i;
    dungeon = get_players_dungeon(player);
    stl_x = (long)soe_pos->x.stl.num - MAX_SOE_RADIUS;
    for (soe_x=0; soe_x < 2*MAX_SOE_RADIUS; soe_x++,stl_x++)
    {
        if ( (stl_x >= 0) && (stl_x <= 255) )
        {
            stl_y = (long)soe_pos->y.stl.num - MAX_SOE_RADIUS;
            for (soe_y=0; soe_y <= MAX_SOE_RADIUS; soe_y++,stl_y++)
            {
                if (dungeon->soe_explored_flags[soe_y][soe_x])
                {
                    soe_y++;
                    // Find max value for delta
                    delta = 0;
                    for (i=1; soe_y < 2*MAX_SOE_RADIUS; soe_y++,i++)
                    {
                        if (dungeon->soe_explored_flags[soe_y][soe_x])
                            delta = i;
                    }
                    boundstl_y = stl_y + delta;
                    if (boundstl_y < 0)
                    {
                        boundstl_y = 0;
                    } else
                    if (boundstl_y > map_subtiles_y-1)
                    {
                        boundstl_y = map_subtiles_y-1;
                    }
                    if (stl_y < 0)
                    {
                        stl_y = 0;
                    } else
                    if (stl_y > map_subtiles_y-1)
                    {
                        stl_y = map_subtiles_y-1;
                    }
                    if (stl_y <= boundstl_y)
                    {
                      delta = boundstl_y - stl_y + 1;
                      slb_x = subtile_slab_fast(stl_x);
                      for (i=0; i < delta; i++)
                      {
                          struct Map *mapblk;
                          slb_y = subtile_slab_fast(stl_y+i);
                          mapblk = get_map_block_at(stl_x, stl_y+i);
                          reveal_map_block(mapblk, player->id_number);
                          struct SlabMap *slb;
                          struct SlabAttr *slbattr;
                          slb = get_slabmap_block(slb_x, slb_y);
                          slbattr = get_slab_attrs(slb);
                          if ( !slbattr->is_unknflg14 )
                              mapblk->flags &= ~(MapFlg_Unkn80|MapFlg_Unkn04);
                      }
                      stl_y += delta;
                    }
                }
            }
        }
    }
}
Пример #15
0
long process_creature_in_workshop(struct Thing *creatng, struct Room *room)
{
    //return _DK_process_creature_in_workshop(creatng, room);
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(creatng);
    struct Dungeon *dungeon;
    dungeon = get_dungeon(creatng->owner);
    if ((game.play_gameturn - dungeon->field_118B < 50) && ((game.play_gameturn + creatng->index) & 3) == 0)
    {
        if (cctrl->instance_id == CrInst_NULL) {
            set_creature_instance(creatng, CrInst_CELEBRATE_SHORT, 1, 0, 0);
        }
        return 1;
    }
    if (cctrl->instance_id != CrInst_NULL) {
        return 1;
    }
    long mvret;
    MapSlabCoord slb_x, slb_y;
    SYNCDBG(19,"Work in %s, the %s in state %d",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A);
    switch (cctrl->byte_9A)
    {
    case 1:
        cctrl->byte_9E--;
        if (cctrl->byte_9E <= 0)
        {
            setup_workshop_search_for_post(creatng);
            cctrl->byte_9E = 100;
            break;
        }
        mvret = creature_move_to(creatng, &cctrl->moveto_pos, get_creature_speed(creatng), 0, 0);
        if (mvret != 1)
        {
            if (mvret == -1) {
                SYNCDBG(9,"Room %s move problem, the %s goes from %d to start state",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A);
                set_start_state(creatng);
            }
            break;
        }
        slb_x = subtile_slab_fast(creatng->mappos.x.stl.num);
        slb_y = subtile_slab_fast(creatng->mappos.y.stl.num);
        struct Thing *objtng;
        objtng = get_workshop_equipment_to_work_with_on_subtile(creatng->owner, slab_subtile_center(slb_x),slab_subtile_center(slb_y));
        if (!thing_is_invalid(objtng))
        {
            SYNCDBG(19,"Got %s post, the %s goes from %d to 2",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A);
            cctrl->byte_9A = 2;
            cctrl->byte_9E = 100;
            break;
        }
        SYNCDBG(19,"No %s post at current pos, the %s goes from %d to search position",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A);
        setup_move_to_new_workshop_position(creatng, room, 0);
        break;
    case 2:
    {
        SubtlCodedCoords stl_num;
        stl_num = find_unused_adjacent_position_in_workshop(&creatng->mappos, creatng->owner);
        if (stl_num != 0) {
            slb_x = subtile_slab_fast(stl_num_decode_x(stl_num));
            slb_y = subtile_slab_fast(stl_num_decode_y(stl_num));
            cctrl->byte_9C = slab_subtile_center(slb_x);
            cctrl->byte_9D = slab_subtile_center(slb_y);
            setup_workshop_move(creatng, stl_num);
            cctrl->byte_9A = 3;
            break;
        }
        SYNCDBG(9,"No free adjacent %s post, the %s goes from %d to search position",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A);
        setup_move_to_new_workshop_position(creatng, room, 1);
        break;
    }
    case 3:
    {
        mvret = creature_move_to(creatng, &cctrl->moveto_pos, get_creature_speed(creatng), 0, 0);
        if (mvret != 1)
        {
            if (mvret == -1) {
                SYNCDBG(9,"Room %s move problem, the %s goes from %d to start state",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A);
                set_start_state(creatng);
            }
            break;
        }
        struct Thing *mnfc_creatng;
        mnfc_creatng = get_other_creature_manufacturing_on_subtile(creatng->owner, creatng->mappos.x.stl.num, creatng->mappos.y.stl.num, creatng);
        if (thing_is_invalid(mnfc_creatng)) {
            cctrl->byte_9A = 4;
            break;
        }
        // Position used by another manufacturer
        SYNCDBG(9,"The %s post already in use, the %s goes from %d to search position",room_code_name(room->kind),thing_model_name(creatng),(int)cctrl->byte_9A);
        setup_move_to_new_workshop_position(creatng, room, 1);
        break;
    }
    case 4:
    {
        struct Coord3d pos;
        pos.x.val = subtile_coord_center(cctrl->byte_9C);
        pos.y.val = subtile_coord_center(cctrl->byte_9D);
        if (creature_turn_to_face(creatng, &pos) < 56)
        {
            cctrl->byte_9A = 5;
            cctrl->byte_9B = 75;
        }
        break;
    }
    case 5:
    default:
        cctrl->byte_9B--;
        if (cctrl->byte_9B <= 0)
        {
            SYNCDBG(9,"Room %s move counter %d, the %s keeps moving in state %d",room_code_name(room->kind),(int)cctrl->byte_9B,thing_model_name(creatng),(int)cctrl->byte_9A);
            setup_move_to_new_workshop_position(creatng, room, 1);
        } else
        if ((cctrl->byte_9B % 8) == 0) {
            set_creature_instance(creatng, CrInst_SWING_WEAPON_SWORD, 1, 0, 0);
        }
        break;
    }
    return 1;
}
Пример #16
0
void process_creature_in_training_room(struct Thing *thing, struct Room *room)
{
    static const struct Around corners[] = {
        {1, 2},
        {0, 1},
        {1, 0},
        {2, 1},
    };
    struct CreatureControl *cctrl;
    struct CreatureStats *crstat;
    struct Thing *traintng;
    struct Thing *crtng;
    struct CreatureControl *cctrl2;
    struct Coord3d pos;
    long speed,dist;
    long i;
    cctrl = creature_control_get_from_thing(thing);
    SYNCDBG(8,"Starting %s mode %d",thing_model_name(thing),(int)cctrl->training.mode);
    //_DK_process_creature_in_training_room(thing, room); return;
    cctrl->field_4A = 0;
    switch (cctrl->training.mode)
    {
    case CrTrMd_SearchForTrainPost:
        // While we're in an instance, just wait
        if (cctrl->instance_id != CrInst_NULL)
            break;
        // On timeout, search for nearby training posts to start training ASAP
        if (cctrl->training.search_timeout < 1)
        {
            SYNCDBG(6,"Search timeout - selecting post nearest to (%d,%d)",(int)thing->mappos.x.stl.num, (int)thing->mappos.y.stl.num);
            setup_training_search_for_post(thing);
            cctrl->training.search_timeout = 100;
            break;
        }
        // Do a moving step
        cctrl->training.search_timeout--;
        speed = get_creature_speed(thing);
        i = creature_move_to(thing, &cctrl->moveto_pos, speed, 0, 0);
        if (i == 1)
        {
            // Move target is reached - find a training post which is supposed to be around here
            traintng = find_training_post_just_next_to_creature(thing);
            if (thing_is_invalid(traintng))
            {
                SYNCDBG(6,"Reached (%d,%d) but there's no training post there",(int)thing->mappos.x.stl.num, (int)thing->mappos.y.stl.num);
                setup_move_to_new_training_position(thing, room, false);
                break;
            }
            // Found - go to next mode
            cctrl->training.mode = CrTrMd_SelectPositionNearTrainPost;
            cctrl->training.search_timeout = 50;
        } else
        if (i == -1)
        {
            ERRORLOG("Cannot get to (%d,%d) in the training room",(int)cctrl->moveto_pos.x.stl.num,(int)cctrl->moveto_pos.y.stl.num);
            set_start_state(thing);
        }
        break;
    case CrTrMd_SelectPositionNearTrainPost:
        for (i=0; i < 4; i++)
        {
            long slb_x,slb_y;
            long stl_x,stl_y;
            struct SlabMap *slb;
            slb_x = subtile_slab_fast(thing->mappos.x.stl.num) + (long)small_around[i].delta_x;
            slb_y = subtile_slab_fast(thing->mappos.y.stl.num) + (long)small_around[i].delta_y;
            slb = get_slabmap_block(slb_x,slb_y);
            if ((slb->kind != SlbT_TRAINING) || (slabmap_owner(slb) != thing->owner))
                continue;
            stl_x = slab_subtile(slb_x,corners[i].delta_x);
            stl_y = slab_subtile(slb_y,corners[i].delta_y);
            traintng = INVALID_THING;
            // Check if any other creature is using that post; allow only unused posts
            crtng = get_creature_of_model_training_at_subtile_and_owned_by(stl_x, stl_y, -1, thing->owner, thing->index);
            if (thing_is_invalid(crtng))
            {
                traintng = get_object_at_subtile_of_model_and_owned_by(slab_subtile_center(slb_x), slab_subtile_center(slb_y), 31, thing->owner);
            }
            if (!thing_is_invalid(traintng))
            {
                cctrl->training.pole_stl_x = slab_subtile_center(subtile_slab_fast(thing->mappos.x.stl.num));
                cctrl->training.pole_stl_y = slab_subtile_center(subtile_slab_fast(thing->mappos.y.stl.num));
                cctrl->moveto_pos.x.stl.num = stl_x;
                cctrl->moveto_pos.y.stl.num = stl_y;
                cctrl->moveto_pos.x.stl.pos = 128;
                cctrl->moveto_pos.y.stl.pos = 128;
                cctrl->moveto_pos.z.val = get_thing_height_at(thing, &cctrl->moveto_pos);
                if (thing_in_wall_at(thing, &cctrl->moveto_pos))
                {
                    ERRORLOG("Illegal setup to (%d,%d)", (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num);
                    break;
                }
                cctrl->training.mode = CrTrMd_MoveToTrainPost;
                break;
            }
        }
        if (cctrl->training.mode == CrTrMd_SelectPositionNearTrainPost)
          setup_move_to_new_training_position(thing, room, 1);
        break;
    case CrTrMd_MoveToTrainPost:
        speed = get_creature_speed(thing);
        i = creature_move_to(thing, &cctrl->moveto_pos, speed, 0, 0);
        if (i == 1)
        {
            // If there's already someone training at that position, go somewhere else
            crtng = get_creature_of_model_training_at_subtile_and_owned_by(thing->mappos.x.stl.num, thing->mappos.y.stl.num, -1, thing->owner, thing->index);
            if (!thing_is_invalid(crtng))
            {
                setup_move_to_new_training_position(thing, room, 1);
                break;
            }
            // Otherwise, train at this position
            cctrl->training.mode = CrTrMd_TurnToTrainPost;
        } else
        if (i == -1)
        {
            ERRORLOG("Cannot get where we're going in the training room.");
            set_start_state(thing);
        }
        break;
    case CrTrMd_TurnToTrainPost:
        pos.x.val = subtile_coord_center(cctrl->training.pole_stl_x);
        pos.y.val = subtile_coord_center(cctrl->training.pole_stl_y);
        if (creature_turn_to_face(thing, &pos) < 56)
        {
          cctrl->training.mode = CrTrMd_DoTrainWithTrainPost;
          cctrl->training.train_timeout = 75;
        }
        break;
    case CrTrMd_PartnerTraining:
        if (cctrl->training.partner_idx == 0)
        {
            setup_move_to_new_training_position(thing, room, false);
            return;
        }
        crtng = thing_get(cctrl->training.partner_idx);
        TRACE_THING(crtng);
        if (!thing_exists(crtng) || (get_creature_state_besides_move(crtng) != CrSt_Training) || (crtng->creation_turn != cctrl->training.partner_creation))
        {
            SYNCDBG(8,"The %s cannot start partner training - creature to train with is gone.",thing_model_name(thing));
            setup_move_to_new_training_position(thing, room, false);
            return;
        }
        cctrl2 = creature_control_get_from_thing(crtng);
        if (cctrl2->training.partner_idx != thing->index)
        {
            SYNCDBG(6,"The %s cannot start partner training - %s changed the partner.",thing_model_name(thing),thing_model_name(crtng));
            cctrl->training.partner_idx = 0;
            setup_move_to_new_training_position(thing, room, false);
            break;
        }
        if (get_room_thing_is_on(crtng) != room)
        {
            SYNCDBG(8,"The %s cannot start partner training - partner has left the room.",thing_model_name(thing));
            cctrl->training.partner_idx = 0;
            cctrl2->training.partner_idx = 0;
            setup_move_to_new_training_position(thing, room, false);
            break;
        }
        crstat = creature_stats_get_from_thing(thing);
        dist = get_combat_distance(thing, crtng);
        if (dist > 284)
        {
            if (creature_move_to(thing, &crtng->mappos, get_creature_speed(thing), 0, 0) == -1)
            {
              WARNLOG("The %s cannot navigate to training partner",thing_model_name(thing));
              setup_move_to_new_training_position(thing, room, false);
              cctrl->training.partner_idx = 0;
            }
        } else
        if (dist >= 156)
        {
            if (creature_turn_to_face(thing, &crtng->mappos) < 56)
            {
              cctrl->training.train_timeout--;
              if (cctrl->training.train_timeout > 0)
              {
                if ((cctrl->instance_id == CrInst_NULL) && ((cctrl->training.train_timeout % 8) == 0))
                {
                    set_creature_instance(thing, CrInst_SWING_WEAPON_SWORD, 1, 0, 0);
                }
              } else
              {
                if (cctrl->instance_id == CrInst_NULL)
                {
                    setup_move_to_new_training_position(thing, room, false);
                    cctrl->training.partner_idx = 0;
                } else
                {
                    cctrl->training.train_timeout = 1;
                }
                cctrl->exp_points += (room->efficiency * crstat->training_value);
              }
            }
        } else
        {
            creature_retreat_from_combat(thing, crtng, 33, 0);
        }
        break;
    case CrTrMd_DoTrainWithTrainPost:
        if (cctrl->training.train_timeout > 0)
        {
            // While training timeout is positive, continue initiating the train instances
            cctrl->training.train_timeout--;
            if ((cctrl->instance_id == CrInst_NULL) && ((cctrl->training.train_timeout % 8) == 0))
            {
                set_creature_instance(thing, CrInst_SWING_WEAPON_SWORD, 1, 0, 0);
            }
        } else
        {
            // Wait for the instance to end, then select new move position
            if (cctrl->instance_id != CrInst_NULL)
            {
                cctrl->training.train_timeout = 0;
            } else
            {
                cctrl->training.train_timeout = 0;
                setup_move_to_new_training_position(thing, room, true);
            }
        }
        break;
    default:
        WARNLOG("Invalid %s training mode %d; reset",thing_model_name(thing),(int)cctrl->training.mode);
        cctrl->training.mode = CrTrMd_SearchForTrainPost;
        cctrl->training.search_timeout = 0;
        break;
    }
    SYNCDBG(18,"End");
}
Пример #17
0
TbBool find_place_to_put_door_around_room(const struct Room *room, struct Coord3d *pos)
{
    long m,n;
    m = ACTION_RANDOM(SMALL_AROUND_SLAB_LENGTH);
    for (n = 0; n < SMALL_AROUND_SLAB_LENGTH; n++)
    {
        // Get position containing room center
        MapSlabCoord slb_x,slb_y;
        slb_x = subtile_slab_fast(room->central_stl_x);
        slb_y = subtile_slab_fast(room->central_stl_y);
        // Move the position to edge of the room
        struct Room *sibroom;
        sibroom = slab_room_get(slb_x, slb_y);
        while (!room_is_invalid(sibroom) && (sibroom->index == room->index))
        {
            slb_x += small_around[m].delta_x;
            slb_y += small_around[m].delta_y;
            sibroom = slab_room_get(slb_x, slb_y);
        }
        // Move the position a few tiles further in that direction searching for a place to put door
        //TODO COMPUTER_PLAYER Why we can only have doors if corridor is at center of the room? This should be fixed to allow doors everywhere around room.
        int i;
        for (i = 4; i > 0; i--)
        {
            struct SlabMap *slb;
            slb = get_slabmap_block(slb_x, slb_y);
            if ((slabmap_owner(slb) != room->owner) || (slb->kind != SlbT_CLAIMED)) {
                i = 0;
                break;
            }
            if (tag_cursor_blocks_place_door(room->owner, slab_subtile_center(slb_x), slab_subtile_center(slb_y))) {
                break;
            }
            if (!subtile_has_door_thing_on(slab_subtile_center(slb_x), slab_subtile_center(slb_y))) {
                // No door - the position looks ok
                break;
            }
            slb_x += small_around[m].delta_x;
            slb_y += small_around[m].delta_y;
        }
        // Now if we were able to move, then the position seem ok. One last check - make sure the corridor is not dead end and doesn't already have a door
        if (i > 0)
        {
            MapSlabCoord nxslb_x,nxslb_y;
            nxslb_x = slb_x + small_around[m].delta_x;
            nxslb_y = slb_y + small_around[m].delta_y;
            struct SlabMap *nxslb;
            nxslb = get_slabmap_block(nxslb_x, nxslb_y);
            if ((slabmap_owner(nxslb) == room->owner) && (nxslb->kind == SlbT_CLAIMED))
            {
                if (!subtile_has_door_thing_on(slab_subtile_center(nxslb_x), slab_subtile_center(nxslb_y))) {
                    pos->x.val = subtile_coord_center(slab_subtile_center(slb_x));
                    pos->y.val = subtile_coord_center(slab_subtile_center(slb_y));
                    pos->z.val = subtile_coord(1,0);
                    return true;
                }
            }
        }
        m = (m + 1) % SMALL_AROUND_SLAB_LENGTH;
    }
    return false;
}