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; }
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; }
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; } } } }