// Return 0 if object is in expected segment, else return 1 static int verify_object_seg(const vobjptridx_t objp, const vms_vector &newpos) { const auto &&result = get_seg_masks(newpos, vcsegptr(objp->segnum), objp->size); if (result.facemask == 0) return 0; else return move_object_within_mine(objp, newpos); }
void sort_seg_list(count_segment_array_t &segnumlist,const vms_vector &pos) { array<fix, MAX_SEGMENTS> dist; range_for (const auto &ss, segnumlist) dist[ss] = compute_dist(vcsegptr(ss), pos); auto predicate = [&dist](count_segment_array_t::const_reference a, count_segment_array_t::const_reference b) { return dist[a] < dist[b]; }; std::sort(segnumlist.begin(), segnumlist.end(), predicate); }
// ------------------------------------------------------------------------------------------------------ int ObjectSetDefault(void) { //update_due_to_new_segment(); if (Cur_object_index == object_none) { editor_status("No current object, cannot move."); return 1; } const auto &&objp = vobjptr(Cur_object_index); compute_segment_center(objp->pos, vcsegptr(objp->segnum)); Update_flags |= UF_WORLD_CHANGED; return 1; }
static void move_object_to_position(const vobjptridx_t objp, const vms_vector &newpos) { if (get_seg_masks(newpos, vcsegptr(objp->segnum), objp->size).facemask == 0) { objp->pos = newpos; } else { if (verify_object_seg(objp, newpos)) { int fate; object temp_viewer_obj; fvi_query fq; fvi_info hit_info; temp_viewer_obj = *Viewer; auto viewer_segnum = find_object_seg(vobjptr(Viewer)); temp_viewer_obj.segnum = viewer_segnum; // If the viewer is outside the mine, get him in the mine! if (viewer_segnum == segment_none) { editor_status("Unable to move object, viewer not in mine. Aborting"); return; #if 0 vms_vector last_outside_pos; // While outside mine, move towards object count = 0; while (viewer_segnum == segment_none) { vms_vector temp_vec; last_outside_pos = temp_viewer_obj.pos; vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, newpos); temp_viewer_obj.pos = temp_vec; viewer_segnum = find_object_seg(&temp_viewer_obj); temp_viewer_obj.segnum = viewer_segnum; if (count > 5) { editor_status("Unable to move object, can't get viewer in mine. Aborting"); return; } } count = 0; // While inside mine, move away from object. while (viewer_segnum != segment_none) { vms_vector temp_vec; vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, &last_outside_pos); temp_viewer_obj.pos = temp_vec; update_object_seg(&temp_viewer_obj); viewer_segnum = find_object_seg(&temp_viewer_obj); temp_viewer_obj.segnum = viewer_segnum; if (count > 5) { editor_status("Unable to move object, can't get viewer back out of mine. Aborting"); return; } } #endif } fq.p0 = &temp_viewer_obj.pos; fq.startseg = temp_viewer_obj.segnum; fq.p1 = &newpos; fq.rad = temp_viewer_obj.size; fq.thisobjnum = object_none; fq.ignore_obj_list.first = nullptr; fq.flags = 0; fate = find_vector_intersection(fq, hit_info); if (fate == HIT_WALL) { objp->pos = hit_info.hit_pnt; const auto &&segp = find_object_seg(objp); if (segp != segment_none) obj_relink(objp, segp); } else { editor_status("Attempted to move object out of mine. Object not moved."); } } } Update_flags |= UF_WORLD_CHANGED; }
static void reset_object(const vobjptridx_t obj) { med_extract_matrix_from_segment(vcsegptr(obj->segnum), &obj->orient); }