Example #1
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;
                    }
                }
            }
        }
    }
}
Example #2
0
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;
                    }
                }
            }
        }
    }
}
Example #3
0
TbBool can_thing_be_possessed(const struct Thing *thing, PlayerNumber plyr_idx)
{
    //return _DK_can_thing_be_possessed(thing, plyr_idx);
    if (thing->owner != plyr_idx)
        return false;
    if (thing_is_creature(thing))
    {
        if (thing_is_picked_up(thing))  {
            return false;
        }
        if ((thing->active_state == CrSt_CreatureUnconscious)
          || creature_affected_by_spell(thing, SplK_Teleport))  {
            return false;
        }
        if (creature_is_being_sacrificed(thing) || creature_is_being_summoned(thing))  {
            return false;
        }
        if (creature_is_kept_in_custody_by_enemy(thing))  {
            return false;
        }
        return true;
    }
    if (thing_is_object(thing))
    {
        if (object_is_mature_food(thing))  {
            return true;
        }
        return false;
    }
    return false;
}
Example #4
0
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);
}
Example #5
0
void process_disease(struct Thing *creatng)
{
    SYNCDBG(18,"Starting");
    //_DK_process_disease(thing);
    struct CreatureControl *cctrl;
    cctrl = creature_control_get_from_thing(creatng);
    if (!creature_affected_by_spell(creatng, SplK_Disease)) {
        return;
    }
    if (ACTION_RANDOM(100) < game.disease_transfer_percentage)
    {
        SubtlCodedCoords stl_num;
        long n;
        stl_num = get_subtile_number(creatng->mappos.x.stl.num,creatng->mappos.y.stl.num);
        for (n=0; n < AROUND_MAP_LENGTH; n++)
        {
            struct Thing *thing;
            struct Map *mapblk;
            unsigned long k;
            long i;
            mapblk = get_map_block_at_pos(stl_num+around_map[n]);
            k = 0;
            i = get_mapwho_thing_index(mapblk);
            while (i != 0)
            {
              thing = thing_get(i);
              if (thing_is_invalid(thing))
              {
                WARNLOG("Jump out of things array");
                break;
              }
              i = thing->next_on_mapblk;
              // Per thing code
              if (thing_is_creature(thing) && ((get_creature_model_flags(thing) & CMF_IsSpecDigger) == 0)
                && (thing->owner != cctrl->disease_caster_plyridx) && !creature_affected_by_spell(thing, SplK_Disease))
              {
                  struct CreatureControl *tngcctrl;
                  tngcctrl = creature_control_get_from_thing(thing);
                  apply_spell_effect_to_thing(thing, SplK_Disease, cctrl->explevel);
                  tngcctrl->disease_caster_plyridx = cctrl->disease_caster_plyridx;
              }
              // Per thing code ends
              k++;
              if (k > THINGS_COUNT)
              {
                  ERRORLOG("Infinite loop detected when sweeping things list");
                  erstat_inc(ESE_InfChainTngPerMapWho);
                  break_mapwho_infinite_chain(mapblk);
                  break;
              }
            }
        }
    }
    if (((game.play_gameturn - cctrl->disease_start_turn) % game.disease_lose_health_time) == 0)
    {
        apply_damage_to_thing_and_display_health(creatng, game.disease_lose_percentage_health * cctrl->max_health / 100, DmgT_Biological, cctrl->disease_caster_plyridx);
    }
}
TbBool find_combat_target_passing_by_subtile_but_having_unrelated_job(const struct Thing *creatng, CreatureJob job_kind, MapSubtlCoord stl_x, MapSubtlCoord stl_y, unsigned long *found_dist, struct Thing **found_thing)
{
    struct Thing *thing;
    struct Map *mapblk;
    long i;
    unsigned long k;
    long dist;
    mapblk = get_map_block_at(stl_x,stl_y);
    k = 0;
    i = get_mapwho_thing_index(mapblk);
    while (i != 0)
    {
        thing = thing_get(i);
        TRACE_THING(thing);
        if (thing_is_invalid(thing))
        {
            ERRORLOG("Jump to invalid thing detected");
            break;
        }
        i = thing->next_on_mapblk;
        // Per thing code start
        if (thing_is_creature(thing) && (thing->index != creatng->index) && !creature_has_job(thing, job_kind)
            && !creature_is_kept_in_custody(thing) && !creature_is_being_unconscious(thing)
            && !creature_is_dying(thing) && !creature_is_doing_anger_job(thing))
        {
            if (!creature_is_invisible(thing) || creature_can_see_invisible(creatng))
            {
                dist = get_combat_distance(creatng, thing);
                // If we have combat sight - we want that target, don't search anymore
                if (creature_can_see_combat_path(creatng, thing, dist) > AttckT_Unset)
                {
                    *found_dist = dist;
                    *found_thing = thing;
                    return true;
                }
                // No combat sight - but maybe it's at least closer than previous one
                if ( *found_dist > dist )
                {
                    *found_dist = dist;
                    *found_thing = thing;
                }
            }
        }
        // Per thing code end
        k++;
        if (k > THINGS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping things list");
            break;
        }
    }
    return false;
}
Example #7
0
TbBool find_pressure_trigger_trap_target_passing_by_subtile(const struct Thing *traptng, MapSubtlCoord stl_x, MapSubtlCoord stl_y, struct Thing **found_thing)
{
    struct Thing *thing;
    struct Map *mapblk;
    long i;
    unsigned long k;
    mapblk = get_map_block_at(stl_x,stl_y);
    k = 0;
    i = get_mapwho_thing_index(mapblk);
    while (i != 0)
    {
        thing = thing_get(i);
        TRACE_THING(thing);
        if (thing_is_invalid(thing))
        {
            ERRORLOG("Jump to invalid thing detected");
            break;
        }
        i = thing->next_on_mapblk;
        // Per thing code start
        if (thing_is_creature(thing) && (thing->owner != traptng->owner))
        {
            if (!creature_is_being_unconscious(thing) && !thing_is_dragged_or_pulled(thing)
             && !creature_is_kept_in_custody_by_enemy(thing) && !creature_is_dying(thing)
             && ((get_creature_model_flags(thing) & CMF_IsSpectator) == 0))
            {
                if (!is_neutral_thing(thing) && !players_are_mutual_allies(traptng->owner,thing->owner))
                {
                    *found_thing = thing;
                    return true;
                }
            }
        }
        // Per thing code end
        k++;
        if (k > THINGS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping things list");
            break;
        }
    }
    return false;
}
Example #8
0
TbBool update_trap_trigger_line_of_sight_90_on_subtile(struct Thing *traptng, MapSubtlCoord stl_x, MapSubtlCoord stl_y)
{
    struct Thing *thing;
    struct Map *mapblk;
    long i;
    unsigned long k;
    mapblk = get_map_block_at(stl_x,stl_y);
    k = 0;
    i = get_mapwho_thing_index(mapblk);
    while (i != 0)
    {
        thing = thing_get(i);
        TRACE_THING(thing);
        if (thing_is_invalid(thing))
        {
            ERRORLOG("Jump to invalid thing detected");
            break;
        }
        i = thing->next_on_mapblk;
        // Per thing code start
        if (thing_is_creature(thing) && (thing->owner != traptng->owner))
        {
            // Trigger for enemy player, or any player for neutral traps (otherwise neutral traps would be useless)
            if (players_are_enemies(traptng->owner,thing->owner) || is_neutral_thing(traptng))
            {
                if (!creature_is_being_unconscious(thing) && !thing_is_dragged_or_pulled(thing)
                 && !creature_is_kept_in_custody_by_enemy(thing) && !creature_is_dying(thing)
                 && ((get_creature_model_flags(thing) & CMF_IsSpectator) == 0)) {
                    activate_trap(traptng, thing);
                    return true;
                }
            }
        }
        // Per thing code end
        k++;
        if (k > THINGS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping things list");
            break;
        }
    }
    return false;
}
TbBool thing_is_valid_scavenge_target(const struct Thing *calltng, const struct Thing *scavtng)
{
    if (!thing_is_creature(scavtng) || (scavtng->model != calltng->model)) {
        return false;
    }
    if (!is_neutral_thing(scavtng))
    {
        if (!players_are_enemies(calltng->owner, scavtng->owner)) {
            return false;
        }
    }
    if (thing_is_picked_up(scavtng)) {
        return false;
    }
    if (is_thing_passenger_controlled(scavtng) || creature_is_kept_in_custody(scavtng)) {
        return false;
    }
    if (is_hero_thing(scavtng) && (!gameadd.scavenge_good_allowed)) {
        return false;
    }
    if (is_neutral_thing(scavtng) && (!gameadd.scavenge_neutral_allowed)) {
        return false;
    }
    struct PlayerInfo *scavplyr;
    scavplyr = INVALID_PLAYER;
    if (!is_neutral_thing(scavtng)) {
        scavplyr = get_player(scavtng->owner);
    }
    if (scavplyr->controlled_thing_idx != scavtng->index)
    {
        struct CreatureControl *cctrl;
        cctrl = creature_control_get_from_thing(scavtng);
        if (game.play_gameturn - cctrl->temple_cure_gameturn > game.temple_scavenge_protection_turns)
        {
            return true;
        }
    }
    return false;
}
Example #10
0
/**
 * Returns a creature manufacturing on a subtile other than given creature.
 * @param plyr_idx
 * @param stl_x
 * @param stl_y
 * @param othertng
 * @return
 */
struct Thing *get_other_creature_manufacturing_on_subtile(PlayerNumber plyr_idx, MapSubtlCoord stl_x, MapSubtlCoord stl_y, struct Thing *othertng)
{
    struct Thing *thing;
    long i;
    unsigned long k;
    struct Map *mapblk;
    mapblk = get_map_block_at(stl_x,stl_y);
    k = 0;
    i = get_mapwho_thing_index(mapblk);
    while (i != 0)
    {
        thing = thing_get(i);
        TRACE_THING(thing);
        if (thing_is_invalid(thing))
        {
            ERRORLOG("Jump to invalid thing detected");
            break;
        }
        i = thing->next_on_mapblk;
        // Per thing code start
        if (thing_is_creature(thing) && (thing->active_state == CrSt_Manufacturing) && (thing->index != othertng->index))
        {
            struct CreatureControl *cctrl;
            cctrl = creature_control_get_from_thing(thing);
            if ((cctrl->byte_9A > 1) && (thing->owner == plyr_idx)) {
                return thing;
            }
        }
        // Per thing code end
        k++;
        if (k > THINGS_COUNT)
        {
            ERRORLOG("Infinite loop detected when sweeping things list");
            break;
        }
    }
    return INVALID_THING;
}
TbBool process_scavenge_creature_from_level(struct Thing *scavtng, struct Thing *calltng, long work_value)
{
    struct Dungeon *calldngn;
    long num_prayers;
    calldngn = get_dungeon(calltng->owner);
    if (dungeon_invalid(calldngn)) {
        ERRORLOG("The %s owner %d can't do scavenging - has no dungeon",thing_model_name(calltng),(int)calltng->owner);
        return false;
    }
    // Compute amount of creatures praying against the scavenge
    if (!is_neutral_thing(scavtng)) {
        struct Dungeon *scavdngn;
        scavdngn = get_dungeon(scavtng->owner);
        num_prayers = scavdngn->creatures_praying[scavtng->model];
    } else {
        num_prayers = 0;
    }
    // Increase scavenging counter, used to break the prayers counter
    calldngn->creatures_scavenging[scavtng->model]++;
    // If scavenge is blocked by prayers, return
    if (calldngn->creatures_scavenging[calltng->model] < 2 * num_prayers) {
        SYNCDBG(8, "Player %d prayers (%d) are blocking player %d scavenging (%d) of %s", (int)scavtng->owner,
            (int)num_prayers, (int)calltng->owner, (int)calldngn->creatures_scavenging[calltng->model], thing_model_name(calltng));
        return false;
    }
    SYNCDBG(18,"The %s index %d scavenges %s index %d",thing_model_name(calltng),(int)calltng->index,thing_model_name(scavtng),(int)scavtng->index);
    // If we're starting to scavenge a new creature, do the switch
    if (calldngn->scavenge_targets[calltng->model] != scavtng->index)
    {
        calldngn->scavenge_turn_points[calltng->model] = work_value;
        if (calldngn->scavenge_targets[calltng->model] > 0)
        {
            // Stop scavenging old creature
            struct Thing *thing;
            thing = thing_get(calldngn->scavenge_targets[calltng->model]);
            if (thing_is_creature(thing) && (thing->model == calltng->model))
            {
                if (creature_is_being_scavenged(thing)) {
                    set_start_state(thing);
                }
            }
        }
        // Start the new scavenging
        calldngn->scavenge_targets[calltng->model] = scavtng->index;
        if (is_my_player_number(scavtng->owner)) {
            output_message(SMsg_CreatureScanvenged, 500, 1);
        }
        event_create_event(scavtng->mappos.x.val, scavtng->mappos.y.val, EvKind_CreatrScavenged, scavtng->owner, scavtng->index);
    } else
    {
        calldngn->scavenge_turn_points[calltng->model] += work_value;
    }
    // Make sure the scavenged creature is in correct state
    if (!creature_is_being_scavenged(scavtng))
    {
        if (!is_neutral_thing(scavtng)) {
            external_set_thing_state(scavtng, CrSt_CreatureBeingScavenged);
        }
    }
    long scavpts;
    scavpts = calculate_correct_creature_scavenge_required(scavtng, calltng->owner);
    if ((scavpts << 8) < calldngn->scavenge_turn_points[calltng->model])
    {
        SYNCDBG(8,"The %s index %d owner %d accumulated enough points to turn to scavenger",thing_model_name(scavtng),(int)scavtng->index,(int)scavtng->owner);
        turn_creature_to_scavenger(scavtng, calltng);
        calldngn->scavenge_turn_points[calltng->model] -= (scavpts << 8);
        return true;
    }
    return false;
}
Example #12
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;
}