diff --git a/README.md b/README.md index 47ad40f8..0be5ed79 100644 --- a/README.md +++ b/README.md @@ -377,15 +377,22 @@ r_useFilmicPostProcessEffects | Apply several post process effects to m ## Modding Support Name | Description :--------------------------------------| :------------------------------------------------ -exportDeclsToJSON | Command: exports all entity and model defs to exported/entities.json for usage in Blender -postLoadExportModels | Export models after loading to OBJ model format -exportMapToOBJ | Convert .map file to .obj/.mtl +exportScriptEvents | Command: Generates a new script/doom_events.script that reflects all registered class events in the idClass C++ system. The gamecode still needs to be extended to add the original comments of the events +exportDeclsToJSON | Command: Exports all entity and model defs to exported/entities.json for usage in Blender +postLoadExportModels | Cvar: Export models after loading to OBJ model format. Set it to 1 before loading a map. +exportMapToOBJ | Command: Convert .map file to .obj/.mtl +swf_exportAtlas | Cvar: Set to 1 at startup to dump the Flash images to exported/swf/ +swf_exportSWF | Cvar: Set to 1 at startup to dump the Flash .bswf files as .swf (WIP) +swf_exportJSON | Cvar: Set to 1 at startup to dump the Flash .bswf files as .json. Can be reimported into the engine and imported into Blender for inspection +swf_show | Cvar: Draws the bounding box of instanced Flash sprites in red and their names dmap | Command: Compiles a .map to its corresponding BSP .proc, Collision .cm files and Area Awareness System (AI navigation) .aas files. Just type dmap to list all options dmap -glview | DMap option that exports the BSP areas and portals to .obj for debugging purposes -convertMapToJSON | Command: Convert .map file to new .json map format with polygons instead of brushes. This was easy because the original .map format is only an array of entities and each entity has a simple dictionary for its values. This JSON format contains all level data and can be imported and exported to Blender without loosing any data. The new DMap can also compile map files with the .json suffix like regular maps. +convertMapToJSON | Command: Convert .map file to new .json map format with polygons instead of brushes. This was easy because the original .map format is only an array of entities and each entity has a simple dictionary for its values. This JSON format contains all level data and can be imported and exported to Blender without loosing any data. The new DMap can also compile map files with the .json suffix like regular maps. + + + + - - ____ # Known Issues diff --git a/neo/d3xp/Player.cpp b/neo/d3xp/Player.cpp index 84f6ed2a..6ec28f6d 100644 --- a/neo/d3xp/Player.cpp +++ b/neo/d3xp/Player.cpp @@ -106,7 +106,9 @@ const idEventDef EV_Player_ExitTeleporter( "exitTeleporter" ); const idEventDef EV_Player_StopAudioLog( "stopAudioLog" ); const idEventDef EV_Player_HideTip( "hideTip" ); const idEventDef EV_Player_LevelTrigger( "levelTrigger" ); -const idEventDef EV_SpectatorTouch( "spectatorTouch", "et" ); +// RB: changed to internal event as it was not exposed to Doom Script by default and broke the automatic export +const idEventDef EV_SpectatorTouch( "", "et" ); +// RB end const idEventDef EV_Player_GiveInventoryItem( "giveInventoryItem", "s" ); const idEventDef EV_Player_RemoveInventoryItem( "removeInventoryItem", "s" ); const idEventDef EV_Player_GetIdealWeapon( "getIdealWeapon", NULL, 's' ); diff --git a/neo/d3xp/gamesys/Class.cpp b/neo/d3xp/gamesys/Class.cpp index 108eb039..4df93379 100644 --- a/neo/d3xp/gamesys/Class.cpp +++ b/neo/d3xp/gamesys/Class.cpp @@ -1143,3 +1143,288 @@ void idClass::Event_SafeRemove() // Forces the remove to be done at a safe time PostEventMS( &EV_Remove, 0 ); } + + +// RB: development tool +void idClass::ExportScriptEvents_f( const idCmdArgs& args ) +{ + // allocate temporary memory for flags so that the subclass's event callbacks + // override the superclass's event callback + int numEventDefs = idEventDef::NumEventCommands(); + bool* set = new bool[ numEventDefs ]; + + enum + { + EXPORTLANG_DOOMSCRIPT, + EXPORTLANG_DOOMSHARP, + NUM_EXPORTLANGS, + }; + + // go through the inheritence order +#if 1 //defined(USE_DOOMSHARP) + for( int exportLang = 0; exportLang < NUM_EXPORTLANGS; exportLang++ ) +#else + int exportLang = 0; +#endif + { + bool threadClassFound = false; + bool firstEntityClassFound = false; + + memset( set, 0, sizeof( bool ) * numEventDefs ); + +#if 1 //defined(USE_DOOMSHARP) + idFile* file = NULL; + if( exportLang == EXPORTLANG_DOOMSHARP ) + { + file = fileSystem->OpenFileWrite( "script/doom_events.cs", "fs_basepath" ); + } + else + { + file = fileSystem->OpenFileWrite( "script/doom_events.script", "fs_basepath" ); + } +#else + idFile* file = fileSystem->OpenFileWrite( "script/doom_events.script", "fs_basepath" ); + +#endif + + file->Printf( "// generated by RBDOOM-3-BFG\n//\n\n" ); + + if( exportLang == EXPORTLANG_DOOMSHARP ) + { + //file->Printf( "#if CSHARP\n\n" ); + + file->Printf( "using vector;\n\n" ); + } + + for( const idTypeInfo* c = classHierarchy.GetNext(); c != NULL; c = c->node.GetNext() ) + { + idEventFunc* def = c->eventCallbacks; + if( !def || !def[ 0 ].event ) + { + // no new events or overrides + continue; + } + + + if( exportLang == EXPORTLANG_DOOMSHARP ) + { + //if( c->IsType( idEntity::Type ) && threadClassFound ) + //{ + // file->Printf( "\n}\n\n\n" ); + //} + + file->Printf( "\n/// \n" ); + file->Printf( "/// %-24s ---> %-24s\n", c->classname, c->superclass ); + file->Printf( "/// \n" ); + + if( !c->IsType( idThread::Type ) && !c->IsType( idEntity::Type ) ) + { + continue; + } + else if( c->IsType( idThread::Type ) ) + { + file->Printf( "class sys\n{\n" ); + + threadClassFound = true; + } + else if( c->IsType( idEntity::Type ) && !firstEntityClassFound ) + { + file->Printf( "\n}\n\n\n" ); + + file->Printf( "class entity\n{\n" ); + file->Printf( "\tpublic void remove() { }\n\n" ); + + firstEntityClassFound = true; + } + } + else + { + file->Printf( "/*\n\n" ); + file->Printf( "%-24s ---> %-24s\n\n", c->classname, c->superclass ); + file->Printf( "*/\n\n" ); + } + + + // go through each entry until we hit the NULL terminator + for( int j = 0; def[ j ].event != NULL; j++ ) + { + const idEventDef* ev = def[ j ].event; + int evNum = ev->GetEventNum(); + + if( set[ evNum ] ) + { + //continue; + } + + if( ev->GetName()[0] == '_' || ev->GetName()[0] == '<' ) + { + // internal event + continue; + } + + if( set[ evNum ] ) + { + file->Printf( "// override " ); + } + + set[ evNum ] = true; + + if( exportLang == EXPORTLANG_DOOMSHARP ) + { + if( c->IsType( idThread::Type ) ) + { + file->Printf( "\tpublic static " ); + } + else + { + file->Printf( "\tpublic " ); + } + } + else + { + file->Printf( "scriptEvent " ); + } + + switch( ev->GetReturnType() ) + { + case D_EVENT_FLOAT : + file->Printf( "float " ); + break; + + case D_EVENT_INTEGER : + file->Printf( "float " ); + break; + + case D_EVENT_VECTOR : + file->Printf( "vector " ); + break; + + case D_EVENT_STRING : + file->Printf( "string " ); + break; + + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + file->Printf( "entity " ); + break; + + case 0: + file->Printf( "void " ); + break; + + default: + case D_EVENT_TRACE : + file->Printf( " " ); + break; + } + + file->Printf( "%s(", ev->GetName() ); + + if( ev->GetNumArgs() ) + { + file->Printf( " " ); + } + + const char* formatspec = ev->GetArgFormat(); + for( int arg = 0; arg < ev->GetNumArgs(); arg++ ) + { + if( arg != 0 ) + { + file->Printf( ", " ); + } + + switch( formatspec[ arg ] ) + { + case D_EVENT_FLOAT : + file->Printf( "float parm%d", arg ); + break; + + case D_EVENT_INTEGER : + file->Printf( "float parm%d", arg ); + break; + + case D_EVENT_VECTOR : + file->Printf( "vector parm%d", arg ); + break; + + case D_EVENT_STRING : + file->Printf( "string parm%d", arg ); + break; + + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + file->Printf( "entity parm%d", arg ); + break; + + case 0: + // void + break; + + default: + case D_EVENT_TRACE : + file->Printf( " parm%d", arg ); + break; + } + } + + if( ev->GetNumArgs() ) + { + file->Printf( " " ); + } + + if( exportLang == EXPORTLANG_DOOMSHARP ) + { + file->Printf( ") " ); + + switch( ev->GetReturnType() ) + { + case D_EVENT_FLOAT : + file->Printf( "{ return 0; }\n\n" ); + break; + + case D_EVENT_INTEGER : + file->Printf( "{ return 0; }\n\n" ); + break; + + case D_EVENT_VECTOR : + file->Printf( "{ return new vector( 0, 0, 0 ); }\n\n" ); + break; + + case D_EVENT_STRING : + file->Printf( "{ return \"\"; }\n\n" ); + break; + + case D_EVENT_ENTITY : + case D_EVENT_ENTITY_NULL : + file->Printf( "{ return null; }\n\n" ); + break; + + case 0: + file->Printf( "{ }\n\n" ); + break; + + default: + case D_EVENT_TRACE : + file->Printf( " " ); + break; + } + } + else + { + file->Printf( ");\n\n" ); + } + } + } + + if( exportLang == EXPORTLANG_DOOMSHARP ) + { + file->Printf( "\n}\n\n" ); + //file->Printf( "#endif // CSHARP\n\n" ); + } + + fileSystem->CloseFile( file ); + } + + delete[] set; +} +// RB end \ No newline at end of file diff --git a/neo/d3xp/gamesys/SysCmds.cpp b/neo/d3xp/gamesys/SysCmds.cpp index e85fba0a..7f4a1cb9 100644 --- a/neo/d3xp/gamesys/SysCmds.cpp +++ b/neo/d3xp/gamesys/SysCmds.cpp @@ -2737,6 +2737,10 @@ void idGameLocal::InitConsoleCommands() cmdSystem->AddCommand( "showViewNotes", Cmd_ShowViewNotes_f, CMD_FL_GAME | CMD_FL_CHEAT, "show any view notes for the current map, successive calls will cycle to the next note" ); cmdSystem->AddCommand( "closeViewNotes", Cmd_CloseViewNotes_f, CMD_FL_GAME | CMD_FL_CHEAT, "close the view showing any notes for this map" ); + // RB begin + cmdSystem->AddCommand( "exportScriptEvents", idClass::ExportScriptEvents_f, CMD_FL_GAME | CMD_FL_CHEAT, "update script/doom_events.script" ); + // RB end + // multiplayer client commands ( replaces old impulses stuff ) //cmdSystem->AddCommand( "clientDropWeapon", idMultiplayerGame::DropWeapon_f, CMD_FL_GAME, "drop current weapon" ); cmdSystem->AddCommand( "clientMessageMode", idMultiplayerGame::MessageMode_f, CMD_FL_GAME, "ingame gui message mode" );