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; }
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; }
long get_wanderer_possible_targets_count_in_list(long first_thing_idx, struct Thing *wanderer) { struct CreatureControl *cctrl; struct Thing *thing; long victims_count; unsigned long k; long i; victims_count = 0; // Get the amount of possible targets k = 0; i = first_thing_idx; while (i != 0) { thing = thing_get(i); TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { ERRORLOG("Jump to invalid creature detected"); break; } i = cctrl->players_next_creature_idx; // Thing list loop body if (!thing_is_picked_up(thing) && !creature_is_kept_in_custody_by_enemy(thing)) { // Don't check for being navigable - it's too CPU-expensive to check all creatures //if ( creature_can_navigate_to(wanderer, &thing->mappos, NavTF_Default) ) { victims_count++; } } // Thing list loop body ends k++; if (k > CREATURES_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); break; } } return victims_count; }
TbBool wander_to_specific_possible_target_in_list(long first_thing_idx, struct Thing *wanderer, long specific_target) { struct CreatureControl *cctrl; struct Thing *thing; long target_match; long matched_thing_idx; unsigned long k; long i; target_match = specific_target; // Find the target k = 0; i = first_thing_idx; matched_thing_idx = i; while (i != 0) { thing = thing_get(i); TRACE_THING(thing); cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { ERRORLOG("Jump to invalid creature detected"); break; } i = cctrl->players_next_creature_idx; // Thing list loop body if (!thing_is_picked_up(thing) && !creature_is_kept_in_custody_by_enemy(thing)) { // If it's not the one we want, continue sweeping if (target_match > 0) { target_match--; // Store the last unmatched thing, so we know where to stop when wrapped matched_thing_idx = thing->index; } else // If it is the one, try moving to it if (setup_person_move_to_coord(wanderer, &thing->mappos, NavRtF_Default)) { SYNCDBG(8,"The %s wanders towards %s",thing_model_name(wanderer),thing_model_name(thing)); return true; } // If we've got the right creature, but moving failed for some reason, try next one. } // Wrap to first thing if reached end of list. if (i == 0) { i = first_thing_idx; if (target_match != 0) WARNLOG("Wrapping to start of the list shouldn't occur before target_match reaches 0!"); } // When wrapped, process things only to the start index if (i == matched_thing_idx) break; // Thing list loop body ends k++; if (k > CREATURES_COUNT) { ERRORLOG("Infinite loop detected when sweeping creatures list"); break; } } return false; }