예제 #1
0
TbBool placing_offmap_workshop_item(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel)
{
    SYNCDBG(18,"Starting");
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    if (dungeon_invalid(dungeon)) {
        // Player with no dungeon has only on-map items
        // But this shouldn't really happen
        return true;
    }
    switch (tngclass)
    {
    case TCls_Trap:
        if (dungeon->trap_amount_stored[tngmodel] > 0) {
            return false;
        }
        if (dungeon->trap_amount_offmap[tngmodel] > 0) {
            return true;
        }
        break;
    case TCls_Door:
        if (dungeon->door_amount_stored[tngmodel] > 0) {
            return false;
        }
        if (dungeon->door_amount_offmap[tngmodel] > 0) {
            return true;
        }
        break;
    }
    return false;
}
예제 #2
0
TbBool creature_can_do_barracking_for_player(const struct Thing *creatng, PlayerNumber plyr_idx, CreatureJob new_job)
{
    // Grouping or barracking only makes sense if we have more than one creature
    const struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    return (dungeon->num_active_creatrs > 1);
}
예제 #3
0
/** Returns if given player owns a room of given kind.
 *
 * @param plyr_idx
 * @param rkind Room kind being checked.
 * @return
 */
TbBool player_has_room(PlayerNumber plyr_idx, RoomKind rkind)
{
    struct Dungeon *dungeon;
    if (plyr_idx == game.neutral_player_num)
        return false;
    dungeon = get_players_num_dungeon(plyr_idx);
    return (dungeon->room_kind[rkind] > 0);
}
예제 #4
0
struct Thing *get_player_soul_container(PlayerNumber plyr_idx)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    if (dungeon->dnheart_idx > 0) {
        return thing_get(dungeon->dnheart_idx);
    }
    return INVALID_THING;
}
예제 #5
0
struct Room *player_has_room_of_type(PlayerNumber plyr_idx, RoomKind rkind)
{
    //return _DK_player_has_room_of_type(plyr_idx, rkind);
    struct Dungeon *dungeon;
    if (plyr_idx == game.neutral_player_num)
        return false;
    dungeon = get_players_num_dungeon(plyr_idx);
    return room_get(dungeon->room_kind[rkind]);
}
예제 #6
0
void frontstats_save_high_score(void)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(my_player_number);
    if (dungeon->lvstats.allow_save_score)
    {
        dungeon->lvstats.allow_save_score = false;
        add_score_to_high_score_table();
    }
    lbInkey = 0;
}
예제 #7
0
const struct Coord3d *dungeon_get_essential_pos(PlayerNumber plyr_idx)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    if (dungeon->dnheart_idx > 0) {
        struct Thing *heartng;
        heartng = thing_get(dungeon->dnheart_idx);
        if (thing_exists(heartng)) {
            return &heartng->mappos;
        }
    }
    return &dungeon->essential_pos;
}
예제 #8
0
void turn_off_event_box_if_necessary(PlayerNumber plyr_idx, unsigned char event_idx)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    if (dungeon->visible_event_idx != event_idx) {
        return;
    }
    dungeon->visible_event_idx = 0;
    if (is_my_player_number(plyr_idx))
    {
        turn_off_menu(GMnu_TEXT_INFO);
        turn_off_menu(GMnu_BATTLE);
        turn_off_menu(GMnu_DUNGEON_SPECIAL);
    }
}
예제 #9
0
TbBool check_workshop_item_limit_reached(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    if (dungeon_invalid(dungeon))
        return true;
    switch (tngclass)
    {
    case TCls_Trap:
        return (dungeon->trap_amount_stored[tngmodel] >= MANUFACTURED_ITEMS_LIMIT);
    case TCls_Door:
        return (dungeon->door_amount_stored[tngmodel] >= MANUFACTURED_ITEMS_LIMIT);
    }
    return true;
}
예제 #10
0
/**
 * Returns if the trap was at least one built by a player.
 */
TbBool is_trap_built(PlayerNumber plyr_idx, long tngmodel)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    // Check if the player even have a dungeon
    if (dungeon_invalid(dungeon)) {
        return false;
    }
    if ((tngmodel <= 0) || (tngmodel >= TRAP_TYPES_COUNT)) {
        ERRORLOG("Incorrect trap %d (player %d)",(int)tngmodel, (int)plyr_idx);
        return false;
    }
    if ((dungeon->trap_build_flags[tngmodel] & MnfBldF_Built) != 0) {
        return true;
    }
    return false;
}
예제 #11
0
TbBool player_creature_tends_to(PlayerNumber plyr_idx, unsigned short tend_type)
{
    const struct Dungeon *dungeon;
    if (plyr_idx == game.neutral_player_num)
        return false;
    dungeon = get_players_num_dungeon(plyr_idx);
    switch (tend_type)
    {
    case CrTend_Imprison:
        return ((dungeon->creature_tendencies & 0x01) != 0);
    case CrTend_Flee:
        return ((dungeon->creature_tendencies & 0x02) != 0);
    default:
        ERRORLOG("Bad tendency type %d",(int)tend_type);
        return false;
    }
}
예제 #12
0
/**
 * Returns if the trap can be placed by a player.
 * Checks only if it's available and if the player is 'alive'.
 * Doesn't check if map position is on correct spot.
 */
TbBool is_trap_placeable(PlayerNumber plyr_idx, long tngmodel)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    // Check if the player even have a dungeon
    if (dungeon_invalid(dungeon)) {
        return false;
    }
    // Player must have dungeon heart to place traps
    if (!player_has_heart(plyr_idx)) {
        return false;
    }
    if ((tngmodel <= 0) || (tngmodel >= TRAP_TYPES_COUNT)) {
        ERRORLOG("Incorrect trap %d (player %d)",(int)tngmodel, (int)plyr_idx);
        return false;
    }
    if (dungeon->trap_amount_placeable[tngmodel] > 0) {
        return true;
    }
    return false;
}
예제 #13
0
/**
 * Returns if the door was at least one built by a player.
 */
TbBool is_door_built(PlayerNumber plyr_idx, long door_idx)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    // Check if the player even have a dungeon
    if (dungeon_invalid(dungeon)) {
        return false;
    }
    // Player must have dungeon heart to build anything
    if (!player_has_heart(plyr_idx)) {
        return false;
    }
    if ((door_idx <= 0) || (door_idx >= DOOR_TYPES_COUNT)) {
        ERRORLOG("Incorrect door %d (player %d)",(int)door_idx, (int)plyr_idx);
        return false;
    }
    if ((dungeon->door_build_flags[door_idx] & MnfBldF_Built) != 0) {
        return true;
    }
    return false;
}
예제 #14
0
/**
 * Returns if the trap can be manufactured by a player.
 * Checks only if it's set as buildable in level script.
 * Doesn't check if player has workshop or workforce for the task.
 */
TbBool is_trap_buildable(PlayerNumber plyr_idx, long tngmodel)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    // Check if the player even have a dungeon
    if (dungeon_invalid(dungeon)) {
        return false;
    }
    // Player must have dungeon heart to build anything
    if (!player_has_heart(plyr_idx)) {
        return false;
    }
    if ((tngmodel <= 0) || (tngmodel >= TRAP_TYPES_COUNT)) {
        ERRORLOG("Incorrect trap %d (player %d)",(int)tngmodel, (int)plyr_idx);
        return false;
    }
    if ((dungeon->trap_build_flags[tngmodel] & MnfBldF_Manufacturable) != 0) {
        return true;
    }
    return false;
}
예제 #15
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;
}
예제 #16
0
void resurrect_creature(struct Thing *boxtng, PlayerNumber owner, ThingModel crmodel, unsigned char crlevel)
{
    struct Thing *creatng;
    if (!thing_exists(boxtng) || (box_thing_to_special(boxtng) != SpcKind_Resurrect) ) {
        ERRORMSG("Invalid resurrect box object!");
        return;
    }
    creatng = create_creature(&boxtng->mappos, crmodel, owner);
    if (!thing_is_invalid(creatng))
    {
        init_creature_level(creatng, crlevel);
        if (is_my_player_number(owner))
          output_message(SMsg_CommonAcknowledge, 0, true);
    }
    create_special_used_effect(&boxtng->mappos, owner);
    remove_events_thing_is_attached_to(boxtng);
    force_any_creature_dragging_owned_thing_to_drop_it(boxtng);
    if ((gameadd.classic_bugs_flags & ClscBug_ResurrectForever) == 0) {
        remove_item_from_dead_creature_list(get_players_num_dungeon(owner), crmodel, crlevel);
    }
    delete_thing_structure(boxtng, 0);
}
예제 #17
0
TbBool attempt_anger_job_persuade(struct Thing *creatng)
{
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(creatng);
    if (cctrl->explevel <= 5) {
        return false;
    }
    if (!can_change_from_state_to(creatng, creatng->active_state, CrSt_CreaturePersuade)) {
        return false;
    }
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(creatng->owner);
    int persuade_count;
    persuade_count = min(dungeon->num_active_creatrs-1, 5);
    if (persuade_count <= 0) {
        return false;
    }
    persuade_count = ACTION_RANDOM(persuade_count) + 1;
    if (!external_set_thing_state(creatng, CrSt_CreaturePersuade)) {
        return false;
    }
    cctrl->byte_9A = persuade_count;
    return true;
}
예제 #18
0
void redraw_isometric_view(void)
{
    struct PlayerInfo *player;
    struct Dungeon *dungeon;
    TbGraphicsWindow ewnd;
    struct Coord3d pos;
    SYNCDBG(6,"Starting");

    player = get_my_player();
    if (player->acamera == NULL)
        return;
    memcpy(&pos,&player->acamera->mappos,sizeof(struct Coord3d));
    LbMemorySet(&ewnd, 0, sizeof(TbGraphicsWindow));
    if (player->field_45F != 1)
      player->field_45F = 1;
    dungeon = get_players_num_dungeon(my_player_number);
    // Camera position modifications
    make_camera_deviations(player,dungeon);
    update_explored_flags_for_power_sight(player);
    if ((game.flags_font & FFlg_unk08) != 0)
    {
        store_engine_window(&ewnd,1);
        setup_engine_window(ewnd.x, ewnd.y, ewnd.width >> 1, ewnd.height >> 1);
    }
예제 #19
0
short process_player_manufacturing(PlayerNumber plyr_idx)
{
    struct Dungeon *dungeon;
    struct Room *room;
    int k;
    SYNCDBG(7,"Starting for player %d",(int)plyr_idx);

    dungeon = get_players_num_dungeon(plyr_idx);
    if (!player_has_room_of_role(plyr_idx, RoRoF_CratesManufctr))
    {
        return true;
    }
    if (dungeon->manufacture_class == TCls_Empty)
    {
        get_next_manufacture(dungeon);
        return true;
    }
    k = manufacture_points_required(dungeon->manufacture_class, dungeon->manufacture_kind);
    // If we don't have enough manufacture points, don't do anything
    if (dungeon->manufacture_progress < (k << 8))
        return true;
    // Try to do the manufacturing
    room = find_room_with_spare_room_item_capacity(plyr_idx, RoK_WORKSHOP);
    if (room_is_invalid(room))
    {
        dungeon->manufacture_class = TCls_Empty;
        return false;
    }
    if (check_workshop_item_limit_reached(plyr_idx, dungeon->manufacture_class, dungeon->manufacture_kind))
    {
        ERRORLOG("Bad choice for manufacturing - limit reached for %s kind %d",thing_class_code_name(dungeon->manufacture_class),(int)dungeon->manufacture_kind);
        get_next_manufacture(dungeon);
        return false;
    }
    if (create_workshop_object_in_workshop_room(plyr_idx, dungeon->manufacture_class, dungeon->manufacture_kind) == 0)
    {
        ERRORLOG("Could not create manufactured %s kind %d",thing_class_code_name(dungeon->manufacture_class),(int)dungeon->manufacture_kind);
        return false;
    }
    add_workshop_item_to_amounts(plyr_idx, dungeon->manufacture_class, dungeon->manufacture_kind);

    switch (dungeon->manufacture_class)
    {
    case TCls_Trap:
        dungeon->lvstats.manufactured_traps++;
        // If that's local player - make a message
        if (is_my_player_number(plyr_idx))
            output_message(SMsg_ManufacturedTrap, 0, true);
        break;
    case TCls_Door:
        dungeon->lvstats.manufactured_doors++;
        // If that's local player - make a message
        if (is_my_player_number(plyr_idx))
            output_message(SMsg_ManufacturedDoor, 0, true);
        break;
    default:
        ERRORLOG("Invalid type of new manufacture, %d",(int)dungeon->manufacture_class);
        return false;
    }

    dungeon->manufacture_progress -= (k << 8);
    dungeon->field_118B = game.play_gameturn;
    dungeon->lvstats.manufactured_items++;
    get_next_manufacture(dungeon);
    return true;
}
예제 #20
0
TbBool create_workshop_object_in_workshop_room(PlayerNumber plyr_idx, ThingClass tngclass, ThingModel tngmodel)
{
    struct Coord3d pos;
    struct Thing *cratetng;
    struct Room *room;
    struct Dungeon *dungeon;
    SYNCDBG(7,"Making player %d new %s",(int)plyr_idx,thing_class_code_name(tngclass));
    pos.x.val = 0;
    pos.y.val = 0;
    pos.z.val = 0;
    switch (tngclass)
    {
    case TCls_Trap:
        cratetng = create_object(&pos, trap_crate_object_model(tngmodel), plyr_idx, -1);
        break;
    case TCls_Door:
        cratetng = create_object(&pos, door_crate_object_model(tngmodel), plyr_idx, -1);
        break;
    default:
        cratetng = INVALID_THING;
        ERRORLOG("No known workshop crate can represent %s model %d",thing_class_code_name(tngclass),(int)tngmodel);
        break;
    }
    if (thing_is_invalid(cratetng))
    {
        ERRORLOG("Could not create workshop crate thing for %s",thing_class_code_name(tngclass));
        return false;
    }
    room = find_random_room_for_thing_with_spare_room_item_capacity(cratetng, plyr_idx, RoK_WORKSHOP, 0);
    if (room_is_invalid(room))
    {
        ERRORLOG("No %s room found which would accept %s crate",room_code_name(RoK_WORKSHOP),thing_class_code_name(tngclass));
        destroy_object(cratetng);
        return false;
    }
    if (!find_random_valid_position_for_thing_in_room_avoiding_object(cratetng, room, &pos))
    {
        ERRORLOG("Could not find a place in %s index %d for the new %s crate",
            room_code_name(room->kind),(int)room->index,thing_class_code_name(tngclass));
        destroy_object(cratetng);
        return false;
    }
    pos.z.val = get_thing_height_at(cratetng, &pos);
    move_thing_in_map(cratetng, &pos);
    if (!add_workshop_object_to_workshop(room, cratetng)) {
        ERRORLOG("Could not fit %s crate in %s index %d",
            thing_class_code_name(tngclass),room_code_name(room->kind),(int)room->index);
        destroy_object(cratetng);
        return false;
    }
    dungeon = get_players_num_dungeon(plyr_idx);
    switch (tngclass)
    {
    case TCls_Trap:
        if ((dungeon->trap_build_flags[tngmodel] & MnfBldF_Built) == 0) {
            event_create_event(cratetng->mappos.x.val, cratetng->mappos.y.val, EvKind_NewTrap, plyr_idx, tngmodel);
        }
        break;
    case TCls_Door:
        if ((dungeon->door_build_flags[tngmodel] & MnfBldF_Built) == 0) {
          event_create_event(cratetng->mappos.x.val, cratetng->mappos.y.val, EvKind_NewDoor, plyr_idx, tngmodel);
        }
        break;
    default:
        break;
    }
    create_effect(&pos, TngEff_Unknown56, cratetng->owner);
    thing_play_sample(cratetng, 89, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
    return true;
}
예제 #21
0
TbBool steal_hero(struct PlayerInfo *player, struct Coord3d *pos)
{
    //TODO CONFIG creature models dependency; put them in config files
    static ThingModel skip_steal_models[] = {6, 7};
    static ThingModel prefer_steal_models[] = {3, 12};
    struct Thing *herotng;
    herotng = INVALID_THING;
    int heronum;
    struct Dungeon *herodngn;
    struct CreatureControl *cctrl;
    unsigned long k;
    int i;
    SYNCDBG(8,"Starting");
    herodngn = get_players_num_dungeon(game.hero_player_num);
    k = 0;
    if (herodngn->num_active_creatrs > 0) {
        heronum = ACTION_RANDOM(herodngn->num_active_creatrs);
        i = herodngn->creatr_list_start;
        SYNCDBG(4,"Selecting random creature %d out of %d heroes",(int)heronum,(int)herodngn->num_active_creatrs);
    } else {
        heronum = 0;
        i = 0;
        SYNCDBG(4,"No heroes on map, skipping selection");
    }
    while (i != 0)
    {
        struct Thing *thing;
        thing = thing_get(i);
        TRACE_THING(thing);
        cctrl = creature_control_get_from_thing(thing);
        if (thing_is_invalid(thing) || creature_control_invalid(cctrl))
        {
            ERRORLOG("Jump to invalid creature detected");
            break;
        }
        i = cctrl->players_next_creature_idx;
        // Thing list loop body
        TbBool heroallow;
        heroallow = true;
        ThingModel skipidx;
        for (skipidx=0; skipidx < sizeof(skip_steal_models)/sizeof(skip_steal_models[0]); skipidx++)
        {
            if (thing->model == skip_steal_models[skipidx]) {
                heroallow = false;
            }
        }
        if (heroallow) {
            herotng = thing;
        }
        // If we've reached requested hero number, return either current hero on previously selected one
        if ((heronum <= 0) && thing_is_creature(herotng)) {
            break;
        }
        heronum--;
        if (i == 0) {
            i = herodngn->creatr_list_start;
        }
        // Thing list loop body ends
        k++;
        if (k > CREATURES_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping creatures list");
            erstat_inc(ESE_InfChainTngPerOwner);
            break;
        }
    }
    if (!thing_is_invalid(herotng))
    {
        move_thing_in_map(herotng, pos);
        change_creature_owner(herotng, player->id_number);
        SYNCDBG(3,"Converted %s to owner %d",thing_model_name(herotng),(int)player->id_number);
    }
    else
    {
        i = ACTION_RANDOM(sizeof(prefer_steal_models)/sizeof(prefer_steal_models[0]));
        struct Thing *creatng;
        creatng = create_creature(pos, prefer_steal_models[i], player->id_number);
        if (thing_is_invalid(creatng))
            return false;
        SYNCDBG(3,"Created %s owner %d",thing_model_name(creatng),(int)player->id_number);
    }
    return true;
}
예제 #22
0
TbBool player_uses_call_to_arms(PlayerNumber plyr_idx)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    return (dungeon->cta_start_turn != 0);
}
예제 #23
0
short creature_being_scavenged(struct Thing *creatng)
{
    //return _DK_creature_being_scavenged(creatng);
    struct Thing *fellowtng;
    struct Dungeon *dungeon;
    SYNCDBG(8,"Starting");
    //return _DK_make_all_players_creatures_angry(plyr_idx);
    dungeon = get_players_num_dungeon(creatng->owner);
    fellowtng = INVALID_THING;
    if (dungeon->num_active_creatrs <= 1)
    {
        SYNCDBG(19,"No other creatures");
        return 0;
    }
    int n;
    n = ACTION_RANDOM(dungeon->num_active_creatrs-1);
    unsigned long k;
    int i;
    k = 0;
    i = dungeon->creatr_list_start;
    while (i != 0)
    {
        struct Thing *thing;
        thing = thing_get(i);
        TRACE_THING(thing);
        struct CreatureControl *cctrl;
        cctrl = creature_control_get_from_thing(thing);
        if (thing_is_invalid(thing) || creature_control_invalid(cctrl))
        {
            ERRORLOG("Jump to invalid creature detected");
            break;
        }
        i = cctrl->players_next_creature_idx;
        // Thing list loop body
        if ((n <= 0) && (thing->index != creatng->index)) {
            fellowtng = thing;
            break;
        }
        n--;
        // Thing list loop body ends
        k++;
        if (k > CREATURES_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping creatures list");
            break;
        }
    }
    if (thing_is_invalid(fellowtng))
    {
        SYNCDBG(19,"Cannot get creature");
        return 0;
    }
    if (setup_person_move_to_coord(creatng, &fellowtng->mappos, NavRtF_Default) <= 0)
    {
        SYNCDBG(19,"Cannot move to coord");
        return 0;
    }
    creatng->continue_state = CrSt_CreatureBeingScavenged;
    if (!S3DEmitterIsPlayingSample(creatng->snd_emitter_id, 156, 0))
        thing_play_sample(creatng, 156, NORMAL_PITCH, 0, 3, 1, 2, FULL_LOUDNESS);
    SYNCDBG(19,"Finished");
    return 1;
}
예제 #24
0
TbBool player_uses_power_sight(PlayerNumber plyr_idx)
{
    struct Dungeon *dungeon;
    dungeon = get_players_num_dungeon(plyr_idx);
    return (dungeon->sight_casted_thing_idx > 0);
}