TbBool creature_move_to_using_teleport(struct Thing *thing, struct Coord3d *pos, long walk_speed) { struct CreatureControl *cctrl; short destination_valid; cctrl = creature_control_get_from_thing(thing); if (creature_instance_is_available(thing, CrInst_TELEPORT) && creature_instance_has_reset(thing, CrInst_TELEPORT) && (cctrl->instance_id == CrInst_NULL)) { // Creature can only be teleported to a revealed location destination_valid = true; if (!is_hero_thing(thing) && !is_neutral_thing(thing)) { destination_valid = subtile_revealed(pos->x.stl.num, pos->y.stl.num, thing->owner); } if (destination_valid) { // Use teleport only over large enough distances if (get_2d_box_distance(&thing->mappos, pos) > COORD_PER_STL*game.min_distance_for_teleport) { set_creature_instance(thing, CrInst_TELEPORT, 1, 0, pos); return true; } } } return false; }
short creature_freeze_prisonors(struct Thing *creatng) { struct CreatureControl *cctrl; cctrl = creature_control_get_from_thing(creatng); if (cctrl->instance_id != CrInst_NULL) { return 1; } if (!creature_instance_has_reset(creatng, CrInst_FREEZE)) { if (creature_choose_random_destination_on_valid_adjacent_slab(creatng)) { creatng->continue_state = CrSt_CreatureFreezePrisoners; } return 1; } struct Thing *victng; victng = find_prisoner_for_thing(creatng); if (thing_is_invalid(victng)) { set_start_state(creatng); return 0; } long dist; dist = get_combat_distance(creatng, victng); if (dist < 156) { creature_retreat_from_combat(creatng, victng, CrSt_CreatureFreezePrisoners, 0); } else if ((dist <= 2048) && (creature_can_see_combat_path(creatng, victng, dist) > AttckT_Unset)) { set_creature_instance(creatng, CrInst_FREEZE, 1, victng->index, 0); } else { creature_move_to(creatng, &victng->mappos, cctrl->max_speed, 0, 0); } return 1; }