/* Universe Object Management Utilities Functions: int UNVAllocScores(xsw_object_struct *obj_ptr) int UNVAllocObjectWeapons( xsw_object_struct *obj_ptr, int total_weapons ) int UNVAllocEco(xsw_object_struct *obj_ptr) char *UNVGetObjectFormalName( xsw_object_struct *obj_ptr, int obj_num ) xsw_object_struct *UNVDupObject(xsw_object_struct *obj_ptr) void UNVResetObject(xsw_object_struct *obj_ptr) void UNVDeleteObject(xsw_object_struct *obj_ptr) void UNVDeleteAllObjects(xsw_object_struct **obj_ptr, int total) --- */ #include #include #include #include #include #include #include "../include/string.h" #include "../include/reality.h" #include "../include/objects.h" #include "../include/unvmain.h" #include "../include/unvutil.h" #include "../include/unvmatch.h" #include "../include/unvfile.h" /* * Allocates a score structure as needed on object. */ int UNVAllocScores(xsw_object_struct *obj_ptr) { if(obj_ptr == NULL) return(-1); if(obj_ptr->score == NULL) { obj_ptr->score = (xsw_score_struct *)calloc( 1, sizeof(xsw_score_struct) ); if(obj_ptr->score == NULL) { return(-1); } } return(0); } /* * Allocates or deallocates weapons on object as needed. */ int UNVAllocObjectWeapons(xsw_object_struct *obj_ptr, int total_weapons) { int i, prev; xsw_weapons_struct **ptr; if(obj_ptr == NULL) return(-1); /* Deallocate all weapons? */ if(total_weapons <= 0) { /* Deallocate all weapons on object. */ for(i = 0, ptr = obj_ptr->weapons; i < obj_ptr->total_weapons; i++, ptr++ ) free(*ptr); free(obj_ptr->weapons); obj_ptr->weapons = NULL; obj_ptr->total_weapons = 0; obj_ptr->selected_weapon = -1; } else { /* Total weapons is 1 or greater. */ /* Sanitize total. */ if(total_weapons > MAX_WEAPONS) total_weapons = MAX_WEAPONS; /* Sanitize total on object. */ if(obj_ptr->total_weapons < 0) obj_ptr->total_weapons = 0; /* Record previous total on object. */ prev = obj_ptr->total_weapons; /* Deallocate weapons? */ if(total_weapons < prev) { /* Deallocate weapons on object. */ for(i = total_weapons; i < prev; i++) { /* Unselect weapon if it will be deleted. */ if(obj_ptr->selected_weapon == i) obj_ptr->selected_weapon = -1; free(obj_ptr->weapons[i]); obj_ptr->weapons[i] = NULL; } obj_ptr->weapons = (xsw_weapons_struct **)realloc( obj_ptr->weapons, total_weapons * sizeof(xsw_weapons_struct *) ); if(obj_ptr->weapons == NULL) { obj_ptr->total_weapons = 0; obj_ptr->selected_weapon = -1; return(-1); } /* Set new total on object. */ obj_ptr->total_weapons = total_weapons; } /* Allocate more weapons? */ else if(total_weapons > prev) { /* Allocate more weapons on object. */ obj_ptr->weapons = (xsw_weapons_struct **)realloc( obj_ptr->weapons, total_weapons * sizeof(xsw_weapons_struct *) ); if(obj_ptr->weapons == NULL) { obj_ptr->total_weapons = 0; obj_ptr->selected_weapon = -1; return(-1); } for(i = prev; i < total_weapons; i++) { obj_ptr->weapons[i] = (xsw_weapons_struct *)calloc( 1, sizeof(xsw_weapons_struct) ); if(obj_ptr->weapons[i] == NULL) { obj_ptr->total_weapons = 0; obj_ptr->selected_weapon = -1; return(-1); } } /* Set new total on object. */ obj_ptr->total_weapons = total_weapons; } } /* Sanitize selected weapon. */ if(obj_ptr->selected_weapon >= obj_ptr->total_weapons) obj_ptr->selected_weapon = obj_ptr->total_weapons - 1; if(obj_ptr->selected_weapon < 0) obj_ptr->selected_weapon = -1; return(0); } /* * Allocates an economy structure as needed. */ int UNVAllocEco(xsw_object_struct *obj_ptr) { if(obj_ptr == NULL) return(-1); if(obj_ptr->eco == NULL) { obj_ptr->eco = (xsw_ecodata_struct *)calloc( 1, sizeof(xsw_ecodata_struct) ); if(obj_ptr->eco == NULL) { return(-1); } } return(0); } /* * Returns a statically allocated string containing the object's * formal name. */ char *UNVGetObjectFormalName(xsw_object_struct *obj_ptr, int obj_num) { char *strptr; static char name[XSW_OBJ_NAME_MAX + 80]; if(obj_ptr == NULL) return(XSW_OBJ_GARBAGE_NAME); if(obj_ptr->type <= XSW_OBJ_TYPE_GARBAGE) return(XSW_OBJ_GARBAGE_NAME); if(obj_num < 0) { /* Object index number is invalid, implies garbage. */ strncpy(name, XSW_OBJ_GARBAGE_NAME, XSW_OBJ_NAME_MAX); name[XSW_OBJ_NAME_MAX - 1] = '\0'; return(name); } else if(obj_ptr->type <= XSW_OBJ_TYPE_GARBAGE) { /* Object type is garbage. */ strncpy(name, XSW_OBJ_GARBAGE_NAME, XSW_OBJ_NAME_MAX); name[XSW_OBJ_NAME_MAX - 1] = '\0'; return(name); } sprintf( name, "%s(#%i", obj_ptr->name, obj_num ); strptr = name; while(*strptr != '\0') strptr++; /* Type. */ switch(obj_ptr->type) { case XSW_OBJ_TYPE_DYNAMIC: *strptr++ = 'D'; break; case XSW_OBJ_TYPE_CONTROLLED: *strptr++ = 'C'; break; case XSW_OBJ_TYPE_PLAYER: *strptr++ = 'P'; break; case XSW_OBJ_TYPE_WEAPON: *strptr++ = 'W'; break; case XSW_OBJ_TYPE_STREAMWEAPON: *strptr++ = 'W'; break; case XSW_OBJ_TYPE_SPHEREWEAPON: *strptr++ = 'W'; break; case XSW_OBJ_TYPE_HOME: *strptr++ = 'H'; break; case XSW_OBJ_TYPE_AREA: *strptr++ = 'A'; break; case XSW_OBJ_TYPE_ANIMATED: *strptr++ = 'V'; break; default: *strptr++ = '-'; break; } if(obj_ptr->eco != NULL) *strptr++ = 'E'; *strptr++ = ')'; /* Null terminate. */ *strptr = '\0'; return(name); } /* * Dynamically allocates a new object in memory that contains * the exact same values (except for pointers to substructures) as * obj_ptr. Can return NULL on error. * * Calling function must use UNVDeleteObject() to deallocate * this object structure and its substructures. */ xsw_object_struct *UNVDupObject(xsw_object_struct *obj_ptr) { int i; xsw_object_struct *new_obj_ptr = NULL; if(obj_ptr == NULL) return(new_obj_ptr); /* Allocate new object structure. */ new_obj_ptr = (xsw_object_struct *)calloc( 1, sizeof(xsw_object_struct) ); if(new_obj_ptr == NULL) return(new_obj_ptr); /* Copy over core values. */ memcpy( new_obj_ptr, obj_ptr, sizeof(xsw_object_struct) ); /* Copy over substructures. */ /* Weapons. */ if(obj_ptr->weapons != NULL) { /* Copy over each weapon. */ new_obj_ptr->weapons = (xsw_weapons_struct **)calloc( 1, new_obj_ptr->total_weapons * sizeof(xsw_weapons_struct *) ); if(new_obj_ptr->weapons == NULL) { new_obj_ptr->total_weapons = 0; } for(i = 0; i < new_obj_ptr->total_weapons; i++) { if(obj_ptr->weapons[i] == NULL) continue; new_obj_ptr->weapons[i] = (xsw_weapons_struct *)calloc( 1, sizeof(xsw_weapons_struct) ); if(new_obj_ptr->weapons[i] == NULL) continue; memcpy( new_obj_ptr->weapons[i], obj_ptr->weapons[i], sizeof(xsw_weapons_struct) ); } } /* Score. */ if(obj_ptr->score != NULL) { new_obj_ptr->score = (xsw_score_struct *)malloc( sizeof(xsw_score_struct) ); if(new_obj_ptr->score != NULL) { memcpy( new_obj_ptr->score, obj_ptr->score, sizeof(xsw_score_struct) ); } } /* Economy. */ if(obj_ptr->eco != NULL) { new_obj_ptr->eco = (xsw_ecodata_struct *)malloc( sizeof(xsw_ecodata_struct) ); if(new_obj_ptr->eco != NULL) { memcpy( new_obj_ptr->eco, obj_ptr->eco, sizeof(xsw_ecodata_struct) ); } /* Copy over each eco product. */ if(obj_ptr->eco->product != NULL) { new_obj_ptr->eco->product = (xsw_ecoproduct_struct **)calloc( 1, new_obj_ptr->eco->total_products * sizeof(xsw_ecoproduct_struct *) ); if(new_obj_ptr->eco->product == NULL) { new_obj_ptr->eco->total_products = 0; } for(i = 0; i < new_obj_ptr->eco->total_products; i++) { if(obj_ptr->eco->product[i] == NULL) continue; new_obj_ptr->eco->product[i] = (xsw_ecoproduct_struct *)calloc( 1, sizeof(xsw_ecoproduct_struct) ); if(new_obj_ptr->eco->product[i] == NULL) continue; memcpy( new_obj_ptr->eco->product[i], obj_ptr->eco->product[i], sizeof(xsw_ecoproduct_struct) ); } } } return(new_obj_ptr); } /* * Resets values and deallocates all substructures on * object. */ void UNVResetObject(xsw_object_struct *obj_ptr) { int i; if(obj_ptr == NULL) return; /* Deallocate weapons. */ for(i = 0; i < obj_ptr->total_weapons; i++) { if(obj_ptr->weapons[i] == NULL) continue; free(obj_ptr->weapons[i]); } free(obj_ptr->weapons); obj_ptr->weapons = NULL; obj_ptr->total_weapons = 0; obj_ptr->selected_weapon = -1; /* Deallocate tractored objects. */ free(obj_ptr->tractored_object); obj_ptr->tractored_object = NULL; obj_ptr->total_tractored_objects = 0; /* Deallocate score structure. */ free(obj_ptr->score); obj_ptr->score = NULL; /* Deallocate economy structure. */ if(obj_ptr->eco != NULL) { for(i = 0; i < obj_ptr->eco->total_products; i++) { free(obj_ptr->eco->product[i]); obj_ptr->eco->product[i] = NULL; } free(obj_ptr->eco->product); obj_ptr->eco->product = NULL; } free(obj_ptr->eco); obj_ptr->eco = NULL; /* Reset values to that of the unv_garbage_object. */ memcpy( obj_ptr, /* Destination. */ &unv_garbage_object, /* Source. */ sizeof(xsw_object_struct) ); return; } /* * Deallocates object and all its substructures. */ void UNVDeleteObject(xsw_object_struct *obj_ptr) { if(obj_ptr == NULL) return; /* Free object's allocated resources and substructures. */ UNVResetObject(obj_ptr); /* Free object base structure. */ free(obj_ptr); return; } /* * Deletes an array of objects and their substructures, * including the array itself. */ void UNVDeleteAllObjects(xsw_object_struct **obj_ptr, int total) { int i; xsw_object_struct **ptr; /* Deallocate each object. */ for(i = 0, ptr = obj_ptr; i < total; i++, ptr++ ) UNVDeleteObject(*ptr); /* Deallocate object pointer array. */ free(obj_ptr); return; }