コード例 #1
0
void setup_training_move_near(struct Thing *creatng, SubtlCodedCoords stl_num)
{
    SubtlCodedCoords near_stl_num;
    MapSubtlDelta dist_x,dist_y;
    long stl_x,stl_y;
    stl_x = stl_num_decode_x(stl_num);
    stl_y = stl_num_decode_y(stl_num);
    // Select a subtile closer to current position
    dist_x = stl_x - (MapSubtlDelta)creatng->mappos.x.stl.num;
    dist_y = stl_y - (MapSubtlDelta)creatng->mappos.y.stl.num;
    if (abs(dist_x) > abs(dist_y))
    {
        if (dist_x > 0) {
            stl_x -= 1;
        } else {
            stl_x += 1;
        }
    } else
    {
        if (dist_y > 0) {
            stl_y -= 1;
        } else {
            stl_y += 1;
        }
    }
    near_stl_num = get_subtile_number(stl_x,stl_y);
    setup_training_move(creatng, near_stl_num);
}
コード例 #2
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;
}
コード例 #3
0
ファイル: player_compchecks.c プロジェクト: sniquot/keeperfx
long computer_check_for_pretty(struct Computer2 *comp, struct ComputerCheck * check)
{
    struct Dungeon *dungeon;
    SYNCDBG(8,"Starting");
    dungeon = comp->dungeon;
    MapSubtlCoord stl_x, stl_y;
    if (computer_able_to_use_magic(comp, PwrK_HAND, 1, 1) != CTaskRet_Unk1) {
        return CTaskRet_Unk4;
    }
    {
        long stack_len;
        stack_len = dungeon->digger_stack_length;
        if (stack_len <= check->param1 * dungeon->total_area / 100) {
            return CTaskRet_Unk4;
        }
        long n;
        n = find_in_imp_stack_starting_at(DigTsk_ImproveDungeon, ACTION_RANDOM(stack_len), dungeon);
        if (n < 0) {
            return CTaskRet_Unk4;
        }
        const struct DiggerStack *dstack;
        dstack = &dungeon->digger_stack[n];
        stl_x = stl_num_decode_x(dstack->stl_num);
        stl_y = stl_num_decode_y(dstack->stl_num);
    }
    struct Thing * creatng;
    creatng = find_imp_for_pickup(comp, stl_x, stl_y);
    if (thing_is_invalid(creatng)) {
        return CTaskRet_Unk4;
    }
    if (!create_task_move_creature_to_subtile(comp, creatng, stl_x, stl_y, CrSt_ImpImprovesDungeon)) {
        return CTaskRet_Unk4;
    }
    return CTaskRet_Unk1;
}
コード例 #4
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;
    }
}
コード例 #5
0
void setup_training_move(struct Thing *creatng, SubtlCodedCoords stl_num)
{
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(creatng);
    cctrl->moveto_pos.x.val = subtile_coord_center(stl_num_decode_x(stl_num));
    cctrl->moveto_pos.y.val = subtile_coord_center(stl_num_decode_y(stl_num));
    cctrl->moveto_pos.z.val = get_thing_height_at(creatng, &cctrl->moveto_pos);
    if (thing_in_wall_at(creatng, &cctrl->moveto_pos))
    {
        ERRORLOG("Illegal setup to wall at (%d,%d)",
            (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num);
        set_start_state(creatng);
    }
    SYNCDBG(18,"The %s is moving to (%d,%d)", thing_model_name(creatng),
        (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num);
}
コード例 #6
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;
}
コード例 #7
0
TbBool setup_workshop_move(struct Thing *thing, SubtlCodedCoords stl_num)
{
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(thing);
    cctrl->moveto_pos.x.stl.num = stl_num_decode_x(stl_num);
    cctrl->moveto_pos.x.stl.pos = 128;
    cctrl->moveto_pos.y.stl.num = stl_num_decode_y(stl_num);
    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 subtile (%d,%d)", (int)cctrl->moveto_pos.x.stl.num, (int)cctrl->moveto_pos.y.stl.num);
        set_start_state(thing);
        return false;
    }
    return true;
}
コード例 #8
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));
    }
}
コード例 #9
0
short good_back_at_start(struct Thing *thing)
{
    // Debug code to find incorrect states
    if (!is_hero_thing(thing))
    {
        ERRORLOG("Non hero thing %ld, %s, owner %ld - reset",(long)thing->index,thing_model_name(thing),(long)thing->owner);
        set_start_state(thing);
        return false;
    }
    //return _DK_good_back_at_start(thing);
    if (thing->creature.gold_carried <= 0)
    {
        set_start_state(thing);
        return 1;
    }
    SubtlCodedCoords stl_num;
    long m,n;
    stl_num = get_subtile_number(thing->mappos.x.stl.num,thing->mappos.y.stl.num);
    m = ACTION_RANDOM(AROUND_MAP_LENGTH);
    for (n=0; n < AROUND_MAP_LENGTH; n++)
    {
        struct Map *mapblk;
        mapblk = get_map_block_at_pos(stl_num+around_map[m]);
        // Per-block code
        if ((mapblk->flags & MapFlg_IsTall) == 0)
        {
            MapSubtlCoord stl_x, stl_y;
            stl_x = stl_num_decode_x(stl_num+around_map[m]);
            stl_y = stl_num_decode_y(stl_num+around_map[m]);
            if (setup_person_move_to_position(thing, stl_x, stl_y, NavRtF_Default)) {
                thing->continue_state = CrSt_GoodDropsGold;
                return 1;
            }
        }
        // Per-block code ends
        m = (m + 1) % AROUND_MAP_LENGTH;
    }
    set_start_state(thing);
    return 1;

}
コード例 #10
0
long instf_tunnel(struct Thing *creatng, long *param)
{
    struct CreatureControl *cctrl;
    struct SlabMap *slb;
    SYNCDBG(16,"Starting");
    TRACE_THING(creatng);
    cctrl = creature_control_get_from_thing(creatng);
    MapSubtlCoord stl_x,stl_y;
    stl_x = stl_num_decode_x(cctrl->navi.field_15);
    stl_y = stl_num_decode_y(cctrl->navi.field_15);
    slb = get_slabmap_for_subtile(stl_x, stl_y);
    if (slabmap_block_invalid(slb)) {
        return 0;
    }
    thing_play_sample(creatng, 69+UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
    if (slb->health > 1) {
        slb->health--;
    } else {
        dig_out_block(stl_x, stl_y, creatng->owner);
    }
    return 1;
}
コード例 #11
0
long instf_dig(struct Thing *creatng, long *param)
{
    struct CreatureControl *cctrl;
    struct Dungeon *dungeon;
    struct SlabMap *slb;
    long stl_x,stl_y;
    long task_idx,taskkind;
    long dig_damage,gold;
    SYNCDBG(16,"Starting");
    TRACE_THING(creatng);
    //return _DK_instf_dig(thing, param);
    cctrl = creature_control_get_from_thing(creatng);
    dungeon = get_dungeon(creatng->owner);
    task_idx = cctrl->word_91;
    {
      struct MapTask *task;
      task = get_dungeon_task_list_entry(dungeon,task_idx);
      taskkind = task->kind;
      if (task->coords != cctrl->word_8F) {
        return 0;
      }
      stl_x = stl_num_decode_x(cctrl->word_8F);
      stl_y = stl_num_decode_y(cctrl->word_8F);
    }
    slb = get_slabmap_for_subtile(stl_x, stl_y);
    if (slabmap_block_invalid(slb)) {
        return 0;
    }
    dig_damage = calculate_damage_did_to_slab_with_single_hit(creatng, slb);
    if (slb->health > dig_damage)
    {
        if (!slab_kind_is_indestructible(slb->kind))
            slb->health -= dig_damage;
        thing_play_sample(creatng, 63 + UNSYNC_RANDOM(6), NORMAL_PITCH, 0, 3, 0, 2, FULL_LOUDNESS);
        create_effect(&creatng->mappos, TngEff_Unknown25, creatng->owner);
        if (taskkind == SDDigTask_MineGold)
        {
            gold = calculate_gold_digged_out_of_slab_with_single_hit(dig_damage, creatng->owner, cctrl->explevel, slb);
            creatng->creature.gold_carried += gold;
            dungeon->lvstats.gold_mined += gold;
        }
        return 0;
    }
    // slb->health <= dig_damage - we're going to destroy the slab
    remove_from_task_list(creatng->owner, task_idx);
    if (taskkind == SDDigTask_MineGold)
    {
        gold = calculate_gold_digged_out_of_slab_with_single_hit(slb->health, creatng->owner, cctrl->explevel, slb);
        creatng->creature.gold_carried += gold;
        dungeon->lvstats.gold_mined += gold;
        mine_out_block(stl_x, stl_y, creatng->owner);
        if (dig_has_revealed_area(stl_x, stl_y, creatng->owner))
        {
            EventIndex evidx;
            evidx = event_create_event_or_update_nearby_existing_event(
                subtile_coord_center(stl_x), subtile_coord_center(stl_y),
                EvKind_AreaDiscovered, creatng->owner, 0);
            if ((evidx > 0) && is_my_player_number(creatng->owner))
                output_message(SMsg_DugIntoNewArea, 0, true);
        }
    } else
    if (taskkind == SDDigTask_DigEarth)
    {
        dig_out_block(stl_x, stl_y, creatng->owner);
        if (dig_has_revealed_area(stl_x, stl_y, creatng->owner))
        {
            EventIndex evidx;
            evidx = event_create_event_or_update_nearby_existing_event(
                subtile_coord_center(stl_x), subtile_coord_center(stl_y),
                EvKind_AreaDiscovered, creatng->owner, 0);
            if ((evidx > 0) && is_my_player_number(creatng->owner))
                output_message(SMsg_DugIntoNewArea, 0, true);
        }
    }
    check_map_explored(creatng, stl_x, stl_y);
    thing_play_sample(creatng, 72 + UNSYNC_RANDOM(3), NORMAL_PITCH, 0, 3, 0, 4, FULL_LOUDNESS);
    return 1;
}
コード例 #12
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;
}