/* * $Logfile: /DescentIII/Main/manage/generic.cpp $ * $Revision: 100 $ * $Date: 9/06/01 10:32a $ * $Author: Matt $ * * * $Log: /DescentIII/Main/manage/generic.cpp $ * * 100 9/06/01 10:32a Matt * Added code to fix problem poping add-on pages when the original pages * were in the extra.gam file. * * 99 4/19/00 5:27p Matt * From Duane for 1.4 * Mac file extension change * * 98 10/26/99 3:30p Jeff * handle extra.gam addon tablefile * * 97 10/22/99 10:41p Jeff * correctly merged and handle this mac code merge stuff * * 96 10/22/99 6:04p Jeff * fixed bugs and compiler errors resulting from mac code merge * * 95 10/22/99 2:56p Kevin * Mac merge w/memory savings * * 94 9/18/99 8:49p Jeff * fixed bug with addon pages that have dependencies on other pages in the * addon tablefile * * 93 8/11/99 5:32p Jeff * changes to fix addon tablefile support so it works correctly * * 92 4/25/99 10:19p Matt * Fixed multiplayer and demo problems will killing an object from script, * and cleaned up the death code a bit in the process. * * 91 4/22/99 7:08p Matt * Reduced the number of object sounds from 3 to 2, since we were only * using two. * * 90 4/19/99 3:57p Matt * Took out guidebot velocity hack. * * 89 4/18/99 4:49p Matt * Took out code that hacked in ammo amounts for weapon powerups, and * added code to set the counts on the page and read and write to the * table file. * * 88 4/15/99 5:21p Jason * sped up table file loading * * 87 4/14/99 1:33a Jeff * fixed case mismatched #includes * * 86 4/10/99 5:56p Matt * Cleaned up object initialization code, including create object & load * object. * * 85 4/06/99 6:02p Matt * Added score system * * 84 3/29/99 11:20a Matt * Added more flexibility to death delays, and added fade away deaths. * * 83 3/27/99 2:15p Jason * took out bashing of hangturret * * 82 3/09/99 1:44p Kevin * Bashed the aiming point value for the hangturret. * * 81 3/04/99 4:47p Jason * temp fix (ie BAD HACK) for OEM table file woes * * 80 2/28/99 6:20p Matt * Added the ability to set death types for generic objects. * * 79 2/23/99 12:39p Jason * added more options for generic objects * * 78 2/23/99 11:02a Matt * Changed generic object spew info to use -1 for none * * 77 2/23/99 10:19a Matt * Temporary fix * * 76 2/16/99 12:38a Matt * Took out gunboy sound hack * * 75 2/02/99 8:44a Chris * I made buildings with AI work correctly (ie really big robots should be * buildings) * anim to and from states are now shorts instead of bytes * * 74 1/21/99 11:16p Jeff * pulled out some structs and defines from header files and moved them * into seperate header files so that multiplayer dlls don't require major * game headers, just those new headers. Side effect is a shorter build * time. Also cleaned up some header file #includes that weren't needed. * This affected polymodel.h, object.h, player.h, vecmat.h, room.h, * manage.h and multi.h * * 73 1/13/99 7:04a Jeff * put #ifdef around #include * * 72 12/30/98 5:17p Jeff * changes made to handle script name override, to override the name of * the script to use in a module. * * 71 12/29/98 4:30p Jason * added add-on data functionality * * 70 12/17/98 7:26p Jeff * new script system data * * 69 12/01/98 4:31p Chris * * 68 12/01/98 4:31p Chris * Checked in a massive amount of AI work. Improved flocking code. :) * (Still hacked lightly). In addition, I am moving toward using the * composite dir. :) * * 67 11/19/98 8:36p Chris * Tweaked * * 66 11/19/98 8:26p Chris * Starting to add generic team avoidance code * * 65 11/13/98 12:30p Jason * changes for weapons * * 64 11/06/98 12:35p Jason * more speedups for manage system * * 63 11/05/98 7:54p Jason * changes for new manage system * * 62 11/02/98 6:02p Jason * made yes network updates much faster * * 61 10/23/98 6:43p Matt * Kill the gunboy's sounds (for the demo). * * 60 10/12/98 11:38p Jeff * wrapped all the Object_info[].description whenever freed...trying to * find an obscure bug. Added icon_name to manage page of Generic * * 59 10/09/98 2:27p Jason * reorganized table file system * * 58 10/08/98 10:03p Jason * more filtered table file stuff * * 57 9/22/98 2:29p Kevin * moved ships allowed code out of dll and into main app. Also added * powerup exclusions * * 56 8/26/98 8:07p Jason * added directional lights to objects * * 55 8/25/98 3:42p Jason * fixed generic object problems * * 54 8/24/98 2:37p Jason * made table file more efficient with regards to invalid names * * 53 8/19/98 6:29p Chris * * 52 8/16/98 6:17p Chris * Added generic object spewing code * * 51 8/15/98 6:12p Chris * Added 13 new AI fields * * 50 8/14/98 4:56p Jeff * added quad fire mask for weapon battery * * 49 6/12/98 1:06p Jason * added smart loading from local table file * * 48 6/04/98 6:44p Jason * implemented smart FindGenericPage function * * 47 6/01/98 10:37a Matt * Added system to spew powerups when the player dies. Still needs Jason * to deal with mng_FindSpecificGenericPage(). * * 46 5/18/98 8:06p Chris * Removed an unused AI value * * 45 5/07/98 1:41p Chris * Added hit_death_dot * * 44 5/03/98 5:38p Chris * Added sounds to anim page * * 43 4/30/98 12:22p Jason * did some lo-res model optimizations * * 42 4/03/98 10:07a Chris * Added support for objects getting their size computed when the * polymodel is paged in the first time as an object * * 41 4/02/98 3:54p Jason * first pass in getting polymodel paging to work * * 40 3/31/98 3:49p Jason * added memory lib * * 39 3/23/98 10:03a Chris * Added independant wb animations * * 38 3/13/98 5:55p Chris * Added the new collision spheres * * 37 3/11/98 4:59p Chris * Changed the ComputeDefualtSize function call * * 36 3/10/98 6:54p Chris * All start and end frame for ComputeDefaultSize * * 35 3/02/98 6:56p Chris * Changed melee_dist to melee_damage * * 34 3/02/98 6:43p Chris * * 33 3/02/98 4:16p Chris * Added 14 new fields to the AI Settings Dialog/page. * * 32 2/23/98 1:22p Jason * made FindSpecific* read from the local drive, not the net drive - when * starting the editor * * 31 2/06/98 2:15a Chris * Activated the max_velocity, max_delta_velocity, and max_turn_rate * fields for AI objects. * * 30 2/04/98 11:47a Jason * added dynamic description field to generic pages * * 29 1/29/98 3:29p Chris * Major update to the AI system. * * 28 1/23/98 6:25p Jason * Got spray weapons working * * 27 1/15/98 6:22p Jason * added safety checks so the network won't copy over a primitive you have * held locally * * 26 1/05/98 3:55p Chris * Added explosion and ambient sounds * * 25 12/22/97 6:19p Chris * Moved weapon battery firing sound off the projectile (weapon) and into * the weapon battery. * * 24 12/01/97 9:54a Chris * Added support for concussive forces, generalized robot collisions to * generic collisions * * 23 11/25/97 1:16p Jason * added lod system for certain objects * * 22 11/17/97 10:47p Jason * fixed loading/saving of flicker_distance * * 21 11/05/97 12:22p Chris * Fixed size of wb_info in the page file * * 20 11/06/97 11:09a Jason * added extra assert to catch errors * * 19 10/28/97 12:23p Chris * We now save out more AI info * * 18 10/01/97 11:01a Chris * Added new support for additional physics items * * 17 9/24/97 6:18p Samir * Use script names instead of script id values to identify scripts. * * 16 9/17/97 10:59a Chris * Added a new way to compute radi * * 15 9/10/97 5:26p Jason * fixed stupid off by one bug * * 14 9/10/97 5:17p Jason * more lighting improvements * * 13 9/10/97 11:44a Chris * Added support for weapon batteries * * 12 9/08/97 11:51a Chris * Extended the weapon system * * 11 9/05/97 1:29p Jason * revamped generic object lighting * * 10 9/04/97 5:49p Jason * made generic pages read/write pulse time for lighting * * 9 9/04/97 3:21p Jason * added pulse timing for lit objects * * 8 9/03/97 6:18p Jason * added code to support powerups/robots/etc that cast light * * 7 9/03/97 2:12p Chris * Added new weapon battery system and made the animation system usable. * * 6 8/13/97 4:54p Matt * Added destroyable flag & hitpoints * * 5 8/11/97 6:47p Matt * Fixed read/write size mismatches in generic page * * 4 8/11/97 1:53p Matt * Ripped out robot & powerup pages, and added generic page * * 3 8/08/97 5:25p Matt * Type was writing as byte but reading as int * * 2 8/08/97 3:44p Jason * added code to support new generic page * * 1 8/08/97 1:29p Jason * file for object_info pages * * $NoKeywords: $ */ #if defined(WIN32) #include #endif #include "CFILE.H" #include "manage.h" #include "genericpage.h" #include "soundpage.h" #include "weaponpage.h" #include "mono.h" #include "pserror.h" #include "polymodel.h" #include "ddio.h" #include #include "robotfire.h" #include "weapon.h" #include "sounds.h" #include "mem.h" #include "args.h" #define GENERICFILE_VERSION 27 // genericpage commands that are read/written // A command is followed by a byte count describing how many bytes // are in the data for the command #define GENERICPAGE_COMMAND_NAME 1 #define GENERICPAGE_COMMAND_END 2 #define GENERICPAGE_COMMAND_IMAGE_NAME 3 #define GENERICPAGE_COMMAND_VERSION 4 #define GENERICPAGE_COMMAND_PHYS_MASS 5 #define GENERICPAGE_COMMAND_PHYS_DRAG 6 #define GENERICPAGE_COMMAND_SIZE 7 #define GENERICPAGE_COMMAND_ANIM_STATES 8 #define GENERICPAGE_COMMAND_FLAGS 9 #define GENERICPAGE_COMMAND_PHYS_FLAGS 10 //AI info #define GENERICPAGE_COMMAND_AI_INFO 11 #define GENERICPAGE_COMMAND_TYPE 12 #define GENERICPAGE_COMMAND_SCORE 13 #define GENERICPAGE_COMMAND_SCRIPT 14 #define GENERICPAGE_COMMAND_SOUND_NAME 15 #define GENERICPAGE_COMMAND_HITPOINTS 16 #define GENERICPAGE_COMMAND_LIGHT_CAST 17 #define GENERICPAGE_COMMAND_WB_INFO 18 #define GENERICPAGE_COMMAND_WB_WEAPON 19 #define GENERICPAGE_COMMAND_SCRIPTNAME 20 #define GENERICPAGE_COMMAND_ROT_DRAG 21 #define GENERICPAGE_COMMAND_FULL_THRUST 22 #define GENERICPAGE_COMMAND_FULL_ROTTHRUST 23 #define GENERICPAGE_COMMAND_TURNROLL_RATE 24 #define GENERICPAGE_COMMAND_TURNROLL_RATIO 25 #define GENERICPAGE_COMMAND_WIGGLE_AMP 26 #define GENERICPAGE_COMMAND_WIGGLE_FREQ 27 #define GENERICPAGE_COMMAND_INT_VELOCITY 28 #define GENERICPAGE_COMMAND_INT_ROTVEL 29 #define GENERICPAGE_COMMAND_NUM_BOUNCES 30 #define GENERICPAGE_COMMAND_COEFF_REST 31 #define GENERICPAGE_COMMAND_FLICKER_DISTANCE 32 #define GENERICPAGE_COMMAND_LOD_MODELS 33 // Impact stuff #define GENERICPAGE_COMMAND_IMPACT 34 #define GENERICPAGE_COMMAND_WB_FIRE_SOUND 35 #define GENERICPAGE_COMMAND_WB_FLAGS 36 #define GENERICPAGE_COMMAND_DESCRIPTION 37 #define GENERICPAGE_COMMAND_AI_SOUND_NAME 38 #define GENERICPAGE_COMMAND_LOD_DISTANCE 39 #define GENERICPAGE_COMMAND_ANIM_SOUND_NAME 40 #define GENERICPAGE_COMMAND_HIT_DIE_DOT 41 #define GENERICPAGE_COMMAND_WB_QUADMASK 42 #define GENERICPAGE_COMMAND_AI_INFO2 43 #define GENERICPAGE_COMMAND_DSPEW_INFO 44 #define GENERICPAGE_COMMAND_DIRECTION_DOT 45 #define GENERICPAGE_COMMAND_ICON_NAME 46 void mng_WriteLightingChunk ( light_info *lighting_info,CFILE *outfile); void mng_ReadLightingChunk (light_info *lighting_info,CFILE *infile); extern bool Running_editor;//in init.cpp extern char *TablefileNameOverride; // Sets a page structure to default values void mng_InitGenericPage (mngs_generic_page *genericpage) { int i; memset (genericpage,0,sizeof(mngs_generic_page)); strcpy (genericpage->image_name,""); strcpy (genericpage->med_image_name,""); strcpy (genericpage->lo_image_name,""); for (i=0;isound_name[i],""); for (i=0;iai_sound_name[i],""); for (i = 0; i < MAX_DSPEW_TYPES; i++) { strcpy(genericpage->dspew_name[i],"\0"); } genericpage->objinfo_struct.description = NULL; genericpage->objinfo_struct.icon_name[0] = '\0'; for (i=0;ianim_sound_name[i][j],""); genericpage->objinfo_struct.med_lod_distance=DEFAULT_MED_LOD_DISTANCE; genericpage->objinfo_struct.lo_lod_distance=DEFAULT_LO_LOD_DISTANCE; genericpage->objinfo_struct.phys_info.hit_die_dot = 1.0f; genericpage->objinfo_struct.respawn_scalar = 1.0f; genericpage->ai_info.curiousity = .5f; genericpage->ai_info.night_vision = .7f; genericpage->ai_info.fog_vision = .7f; genericpage->ai_info.lead_accuracy = 1.0f; genericpage->ai_info.lead_varience = 0.0f; genericpage->ai_info.fire_spread = 0.0f; genericpage->ai_info.fight_team = 0.15f; genericpage->ai_info.fight_same = 0.8f; genericpage->ai_info.agression = 0.5f; genericpage->ai_info.hearing = 1.0f; genericpage->ai_info.frustration = 0.5f; genericpage->ai_info.roaming = 0.5f; genericpage->ai_info.life_preservation = 0.0f; genericpage->objinfo_struct.module_name[0] = '\0'; for (i=0;iobjinfo_struct.death_types[i].flags = 0; genericpage->objinfo_struct.death_types[i].delay_min = 0.0; genericpage->objinfo_struct.death_types[i].delay_max = 0.0; genericpage->objinfo_struct.death_probabilities[i] = 0; } } // Given an open file pointer and a generic_page struct, writes that generic page out void mng_WriteGenericPage (CFILE *outfile,mngs_generic_page *genericpage) { int i,size; ASSERT (outfile!=NULL); ASSERT (genericpage!=NULL); ASSERT ((strlen(genericpage->image_name))>2); cf_WriteByte (outfile,PAGETYPE_GENERIC); cf_WriteByte (outfile,GENERICPAGE_COMMAND_VERSION); cf_WriteByte (outfile,1); cf_WriteByte (outfile,GENERICFILE_VERSION); cf_WriteByte (outfile,GENERICPAGE_COMMAND_TYPE); cf_WriteByte (outfile,1); cf_WriteByte (outfile,genericpage->objinfo_struct.type); // Write the name cf_WriteByte (outfile,GENERICPAGE_COMMAND_NAME); cf_WriteByte (outfile,strlen(genericpage->objinfo_struct.name)+1); cf_WriteString (outfile,genericpage->objinfo_struct.name); // Write the model name cf_WriteByte (outfile,GENERICPAGE_COMMAND_IMAGE_NAME); cf_WriteByte (outfile,strlen(genericpage->image_name)+1); cf_WriteString (outfile,genericpage->image_name); cf_WriteByte (outfile,GENERICPAGE_COMMAND_IMPACT); cf_WriteByte (outfile, 3*sizeof(float)); cf_WriteFloat(outfile, genericpage->objinfo_struct.impact_size); cf_WriteFloat(outfile, genericpage->objinfo_struct.impact_time); cf_WriteFloat(outfile, genericpage->objinfo_struct.damage); // Write the LOD model names cf_WriteByte (outfile,GENERICPAGE_COMMAND_LOD_MODELS); size=strlen(genericpage->med_image_name)+1; size+=strlen(genericpage->lo_image_name)+1; cf_WriteByte (outfile,size); cf_WriteString (outfile,genericpage->med_image_name); cf_WriteString (outfile,genericpage->lo_image_name); cf_WriteByte (outfile,GENERICPAGE_COMMAND_SCORE); cf_WriteByte (outfile,1); cf_WriteByte (outfile,genericpage->objinfo_struct.score); cf_WriteByte (outfile,GENERICPAGE_COMMAND_SCRIPTNAME); cf_WriteByte (outfile,strlen("")+1);//genericpage->objinfo_struct.script_name cf_WriteString (outfile,""); if (genericpage->objinfo_struct.description!=NULL) { cf_WriteByte (outfile,GENERICPAGE_COMMAND_DESCRIPTION); cf_WriteByte (outfile,strlen(genericpage->objinfo_struct.description)+1); cf_WriteString (outfile,genericpage->objinfo_struct.description); } if (genericpage->objinfo_struct.icon_name[0]!='\0') { cf_WriteByte (outfile,GENERICPAGE_COMMAND_ICON_NAME); cf_WriteByte (outfile,strlen(genericpage->objinfo_struct.icon_name)+1); cf_WriteString (outfile,genericpage->objinfo_struct.icon_name); } cf_WriteByte (outfile,GENERICPAGE_COMMAND_LOD_DISTANCE); cf_WriteByte (outfile,8); cf_WriteFloat (outfile,genericpage->objinfo_struct.med_lod_distance); cf_WriteFloat (outfile,genericpage->objinfo_struct.lo_lod_distance); cf_WriteByte (outfile,GENERICPAGE_COMMAND_PHYS_MASS); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.mass); cf_WriteByte (outfile,GENERICPAGE_COMMAND_PHYS_DRAG); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.drag); cf_WriteByte (outfile,GENERICPAGE_COMMAND_SIZE); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.size); cf_WriteByte (outfile,GENERICPAGE_COMMAND_LIGHT_CAST); cf_WriteByte (outfile,(10*4)+2); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.light_distance); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.red_light1); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.green_light1); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.blue_light1); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.time_interval); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.red_light2); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.green_light2); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.blue_light2); cf_WriteInt (outfile,genericpage->objinfo_struct.lighting_info.flags); cf_WriteInt (outfile,genericpage->objinfo_struct.lighting_info.timebits); cf_WriteByte (outfile,genericpage->objinfo_struct.lighting_info.angle); cf_WriteByte (outfile,genericpage->objinfo_struct.lighting_info.lighting_render_type); cf_WriteByte (outfile,GENERICPAGE_COMMAND_FLICKER_DISTANCE); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.flicker_distance); cf_WriteByte (outfile,GENERICPAGE_COMMAND_DIRECTION_DOT); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.lighting_info.directional_dot); cf_WriteByte (outfile,GENERICPAGE_COMMAND_HITPOINTS); cf_WriteByte (outfile,4); cf_WriteInt (outfile,genericpage->objinfo_struct.hit_points); cf_WriteByte (outfile,GENERICPAGE_COMMAND_FLAGS); cf_WriteByte (outfile,4); cf_WriteInt (outfile,genericpage->objinfo_struct.flags); cf_WriteByte (outfile,GENERICPAGE_COMMAND_PHYS_FLAGS); cf_WriteByte (outfile,4); cf_WriteInt (outfile,genericpage->objinfo_struct.phys_info.flags); cf_WriteByte (outfile, GENERICPAGE_COMMAND_ROT_DRAG); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.rotdrag); cf_WriteByte (outfile, GENERICPAGE_COMMAND_FULL_THRUST); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.full_thrust); cf_WriteByte (outfile, GENERICPAGE_COMMAND_FULL_ROTTHRUST); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.full_rotthrust); cf_WriteByte (outfile, GENERICPAGE_COMMAND_TURNROLL_RATE); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.max_turnroll_rate); cf_WriteByte (outfile, GENERICPAGE_COMMAND_TURNROLL_RATIO); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.turnroll_ratio); cf_WriteByte (outfile, GENERICPAGE_COMMAND_WIGGLE_AMP); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.wiggle_amplitude); cf_WriteByte (outfile, GENERICPAGE_COMMAND_WIGGLE_FREQ); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.wiggles_per_sec); cf_WriteByte (outfile, GENERICPAGE_COMMAND_INT_VELOCITY); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.velocity.z); cf_WriteByte (outfile, GENERICPAGE_COMMAND_INT_ROTVEL); cf_WriteByte (outfile,12); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.rotvel.x); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.rotvel.y); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.rotvel.z); cf_WriteByte (outfile, GENERICPAGE_COMMAND_NUM_BOUNCES); cf_WriteByte (outfile,4); cf_WriteInt (outfile,genericpage->objinfo_struct.phys_info.num_bounces); cf_WriteByte (outfile, GENERICPAGE_COMMAND_COEFF_REST); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.coeff_restitution); cf_WriteByte (outfile, GENERICPAGE_COMMAND_HIT_DIE_DOT); cf_WriteByte (outfile,4); cf_WriteFloat (outfile,genericpage->objinfo_struct.phys_info.hit_die_dot); cf_WriteByte (outfile,GENERICPAGE_COMMAND_AI_INFO); cf_WriteByte (outfile, 76); cf_WriteInt (outfile, genericpage->ai_info.flags); cf_WriteByte (outfile, genericpage->ai_info.ai_class); cf_WriteByte (outfile, genericpage->ai_info.ai_type); cf_WriteByte (outfile, genericpage->ai_info.movement_type); cf_WriteByte (outfile, genericpage->ai_info.movement_subtype); cf_WriteFloat(outfile, genericpage->ai_info.fov); cf_WriteFloat(outfile, genericpage->ai_info.max_velocity); cf_WriteFloat(outfile, genericpage->ai_info.max_delta_velocity); cf_WriteFloat(outfile, genericpage->ai_info.max_turn_rate); cf_WriteFloat(outfile, genericpage->ai_info.avoid_friends_distance); // Makes sure there are no bugs as things are added and removed -- ask chris genericpage->ai_info.notify_flags &= ~AI_NOTIFIES_ALWAYS_ON; cf_WriteInt (outfile, genericpage->ai_info.notify_flags); genericpage->ai_info.notify_flags |= AI_NOTIFIES_ALWAYS_ON; cf_WriteFloat(outfile, genericpage->ai_info.max_delta_turn_rate); cf_WriteFloat(outfile, genericpage->ai_info.circle_distance); cf_WriteFloat(outfile, genericpage->ai_info.attack_vel_percent); cf_WriteFloat(outfile, genericpage->ai_info.dodge_percent); cf_WriteFloat(outfile, genericpage->ai_info.dodge_vel_percent); cf_WriteFloat(outfile, genericpage->ai_info.flee_vel_percent); cf_WriteFloat(outfile, genericpage->ai_info.melee_damage[0]); cf_WriteFloat(outfile, genericpage->ai_info.melee_damage[1]); cf_WriteFloat(outfile, genericpage->ai_info.melee_latency[0]); cf_WriteFloat(outfile, genericpage->ai_info.melee_latency[1]); for (i=0;isound_name[i])+2); // 1 for sound index, 1 for null term cf_WriteByte (outfile,i); cf_WriteString (outfile,genericpage->sound_name[i]); } for (i=0;iai_sound_name[i])+2); // 1 for sound index, 1 for null term cf_WriteByte (outfile,i); cf_WriteString (outfile,genericpage->ai_sound_name[i]); } for (i = 0; idspew_name[i]) + 9); // 1 for null charactor cf_WriteByte(outfile, i); cf_WriteByte(outfile, genericpage->objinfo_struct.f_dspew); cf_WriteFloat(outfile, genericpage->objinfo_struct.dspew_percent[i]); cf_WriteShort(outfile, genericpage->objinfo_struct.dspew_number[i]); cf_WriteString(outfile, genericpage->dspew_name[i]); } cf_WriteByte(outfile,GENERICPAGE_COMMAND_AI_INFO2); cf_WriteByte(outfile,13*sizeof(float)); cf_WriteFloat(outfile, genericpage->ai_info.curiousity); cf_WriteFloat(outfile, genericpage->ai_info.night_vision); cf_WriteFloat(outfile, genericpage->ai_info.fog_vision); cf_WriteFloat(outfile, genericpage->ai_info.lead_accuracy); cf_WriteFloat(outfile, genericpage->ai_info.lead_varience); cf_WriteFloat(outfile, genericpage->ai_info.fire_spread); cf_WriteFloat(outfile, genericpage->ai_info.fight_team); cf_WriteFloat(outfile, genericpage->ai_info.fight_same); cf_WriteFloat(outfile, genericpage->ai_info.agression); cf_WriteFloat(outfile, genericpage->ai_info.hearing); cf_WriteFloat(outfile, genericpage->ai_info.frustration); cf_WriteFloat(outfile, genericpage->ai_info.roaming); cf_WriteFloat(outfile, genericpage->ai_info.life_preservation); for (i=0;ianim[i].elem[j].from); cf_WriteShort (outfile, genericpage->anim[i].elem[j].to); cf_WriteFloat (outfile, genericpage->anim[i].elem[j].spc); } } cf_WriteByte (outfile,GENERICPAGE_COMMAND_WB_FLAGS); cf_WriteByte (outfile, sizeof(int) * MAX_WBS_PER_OBJ); for(i = 0; i < MAX_WBS_PER_OBJ; i++) cf_WriteByte(outfile, genericpage->static_wb[i].flags); for(i = 0; i < MAX_WBS_PER_OBJ; i++) { int j; cf_WriteByte (outfile, GENERICPAGE_COMMAND_WB_INFO); size = 202; cf_WriteByte (outfile,size); cf_WriteByte (outfile,i); for(j = 0; j < MAX_WB_GUNPOINTS; j++) cf_WriteShort(outfile, genericpage->static_wb[i].gp_weapon_index[j]); cf_WriteShort(outfile, genericpage->static_wb[i].aiming_gp_index); cf_WriteByte(outfile, genericpage->static_wb[i].num_masks); for(j = 0; j < MAX_WB_FIRING_MASKS; j++) cf_WriteByte(outfile, genericpage->static_wb[i].gp_fire_masks[j]); for(j = 0; j < MAX_WB_FIRING_MASKS; j++) cf_WriteFloat(outfile, genericpage->static_wb[i].gp_fire_wait[j]); for(j = 0; j < MAX_WB_FIRING_MASKS; j++) { cf_WriteFloat(outfile, genericpage->static_wb[i].anim_time[j]); cf_WriteFloat(outfile, genericpage->static_wb[i].anim_start_frame[j]); cf_WriteFloat(outfile, genericpage->static_wb[i].anim_fire_frame[j]); cf_WriteFloat(outfile, genericpage->static_wb[i].anim_end_frame[j]); } cf_WriteByte(outfile, genericpage->static_wb[i].aiming_flags); cf_WriteFloat(outfile, genericpage->static_wb[i].aiming_3d_dot); cf_WriteFloat(outfile, genericpage->static_wb[i].aiming_3d_dist); cf_WriteFloat(outfile, genericpage->static_wb[i].aiming_XZ_dot); } for(i = 0; i < MAX_WBS_PER_OBJ; i++) { int j; for(j = 0; j < MAX_WB_GUNPOINTS; j++) { cf_WriteByte (outfile, GENERICPAGE_COMMAND_WB_WEAPON); size = strlen(genericpage->weapon_name[i][j])+1+2; // 1 for the null charactor and 2 for the 2 indices cf_WriteByte (outfile,size); cf_WriteByte (outfile,i); cf_WriteByte (outfile,j); cf_WriteString (outfile,genericpage->weapon_name[i][j]); } } cf_WriteByte (outfile, GENERICPAGE_COMMAND_WB_QUADMASK); cf_WriteByte (outfile, MAX_WBS_PER_OBJ); for(i = 0; i < MAX_WBS_PER_OBJ; i++) { cf_WriteByte (outfile, genericpage->static_wb[i].gp_quad_fire_mask); } for(i = 0; i < MAX_WBS_PER_OBJ; i++) { int j; for(j = 0; j < MAX_WB_FIRING_MASKS; j++) { cf_WriteByte (outfile, GENERICPAGE_COMMAND_WB_FIRE_SOUND); size = strlen(genericpage->fire_sound_name[i][j])+1+2; // 1 for the null charactor and 2 for the 2 indices cf_WriteByte (outfile,size); cf_WriteByte (outfile,i); cf_WriteByte (outfile,j); cf_WriteString (outfile,genericpage->fire_sound_name[i][j]); } } for(i = 0; i < NUM_MOVEMENT_CLASSES; i++) { int j; for(j = 0; j < NUM_ANIMS_PER_CLASS; j++) { cf_WriteByte (outfile, GENERICPAGE_COMMAND_ANIM_SOUND_NAME); size = strlen(genericpage->anim_sound_name[i][j])+1+2; // 1 for the null charactor and 2 for the 2 indices cf_WriteByte (outfile,size); cf_WriteByte (outfile,i); cf_WriteByte (outfile,j); cf_WriteString (outfile,genericpage->anim_sound_name[i][j]); } } cf_WriteByte (outfile,GENERICPAGE_COMMAND_END); // we're all done cf_WriteByte (outfile,0); } // Given an open file pointer and a generic_page struct, writes that generic page out void mng_WriteNewGenericPage (CFILE *outfile,mngs_generic_page *genericpage) { int i,j; ASSERT (outfile!=NULL); ASSERT (genericpage!=NULL); ASSERT ((strlen(genericpage->image_name))>2); int offset=StartManagePage (outfile,PAGETYPE_GENERIC); cf_WriteShort (outfile,GENERICFILE_VERSION); cf_WriteByte (outfile,genericpage->objinfo_struct.type); // Write out object name cf_WriteString (outfile,genericpage->objinfo_struct.name); // Write out model names cf_WriteString (outfile,genericpage->image_name); cf_WriteString (outfile,genericpage->med_image_name); cf_WriteString (outfile,genericpage->lo_image_name); // Write out impact data cf_WriteFloat(outfile, genericpage->objinfo_struct.impact_size); cf_WriteFloat(outfile, genericpage->objinfo_struct.impact_time); cf_WriteFloat(outfile, genericpage->objinfo_struct.damage); // Write score cf_WriteShort(outfile,genericpage->objinfo_struct.score); // Write ammo if (genericpage->objinfo_struct.type == OBJ_POWERUP) cf_WriteShort(outfile,genericpage->objinfo_struct.ammo_count); //Write script name cf_WriteString (outfile,"");//genericpage->objinfo_struct.script_name //Write module name cf_WriteString (outfile,genericpage->objinfo_struct.module_name); //Write scriptname override cf_WriteString (outfile,genericpage->objinfo_struct.script_name_override); if (genericpage->objinfo_struct.description!=NULL) { // Write description if there is one cf_WriteByte (outfile,1); cf_WriteString (outfile,genericpage->objinfo_struct.description); } else cf_WriteByte (outfile,0); // Write icon name cf_WriteString (outfile,genericpage->objinfo_struct.icon_name); // Write LOD distances cf_WriteFloat (outfile,genericpage->objinfo_struct.med_lod_distance); cf_WriteFloat (outfile,genericpage->objinfo_struct.lo_lod_distance); // Write physics stuff mng_WritePhysicsChunk (&genericpage->objinfo_struct.phys_info,outfile); // Write size cf_WriteFloat (outfile,genericpage->objinfo_struct.size); // Write light info mng_WriteLightingChunk (&genericpage->objinfo_struct.lighting_info,outfile); // Write hit points cf_WriteInt (outfile,genericpage->objinfo_struct.hit_points); // Write flags cf_WriteInt (outfile,genericpage->objinfo_struct.flags); // Write AI info cf_WriteInt (outfile, genericpage->ai_info.flags); cf_WriteByte (outfile, genericpage->ai_info.ai_class); cf_WriteByte (outfile, genericpage->ai_info.ai_type); cf_WriteByte (outfile, genericpage->ai_info.movement_type); cf_WriteByte (outfile, genericpage->ai_info.movement_subtype); cf_WriteFloat(outfile, genericpage->ai_info.fov); cf_WriteFloat(outfile, genericpage->ai_info.max_velocity); cf_WriteFloat(outfile, genericpage->ai_info.max_delta_velocity); cf_WriteFloat(outfile, genericpage->ai_info.max_turn_rate); // Makes sure there are no bugs as things are added and removed -- ask chris genericpage->ai_info.notify_flags &= ~AI_NOTIFIES_ALWAYS_ON; cf_WriteInt (outfile, genericpage->ai_info.notify_flags); genericpage->ai_info.notify_flags |= AI_NOTIFIES_ALWAYS_ON; cf_WriteFloat(outfile, genericpage->ai_info.max_delta_turn_rate); cf_WriteFloat(outfile, genericpage->ai_info.circle_distance); cf_WriteFloat(outfile, genericpage->ai_info.attack_vel_percent); cf_WriteFloat(outfile, genericpage->ai_info.dodge_percent); cf_WriteFloat(outfile, genericpage->ai_info.dodge_vel_percent); cf_WriteFloat(outfile, genericpage->ai_info.flee_vel_percent); cf_WriteFloat(outfile, genericpage->ai_info.melee_damage[0]); cf_WriteFloat(outfile, genericpage->ai_info.melee_damage[1]); cf_WriteFloat(outfile, genericpage->ai_info.melee_latency[0]); cf_WriteFloat(outfile, genericpage->ai_info.melee_latency[1]); cf_WriteFloat(outfile, genericpage->ai_info.curiousity); cf_WriteFloat(outfile, genericpage->ai_info.night_vision); cf_WriteFloat(outfile, genericpage->ai_info.fog_vision); cf_WriteFloat(outfile, genericpage->ai_info.lead_accuracy); cf_WriteFloat(outfile, genericpage->ai_info.lead_varience); cf_WriteFloat(outfile, genericpage->ai_info.fire_spread); cf_WriteFloat(outfile, genericpage->ai_info.fight_team); cf_WriteFloat(outfile, genericpage->ai_info.fight_same); cf_WriteFloat(outfile, genericpage->ai_info.agression); cf_WriteFloat(outfile, genericpage->ai_info.hearing); cf_WriteFloat(outfile, genericpage->ai_info.frustration); cf_WriteFloat(outfile, genericpage->ai_info.roaming); cf_WriteFloat(outfile, genericpage->ai_info.life_preservation); cf_WriteFloat(outfile, genericpage->ai_info.avoid_friends_distance); cf_WriteFloat(outfile, genericpage->ai_info.biased_flight_importance); cf_WriteFloat(outfile, genericpage->ai_info.biased_flight_min); cf_WriteFloat(outfile, genericpage->ai_info.biased_flight_max); // Write out objects spewed for (i = 0; iobjinfo_struct.f_dspew); cf_WriteFloat(outfile, genericpage->objinfo_struct.dspew_percent[i]); cf_WriteShort(outfile, genericpage->objinfo_struct.dspew_number[i]); cf_WriteString(outfile, genericpage->dspew_name[i]); } // Write out animation info for (i=0;ianim[i].elem[j].from); cf_WriteShort (outfile, genericpage->anim[i].elem[j].to); cf_WriteFloat (outfile, genericpage->anim[i].elem[j].spc); } } // Write out weapon batteries for(i = 0; i < MAX_WBS_PER_OBJ; i++) mng_WriteWeaponBatteryChunk (&genericpage->static_wb[i],outfile); // Write out weapon names for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_GUNPOINTS; j++) cf_WriteString (outfile,genericpage->weapon_name[i][j]); } // Write out sounds for (i=0;isound_name[i]); for (i=0;iai_sound_name[i]); for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_FIRING_MASKS; j++) cf_WriteString (outfile,genericpage->fire_sound_name[i][j]); } for(i = 0; i < NUM_MOVEMENT_CLASSES; i++) { for(j = 0; j < NUM_ANIMS_PER_CLASS; j++) cf_WriteString (outfile,genericpage->anim_sound_name[i][j]); } // Write out respawn scalar cf_WriteFloat (outfile,genericpage->objinfo_struct.respawn_scalar); //Write out death information cf_WriteShort(outfile,MAX_DEATH_TYPES); for (i=0;iobjinfo_struct.death_types[i].flags); cf_WriteFloat(outfile,genericpage->objinfo_struct.death_types[i].delay_min); cf_WriteFloat(outfile,genericpage->objinfo_struct.death_types[i].delay_max); cf_WriteByte(outfile,genericpage->objinfo_struct.death_probabilities[i]); } EndManagePage (outfile,offset); } //Old delay types #define OLD_DF_DELAY_NONE 0x0000000 #define OLD_DF_DELAY_MIN_MAX 0x0000001 #define OLD_DF_DELAY_FROM_ANIM 0x0000002 #define OLD_DF_DELAY_MASK 0x0000003 #define OLD_DF_DELAY_SHIFT 0 void GenericPageSetPowerupDefaultAmmo(object_info *ip) { //Default is zero ip->ammo_count = 0; //Set for specific types if (!stricmp(ip->name,"Vauss")) ip->ammo_count = 5000; if (!stricmp(ip->name,"Napalm")) ip->ammo_count = 500; if (!stricmp(ip->name,"MassDriver")) ip->ammo_count = 20; if (!stricmp(ip->name,"Frag")) ip->ammo_count = 1; if (!stricmp(ip->name,"ImpactMortar")) ip->ammo_count = 1; if (!stricmp(ip->name,"NapalmRocket")) ip->ammo_count = 1; if (!stricmp(ip->name,"Cyclone")) ip->ammo_count = 1; if (!stricmp(ip->name,"BlackShark")) ip->ammo_count = 1; if (!stricmp(ip->name,"Concussion")) ip->ammo_count = 1; if (!stricmp(ip->name,"Homing")) ip->ammo_count = 1; if (!stricmp(ip->name,"Smart")) ip->ammo_count = 1; if (!stricmp(ip->name,"Mega")) ip->ammo_count = 1; if (!stricmp(ip->name,"Guided")) ip->ammo_count = 1; if (!stricmp(ip->name,"4PackHoming")) ip->ammo_count = 4; if (!stricmp(ip->name,"4PackConc")) ip->ammo_count = 4; if (!stricmp(ip->name,"4PackFrag")) ip->ammo_count = 4; if (!stricmp(ip->name,"4PackGuided")) ip->ammo_count = 4; if (!stricmp(ip->name,"Vauss clip")) ip->ammo_count = 1250; if (!stricmp(ip->name,"MassDriverAmmo")) ip->ammo_count = 5; if (!stricmp(ip->name,"NapalmTank")) ip->ammo_count = 100; } // Reads a generic page from an open file. Returns 0 on error. int mng_ReadNewGenericPage (CFILE *infile,mngs_generic_page *genericpage) { int i,j; ASSERT (infile!=NULL); mng_InitGenericPage (genericpage); int version=cf_ReadShort (infile); genericpage->objinfo_struct.type=cf_ReadByte (infile); // Read object name cf_ReadString (genericpage->objinfo_struct.name,PAGENAME_LEN,infile); // Read model names cf_ReadString (genericpage->image_name,PAGENAME_LEN,infile); cf_ReadString (genericpage->med_image_name,PAGENAME_LEN,infile); cf_ReadString (genericpage->lo_image_name,PAGENAME_LEN,infile); // Read out impact data genericpage->objinfo_struct.impact_size=cf_ReadFloat (infile); genericpage->objinfo_struct.impact_time=cf_ReadFloat (infile); genericpage->objinfo_struct.damage=cf_ReadFloat (infile); // Read score if (version >= 24) genericpage->objinfo_struct.score = cf_ReadShort(infile); else genericpage->objinfo_struct.score = cf_ReadByte(infile); // Read ammo if (genericpage->objinfo_struct.type == OBJ_POWERUP) { if (version >= 25) genericpage->objinfo_struct.ammo_count = cf_ReadShort(infile); else GenericPageSetPowerupDefaultAmmo(&genericpage->objinfo_struct); } else genericpage->objinfo_struct.ammo_count = 0; //Read script name char dummy[256]; cf_ReadString (dummy,PAGENAME_LEN,infile);//genericpage->objinfo_struct.script_name if(version>=18) { cf_ReadString (genericpage->objinfo_struct.module_name,MAX_MODULENAME_LEN,infile); #ifdef MACINTOSH //DAJ char *dot = strchr(genericpage->objinfo_struct.module_name, '.'); if(dot) strcpy(dot, ".msl"); #endif }else { genericpage->objinfo_struct.module_name[0] = '\0'; } if(version>=19) { cf_ReadString (genericpage->objinfo_struct.script_name_override,PAGENAME_LEN,infile); }else { genericpage->objinfo_struct.script_name_override[0] = '\0'; } int desc=cf_ReadByte (infile); if (desc) { // Read description if there is one char tempbuf[1024]; cf_ReadString (tempbuf,1024,infile); int slen=strlen (tempbuf)+1; genericpage->objinfo_struct.description=(char *)mem_malloc (slen); ASSERT (genericpage->objinfo_struct.description); strcpy (genericpage->objinfo_struct.description,tempbuf); } else genericpage->objinfo_struct.description=NULL; // Read icon name cf_ReadString (genericpage->objinfo_struct.icon_name,PAGENAME_LEN,infile); // Read LOD distances genericpage->objinfo_struct.med_lod_distance=cf_ReadFloat (infile); genericpage->objinfo_struct.lo_lod_distance=cf_ReadFloat (infile); // Read physics stuff mng_ReadPhysicsChunk (&genericpage->objinfo_struct.phys_info,infile); // Write size genericpage->objinfo_struct.size=cf_ReadFloat(infile); // Write light info mng_ReadLightingChunk (&genericpage->objinfo_struct.lighting_info,infile); // Read hit points genericpage->objinfo_struct.hit_points=cf_ReadInt(infile); // Read flags genericpage->objinfo_struct.flags=cf_ReadInt (infile); // Write AI info genericpage->ai_info.flags=cf_ReadInt(infile); genericpage->ai_info.ai_class=cf_ReadByte (infile); genericpage->ai_info.ai_type=cf_ReadByte (infile); genericpage->ai_info.movement_type=cf_ReadByte (infile); genericpage->ai_info.movement_subtype=cf_ReadByte (infile); genericpage->ai_info.fov=cf_ReadFloat (infile); genericpage->ai_info.max_velocity=cf_ReadFloat (infile); genericpage->ai_info.max_delta_velocity=cf_ReadFloat (infile); genericpage->ai_info.max_turn_rate=cf_ReadFloat (infile); // Makes sure there are no bugs as things are added and removed -- ask chris genericpage->ai_info.notify_flags &= ~AI_NOTIFIES_ALWAYS_ON; genericpage->ai_info.notify_flags=cf_ReadInt(infile); genericpage->ai_info.notify_flags |= AI_NOTIFIES_ALWAYS_ON; genericpage->ai_info.max_delta_turn_rate=cf_ReadFloat (infile); genericpage->ai_info.circle_distance=cf_ReadFloat (infile); genericpage->ai_info.attack_vel_percent=cf_ReadFloat (infile); genericpage->ai_info.dodge_percent=cf_ReadFloat (infile); genericpage->ai_info.dodge_vel_percent=cf_ReadFloat (infile); genericpage->ai_info.flee_vel_percent=cf_ReadFloat (infile); genericpage->ai_info.melee_damage[0]=cf_ReadFloat (infile); genericpage->ai_info.melee_damage[1]=cf_ReadFloat (infile); genericpage->ai_info.melee_latency[0]=cf_ReadFloat (infile); genericpage->ai_info.melee_latency[1]=cf_ReadFloat (infile); genericpage->ai_info.curiousity=cf_ReadFloat (infile); genericpage->ai_info.night_vision=cf_ReadFloat (infile); genericpage->ai_info.fog_vision=cf_ReadFloat (infile); genericpage->ai_info.lead_accuracy=cf_ReadFloat (infile); genericpage->ai_info.lead_varience=cf_ReadFloat (infile); genericpage->ai_info.fire_spread=cf_ReadFloat (infile); genericpage->ai_info.fight_team=cf_ReadFloat (infile); genericpage->ai_info.fight_same=cf_ReadFloat (infile); genericpage->ai_info.agression=cf_ReadFloat (infile); genericpage->ai_info.hearing=cf_ReadFloat (infile); genericpage->ai_info.frustration=cf_ReadFloat (infile); genericpage->ai_info.roaming=cf_ReadFloat (infile); genericpage->ai_info.life_preservation=cf_ReadFloat (infile); if(version >= 16) { genericpage->ai_info.avoid_friends_distance =cf_ReadFloat (infile); } else if((genericpage->objinfo_struct.flags | OIF_USES_PHYSICS) && genericpage->ai_info.max_velocity > 0.0f) { genericpage->ai_info.flags |= AIF_AUTO_AVOID_FRIENDS; genericpage->ai_info.avoid_friends_distance = genericpage->ai_info.circle_distance / 10.f; if(genericpage->ai_info.avoid_friends_distance < 4.0f) genericpage->ai_info.avoid_friends_distance = 4.0f; } else { genericpage->ai_info.avoid_friends_distance = 4.0f; } if(version >= 17) { genericpage->ai_info.biased_flight_importance = cf_ReadFloat(infile); genericpage->ai_info.biased_flight_min = cf_ReadFloat(infile); genericpage->ai_info.biased_flight_max = cf_ReadFloat(infile); } else { genericpage->ai_info.biased_flight_importance = .5f; genericpage->ai_info.biased_flight_min = 10.0f; genericpage->ai_info.biased_flight_max = 50.0f; } // Write out objects spewed for (i = 0; iobjinfo_struct.f_dspew=cf_ReadByte (infile); genericpage->objinfo_struct.dspew_percent[i]=cf_ReadFloat (infile); genericpage->objinfo_struct.dspew_number[i]=cf_ReadShort (infile); // Read spew name cf_ReadString (genericpage->dspew_name[i],PAGENAME_LEN,infile); } // Read out animation info for (i=0;ianim[i].elem[j].from=cf_ReadByte (infile); genericpage->anim[i].elem[j].to=cf_ReadByte(infile); } else { genericpage->anim[i].elem[j].from=cf_ReadShort(infile); genericpage->anim[i].elem[j].to=cf_ReadShort(infile); } genericpage->anim[i].elem[j].spc=cf_ReadFloat (infile); } } // read weapon batteries for(i = 0; i < MAX_WBS_PER_OBJ; i++) { if (version>=15) mng_ReadWeaponBatteryChunk (&genericpage->static_wb[i],infile,2); else mng_ReadWeaponBatteryChunk (&genericpage->static_wb[i],infile,1); } // read weapon names for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_GUNPOINTS; j++) cf_ReadString (genericpage->weapon_name[i][j],PAGENAME_LEN,infile); } // read sounds ASSERT(MAX_OBJ_SOUNDS == 2); for (i=0;isound_name[i],PAGENAME_LEN,infile); if (version < 26) { //used to be three sounds char temp_sound_name[PAGENAME_LEN]; cf_ReadString (temp_sound_name,PAGENAME_LEN,infile); } for (i=0;iai_sound_name[i],PAGENAME_LEN,infile); for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_FIRING_MASKS; j++) cf_ReadString (genericpage->fire_sound_name[i][j],PAGENAME_LEN,infile); } for(i = 0; i < NUM_MOVEMENT_CLASSES; i++) { for(j = 0; j < NUM_ANIMS_PER_CLASS; j++) cf_ReadString (genericpage->anim_sound_name[i][j],PAGENAME_LEN,infile); } // Read respawn scalar if (version>=21) genericpage->objinfo_struct.respawn_scalar=cf_ReadFloat (infile); else genericpage->objinfo_struct.respawn_scalar=1.0; if (version >= 22) { int n_death_types = cf_ReadShort(infile); for (i=0;iobjinfo_struct.death_types[i].flags = flags; genericpage->objinfo_struct.death_types[i].delay_min = cf_ReadFloat(infile); genericpage->objinfo_struct.death_types[i].delay_max = cf_ReadFloat(infile); genericpage->objinfo_struct.death_probabilities[i] = cf_ReadByte(infile); //Fix up for changed flags if (version < 27) { if ((flags & OLD_DF_DELAY_MASK) != OLD_DF_DELAY_MIN_MAX) { genericpage->objinfo_struct.death_types[i].delay_min = 0.0; genericpage->objinfo_struct.death_types[i].delay_max = 0.0; } flags &= ~DF_UNUSED; } } } //Set score from hitpoints if old version if (version < 24) { if ((genericpage->objinfo_struct.type == OBJ_ROBOT) || (genericpage->objinfo_struct.type == OBJ_BUILDING && (genericpage->objinfo_struct.flags & OIF_CONTROL_AI))) if (genericpage->objinfo_struct.flags & OIF_DESTROYABLE) genericpage->objinfo_struct.score = 3 * genericpage->objinfo_struct.hit_points; } ASSERT(genericpage->objinfo_struct.type != OBJ_NONE); return 1; // successfully read } // Reads a generic page from an open file. Returns 0 on error. int mng_ReadGenericPage (CFILE *infile,mngs_generic_page *genericpage) { int done=0; char command; ushort len; int i,temp,version,t; if (!Old_table_method) return mng_ReadNewGenericPage (infile,genericpage); ASSERT (infile!=NULL); mng_InitGenericPage (genericpage); while (!done) { // Read in command byte then read in the length of that commands data command=cf_ReadByte (infile); len=cf_ReadByte(infile); switch (command) { case GENERICPAGE_COMMAND_END: done=1; break; case GENERICPAGE_COMMAND_VERSION: version = cf_ReadByte(infile); break; case GENERICPAGE_COMMAND_TYPE: genericpage->objinfo_struct.type = cf_ReadByte(infile); break; case GENERICPAGE_COMMAND_SCORE: genericpage->objinfo_struct.score = cf_ReadByte(infile); break; case GENERICPAGE_COMMAND_SCRIPT: // Obsolete as of 09-24-97 cf_ReadByte(infile); break; case GENERICPAGE_COMMAND_SCRIPTNAME: { char dummy[256]; cf_ReadString(dummy, len+1, infile);//genericpage->objinfo_struct.script_name }break; case GENERICPAGE_COMMAND_DESCRIPTION: genericpage->objinfo_struct.description=(char *)mem_malloc (len+1); ASSERT (genericpage->objinfo_struct.description); // out of memory! cf_ReadString(genericpage->objinfo_struct.description, len+1, infile); break; case GENERICPAGE_COMMAND_ICON_NAME: cf_ReadString(genericpage->objinfo_struct.icon_name, len+1, infile); break; case GENERICPAGE_COMMAND_IMAGE_NAME: // the name of the generic model cf_ReadString (genericpage->image_name,len+1,infile); break; case GENERICPAGE_COMMAND_LOD_MODELS: // the name of the lower res models cf_ReadString (genericpage->med_image_name,len+1,infile); cf_ReadString (genericpage->lo_image_name,len+1,infile); break; case GENERICPAGE_COMMAND_NAME: cf_ReadString (genericpage->objinfo_struct.name,len+1,infile); break; case GENERICPAGE_COMMAND_SIZE: genericpage->objinfo_struct.size=cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_LOD_DISTANCE: genericpage->objinfo_struct.med_lod_distance=cf_ReadFloat(infile); genericpage->objinfo_struct.lo_lod_distance=cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_DSPEW_INFO: { int i = cf_ReadByte(infile); genericpage->objinfo_struct.f_dspew = cf_ReadByte(infile); genericpage->objinfo_struct.dspew_percent[i] = cf_ReadFloat(infile); genericpage->objinfo_struct.dspew_number[i] = cf_ReadShort(infile); cf_ReadString (genericpage->dspew_name[i],len-7,infile); } break; case GENERICPAGE_COMMAND_WB_FLAGS: { for (int i=0;istatic_wb[i].flags=cf_ReadByte (infile); } break; case GENERICPAGE_COMMAND_IMPACT: genericpage->objinfo_struct.impact_size = cf_ReadFloat(infile); genericpage->objinfo_struct.impact_time = cf_ReadFloat(infile); genericpage->objinfo_struct.damage = cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_FLICKER_DISTANCE: genericpage->objinfo_struct.lighting_info.flicker_distance=cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_DIRECTION_DOT: genericpage->objinfo_struct.lighting_info.directional_dot=cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_AI_INFO2: genericpage->ai_info.curiousity=cf_ReadFloat(infile); genericpage->ai_info.night_vision=cf_ReadFloat(infile); genericpage->ai_info.fog_vision=cf_ReadFloat(infile); genericpage->ai_info.lead_accuracy=cf_ReadFloat(infile); genericpage->ai_info.lead_varience=cf_ReadFloat(infile); genericpage->ai_info.fire_spread=cf_ReadFloat(infile); genericpage->ai_info.fight_team=cf_ReadFloat(infile); genericpage->ai_info.fight_same=cf_ReadFloat(infile); genericpage->ai_info.agression=cf_ReadFloat(infile); genericpage->ai_info.hearing=cf_ReadFloat(infile); genericpage->ai_info.frustration=cf_ReadFloat(infile); genericpage->ai_info.roaming=cf_ReadFloat(infile); genericpage->ai_info.life_preservation=cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_LIGHT_CAST: genericpage->objinfo_struct.lighting_info.light_distance=cf_ReadFloat(infile); genericpage->objinfo_struct.lighting_info.red_light1=cf_ReadFloat(infile); genericpage->objinfo_struct.lighting_info.green_light1=cf_ReadFloat(infile); genericpage->objinfo_struct.lighting_info.blue_light1=cf_ReadFloat(infile); if (version>=2) genericpage->objinfo_struct.lighting_info.time_interval=cf_ReadFloat(infile); if (version>=3) { genericpage->objinfo_struct.lighting_info.red_light2=cf_ReadFloat(infile); genericpage->objinfo_struct.lighting_info.green_light2=cf_ReadFloat(infile); genericpage->objinfo_struct.lighting_info.blue_light2=cf_ReadFloat(infile); genericpage->objinfo_struct.lighting_info.flags=cf_ReadInt(infile); genericpage->objinfo_struct.lighting_info.timebits=cf_ReadInt(infile); genericpage->objinfo_struct.lighting_info.angle=cf_ReadByte(infile); } if (version>=5) { genericpage->objinfo_struct.lighting_info.lighting_render_type=cf_ReadByte(infile); } else genericpage->objinfo_struct.lighting_info.lighting_render_type=LRT_STATIC; break; case GENERICPAGE_COMMAND_HITPOINTS: genericpage->objinfo_struct.hit_points = cf_ReadInt(infile); break; case GENERICPAGE_COMMAND_PHYS_MASS: genericpage->objinfo_struct.phys_info.mass=cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_PHYS_DRAG: genericpage->objinfo_struct.phys_info.drag=cf_ReadFloat(infile); break; case GENERICPAGE_COMMAND_ANIM_STATES: temp=cf_ReadByte (infile); { int j; for(j = 0; j < NUM_ANIMS_PER_CLASS;j++) { if(version < 20) { genericpage->anim[temp].elem[j].from = cf_ReadByte(infile); genericpage->anim[temp].elem[j].to = cf_ReadByte(infile); } else { genericpage->anim[temp].elem[j].from = cf_ReadShort(infile); genericpage->anim[temp].elem[j].to = cf_ReadShort(infile); } if(version <= 3) genericpage->anim[temp].elem[j].spc = 1.0f; else genericpage->anim[temp].elem[j].spc = cf_ReadFloat(infile); } } break; case GENERICPAGE_COMMAND_FLAGS: { int t = cf_ReadInt(infile); genericpage->objinfo_struct.flags = t; break; } case GENERICPAGE_COMMAND_WB_INFO: { int i,j; i = cf_ReadByte(infile); if(version <= 7) { for(j = 0; j < MAX_WB_GUNPOINTS; j++) genericpage->static_wb[i].gp_weapon_index[j] = cf_ReadInt(infile); genericpage->static_wb[i].aiming_gp_index = cf_ReadInt(infile); } else { for(j = 0; j < MAX_WB_GUNPOINTS; j++) genericpage->static_wb[i].gp_weapon_index[j] = cf_ReadShort(infile); genericpage->static_wb[i].aiming_gp_index = cf_ReadShort(infile); } genericpage->static_wb[i].num_masks = cf_ReadByte(infile); for(j = 0; j < MAX_WB_FIRING_MASKS; j++) genericpage->static_wb[i].gp_fire_masks[j] = cf_ReadByte(infile); for(j = 0; j < MAX_WB_FIRING_MASKS; j++) genericpage->static_wb[i].gp_fire_wait[j] = cf_ReadFloat(infile); for(j = 0; j < MAX_WB_FIRING_MASKS; j++) { if(version < 12) { genericpage->static_wb[i].anim_time[j] = 0.0f; genericpage->static_wb[i].anim_start_frame[j] = 0.0f; genericpage->static_wb[i].anim_fire_frame[j] = 0.0f; genericpage->static_wb[i].anim_end_frame[j] = 0.0f; } else { genericpage->static_wb[i].anim_time[j] = cf_ReadFloat(infile); genericpage->static_wb[i].anim_start_frame[j] = cf_ReadFloat(infile); genericpage->static_wb[i].anim_fire_frame[j] = cf_ReadFloat(infile); genericpage->static_wb[i].anim_end_frame[j] = cf_ReadFloat(infile); } } genericpage->static_wb[i].aiming_flags = cf_ReadByte(infile); genericpage->static_wb[i].aiming_3d_dot = cf_ReadFloat(infile); genericpage->static_wb[i].aiming_3d_dist = cf_ReadFloat(infile); genericpage->static_wb[i].aiming_XZ_dot = cf_ReadFloat(infile); break; } case GENERICPAGE_COMMAND_WB_QUADMASK: { for(int i = 0; i < MAX_WBS_PER_OBJ; i++) { genericpage->static_wb[i].gp_quad_fire_mask = cf_ReadByte(infile); } break; } case GENERICPAGE_COMMAND_WB_WEAPON: { int i,j; i = cf_ReadByte (infile); j = cf_ReadByte (infile); cf_ReadString (genericpage->weapon_name[i][j],len-1,infile); break; } case GENERICPAGE_COMMAND_WB_FIRE_SOUND: { int i,j; i = cf_ReadByte (infile); j = cf_ReadByte (infile); cf_ReadString (genericpage->fire_sound_name[i][j],len-1,infile); break; } case GENERICPAGE_COMMAND_ANIM_SOUND_NAME: { int i,j; i = cf_ReadByte (infile); j = cf_ReadByte (infile); cf_ReadString (genericpage->anim_sound_name[i][j],len-1,infile); break; } case GENERICPAGE_COMMAND_SOUND_NAME: { int i; i = cf_ReadByte (infile); cf_ReadString (genericpage->sound_name[i],len,infile); break; } case GENERICPAGE_COMMAND_AI_SOUND_NAME: { int i; i = cf_ReadByte (infile); cf_ReadString (genericpage->ai_sound_name[i],len,infile); break; } case GENERICPAGE_COMMAND_AI_INFO: if(version <= 6) { genericpage->ai_info.flags=cf_ReadInt(infile); } else { // Makes sure there are no bugs as things are added and removed -- ask chris genericpage->ai_info.notify_flags = AI_NOTIFIES_ALWAYS_ON; genericpage->ai_info.flags=cf_ReadInt(infile); genericpage->ai_info.ai_class=cf_ReadByte(infile); genericpage->ai_info.ai_type=cf_ReadByte(infile); if(version < 13) cf_ReadInt(infile); genericpage->ai_info.movement_type=cf_ReadByte(infile); genericpage->ai_info.movement_subtype=cf_ReadByte(infile); genericpage->ai_info.fov=cf_ReadFloat(infile); if(version >= 10) { genericpage->ai_info.max_velocity=cf_ReadFloat(infile); genericpage->ai_info.max_delta_velocity=cf_ReadFloat(infile); genericpage->ai_info.max_turn_rate=cf_ReadFloat(infile); // Makes sure there are no bugs as things are added and removed -- ask chris genericpage->ai_info.notify_flags|=cf_ReadInt(infile); } if(version >= 11) { genericpage->ai_info.max_delta_turn_rate=cf_ReadFloat(infile); genericpage->ai_info.circle_distance=cf_ReadFloat(infile); genericpage->ai_info.attack_vel_percent=cf_ReadFloat(infile); genericpage->ai_info.dodge_percent=cf_ReadFloat(infile); genericpage->ai_info.dodge_vel_percent=cf_ReadFloat(infile); genericpage->ai_info.flee_vel_percent=cf_ReadFloat(infile); genericpage->ai_info.melee_damage[0]=cf_ReadFloat(infile); genericpage->ai_info.melee_damage[1]=cf_ReadFloat(infile); genericpage->ai_info.melee_latency[0]=cf_ReadFloat(infile); genericpage->ai_info.melee_latency[1]=cf_ReadFloat(infile); } else { genericpage->ai_info.max_delta_turn_rate = 16000.0; genericpage->ai_info.circle_distance = 10.0f; genericpage->ai_info.attack_vel_percent = 1.0f; genericpage->ai_info.dodge_percent = .4f; genericpage->ai_info.dodge_vel_percent = .5f; genericpage->ai_info.flee_vel_percent = 1.0f; genericpage->ai_info.melee_damage[0] = 9.0f; genericpage->ai_info.melee_damage[1] = 13.0f; genericpage->ai_info.melee_latency[0] = 3.1f; genericpage->ai_info.melee_latency[1] = 4.5f; } if(version >= 16) { genericpage->ai_info.avoid_friends_distance = cf_ReadFloat(infile); } } break; case GENERICPAGE_COMMAND_PHYS_FLAGS: genericpage->objinfo_struct.phys_info.flags=cf_ReadInt(infile); break; case GENERICPAGE_COMMAND_ROT_DRAG: genericpage->objinfo_struct.phys_info.rotdrag=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_FULL_THRUST: genericpage->objinfo_struct.phys_info.full_thrust=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_FULL_ROTTHRUST: genericpage->objinfo_struct.phys_info.full_rotthrust=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_TURNROLL_RATE: genericpage->objinfo_struct.phys_info.max_turnroll_rate=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_TURNROLL_RATIO: genericpage->objinfo_struct.phys_info.turnroll_ratio=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_WIGGLE_AMP: genericpage->objinfo_struct.phys_info.wiggle_amplitude=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_WIGGLE_FREQ: genericpage->objinfo_struct.phys_info.wiggles_per_sec=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_INT_VELOCITY: genericpage->objinfo_struct.phys_info.velocity.z=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_INT_ROTVEL: genericpage->objinfo_struct.phys_info.rotvel.x=cf_ReadFloat (infile); genericpage->objinfo_struct.phys_info.rotvel.y=cf_ReadFloat (infile); genericpage->objinfo_struct.phys_info.rotvel.z=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_NUM_BOUNCES: genericpage->objinfo_struct.phys_info.num_bounces=cf_ReadInt (infile); break; case GENERICPAGE_COMMAND_COEFF_REST: genericpage->objinfo_struct.phys_info.coeff_restitution=cf_ReadFloat (infile); break; case GENERICPAGE_COMMAND_HIT_DIE_DOT: genericpage->objinfo_struct.phys_info.hit_die_dot=cf_ReadFloat (infile); break; default: // Ignore the ones we don't know for (i=0;iobjinfo_struct.type != OBJ_NONE); if(version < 16) { genericpage->ai_info.flags |= AIF_AUTO_AVOID_FRIENDS; genericpage->ai_info.avoid_friends_distance = genericpage->ai_info.circle_distance / 10.f; if(genericpage->ai_info.avoid_friends_distance < 4.0f) genericpage->ai_info.avoid_friends_distance = 4.0f; } if (!strnicmp ("INVALID",genericpage->med_image_name,7)) strcpy (genericpage->med_image_name,""); if (!strnicmp ("INVALID",genericpage->lo_image_name,7)) strcpy (genericpage->lo_image_name,""); for (i=0;isound_name[i],7)) strcpy (genericpage->sound_name[i],""); } for (i=0;idspew_name[i],7)) strcpy (genericpage->dspew_name[i],""); } for (i=0;iai_sound_name[i],7)) strcpy (genericpage->ai_sound_name[i],""); } for (i=0;ifire_sound_name[i][t],7)) strcpy (genericpage->fire_sound_name[i][t],""); } } for (i=0;ianim_sound_name[i][t],7)) strcpy (genericpage->anim_sound_name[i][t],""); } } return 1; // successfully read } // Reads in the generic named "name" into genericpage struct // Returns 0 on error or couldn't find, else 1 if all is good int mng_FindSpecificGenericPage (char *name,mngs_generic_page *genericpage,int offset) { CFILE *infile; ubyte pagetype; int done=0,found=0; int first_try=1; char tablename[TABLE_NAME_LEN]; if (Loading_locals) { infile=cfopen (LocalTableFilename,"rb"); } else if (Loading_addon_table!=-1) { infile=cfopen (AddOnDataTables[Loading_addon_table].AddOnTableFilename,"rb"); } else { if (Network_up && Starting_editor) { int farg=FindArg("-filter"); if (farg) strcpy (tablename,GameArgs[farg+1]); else ddio_MakePath (tablename,LocalTableDir,NET_TABLE,NULL); infile=cfopen (tablename,"rb"); } else { infile = NULL; if(TablefileNameOverride) { infile=cfopen(TablefileNameOverride,"rb"); } if(!infile) infile=cfopen (TableFilename,"rb"); } } if (!infile) { mprintf ((0,"Couldn't open table file to find generic!\n")); Int3(); return 0; } try_again:; if (offset) cfseek (infile,offset,SEEK_SET); // Read in the entire page file until we find the page we want while (!done) { if (cfeof (infile)) { done=1; continue; } pagetype=cf_ReadByte (infile); int len=cf_ReadInt(infile); // If not a generic page, just read it in and ignore it if (pagetype!=PAGETYPE_GENERIC) { cfseek (infile,len-4,SEEK_CUR); continue; } mng_ReadNewGenericPage (infile,genericpage); if (!stricmp(name,genericpage->objinfo_struct.name)) { // This is the page we want found=1; done=1; } else { if (genericpage->objinfo_struct.description!=NULL) { mem_free (genericpage->objinfo_struct.description); genericpage->objinfo_struct.description = NULL; } genericpage->objinfo_struct.icon_name[0] = '\0'; } } cfclose (infile); if (!found && first_try) { done = first_try = 0; infile=cfopen ("extra.gam","rb"); if (infile) goto try_again; } return found; // successful! } // Given a generic page, allocs a generic and calls AssignGenericPageTogeneric to actually // load models and values. Rturns generic handle on success, -1 if fail int mng_SetAndLoadGeneric (mngs_generic_page *genericpage,CFILE *infile) { int i, j, n; bool f_anim = false; bool f_weapons = false; bool f_ai = false; f_ai = (genericpage->objinfo_struct.flags & OIF_CONTROL_AI)?true:false; if(f_ai) { f_weapons = f_anim = true; }else { if(genericpage->objinfo_struct.type == OBJ_ROBOT || genericpage->objinfo_struct.type == OBJ_BUILDING) { f_anim = true; } else if(genericpage->objinfo_struct.type == OBJ_POWERUP) { if(f_ai) { f_anim = true; } else { for (i=0;ianim[i].elem[j].to != 0 || genericpage->anim[i].elem[j].from != 0) { f_anim = true; break; } } } } } else if(genericpage->objinfo_struct.type == OBJ_CLUTTER) { if(f_ai) { f_anim = true; } else { for (i=0;ianim[i].elem[j].to != 0 || genericpage->anim[i].elem[j].from != 0) { f_anim = true; break; } } } } } for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < genericpage->static_wb[i].num_masks; j++) { if( genericpage->static_wb[i].gp_fire_masks[j] != 0) { f_weapons = true; break; } } } } if(Running_editor) { f_ai = f_weapons = f_anim = true; } n=AllocObjectID(genericpage->objinfo_struct.type,f_anim,f_weapons,f_ai); if (n<0) return -1; if (!mng_AssignGenericPageToObjInfo(genericpage,n,infile)) return -1; return n; } // Given a genericpage and a generic handle, attempts to make generic n correspond to // to the genericpage. // Returns 1 on success, 0 otherwise int mng_AssignGenericPageToObjInfo(mngs_generic_page *genericpage,int n,CFILE *infile) { object_info *objinfopointer=&Object_info[n]; int img_handle; int i, j; // copy our values // memcpy (objinfopointer,&genericpage->objinfo_struct,sizeof(*objinfopointer)); memcpy (objinfopointer,&genericpage->objinfo_struct,sizeof(*objinfopointer)-sizeof(anim_elem *)-sizeof(otype_wb_info *)-sizeof(t_ai_info *)); strcpy (objinfopointer->name,genericpage->objinfo_struct.name); if(objinfopointer->anim) memcpy(objinfopointer->anim,&genericpage->anim,sizeof(genericpage->anim)); if(objinfopointer->static_wb) memcpy(objinfopointer->static_wb,&genericpage->static_wb,sizeof(genericpage->static_wb)); if(objinfopointer->ai_info) memcpy(objinfopointer->ai_info,&genericpage->ai_info,sizeof(genericpage->ai_info)); objinfopointer->multi_allowed = 1; //since the description pointer was just copied over, no need to malloc mem, copy and then free old, just move ptr genericpage->objinfo_struct.description = NULL; strcpy(objinfopointer->icon_name,genericpage->objinfo_struct.icon_name); // First see if our image differs from the one on the net // If it is, make a copy // If its a release version, don't do any of this #ifndef RELEASE if (Network_up) { char str[200]; char netstr[200]; ddio_MakePath (str,LocalModelsDir,genericpage->image_name,NULL); ddio_MakePath (netstr,NetModelsDir,genericpage->image_name,NULL); UpdatePrimitive (str,netstr,genericpage->image_name,PAGETYPE_GENERIC,objinfopointer->name); if (stricmp (genericpage->med_image_name,"INVALID NAME") && genericpage->med_image_name[0]!=0) { ddio_MakePath (str,LocalModelsDir,genericpage->med_image_name,NULL); ddio_MakePath (netstr,NetModelsDir,genericpage->med_image_name,NULL); UpdatePrimitive (str,netstr,genericpage->med_image_name,PAGETYPE_GENERIC,objinfopointer->name); } if (stricmp (genericpage->lo_image_name,"INVALID NAME") && genericpage->lo_image_name[0]!=0) { ddio_MakePath (str,LocalModelsDir,genericpage->lo_image_name,NULL); ddio_MakePath (netstr,NetModelsDir,genericpage->lo_image_name,NULL); UpdatePrimitive (str,netstr,genericpage->lo_image_name,PAGETYPE_GENERIC,objinfopointer->name); } } #endif // Try and load our generic model from the disk img_handle=LoadPolyModel (genericpage->image_name,1); if (img_handle<0) { mprintf ((0,"Couldn't load file '%s' in AssignGenericPage...\n",genericpage->image_name)); objinfopointer->render_handle=-1; return 0; } else objinfopointer->render_handle=img_handle; if (stricmp (genericpage->med_image_name,"INVALID NAME") && genericpage->med_image_name[0]!=0) { img_handle=LoadPolyModel (genericpage->med_image_name,1); if (img_handle<0) { mprintf ((0,"Couldn't load file '%s' in AssignGenericPage...\n",genericpage->med_image_name)); objinfopointer->med_render_handle=-1; return 0; } else objinfopointer->med_render_handle=img_handle; } else objinfopointer->med_render_handle=-1; if (stricmp (genericpage->lo_image_name,"INVALID NAME") && genericpage->lo_image_name[0]!=0) { img_handle=LoadPolyModel (genericpage->lo_image_name,1); if (img_handle<0) { mprintf ((0,"Couldn't load file '%s' in AssignGenericPage...\n",genericpage->lo_image_name)); objinfopointer->lo_render_handle=-1; return 0; } else objinfopointer->lo_render_handle=img_handle; } else objinfopointer->lo_render_handle=-1; // Try and load the various sounds for (i=0;isound_name[i],"INVALID NAME") && genericpage->sound_name[i][0]!=0) { int sound_handle=mng_GetGuaranteedSoundPage (genericpage->sound_name[i]); if (sound_handle<0) { mprintf ((0,"Couldn't load sound file '%s' in AssignPowPage %s...\n",genericpage->sound_name[i],genericpage->objinfo_struct.name)); objinfopointer->sounds[i]=SOUND_NONE_INDEX; } else objinfopointer->sounds[i]=sound_handle; } else objinfopointer->sounds[i]=SOUND_NONE_INDEX; } for(i=0;idspew_name[i][0] != '\0') { int obj_handle = mng_GetGuaranteedGenericPage(genericpage->dspew_name[i], infile); if(obj_handle < 0) { objinfopointer->dspew[i] = 0; objinfopointer->dspew_number[i] = 0; objinfopointer->dspew_percent[i] = 0.0f; } else { objinfopointer->dspew[i] = obj_handle; } } else { objinfopointer->dspew[i] = -1; objinfopointer->dspew_number[i] = 0; objinfopointer->dspew_percent[i] = 0.0f; } } // Try and load the various sounds if(objinfopointer->ai_info) { for (i=0;iai_sound_name[i],"INVALID NAME") && genericpage->ai_sound_name[i][0]!=0) { int sound_handle=mng_GetGuaranteedSoundPage (genericpage->ai_sound_name[i]); if (sound_handle<0) { mprintf ((0,"Couldn't load ai sound file '%s' in AssignPowPage %s...\n",genericpage->ai_sound_name[i],genericpage->objinfo_struct.name)); objinfopointer->ai_info->sound[i]=SOUND_NONE_INDEX; } else objinfopointer->ai_info->sound[i]=sound_handle; } else objinfopointer->ai_info->sound[i]=SOUND_NONE_INDEX; } } // Try and load the various weapons if(objinfopointer->static_wb) { for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_GUNPOINTS; j++) { if(genericpage->weapon_name[i][j][0] != '\0') { int weapon_handle = mng_GetGuaranteedWeaponPage (genericpage->weapon_name[i][j]); if (weapon_handle < 0) { mprintf ((0,"Couldn't load weapon file '%s' in AssignPowPage %s...\n",genericpage->weapon_name[i][j],genericpage->objinfo_struct.name)); objinfopointer->static_wb[i].gp_weapon_index[j] = LASER_INDEX; } else objinfopointer->static_wb[i].gp_weapon_index[j] = weapon_handle; } else objinfopointer->static_wb[i].gp_weapon_index[j] = LASER_INDEX; } } // Try and load the various wb sounds for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_FIRING_MASKS; j++) { if(genericpage->fire_sound_name[i][j][0] != '\0') { int fire_sound_handle = mng_GetGuaranteedSoundPage (genericpage->fire_sound_name[i][j]); if (fire_sound_handle < 0) { mprintf ((0,"Couldn't load fire sound file '%s' in AssignPowPage %s...\n",genericpage->fire_sound_name[i][j],genericpage->objinfo_struct.name)); objinfopointer->static_wb[i].fm_fire_sound_index[j] = SOUND_NONE_INDEX; } else objinfopointer->static_wb[i].fm_fire_sound_index[j] = fire_sound_handle; } else objinfopointer->static_wb[i].fm_fire_sound_index[j] = SOUND_NONE_INDEX; } } } // Try and load the various wb sounds if(objinfopointer->anim) { for(i = 0; i < NUM_MOVEMENT_CLASSES; i++) { for(j = 0; j < NUM_ANIMS_PER_CLASS; j++) { if(stricmp(genericpage->anim_sound_name[i][j], "INVALID NAME") && genericpage->anim_sound_name[i][j][0]!=0) { int anim_sound_handle = mng_GetGuaranteedSoundPage (genericpage->anim_sound_name[i][j]); if (anim_sound_handle < 0) { mprintf ((0,"Couldn't load anim sound file '%s' in AssignPowPage %s...\n",genericpage->anim_sound_name[i][j],genericpage->objinfo_struct.name)); objinfopointer->anim[i].elem[j].anim_sound_index = SOUND_NONE_INDEX; } else objinfopointer->anim[i].elem[j].anim_sound_index = anim_sound_handle; } else objinfopointer->anim[i].elem[j].anim_sound_index = SOUND_NONE_INDEX; } } } // objinfopointer->size=(ComputeDefaultSize(objinfopointer->render_handle, &objinfopointer->size_offset, 0, 0)); return 1; } // Copies values from a generic into a generic_page void mng_AssignObjInfoToGenericPage(int n,mngs_generic_page *genericpage) { object_info *objinfopointer=&Object_info[n]; int i,j; // Assign the values memcpy (&genericpage->objinfo_struct,objinfopointer,sizeof(*objinfopointer)); strcpy (genericpage->objinfo_struct.name,objinfopointer->name); if(objinfopointer->anim) memcpy(&genericpage->anim,objinfopointer->anim,sizeof(genericpage->anim)); if(objinfopointer->static_wb) memcpy(&genericpage->static_wb,objinfopointer->static_wb,sizeof(genericpage->static_wb)); if(objinfopointer->ai_info) memcpy(&genericpage->ai_info,objinfopointer->ai_info,sizeof(genericpage->ai_info)); if (objinfopointer->description!=NULL) { int len=strlen (objinfopointer->description); genericpage->objinfo_struct.description=(char *)mem_malloc(len+1); ASSERT (genericpage->objinfo_struct.description); strcpy (genericpage->objinfo_struct.description,objinfopointer->description); }else genericpage->objinfo_struct.description = NULL; strcpy(genericpage->objinfo_struct.icon_name,objinfopointer->icon_name); if (objinfopointer->render_handle!=-1) strcpy (genericpage->image_name,Poly_models[objinfopointer->render_handle].name); else strcpy (genericpage->image_name,""); if (objinfopointer->med_render_handle!=-1) strcpy (genericpage->med_image_name,Poly_models[objinfopointer->med_render_handle].name); else strcpy (genericpage->med_image_name,""); if (objinfopointer->lo_render_handle!=-1) strcpy (genericpage->lo_image_name,Poly_models[objinfopointer->lo_render_handle].name); else strcpy (genericpage->lo_image_name,""); for (i=0;isounds[i]!=SOUND_NONE_INDEX) strcpy (genericpage->sound_name[i],Sounds[objinfopointer->sounds[i]].name); else strcpy (genericpage->sound_name[i],""); } for (i=0; idspew[i] != -1) && Object_info[objinfopointer->dspew[i]].type != OBJ_NONE) strcpy(genericpage->dspew_name[i], Object_info[objinfopointer->dspew[i]].name); else strcpy(genericpage->dspew_name[i], "\0"); } for (i=0;iai_info && objinfopointer->ai_info->sound[i] != SOUND_NONE_INDEX) strcpy (genericpage->ai_sound_name[i],Sounds[objinfopointer->ai_info->sound[i]].name); else strcpy (genericpage->ai_sound_name[i],""); } for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_FIRING_MASKS; j++) { if (objinfopointer->static_wb && objinfopointer->static_wb[i].fm_fire_sound_index[j] >= 0) strcpy (genericpage->fire_sound_name[i][j], Sounds[objinfopointer->static_wb[i].fm_fire_sound_index[j]].name); else strcpy (genericpage->fire_sound_name[i][j],""); } } for(i = 0; i < NUM_MOVEMENT_CLASSES; i++) { for(j = 0; j < NUM_ANIMS_PER_CLASS; j++) { if (objinfopointer->anim && objinfopointer->anim[i].elem[j].anim_sound_index >= 0) strcpy (genericpage->anim_sound_name[i][j], Sounds[objinfopointer->anim[i].elem[j].anim_sound_index].name); else strcpy (genericpage->anim_sound_name[i][j],""); } } for(i = 0; i < MAX_WBS_PER_OBJ; i++) { for(j = 0; j < MAX_WB_GUNPOINTS; j++) { if (objinfopointer->static_wb && objinfopointer->static_wb[i].gp_weapon_index[j] >= 0) strcpy (genericpage->weapon_name[i][j], Weapons[objinfopointer->static_wb[i].gp_weapon_index[j]].name); else strcpy (genericpage->weapon_name[i][j],"Laser"); } } } // Loads a generic found in the net table file. It then allocs a generic and // then calls SetAndLoadgeneric to actually load in any images/models associated // with it void mng_LoadNetGenericPage(CFILE *infile,bool overlay) { mngs_generic_page genericpage; memset(&genericpage, 0, sizeof(mngs_generic_page)); if (mng_ReadNewGenericPage (infile,&genericpage)) { int n = FindObjectIDName (genericpage.objinfo_struct.name); if (n!=-1) { if(overlay) { mprintf((0,"OVERLAYING GENERIC %s\n",genericpage.objinfo_struct.name)); mng_FreePagetypePrimitives (PAGETYPE_GENERIC,genericpage.objinfo_struct.name,0); mng_AssignGenericPageToObjInfo(&genericpage,n); } return; // A weapon has already loaded this generic } int ret=mng_SetAndLoadGeneric (&genericpage,infile); ASSERT (ret>=0); } else mprintf ((0,"Could not load genericpage named %s!\n",genericpage.objinfo_struct.name)); } // Reads a generic page from a local table file. It then allocs a generic and // loads any images/models associated with that generic void mng_LoadLocalGenericPage(CFILE *infile) { mngs_generic_page genericpage; int ok=0; memset(&genericpage, 0, sizeof(mngs_generic_page)); if (mng_ReadNewGenericPage (infile,&genericpage)) { // Check to see if this is a local copy that is supposed // to go over a network copy (supersede the net copy) int i=FindObjectIDName (genericpage.objinfo_struct.name); if (i!=-1) { // Make sure we really have this page checked out mngs_Pagelock pl; strcpy (pl.name,genericpage.objinfo_struct.name); pl.pagetype=PAGETYPE_GENERIC; /*if (Network_up && Stand_alone==0) { int locked=mng_CheckIfPageOwned(&pl,TableUser); if (locked!=1) Int3(); // Your local vs net copies of the lock file do not match }*/ ok=1; bool need_to_load_page = true; if (Loading_addon_table!=-1) { AddOnTablefile *addon; int tidx; // see if we really need to load this page //check to see if we already have loaded this page (because it was //a dependancy of another) addon = &AddOnDataTables[Loading_addon_table]; for(tidx=0;tidxNum_addon_tracklocks;tidx++) { if(addon->Addon_tracklocks[tidx].pagetype==PAGETYPE_GENERIC && !stricmp(addon->Addon_tracklocks[tidx].name,genericpage.objinfo_struct.name) ) { // found it!! mprintf((0,"GenericPage: %s previously loaded\n",genericpage.objinfo_struct.name)); need_to_load_page = false; break; } } } if(need_to_load_page) { mng_FreePagetypePrimitives (PAGETYPE_GENERIC,genericpage.objinfo_struct.name,0); mng_AssignGenericPageToObjInfo (&genericpage,i); // For addon data if (Loading_addon_table!=-1) { // this is an overlay of some sort..see which we are overlaying int overlay = 1; int addidx,tidx; bool found = false; for(addidx = Num_addon_tables-1; addidx>=0; addidx--) { if(addidx==Loading_addon_table) continue; AddOnTablefile *addon = &AddOnDataTables[addidx]; // look for the page in this table file for(tidx=0;tidxNum_addon_tracklocks;tidx++) { if(addon->Addon_tracklocks[tidx].pagetype==PAGETYPE_GENERIC && !stricmp(addon->Addon_tracklocks[tidx].name,genericpage.objinfo_struct.name) ) { // found it!! found = true; overlay = addidx+2; break; } } if(found) break; } mng_PushAddonPage (PAGETYPE_GENERIC,genericpage.objinfo_struct.name,overlay); } } } else { // This is a local generic that has never been checked in if ((i=mng_SetAndLoadGeneric (&genericpage))<0) ok=0; else ok=1; // For addon data if (ok && Loading_addon_table!=-1) mng_PushAddonPage (PAGETYPE_GENERIC,genericpage.objinfo_struct.name,0); } ASSERT (ok==1); if (Loading_addon_table==-1) mng_AllocTrackLock (genericpage.objinfo_struct.name,PAGETYPE_GENERIC); } else mprintf ((0,"Could not load genericpage named %s!\n",genericpage.objinfo_struct.name)); } // First searches through the object index to see if the object is already // loaded. If not, searches in the table file and loads it. // Returns index of object found, -1 if not int mng_GetGuaranteedGenericPage (char *name,CFILE *infile) { int i; mngs_generic_page page; // See if its in memory i = FindObjectIDName(name); if (i!=-1) return i; // Not in memory. Load it from the table file. Start searching from the // current spot in the open table file int ret = mng_FindSpecificGenericPage(name,&page,infile?infile->position:0); if (!ret) return -1; // We've found it in the table file, now load it. ret = mng_SetAndLoadGeneric(&page); ASSERT (ret>=0); if(Loading_addon_table!=-1) { // we're loading addon table pages, this will not overlay anything mng_PushAddonPage (PAGETYPE_GENERIC,page.objinfo_struct.name,0); } return ret; }