Esempio n. 1
0
void init_dungeons(void)
{
    int i,k;
    struct Dungeon *dungeon;
    for (i=0; i < DUNGEONS_COUNT; i++)
    {
        dungeon = get_dungeon(game.hero_player_num);
        dungeon->hates_player[i] = game.fight_max_hate;
        dungeon = get_dungeon(i);
        dungeon->hates_player[game.hero_player_num%DUNGEONS_COUNT] = game.fight_max_hate;
        dungeon->num_active_diggers = 0;
        dungeon->num_active_creatrs = 0;
        dungeon->creatr_list_start = 0;
        dungeon->digger_list_start = 0;
        dungeon->owner = i;
        dungeon->max_creatures_attracted = game.default_max_crtrs_gen_entrance;
        dungeon->dead_creatures_count = 0;
        dungeon->dead_creature_idx = 0;
        for (k=0; k < DUNGEONS_COUNT; k++)
        {
          if (k == i)
            dungeon->hates_player[k] = game.fight_max_love;
          else
            dungeon->hates_player[k] = game.fight_max_hate;
        }
        LbMemorySet(dungeon->creature_models_joined, 0, CREATURE_TYPES_COUNT);
    }
}
Esempio n. 2
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;
}
CrCheckRet process_scavenge_function(struct Thing *calltng)
{
    SYNCDBG(18,"Starting for %s owner %d",thing_model_name(calltng),(int)calltng->owner);
    //return _DK_process_scavenge_function(thing);
    struct CreatureControl *callctrl;
    callctrl = creature_control_get_from_thing(calltng);
    struct Dungeon *calldngn;
    struct Room *room;
    calldngn = get_dungeon(calltng->owner);
    room = get_room_creature_works_in(calltng);
    if ( !room_still_valid_as_type_for_thing(room, RoK_SCAVENGER, calltng) )
    {
        WARNLOG("Room %s owned by player %d is bad work place for %s owned by played %d",room_code_name(room->kind),(int)room->owner,thing_model_name(calltng),(int)calltng->owner);
        set_start_state(calltng);
        return CrCkRet_Continue;
    }
    struct CreatureStats *crstat;
    crstat = creature_stats_get_from_thing(calltng);
    if (!player_can_afford_to_scavenge_creature(calltng))
    {
        if (is_my_player_number(calltng->owner))
            output_message(SMsg_NoGoldToScavenge, 500, 1);
        set_start_state(calltng);
        return CrCkRet_Continue;
    }
    if (calldngn->scavenge_counters_turn != game.play_gameturn)
    {
        reset_scavenge_counts(calldngn);
    }
    long work_value;
    work_value = compute_creature_work_value(crstat->scavenge_value*256, room->efficiency, callctrl->explevel);
    work_value = process_work_speed_on_work_value(calltng, work_value);
    SYNCDBG(9,"The %s index %d owner %d produced %d scavenge points",thing_model_name(calltng),(int)calltng->index,(int)calltng->owner,(int)work_value);
    struct Thing *scavtng;
    scavtng = get_scavenger_target(calltng);
    if (!thing_is_invalid(scavtng))
    {
        process_scavenge_creature_from_level(scavtng, calltng, work_value);
    } else
    if (can_scavenge_creature_from_pool(calldngn, calltng->model))
    {
        process_scavenge_creature_from_pool(calltng, work_value);
    } else
    {
        if (crstat->entrance_force) {
          calldngn->field_1485++;
        }
        return 0;
    }
    callctrl->field_82++;
    if (callctrl->field_82 > game.scavenge_cost_frequency)
    {
        callctrl->field_82 -= game.scavenge_cost_frequency;
        if (take_money_from_dungeon(calltng->owner, crstat->scavenger_cost, 1) < 0) {
            ERRORLOG("Cannot take %d gold from dungeon %d",(int)crstat->scavenger_cost,(int)calltng->owner);
        }
        create_price_effect(&calltng->mappos, calltng->owner, crstat->scavenger_cost);
    }
    return 0;
}
short at_scavenger_room(struct Thing *thing)
{
    struct CreatureControl *cctrl;
    struct CreatureStats *crstat;
    struct Dungeon *dungeon;
    struct Room *room;
    //return _DK_at_scavenger_room(thing);
    room = get_room_thing_is_on(thing);
    if (!room_initially_valid_as_type_for_thing(room, RoK_SCAVENGER, thing))
    {
        WARNLOG("Room %s owned by player %d is invalid for %s index %d",room_code_name(room->kind),(int)room->owner,thing_model_name(thing),(int)thing->index);
        set_start_state(thing);
        return 0;
    }
    cctrl = creature_control_get_from_thing(thing);
    crstat = creature_stats_get_from_thing(thing);
    dungeon = get_dungeon(thing->owner);
    if (crstat->scavenger_cost >= dungeon->total_money_owned)
    {
        if (is_my_player_number(thing->owner))
            output_message(SMsg_NoGoldToScavenge, MESSAGE_DELAY_TREASURY, true);
        set_start_state(thing);
        return 0;
    }
    if (!add_creature_to_work_room(thing, room))
    {
        set_start_state(thing);
        return 0;
    }
    internal_set_thing_state(thing, CrSt_Scavengering);
    cctrl->field_82 = 0;
    return 1;
}
Esempio n. 5
0
TbBool prison_convert_creature_to_skeleton(struct Room *room, struct Thing *thing)
{
    struct Dungeon *dungeon;
    struct CreatureControl *cctrl;
    struct Thing *crthing;
    long crmodel;
    cctrl = creature_control_get_from_thing(thing);
    crmodel = get_room_create_creature_model(room->kind); // That normally returns skeleton breed
    crthing = create_creature(&thing->mappos, crmodel, room->owner);
    if (thing_is_invalid(crthing))
    {
        ERRORLOG("Couldn't create creature %s in prison", creature_code_name(crmodel));
        return false;
    }
    init_creature_level(crthing, cctrl->explevel);
    set_start_state(crthing);
    if (creature_model_bleeds(thing->model))
      create_effect_around_thing(thing, TngEff_Unknown10);
    kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects);
    dungeon = get_dungeon(room->owner);
    if (!dungeon_invalid(dungeon)) {
        dungeon->lvstats.skeletons_raised++;
    }
    return true;
}
Esempio n. 6
0
struct Room * find_nearest_navigable_room_for_thing_with_capacity_and_closer_than(struct Thing *thing, PlayerNumber owner, RoomKind rkind, unsigned char nav_flags, long used, long *neardistance)
{
    struct Dungeon *dungeon;
    struct Room *nearoom;
    long distance;
    int i;
    SYNCDBG(18,"Searching for %s navigable by %s index %d",room_code_name(rkind),thing_model_name(thing),(int)thing->index);
    dungeon = get_dungeon(owner);
    nearoom = INVALID_ROOM;
    distance = *neardistance;
    i = dungeon->room_kind[rkind];
    while (i != 0)
    {
        struct Room *room;
        room = find_next_navigable_room_for_thing_with_capacity_and_closer_than(thing, i, nav_flags, used, &distance);
        if (room_is_invalid(room)) {
            break;
        }
        // Found closer room
        i = room->next_of_owner;
        nearoom = room;
    }
    *neardistance = distance;
    return nearoom;
}
Esempio n. 7
0
long instf_attack_room_slab(struct Thing *creatng, long *param)
{
    TRACE_THING(creatng);
    //return _DK_instf_attack_room_slab(creatng, param);
    struct Room *room;
    room = get_room_thing_is_on(creatng);
    if (room_is_invalid(room))
    {
        ERRORLOG("The %s is not on room",thing_model_name(creatng));
        return 0;
    }
    struct SlabMap *slb;
    slb = get_slabmap_thing_is_on(creatng);
    if (slb->health > 2)
    {
        //TODO CONFIG damage made to room slabs is constant - doesn't look good
        slb->health -= 2;
        thing_play_sample(creatng, 128 + UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
        return 1;
    }
    if (room->owner != game.neutral_player_num)
    {
        struct Dungeon *dungeon;
        dungeon = get_dungeon(room->owner);
        dungeon->rooms_destroyed++;
    }
    if (!delete_room_slab(coord_slab(creatng->mappos.x.val), coord_slab(creatng->mappos.y.val), 1))
    {
        ERRORLOG("Cannot delete %s room tile destroyed by %s",room_code_name(room->kind),thing_model_name(creatng));
        return 0;
    }
    create_effect(&creatng->mappos, 3, creatng->owner);
    thing_play_sample(creatng, 47, NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
    return 1;
}
Esempio n. 8
0
struct Thing *create_and_control_creature_as_controller(struct PlayerInfo *player, long breed, struct Coord3d *pos)
{
    struct CreatureStats *crstat;
    struct CreatureControl *cctrl;
    struct Dungeon *dungeon;
    struct Thing *thing;
    struct Camera *cam;
    struct InitLight ilght;
    SYNCDBG(6,"Request for model %ld at (%d,%d,%d)",breed,(int)pos->x.val,(int)pos->y.val,(int)pos->z.val);
    //return _DK_create_and_control_creature_as_controller(player, a2, pos);
    thing = create_creature(pos, breed, player->id_number);
    if (thing_is_invalid(thing))
      return INVALID_THING;
    dungeon = get_dungeon(thing->owner);
    dungeon->num_active_creatrs--;
    dungeon->owned_creatures_of_model[thing->model]--;
    if (is_my_player(player))
    {
        toggle_status_menu(0);
        turn_off_roaming_menus();
    }
    cam = player->acamera;
    player->controlled_thing_idx = thing->index;
    player->field_31 = thing->creation_turn;
    player->field_4B5 = cam->field_6;
    thing->alloc_flags |= TAlF_IsControlled;
    thing->field_4F |= 0x01;
    cctrl = creature_control_get_from_thing(thing);
    cctrl->flgfield_2 |= 0x02;
    cctrl->max_speed = calculate_correct_creature_maxspeed(thing);
    set_player_mode(player, PVT_CreatureContrl);
    set_start_state(thing);
    // Preparing light object
    LbMemorySet(&ilght, 0, sizeof(struct InitLight));
    ilght.mappos.x.val = thing->mappos.x.val;
    ilght.mappos.y.val = thing->mappos.y.val;
    ilght.mappos.z.val = thing->mappos.z.val;
    ilght.field_2 = 36;
    ilght.field_3 = 1;
    ilght.is_dynamic = 1;
    ilght.field_0 = 2560;
    thing->light_id = light_create_light(&ilght);
    if (thing->light_id != 0)
    {
        light_set_light_never_cache(thing->light_id);
    } else
    {
        ERRORLOG("Cannot allocate light to new hero");
    }
    if (is_my_player_number(thing->owner))
    {
        if (thing->class_id == TCls_Creature)
        {
            crstat = creature_stats_get_from_thing(thing);
            setup_eye_lens(crstat->eye_effect);
        }
    }
    return thing;
}
/**
 * Returns if a player to whom the creature belongs can afford the creature to go scavenging.
 * @param creatng
 * @return
 */
TbBool player_can_afford_to_scavenge_creature(const struct Thing *creatng)
{
    struct Dungeon *dungeon;
    dungeon = get_dungeon(creatng->owner);
    struct CreatureStats *crstat;
    crstat = creature_stats_get_from_thing(creatng);
    return (crstat->scavenger_cost < dungeon->total_money_owned);
}
Esempio n. 10
0
void increase_dungeon_area(PlayerNumber plyr_idx, long value)
{
    struct Dungeon *dungeon;
    if (plyr_idx == game.neutral_player_num)
        return;
    dungeon = get_dungeon(plyr_idx);
    dungeon->total_area += value;
}
Esempio n. 11
0
struct ResearchVal *get_players_current_research_val(PlayerNumber plyr_idx)
{
    struct Dungeon *dungeon;
    dungeon = get_dungeon(plyr_idx);
    if ((dungeon->current_research_idx < 0) || (dungeon->current_research_idx >= DUNGEON_RESEARCH_COUNT))
        return NULL;
    return &dungeon->research[dungeon->current_research_idx];
}
Esempio n. 12
0
short creature_sleep(struct Thing *thing)
{
    //return _DK_creature_sleep(thing);
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(thing);
    if ((cctrl->slap_turns > 0) || !creature_will_sleep(thing)) {
        set_start_state(thing);
        return 0;
    }
    struct Room *room;
    room = get_room_thing_is_on(thing);
    if (room_is_invalid(room) || (room->kind != RoK_LAIR)
        || (cctrl->lair_room_id != room->index) || (room->owner != thing->owner)) {
        set_start_state(thing);
        return 0;
    }
    thing->movement_flags &= ~0x0020;
    struct CreatureStats *crstat;
    crstat = creature_stats_get_from_thing(thing);
    if (((game.play_gameturn + thing->index) % game.recovery_frequency) == 0)
    {
        HitPoints recover;
        recover = compute_creature_max_health(crstat->sleep_recovery, cctrl->explevel);
        apply_health_to_thing_and_display_health(thing, recover);
    }
    anger_set_creature_anger(thing, 0, AngR_NoLair);
    anger_apply_anger_to_creature(thing, crstat->annoy_sleeping, AngR_Other, 1);
    if (cctrl->field_82 > 0) {
        cctrl->field_82--;
    }
    if (((game.play_gameturn + thing->index) & 0x3F) == 0)
    {
        if (ACTION_RANDOM(100) < 5) {
            struct Dungeon *dungeon;
            dungeon = get_dungeon(thing->owner);
            dungeon->lvstats.backs_stabbed++;
        }
    }
    if (crstat->sleep_exp_slab != SlbT_ROCK)
    {
        if (creature_can_gain_experience(thing) && room_has_slab_adjacent(room, crstat->sleep_exp_slab))
        {
            cctrl->exp_points += crstat->sleep_experience;
            check_experience_upgrade(thing);
        }
    }
    {
        HitPoints health_max;
        health_max = compute_creature_max_health(crstat->health, cctrl->explevel);
        if ((crstat->heal_threshold * health_max / 256 <= thing->health) && (!cctrl->field_82))
        {
            set_start_state(thing);
            return 1;
        }
    }
    process_lair_enemy(thing, room);
    return 0;
}
Esempio n. 13
0
void increase_level(struct PlayerInfo *player)
{
    struct Dungeon *dungeon;
    struct CreatureControl *cctrl;
    struct Thing *thing;
    unsigned long k;
    int i;
    dungeon = get_dungeon(player->id_number);
    // Increase level of normal creatures
    k = 0;
    i = dungeon->creatr_list_start;
    while (i != 0)
    {
        thing = thing_get(i);
        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
        creature_increase_level(thing);
        // Thing list loop body ends
        k++;
        if (k > CREATURES_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping creatures list");
            erstat_inc(ESE_InfChainTngPerOwner);
            break;
        }
    }
    // Increase level of special workers
    k = 0;
    i = dungeon->digger_list_start;
    while (i != 0)
    {
        thing = thing_get(i);
        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
        creature_increase_level(thing);
        // Thing list loop body ends
        k++;
        if (k > CREATURES_COUNT)
        {
          ERRORLOG("Infinite loop detected when sweeping creatures list");
          erstat_inc(ESE_InfChainTngPerOwner);
          break;
        }
    }
}
Esempio n. 14
0
TbBool player_can_afford_to_train_creature(const struct Thing *thing)
{
    struct Dungeon *dungeon;
    struct CreatureStats *crstat;
    //return _DK_player_can_afford_to_train_creature(thing);
    dungeon = get_dungeon(thing->owner);
    crstat = creature_stats_get_from_thing(thing);
    return (dungeon->total_money_owned >= crstat->training_cost);
}
Esempio n. 15
0
void init_dungeons_essential_position(void)
{
    int i;
    for (i=0; i < DUNGEONS_COUNT; i++)
    {
        struct Dungeon *dungeon;
        dungeon = get_dungeon(i);
        init_dungeon_essential_position(dungeon);
    }
}
Esempio n. 16
0
TbBool creature_can_do_research(const struct Thing *creatng)
{
    if (is_neutral_thing(creatng)) {
        return false;
    }
    struct CreatureStats *crstat;
    struct Dungeon *dungeon;
    crstat = creature_stats_get_from_thing(creatng);
    dungeon = get_dungeon(creatng->owner);
    return (crstat->research_value > 0) && (dungeon->current_research_idx >= 0);
}
Esempio n. 17
0
TbBool creature_free_for_anger_job(struct Thing *creatng)
{
    struct CreatureControl *cctrl;
    struct Dungeon *dungeon;
    cctrl = creature_control_get_from_thing(creatng);
    dungeon = get_dungeon(creatng->owner);
    return ((cctrl->spell_flags & CSAfF_Unkn0800) == 0)
           && (dungeon->must_obey_turn == 0)
           && ((cctrl->spell_flags & CSAfF_Chicken) == 0)
           && !thing_is_picked_up(creatng) && !is_thing_passenger_controlled(creatng);
}
Esempio n. 18
0
void decrease_dungeon_area(PlayerNumber plyr_idx, long value)
{
    struct Dungeon *dungeon;
    if (plyr_idx == game.neutral_player_num)
        return;
    dungeon = get_dungeon(plyr_idx);
    if (dungeon->total_area < value)
      dungeon->total_area = 0;
    else
      dungeon->total_area -= value;
}
Esempio n. 19
0
void process_armageddon(void)
{
    struct PlayerInfo *player;
    struct Dungeon *dungeon;
    struct Thing *heartng;
    long i;
    SYNCDBG(6,"Starting");
    //_DK_process_armageddon(); return;
    if (game.armageddon_cast_turn == 0)
        return;
    if (game.armageddon.count_down+game.armageddon_cast_turn > game.play_gameturn)
    {
        if (player_cannot_win(game.armageddon_caster_idx))
        {
            // Stop the armageddon if its originator is just losing
            game.armageddon_cast_turn = 0;
        }
    } else
    if (game.armageddon.count_down+game.armageddon_cast_turn == game.play_gameturn)
    {
        for (i=0; i < PLAYERS_COUNT; i++)
        {
            player = get_player(i);
            if (player_exists(player))
            {
              if (player->field_2C == 1)
                reveal_whole_map(player);
            }
        }
    } else
    if (game.armageddon.count_down+game.armageddon_cast_turn < game.play_gameturn)
    {
        for (i=0; i < PLAYERS_COUNT; i++)
        {
            player = get_player(i);
            if ( (player_exists(player)) && (player->field_2C == 1) )
            {
                dungeon = get_dungeon(player->id_number);
                if ((player->victory_state == VicS_Undecided) && (dungeon->num_active_creatrs == 0))
                {
                    event_kill_all_players_events(i);
                    set_player_as_lost_level(player);
                    if (is_my_player_number(i))
                        LbPaletteSet(engine_palette);
                    heartng = get_player_soul_container(player->id_number);
                    if (thing_exists(heartng)) {
                        heartng->health = -1;
                    }
                }
            }
        }
    }
}
Esempio n. 20
0
/**
 * Returns any room of given kind and owner to which the thing can navigate.
 *
 * @param thing The thing to navigate into room.
 * @param owner Owner of the rooms to be checked.
 * @param rkind Room kind to be returned.
 * @param nav_flags Navigation flags, for checking if creature can reach the room.
 * @return Nearest room of given kind and owner, or invalid room if none found.
 */
struct Room *find_any_navigable_room_for_thing_closer_than(struct Thing *thing, PlayerNumber owner, RoomKind rkind, unsigned char nav_flags, long max_distance)
{
    struct Dungeon *dungeon;
    dungeon = get_dungeon(owner);
    SYNCDBG(18,"Searching for %s navigable by %s index %d",room_code_name(rkind),thing_model_name(thing),(int)thing->index);
    long neardistance;
    struct Room *nearoom;
    neardistance = max_distance;
    nearoom = INVALID_ROOM;
    nearoom = find_next_navigable_room_for_thing_with_capacity_and_closer_than(thing, dungeon->room_kind[rkind], nav_flags, 0, &neardistance);
    return nearoom;
}
Esempio n. 21
0
/**
 * Wander the given creature to a random digger belonging to given player.
 * Originally was good_setup_wander_to_imp.
 * @param wanderer
 * @param dngn_id
 * @return
 */
TbBool good_setup_wander_to_spdigger(struct Thing *wanderer, long dngn_id)
{
    struct Dungeon *dungeon;
    SYNCDBG(7,"Starting");
    dungeon = get_dungeon(dngn_id);
    if ( setup_wanderer_move_to_random_creature_from_list(dungeon->digger_list_start,wanderer) )
    {
        wanderer->continue_state = CrSt_GoodDoingNothing;
        return true;
    }
    SYNCDBG(4,"Cannot wander to player %d creatures",(int)dngn_id);
    return false;
}
Esempio n. 22
0
struct Room * find_nearest_navigable_room_for_thing_with_capacity_and_closer_than(struct Thing *thing, PlayerNumber owner, RoomKind rkind, unsigned char nav_flags, long used, long *neardistance)
{
    struct Dungeon *dungeon;
    struct Room *nearoom;
    long distance;
    struct Coord3d pos;

    struct Room *room;
    unsigned long k;
    int i;
    SYNCDBG(18,"Searching for %s navigable by %s index %d",room_code_name(rkind),thing_model_name(thing),(int)thing->index);
    dungeon = get_dungeon(owner);
    nearoom = INVALID_ROOM;
    k = 0;
    i = dungeon->room_kind[rkind];
    while (i != 0)
    {
        room = room_get(i);
        if (room_is_invalid(room))
        {
            ERRORLOG("Jump to invalid room detected");
            break;
        }
        i = room->next_of_owner;
        // Per-room code
        // Compute simplified distance - without use of mul or div
        distance = abs(thing->mappos.x.stl.num - (int)room->central_stl_x)
                 + abs(thing->mappos.y.stl.num - (int)room->central_stl_y);
        if ((*neardistance > distance) && (room->used_capacity >= used))
        {
            if (find_first_valid_position_for_thing_anywhere_in_room(thing, room, &pos))
            {
                if ((thing->class_id != TCls_Creature)
                  || creature_can_navigate_to(thing, &pos, nav_flags))
                {
                    *neardistance = distance;
                    nearoom = room;
                }
            }
        }
        // Per-room code ends
        k++;
        if (k > ROOMS_COUNT)
        {
          ERRORLOG("Infinite loop detected when sweeping rooms list");
          break;
        }
    }
    return nearoom;
}
Esempio n. 23
0
short tunneller_doing_nothing(struct Thing *creatng)
{
    //return _DK_tunneller_doing_nothing(creatng);
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(creatng);
    // Wait for some time
    if (game.play_gameturn - cctrl->last_mood_sound_turn <= 1) {
        return 1;
    }
    /* Sometimes we may have no target dungeon. In that case, destination dungeon
     * index is negative. */
    if (cctrl->party.target_plyr_idx == -1)
    {
        script_support_send_tunneller_to_appropriate_dungeon(creatng);
        return 0;
    }
    if (!player_cannot_win(cctrl->party.target_plyr_idx))
    {
        if (good_can_move_to_dungeon_heart(creatng, cctrl->party.target_plyr_idx))
        {
            internal_set_thing_state(creatng, CrSt_GoodDoingNothing);
            return 1;
        }
    }
    cctrl->party.target_plyr_idx = good_find_enemy_dungeon(creatng);
    if (cctrl->party.target_plyr_idx != -1)
    {
        internal_set_thing_state(creatng, CrSt_GoodDoingNothing);
        return 1;
    }

    int plyr_idx;
    plyr_idx = get_best_dungeon_to_tunnel_to(creatng);
    if (plyr_idx == -1) {
      return 1;
    }
    struct Dungeon *dungeon;
    dungeon = get_dungeon(plyr_idx);
    if ( dungeon->num_active_creatrs || dungeon->num_active_diggers )
    {
        struct Coord3d pos;
        get_random_position_in_dungeon_for_creature(plyr_idx, 1, creatng, &pos);
        send_tunneller_to_point_in_dungeon(creatng, plyr_idx, &pos);
    } else
    {
        good_setup_wander_to_dungeon_heart(creatng, plyr_idx);
    }
    return 1;
}
Esempio n. 24
0
short creature_scavenged_disappear(struct Thing *thing)
{
    struct CreatureControl *cctrl;
    struct Dungeon *dungeon;
    struct Room *room;
    struct Coord3d pos;
    long stl_x, stl_y;
    long i;
    //return _DK_creature_scavenged_disappear(thing);
    cctrl = creature_control_get_from_thing(thing);
    cctrl->byte_9A--;
    if (cctrl->byte_9A > 0)
    {
      if ((cctrl->byte_9A == 7) && (cctrl->byte_9B < PLAYERS_COUNT))
      {
        create_effect(&thing->mappos, get_scavenge_effect_element(cctrl->byte_9B), thing->owner);
      }
      return 0;
    }
    // We don't really have to convert coordinates into numbers and back to XY.
    i = get_subtile_number(cctrl->scavenge.stl_9D_x, cctrl->scavenge.stl_9D_y);
    stl_x = stl_num_decode_x(i);
    stl_y = stl_num_decode_y(i);
    room = subtile_room_get(stl_x, stl_y);
    if (room_is_invalid(room) || (room->kind != RoK_SCAVENGER))
    {
        ERRORLOG("Room %s at (%d,%d) disappeared.",room_code_name(RoK_SCAVENGER),(int)stl_x,(int)stl_y);
        kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects);
        return -1;
    }
    if (find_random_valid_position_for_thing_in_room(thing, room, &pos))
    {
        move_thing_in_map(thing, &pos);
        anger_set_creature_anger_all_types(thing, 0);
        dungeon = get_dungeon(cctrl->byte_9B);
        dungeon->creatures_scavenge_gain++;
        if (is_my_player_number(thing->owner))
          output_message(SMsg_MinionScanvenged, 0, true);
        cctrl->byte_9C = thing->owner;
        change_creature_owner(thing, cctrl->byte_9B);
        internal_set_thing_state(thing, CrSt_CreatureScavengedReappear);
        return 0;
    } else
    {
        ERRORLOG("No valid position inside %s room for %s.",room_code_name(room->kind),thing_model_name(thing));
        kill_creature(thing, INVALID_THING, -1, CrDed_NoEffects);
        return -1;
    }
}
Esempio n. 25
0
TbBool set_script_flag(PlayerNumber plyr_idx, long flag_id, long value)
{
    struct Dungeon *dungeon;
    if ( (flag_id < 0) || (flag_id >= SCRIPT_FLAGS_COUNT) ) {
        ERRORLOG("Can't set flag; invalid flag id %d.",(int)flag_id);
        return false;
    }
    dungeon = get_dungeon(plyr_idx);
    if (dungeon_invalid(dungeon)) {
        ERRORLOG("Can't set flag; player %d has no dungeon",(int)plyr_idx);
        return false;
    }
    dungeon->script_flags[flag_id] = value;
    return true;
}
Esempio n. 26
0
void start_transfer_creature(struct PlayerInfo *player, struct Thing *thing)
{
  struct Dungeon *dungeon;
  dungeon = get_dungeon(player->id_number);
  if (dungeon->num_active_creatrs != 0)
  {
    if (is_my_player(player))
    {
      dungeon_special_selected = thing->index;
      transfer_creature_scroll_offset = 0;
      turn_off_menu(GMnu_DUNGEON_SPECIAL);
      turn_on_menu(GMnu_TRANSFER_CREATURE);
    }
  }
}
Esempio n. 27
0
void start_resurrect_creature(struct PlayerInfo *player, struct Thing *thing)
{
    struct Dungeon *dungeon;
    dungeon = get_dungeon(player->id_number);
    if (dungeon->dead_creatures_count != 0)
    {
        if (is_my_player(player))
        {
          dungeon_special_selected = thing->index;
          resurrect_creature_scroll_offset = 0;
          turn_off_menu(GMnu_DUNGEON_SPECIAL);
          turn_on_menu(GMnu_RESURRECT_CREATURE);
        }
    }
}
Esempio n. 28
0
TbBool process_scavenge_creature_from_pool(struct Thing *calltng, long work_value)
{
    struct Dungeon *calldngn;
    calldngn = get_dungeon(calltng->owner);
    calldngn->scavenge_turn_points[calltng->model] += work_value;
    long scavpts;
    scavpts = calculate_correct_creature_scavenge_required(calltng, calltng->owner);
    if ((scavpts << 8) < calldngn->scavenge_turn_points[calltng->model])
    {
        creature_scavenge_from_creature_pool(calltng);
        calldngn->scavenge_turn_points[calltng->model] -= scavpts;
        return true;
    }
    return false;
}
Esempio n. 29
0
TbBool creature_can_gain_experience(const struct Thing *thing)
{
    struct Dungeon *dungeon;
    struct CreatureStats *crstat;
    struct CreatureControl *cctrl;
    dungeon = get_dungeon(thing->owner);
    cctrl = creature_control_get_from_thing(thing);
    // Creatures which reached players max level can't be trained
    if (cctrl->explevel >= dungeon->creature_max_level[thing->model])
        return false;
    // Creatures which reached absolute max level and have no grow up creature
    crstat = creature_stats_get_from_thing(thing);
    if ((cctrl->explevel >= (CREATURE_MAX_LEVEL-1)) && (crstat->grow_up == 0))
        return false;
    return true;
}
Esempio n. 30
0
TbBool restart_script_timer(PlayerNumber plyr_idx, long timer_id)
{
    struct Dungeon *dungeon;
    if ( (timer_id < 0) || (timer_id >= TURN_TIMERS_COUNT) ) {
        ERRORLOG("Can't restart timer; invalid timer id %d.",(int)timer_id);
        return false;
    }
    dungeon = get_dungeon(plyr_idx);
    if (dungeon_invalid(dungeon)) {
        ERRORLOG("Can't restart timer; player %d has no dungeon.",(int)plyr_idx);
        return false;
    }
    dungeon->turn_timers[timer_id].state = 1;
    dungeon->turn_timers[timer_id].count = game.play_gameturn;
    return true;
}