| 764 | } |
| 765 | |
| 766 | bool Units::teleport(df::unit *unit, df::coord target_pos) |
| 767 | { // Make sure source and dest map blocks are valid |
| 768 | auto old_occ = Maps::getTileOccupancy(unit->pos); |
| 769 | auto new_occ = Maps::getTileOccupancy(target_pos); |
| 770 | if (!old_occ || !new_occ) |
| 771 | return false; |
| 772 | |
| 773 | // Clear appropriate occupancy flags at old tile |
| 774 | if (unit->flags1.bits.on_ground) |
| 775 | // This is potentially wrong, but the game will recompute this as needed |
| 776 | old_occ->bits.unit_grounded = false; |
| 777 | else |
| 778 | old_occ->bits.unit = false; |
| 779 | |
| 780 | // Clear unit projectile info |
| 781 | if (unit->flags1.bits.projectile) { |
| 782 | unit->flags1.bits.projectile = false; |
| 783 | linked_list_remove(&world->projectiles.all, [&](df::projectile *proj) { |
| 784 | if (proj->getType() != df::enums::projectile_type::Unit) |
| 785 | return false; |
| 786 | if (auto unit_proj = virtual_cast<df::proj_unitst>(proj)) |
| 787 | return unit_proj->unit == unit; |
| 788 | return false; |
| 789 | }); |
| 790 | } |
| 791 | |
| 792 | // If there's already somebody standing at the destination, then force the unit to lay down |
| 793 | if (new_occ->bits.unit) |
| 794 | unit->flags1.bits.on_ground = true; |
| 795 | |
| 796 | // Set appropriate occupancy flags at new tile |
| 797 | if (unit->flags1.bits.on_ground) |
| 798 | new_occ->bits.unit_grounded = true; |
| 799 | else |
| 800 | new_occ->bits.unit = true; |
| 801 | |
| 802 | // Move unit to destination |
| 803 | unit->pos = target_pos; |
| 804 | unit->idle_area = target_pos; |
| 805 | |
| 806 | // Move unit's riders (including babies) to destination |
| 807 | if (unit->flags1.bits.ridden) |
| 808 | for (auto rider : world->units.other[units_other_id::ANY_RIDER]) |
| 809 | if (rider->relationship_ids[unit_relationship_type::RiderMount] == unit->id) |
| 810 | rider->pos = unit->pos; |
| 811 | return true; |
| 812 | } |
| 813 | |
| 814 | df::general_ref *Units::getGeneralRef(df::unit *unit, df::general_ref_type type) { |
| 815 | CHECK_NULL_POINTER(unit); |
nothing calls this directly
no test coverage detected