/* * Created by Ian "Goober5000" Warfield for the FreeSpace2 Source Code Project. * You may not sell or otherwise commercially exploit the source or things you * create based on the source. */ #include "object/deadobjectdock.h" #include "object/object.h" // management prototypes void dead_dock_add_instance(object *objp, int dockpoint, object *other_objp); void dead_dock_remove_instance(object *objp, object *other_objp); dock_instance *dead_dock_find_instance(object *objp, object *other_objp); dock_instance *dead_dock_find_instance(object *objp, int dockpoint); object *dock_get_first_dead_docked_object(object *objp) { Assert(objp != NULL); // are we docked? if (!object_is_dead_docked(objp)) return NULL; return objp->dead_dock_list->docked_objp; } int dock_find_dead_dockpoint_used_by_object(object *objp, object *other_objp) { Assert(objp != NULL); Assert(other_objp != NULL); dock_instance *result = dead_dock_find_instance(objp, other_objp); if (result == NULL) return -1; else return result->dockpoint_used; } // dock management functions ------------------------------------------------------------------------------------- void dock_dead_dock_objects(object *objp1, int dockpoint1, object *objp2, int dockpoint2) { Assert(objp1 != NULL); Assert(objp2 != NULL); #ifndef NDEBUG if ((dead_dock_find_instance(objp1, objp2) != NULL) || (dead_dock_find_instance(objp2, objp1) != NULL)) { Error(LOCATION, "Trying to dock an object that's already docked!\n"); } if ((dead_dock_find_instance(objp1, dockpoint1) != NULL) || (dead_dock_find_instance(objp2, dockpoint2) != NULL)) { Error(LOCATION, "Trying to dock to a dockpoint that's in use!\n"); } #endif // put objects on each others' dock lists dead_dock_add_instance(objp1, dockpoint1, objp2); dead_dock_add_instance(objp2, dockpoint2, objp1); } void dock_dead_undock_objects(object *objp1, object *objp2) { Assert(objp1 != NULL); Assert(objp2 != NULL); // remove objects from each others' dock lists dead_dock_remove_instance(objp1, objp2); dead_dock_remove_instance(objp2, objp1); } void dock_dead_undock_all(object *objp) { Assert(objp != NULL); while (object_is_dead_docked(objp)) { object* dockee = dock_get_first_dead_docked_object(objp); dock_dead_undock_objects(objp, dockee); } } void dead_dock_add_instance(object *objp, int dockpoint, object *other_objp) { dock_instance *item; // create item item = (dock_instance *) vm_malloc(sizeof(dock_instance)); item->dockpoint_used = dockpoint; item->docked_objp = other_objp; // prepend item to existing list item->next = objp->dead_dock_list; objp->dead_dock_list = item; } void dead_dock_remove_instance(object *objp, object *other_objp) { int found = 0; dock_instance *prev_ptr, *ptr; prev_ptr = NULL; ptr = objp->dead_dock_list; // iterate until item found while (ptr != NULL) { // if found, exit loop if (ptr->docked_objp == other_objp) { found = 1; break; } // iterate prev_ptr = ptr; ptr = ptr->next; } // delete if found if (found) { // special case... found at beginning of list if (prev_ptr == NULL) { objp->dead_dock_list = ptr->next; } // normal case else { prev_ptr->next = ptr->next; } // delete it vm_free(ptr); } else { // Trigger assertion. We can recover from this, thankfully Assertion(false, "Tried to undock an object that isn't dead docked!\n"); } } // just free the list without worrying about undocking anything void dock_free_dead_dock_list(object *objp) { Assert(objp != NULL); while (objp->dead_dock_list != NULL) { dock_instance *ptr = objp->dead_dock_list; objp->dead_dock_list = ptr->next; vm_free(ptr); } } dock_instance *dead_dock_find_instance(object *objp, object *other_objp) { dock_instance *ptr = objp->dead_dock_list; // iterate until item found while (ptr != NULL) { // if found, return it if (ptr->docked_objp == other_objp) return ptr; // iterate ptr = ptr->next; } // not found return NULL; } dock_instance *dead_dock_find_instance(object *objp, int dockpoint) { dock_instance *ptr = objp->dead_dock_list; // iterate until item found while (ptr != NULL) { // if found, return it if (ptr->dockpoint_used == dockpoint) return ptr; // iterate ptr = ptr->next; } // not found return NULL; }