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;
}
Exemple #2
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;
}
Exemple #3
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;
}
void god_lightning_choose_next_creature(struct Thing *shotng)
{
    SYNCDBG(16,"Starting for %s index %d owner %d",thing_model_name(shotng),(int)shotng->index,(int)shotng->owner);
    //_DK_god_lightning_choose_next_creature(shotng); return;
    long best_dist;
    struct Thing *best_thing;
    best_dist = LONG_MAX;
    best_thing = INVALID_THING;

    unsigned long k;
    int i;
    const struct StructureList *slist;
    slist = get_list_for_thing_class(TCls_Creature);
    k = 0;
    i = slist->index;
    while (i != 0)
    {
        struct Thing *thing;
        thing = thing_get(i);
        if (thing_is_invalid(thing))
        {
            ERRORLOG("Jump to invalid thing detected");
            break;
        }
        i = thing->next_of_class;
        // Per-thing code
        //TODO use hit_type instead of hard coded conditions
        if ((shotng->owner != thing->owner) && !thing_is_picked_up(thing)
            && !creature_is_being_unconscious(thing) && !creature_is_dying(thing))
        {
            long dist;
            dist = get_2d_distance(&shotng->mappos, &thing->mappos);
            if (dist < best_dist)
            {
                const struct MagicStats *pwrdynst;
                pwrdynst = get_power_dynamic_stats(PwrK_LIGHTNING);
                int spell_lev;
                spell_lev = shotng->shot.byte_19;
                if (spell_lev > SPELL_MAX_LEVEL)
                    spell_lev = SPELL_MAX_LEVEL;
                if (subtile_coord(pwrdynst->strength[spell_lev],0) > dist)
                {
                    if (line_of_sight_2d(&shotng->mappos, &thing->mappos)) {
                        best_dist = dist;
                        best_thing = thing;
                    }
                }
            }
        }
        // Per-thing code ends
        k++;
        if (k > slist->count)
        {
            ERRORLOG("Infinite loop detected when sweeping things list");
            erstat_inc(ESE_InfChainTngPerClass);
            break;
        }
    }
    SYNCDBG(8,"The best target for %s index %d owner %d is %s index %d owner %d",
        thing_model_name(shotng),(int)shotng->index,(int)shotng->owner,
        thing_model_name(best_thing),(int)best_thing->index,(int)best_thing->owner);
    if (!thing_is_invalid(best_thing)) {
        shotng->shot.target_idx = best_thing->index;
    } else {
        shotng->shot.target_idx = 0;
    }
}
void update_creature_graphic_anim(struct Thing *thing)
{
    struct CreatureControl *cctrl;
    struct CreatureStats *crstat;
    long i;

    TRACE_THING(thing);
    cctrl = creature_control_get_from_thing(thing);
    crstat = creature_stats_get_from_thing(thing);

    if ((thing->field_50 & 0x01) != 0)
    {
      thing->field_50 &= ~0x01;
    } else
    if ((thing->active_state == CrSt_CreatureHeroEntering) && (cctrl->countdown_282 >= 0))
    {
      thing->field_4F |= TF4F_Unknown01;
    } else
    if (!creature_affected_by_spell(thing, SplK_Chicken))
    {
        if (cctrl->instance_id != CrInst_NULL)
        {
          if (cctrl->instance_id == CrInst_TORTURED)
          {
              thing->field_4F &= ~(TF4F_Unknown20|TF4F_Unknown10);
          }
          struct InstanceInfo *inst_inf;
          inst_inf = creature_instance_info_get(cctrl->instance_id);
          update_creature_anim(thing, cctrl->instance_anim_step_turns, inst_inf->graphics_idx);
        } else
        if ((cctrl->field_B1 != 0) || creature_is_dying(thing) || creature_affected_by_spell(thing, SplK_Freeze))
        {
            update_creature_anim(thing, 256, 8);
        } else
        if ((cctrl->stateblock_flags & CCSpl_ChickenRel) != 0)
        {
            update_creature_anim(thing, 256, 0);
        } else
        if (thing->active_state == CrSt_CreatureSlapCowers)
        {
            update_creature_anim(thing, 256, 10);
        } else
        if ((thing->active_state == CrSt_CreaturePiss) || (thing->active_state == CrSt_CreatureRoar))
        {
            update_creature_anim(thing, 128, 4);
        } else
        if (thing->active_state == CrSt_CreatureUnconscious)
        {
            update_creature_anim(thing, 64, 16);
            thing->field_4F |= TF4F_Unknown40;
        } else
        if (thing->active_state == CrSt_CreatureSleep)
        {
            thing->field_4F &= ~(TF4F_Unknown20|TF4F_Unknown10);
            update_creature_anim(thing, 128, 12);
        } else
        if (cctrl->field_9 == 0)
        {
            update_creature_anim(thing, 256, 0);
        } else
        if (thing->field_60 < thing->mappos.z.val)
        {
            update_creature_anim(thing, 256, 0);
        } else
        if ((cctrl->dragtng_idx != 0) && (thing_get(cctrl->dragtng_idx)->state_flags & TF1_IsDragged1))
        {
            i = (((long)cctrl->field_9) << 8) / (crstat->walking_anim_speed+1);
            update_creature_anim(thing, i, 2);
        } else
        if (creatures[thing->model].field_6 == 4)
        {
            update_creature_anim(thing, 256, 1);
        } else
        {
            i = (((long)cctrl->field_9) << 8) / (crstat->walking_anim_speed+1);
            if (!update_creature_anim(thing, i, 1))
            {
                thing->field_3E = i;
            }
        }
    } else
    {
        thing->field_4F &= ~0x30;
        if (cctrl->field_9 == 0)
        {
            update_creature_anim_td(thing, 256, 820);
        } else
        if (thing->field_60 < thing->mappos.z.val)
        {
            update_creature_anim_td(thing, 256, 820);
        } else
        if (creatures[thing->model].field_6 == 4)
        {
            update_creature_anim_td(thing, 256, 819);
        } else
        {
            i = (((long)cctrl->field_9) << 8) / (crstat->walking_anim_speed+1);
            if (!update_creature_anim_td(thing, i, 819))
            {
                thing->field_3E = i;
            }
        }
    }
}