TbBool attempt_anger_job_destroy_rooms(struct Thing *creatng) { //return _DK_attempt_anger_job_destroy_rooms(creatng); if (!can_change_from_state_to(creatng, creatng->active_state, CrSt_CreatureVandaliseRooms)) { return false; } struct Room *room; struct Coord3d pos; room = find_nearest_room_for_thing_excluding_two_types(creatng, creatng->owner, 7, 1, 1); if (room_is_invalid(room)) { return false; } if (!find_random_valid_position_for_thing_in_room(creatng, room, &pos)) { return false; } if (!creature_can_navigate_to_with_storage(creatng, &pos, NavRtF_NoOwner)) { return false; } if (!external_set_thing_state(creatng, CrSt_CreatureVandaliseRooms)) { return false; } if (!setup_random_head_for_room(creatng, room, NavRtF_NoOwner)) { return false; } struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); creatng->continue_state = CrSt_CreatureVandaliseRooms; cctrl->target_room_id = room->index; return true; }
/** * Returns a hero gate object to which given hero can navigate. * @todo CREATURE_AI It returns first hero door found, not the best one. * Maybe it should find the one he will reach faster, or at least a random one? * @param herotng The hero to be able to make it to gate. * @return The gate thing, or invalid thing. */ struct Thing *find_hero_door_hero_can_navigate_to(struct Thing *herotng) { struct Thing *thing; unsigned long k; int i; k = 0; i = game.thing_lists[TngList_Objects].index; while (i != 0) { thing = thing_get(i); if (thing_is_invalid(thing)) { ERRORLOG("Jump to invalid thing detected"); break; } i = thing->next_of_class; // Per thing code if (object_is_hero_gate(thing)) { if (creature_can_navigate_to_with_storage(herotng, &thing->mappos, NavRtF_Default)) { return thing; } } // Per thing code ends k++; if (k > THINGS_COUNT) { ERRORLOG("Infinite loop detected when sweeping things list"); break; } } return NULL; }
TbBool setup_person_move_backwards_to_position_f(struct Thing *thing, MapSubtlCoord stl_x, MapSubtlCoord stl_y, NaviRouteFlags flags, const char *func_name) { struct CreatureControl *cctrl; struct Coord3d locpos; SYNCDBG(18,"%s: Moving %s index %d to (%d,%d)",func_name,thing_model_name(thing),(int)thing->index,(int)stl_x,(int)stl_y); cctrl = creature_control_get_from_thing(thing); locpos.x.val = subtile_coord_center(stl_x); locpos.y.val = subtile_coord_center(stl_y); locpos.z.val = 0; locpos.z.val = get_thing_height_at(thing, &locpos); if (thing_in_wall_at(thing, &locpos)) { SYNCDBG(16,"%s: The %s would be trapped in wall at (%d,%d)",func_name,thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } if (!creature_can_navigate_to_with_storage(thing, &locpos, flags)) { SYNCDBG(19,"%s: The %s cannot reach subtile (%d,%d)",func_name,thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } cctrl->move_flags = flags; internal_set_thing_state(thing, CrSt_MoveBackwardsToPosition); cctrl->moveto_pos.x.val = locpos.x.val; cctrl->moveto_pos.y.val = locpos.y.val; cctrl->moveto_pos.z.val = locpos.z.val; return true; }
TbBool setup_person_move_close_to_position(struct Thing *thing, MapSubtlCoord stl_x, MapSubtlCoord stl_y, NaviRouteFlags flags) { struct CreatureControl *cctrl; struct Coord3d trgpos; struct Coord3d navpos; SYNCDBG(18,"Moving %s index %d to (%d,%d)",thing_model_name(thing),(int)thing->index,(int)stl_x,(int)stl_y); trgpos.x.val = subtile_coord_center(stl_x); trgpos.y.val = subtile_coord_center(stl_y); trgpos.z.val = thing->mappos.z.val; cctrl = creature_control_get_from_thing(thing); if (creature_control_invalid(cctrl)) { WARNLOG("Tried to move invalid creature to (%d,%d)",(int)stl_x,(int)stl_y); return false; } get_nearest_navigable_point_for_thing(thing, &trgpos, &navpos, flags); if (!creature_can_navigate_to_with_storage(thing, &navpos, flags)) { SYNCDBG(19,"The %s cannot reach subtile (%d,%d)",thing_model_name(thing),(int)stl_x,(int)stl_y); return false; } cctrl->move_flags = flags; internal_set_thing_state(thing, CrSt_MoveToPosition); cctrl->moveto_pos.x.val = navpos.x.val; cctrl->moveto_pos.y.val = navpos.y.val; cctrl->moveto_pos.z.val = navpos.z.val; return true; }
TbBool good_setup_attack_rooms(struct Thing *creatng, long dngn_id) { struct Room *room; struct CreatureControl *cctrl; struct Coord3d pos; room = find_nearest_room_for_thing_excluding_two_types(creatng, dngn_id, 7, 1, 1); if (room_is_invalid(room)) { return false; } if (!find_random_valid_position_for_thing_in_room(creatng, room, &pos) || !creature_can_navigate_to_with_storage(creatng, &pos, NavRtF_NoOwner) ) { ERRORLOG("The %s cannot destroy %s because it can't reach position within it",thing_model_name(creatng),room_code_name(room->kind)); return false; } if (!setup_random_head_for_room(creatng, room, NavRtF_NoOwner)) { ERRORLOG("The %s cannot destroy %s because it can't head for it",thing_model_name(creatng),room_code_name(room->kind)); return false; } cctrl = creature_control_get_from_thing(creatng); creatng->continue_state = CrSt_GoodArrivedAtAttackRoom; cctrl->target_room_id = room->index; return true; }
TbBool attempt_anger_job_steal_gold(struct Thing *creatng) { //return _DK_attempt_anger_job_steal_gold(creatng); if (!can_change_from_state_to(creatng, creatng->active_state, CrSt_CreatureStealGold)) { return false; } struct CreatureStats *crstat; crstat = creature_stats_get_from_thing(creatng); if (creatng->creature.gold_carried >= crstat->gold_hold) { return false; } struct Room *room; struct Coord3d pos; room = find_nearest_room_for_thing_with_used_capacity(creatng, creatng->owner, RoK_TREASURE, NavRtF_NoOwner, 1); if (room_is_invalid(room)) { return false; } if (!find_random_valid_position_for_thing_in_room(creatng, room, &pos)) { return false; } if (!creature_can_navigate_to_with_storage(creatng, &pos, NavRtF_NoOwner)) { return false; } if (!external_set_thing_state(creatng, CrSt_CreatureStealGold)) { return false; } if (!setup_random_head_for_room(creatng, room, NavRtF_NoOwner)) { ERRORLOG("Cannot setup head for treasury."); return false; } struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); creatng->continue_state = CrSt_CreatureSearchForGoldToStealInRoom1; cctrl->target_room_id = room->index; return true; }
/** * Returns a hero gate object to which given hero can navigate. * @todo CREATURE_AI It returns first hero door found, not the best one. * Maybe it should find the one he will reach faster, or at least a random one? * @param herotng The hero to be able to make it to gate. * @return The gate thing, or invalid thing. */ struct Thing *find_hero_door_hero_can_navigate_to(struct Thing *herotng) { struct Thing *thing; unsigned long k; int i; k = 0; const struct StructureList *slist; slist = get_list_for_thing_class(TCls_Object); i = slist->index; while (i != 0) { thing = thing_get(i); if (thing_is_invalid(thing)) { ERRORLOG("Jump to invalid thing detected"); break; } i = thing->next_of_class; // Per thing code if (object_is_hero_gate(thing)) { if (creature_can_navigate_to_with_storage(herotng, &thing->mappos, NavRtF_Default)) { return thing; } } // Per thing code ends k++; if (k > slist->count) { ERRORLOG("Infinite loop detected when sweeping things list"); erstat_inc(ESE_InfChainTngPerClass); break; } } return NULL; }