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; }
struct Thing *get_workshop_box_thing(PlayerNumber owner, ThingModel objmodel) { struct Thing *thing; int i,k; k = 0; i = game.thing_lists[TngList_Objects].index; while (i > 0) { thing = thing_get(i); if (thing_is_invalid(thing)) break; i = thing->next_of_class; // Per-thing code if ( ((thing->alloc_flags & TAlF_Exists) != 0) && (thing->model == objmodel) && (thing->owner == owner) ) { struct Room *room; room = get_room_thing_is_on(thing); if (!thing_is_picked_up(thing) && room_role_matches(room->kind, RoRoF_CratesStorage) && (room->owner == owner)) return thing; } // Per-thing code ends k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } return INVALID_THING; }
TbBool creature_free_for_anger_job(struct Thing *creatng) { struct CreatureControl *cctrl; struct Dungeon *dungeon; cctrl = creature_control_get_from_thing(creatng); dungeon = get_dungeon(creatng->owner); return ((cctrl->spell_flags & CSAfF_Unkn0800) == 0) && (dungeon->must_obey_turn == 0) && ((cctrl->spell_flags & CSAfF_Chicken) == 0) && !thing_is_picked_up(creatng) && !is_thing_passenger_controlled(creatng); }
void creature_stop_affected_by_call_to_arms(struct Thing *thing) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(thing); cctrl->spell_flags &= ~CSAfF_CalledToArms; if (!thing_is_picked_up(thing) && !creature_is_being_unconscious(thing)) { if (creature_is_called_to_arms(thing)) { set_start_state(thing); } } }
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 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; }
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; } }
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; }