void transfer_creature(struct Thing *boxtng, struct Thing *transftng, unsigned char plyr_idx)
{
    SYNCDBG(7,"Starting");
    struct CreatureControl *cctrl;
    if (!thing_exists(boxtng) || (box_thing_to_special(boxtng) != SpcKind_TrnsfrCrtr) ) {
        ERRORMSG("Invalid transfer box object!");
        return;
    }
    // Check if 'things' are correct
    if (!thing_exists(transftng) || !thing_is_creature(transftng) || (transftng->owner != plyr_idx)) {
        ERRORMSG("Invalid transfer creature thing!");
        return;
    }

    cctrl = creature_control_get_from_thing(transftng);
    set_transfered_creature(plyr_idx, transftng->model, cctrl->explevel);
    remove_thing_from_power_hand_list(transftng, plyr_idx);
    kill_creature(transftng, INVALID_THING, -1, CrDed_NoEffects|CrDed_NotReallyDying);
    create_special_used_effect(&boxtng->mappos, plyr_idx);
    remove_events_thing_is_attached_to(boxtng);
    force_any_creature_dragging_owned_thing_to_drop_it(boxtng);
    delete_thing_structure(boxtng, 0);
    if (is_my_player_number(plyr_idx))
      output_message(SMsg_CommonAcknowledge, 0, true);
}
Exemple #2
0
TbBool attempt_anger_job_join_enemy(struct Thing *creatng)
{
    struct Thing *heartng;
    int i, n;
    n = ACTION_RANDOM(PLAYERS_COUNT);
    for (i=0; i < PLAYERS_COUNT; i++, n=(n+1)%PLAYERS_COUNT)
    {
        if ((n == game.neutral_player_num) || (n == creatng->owner))
            continue;
        struct PlayerInfo *player;
        player = get_player(n);
        if (!player_exists(player) || (player->field_2C != 1))
            continue;
        heartng = get_player_soul_container(n);
        if (thing_exists(heartng) && (heartng->active_state != 3))
        {
            TRACE_THING(heartng);
            if (creature_can_navigate_to(creatng, &heartng->mappos, NavRtF_Default)) {
                change_creature_owner(creatng, n);
                anger_set_creature_anger_all_types(creatng, 0);
            }
        }
    }
    return false;
}
Exemple #3
0
void set_sprite_view_isometric(void)
{
    //_DK_set_sprite_view_isometric();
    long i;
    for (i=1; i < THINGS_COUNT; i++)
    {
        struct Thing *thing;
        thing = thing_get(i);
        if (thing_exists(thing))
        {
            if (thing_is_creature(thing) || ((thing->field_4F & 0x01) == 0))
            {
                int n;
                n = straight_td_iso(thing->field_44);
                if (n >= 0)
                {
                    thing->field_44 = n;
                    long nframes;
                    nframes = keepersprite_frames(thing->field_44);
                    if (nframes != thing->field_49)
                    {
                        ERRORLOG("No frames different between views C%d, M%d, A%d, B%d",thing->class_id,thing->model,thing->field_49,nframes);
                        thing->field_49 = nframes;
                        n = thing->field_49 - 1;
                        if (n > thing->field_48) {
                            n = thing->field_48;
                        }
                        thing->field_48 = n;
                        thing->field_40 = n << 8;
                    }
                }
            }
        }
    }
}
short creature_drop_body_in_prison(struct Thing *thing)
{
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(thing);
    struct Thing *dragtng;
    dragtng = thing_get(cctrl->dragtng_idx);
    if (!thing_exists(dragtng) || !creature_is_being_unconscious(dragtng)) {
        set_start_state(thing);
        return 0;
    }
    if (!subtile_is_room(thing->mappos.x.stl.num, thing->mappos.y.stl.num)) {
        set_start_state(thing);
        return 0;
    }
    struct Room *room;
    room = get_room_thing_is_on(thing);
    if ((room->owner != thing->owner) || (room->kind != RoK_PRISON)) {
        set_start_state(thing);
        return 0;
    }
    make_creature_conscious(dragtng);
    initialise_thing_state(dragtng, CrSt_CreatureArrivedAtPrison);
    struct CreatureControl *dragctrl;
    dragctrl = creature_control_get_from_thing(dragtng);
    dragctrl->flgfield_1 |= CCFlg_NoCompControl;
    set_start_state(thing);
    return 1;

}
void set_sprite_view_3d(void)
{
    long i;
    for (i=1; i < THINGS_COUNT; i++)
    {
        struct Thing *thing;
        thing = thing_get(i);
        if (thing_exists(thing))
        {
            if (thing_is_creature(thing) || ((thing->field_4F & TF4F_DoNotDraw) == 0))
            {
                int n;
                n = straight_iso_td(thing->anim_sprite);
                if (n >= 0)
                {
                    thing->anim_sprite = n;
                    long nframes;
                    nframes = keepersprite_frames(thing->anim_sprite);
                    if (nframes != thing->field_49)
                    {
                        ERRORLOG("No frames different between views C%d, M%d, A%d, B%d",thing->class_id,thing->model,thing->field_49,nframes);
                        thing->field_49 = nframes;
                        n = thing->field_49 - 1;
                        if (n > thing->field_48) {
                            n = thing->field_48;
                        }
                        thing->field_48 = n;
                        thing->field_40 = n << 8;
                    }
                }
            }
        }
    }
}
Exemple #6
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;
                    }
                }
            }
        }
    }
}
Exemple #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;
}
Exemple #8
0
struct Thing *allocate_free_thing_structure_f(unsigned char allocflags, const char *func_name)
{
    struct Thing *thing;
    long i;
    // Get a thing from "free things list"
    i = game.free_things_start_index;
    // If there is no free thing, try to free an effect
    if (i >= THINGS_COUNT-1)
    {
        if ((allocflags & FTAF_FreeEffectIfNoSlots) != 0)
        {
            thing = thing_get(game.thing_lists[TngList_EffectElems].index);
            if (!thing_is_invalid(thing))
            {
                delete_thing_structure(thing, 0);
            } else
            {
#if (BFDEBUG_LEVEL > 0)
                ERRORMSG("%s: Cannot free up effect element to allocate new thing!",func_name);
#endif
            }
        }
        i = game.free_things_start_index;
    }
    // Now, if there is still no free thing (we couldn't free any)
    if (i >= THINGS_COUNT-1)
    {
#if (BFDEBUG_LEVEL > 0)
        ERRORMSG("%s: Cannot allocate new thing, no free slots!",func_name);
#endif
        return INVALID_THING;
    }
    // And if there is free one, allocate it
    thing = thing_get(game.free_things[i]);
#if (BFDEBUG_LEVEL > 0)
    if (thing_exists(thing)) {
        ERRORMSG("%s: Found existing thing %d in free things list at pos %d!",func_name,(int)game.free_things[i],(int)i);
    }
#endif
    LbMemorySet(thing, 0, sizeof(struct Thing));
    if (thing_is_invalid(thing)) {
        ERRORMSG("%s: Got invalid thing slot instead of free one!",func_name);
        return INVALID_THING;
    }
    thing->alloc_flags |= TAlF_Exists;
    thing->index = game.free_things[i];
    game.free_things[game.free_things_start_index] = 0;
    game.free_things_start_index++;
    TRACE_THING(thing);
    return thing;
}
long get_explore_sight_distance_in_slabs(const struct Thing *thing)
{
    struct PlayerInfo *player;
    if (!thing_exists(thing)) {
        return 0;
    }
    if (is_neutral_thing(thing)) {
        return 7;
    }
    player = get_player(thing->owner);
    long dist;
    if (player->controlled_thing_idx != thing->index) {
        dist = 7;
    } else {
        dist = get_creature_can_see_subtiles() / STL_PER_SLB;
        if (dist <= 7)
            dist = 7;
    }
    return dist;
}
Exemple #10
0
void select_transfer_creature(struct GuiButton *gbtn)
{
    struct Dungeon *dungeon;
    dungeon = get_my_dungeon();
    struct Thing *thing;
    thing = INVALID_THING;
    int listitm_idx;
    listitm_idx = selected_transfer_creature(dungeon, gbtn);
    if (listitm_idx != -1)
    {
        thing = get_player_list_nth_creature_of_model(dungeon->creatr_list_start, 0, listitm_idx);
    }
    if (thing_exists(thing))
    {
        struct Packet *pckt;
        pckt = get_packet(my_player_number);
        set_packet_action(pckt, PckA_TransferCreatr, dungeon_special_selected, thing->index);
        turn_off_menu(GMnu_TRANSFER_CREATURE);
    }
}
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);
}
Exemple #12
0
TbBool player_has_heart(PlayerNumber plyr_idx)
{
    return thing_exists(get_player_soul_container(plyr_idx));
}
TbBool lights_stats_debug_dump(void)
{
    long lights[LIGHTS_COUNT];
    long lgh_things[THING_CLASSES_COUNT];
    long shadowcs[SHADOW_CACHE_COUNT];
    long shdc_used,shdc_linked,shdc_free;
    long lgh_used,lgh_free;
    long lgh_sttc,lgh_dynm;
    struct Thing * thing;
    struct Light *lgt;
    struct ShadowCache *shdc;
    long i,n;
    for (i=0; i < SHADOW_CACHE_COUNT; i++)
    {
        shdc = &game.lish.shadow_cache[i];
        if ((shdc->flags & ShCF_Allocated) != 0)
            shadowcs[i] = -1;
        else
            shadowcs[i] = 0;
    }
    lgh_sttc = 0;
    lgh_dynm = 0;
    for (i=0; i < LIGHTS_COUNT; i++)
    {
        lgt = &game.lish.lights[i];
        if ((lgt->flags & LgtF_Allocated) != 0)
        {
            lights[i] = -1;
            if ((lgt->flags & LgtF_Dynamic) != 0)
                lgh_dynm++;
            else
                lgh_sttc++;
            if ( (lgt->shadow_index > 0) && (lgt->shadow_index < SHADOW_CACHE_COUNT) )
            {
                if (shadowcs[lgt->shadow_index] == -1) {
                    shadowcs[lgt->shadow_index] = i;
                } else
                if (shadowcs[lgt->shadow_index] == 0) {
                    WARNLOG("Shadow Cache %d is not allocated, but used by light %d!",(int)lgt->shadow_index,(int)i);
                } else {
                    WARNLOG("Shadow Cache %d is double-allocated, for lights %d and %d!",(int)lgt->shadow_index,(int)shadowcs[lgt->shadow_index],(int)i);
                }
            } else
            if ((lgt->flags & LgtF_Dynamic) != 0)
            {
                WARNLOG("Dynamic light %d has bad Shadow Cache %d!",(int)i,(int)lgt->shadow_index);
            }
        } else {
            lights[i] = 0;
        }
    }
    for (i=1; i < THINGS_COUNT; i++)
    {
        thing = thing_get(i);
        if (thing_exists(thing))
        {
            if ((thing->light_id > 0) && (thing->light_id < LIGHTS_COUNT))
            {
                n = 1000+(long)thing->class_id;
                if (lights[thing->light_id] == -1) {
                    lights[thing->light_id] = n;
                } else
                if (lights[thing->light_id] == 0) {
                    WARNLOG("Light %d is not allocated, but used by %s!",(int)thing->light_id, thing_model_name(thing));
                } else {
                    WARNLOG("Light %d is double-allocated, for %d and %d!",(int)thing->light_id, (int)lights[thing->light_id], (int)n);
                }
            }

        }
    }
    lgh_used = 0;
    lgh_free = 0;
    for (i=0; i < THING_CLASSES_COUNT; i++)
        lgh_things[i] = 0;
    for (i=0; i < LIGHTS_COUNT; i++)
    {
        if (lights[i] != 0)
        {
            lgh_used++;
            if ((lights[i] > 1000) && (lights[i] < 1000+THING_CLASSES_COUNT))
                lgh_things[lights[i]-1000]++;
        } else
        {
            lgh_free++;
        }
    }
    shdc_free = 0;
    shdc_used = 0;
    shdc_linked = 0;
    for (i=0; i < SHADOW_CACHE_COUNT; i++)
    {
        if (shadowcs[i] != 0)
        {
            shdc_used++;
            if (shadowcs[i] > 0)
                shdc_linked++;
        } else {
            shdc_free++;
        }
    }
    SYNCLOG("Lights: %ld free, %ld used; %ld static, %ld dynamic; for things:%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld",lgh_free,lgh_used,lgh_sttc,lgh_dynm,lgh_things[1],lgh_things[2],lgh_things[3],lgh_things[4],lgh_things[5],lgh_things[6],lgh_things[7],lgh_things[8],lgh_things[9],lgh_things[10],lgh_things[11],lgh_things[12],lgh_things[13]);
    if ((shdc_used != shdc_linked) || (shdc_used != lgh_dynm))
    {
        WARNLOG("Amount of shadow cache mismatches: %ld free, %ld used, %ld linked to lights, %d dyn. lights.",shdc_free,shdc_used,shdc_linked,light_total_dynamic_lights);
    }
    if (lgh_sttc != light_total_stat_lights)
    {
        WARNLOG("Wrong global lights counter: %ld static lights and counter says %ld.",lgh_sttc,light_total_stat_lights);
    }
    if (lgh_dynm != light_total_dynamic_lights)
    {
        WARNLOG("Wrong global lights counter: %ld dynamic lights and counter says %ld.",lgh_dynm,light_total_dynamic_lights);
    }
    return false;
}
Exemple #14
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");
}
void activate_dungeon_special(struct Thing *cratetng, struct PlayerInfo *player)
{
  SYNCDBG(6,"Starting");
  short used;
  struct Coord3d pos;
  int spkindidx;

  // Gathering data which we'll need if the special is used and disposed.
  memcpy(&pos,&cratetng->mappos,sizeof(struct Coord3d));
  spkindidx = cratetng->model - 86;
  used = 0;
  if (thing_exists(cratetng) && is_dungeon_special(cratetng))
  {
    switch (cratetng->model)
    {
        case 86:
          reveal_whole_map(player);
          remove_events_thing_is_attached_to(cratetng);
          used = 1;
          delete_thing_structure(cratetng, 0);
          break;
        case 87:
          start_resurrect_creature(player, cratetng);
          break;
        case 88:
          start_transfer_creature(player, cratetng);
          break;
        case 89:
          if (steal_hero(player, &cratetng->mappos))
          {
            remove_events_thing_is_attached_to(cratetng);
            used = 1;
            delete_thing_structure(cratetng, 0);
          }
          break;
        case 90:
          multiply_creatures(player);
          remove_events_thing_is_attached_to(cratetng);
          used = 1;
          delete_thing_structure(cratetng, 0);
          break;
        case 91:
          increase_level(player);
          remove_events_thing_is_attached_to(cratetng);
          used = 1;
          delete_thing_structure(cratetng, 0);
          break;
        case 92:
          make_safe(player);
          remove_events_thing_is_attached_to(cratetng);
          used = 1;
          delete_thing_structure(cratetng, 0);
          break;
        case 93:
          activate_bonus_level(player);
          remove_events_thing_is_attached_to(cratetng);
          used = 1;
          delete_thing_structure(cratetng, 0);
          break;
        default:
          ERRORLOG("Invalid dungeon special (Model %d)", (int)cratetng->model);
          break;
      }
      if ( used )
      {
        if (is_my_player(player))
          output_message(special_desc[spkindidx].speech_msg, 0, true);
        create_special_used_effect(&pos, player->id_number);
      }
  }
}
Exemple #16
0
TbBool thing_exists_idx(long tng_idx)
{
    return thing_exists(thing_get(tng_idx));
}