From 854c35ae491d7405187a1cba50ea188a4a0a6108 Mon Sep 17 00:00:00 2001 From: namespace Date: Fri, 5 Jan 2007 22:00:16 +0000 Subject: [PATCH] ... git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@132 8a3a26a2-13c4-0310-b231-cf6edde360e5 --- contrib/ufoai/bitmaps/ufoai_actorclip.bmp | Bin 0 -> 774 bytes contrib/ufoai/bitmaps/ufoai_level1.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_level2.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_level3.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_level4.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_level5.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_level6.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_level7.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_level8.bmp | Bin 0 -> 198 bytes contrib/ufoai/bitmaps/ufoai_stepon.bmp | Bin 0 -> 774 bytes contrib/ufoai/ufoai.cpp | 227 ++++++++++++++++ contrib/ufoai/ufoai.def | 7 + contrib/ufoai/ufoai.h | 22 ++ contrib/ufoai/ufoai.vcproj | 199 ++++++++++++++ contrib/ufoai/ufoai_filters.cpp | 292 +++++++++++++++++++++ contrib/ufoai/ufoai_filters.h | 38 +++ contrib/ufoai/ufoai_gtk.cpp | 181 +++++++++++++ contrib/ufoai/ufoai_gtk.h | 28 ++ contrib/ufoai/ufoai_level.cpp | 300 ++++++++++++++++++++++ contrib/ufoai/ufoai_level.h | 26 ++ 20 files changed, 1320 insertions(+) create mode 100644 contrib/ufoai/bitmaps/ufoai_actorclip.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level1.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level2.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level3.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level4.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level5.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level6.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level7.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_level8.bmp create mode 100644 contrib/ufoai/bitmaps/ufoai_stepon.bmp create mode 100644 contrib/ufoai/ufoai.cpp create mode 100644 contrib/ufoai/ufoai.def create mode 100644 contrib/ufoai/ufoai.h create mode 100644 contrib/ufoai/ufoai.vcproj create mode 100644 contrib/ufoai/ufoai_filters.cpp create mode 100644 contrib/ufoai/ufoai_filters.h create mode 100644 contrib/ufoai/ufoai_gtk.cpp create mode 100644 contrib/ufoai/ufoai_gtk.h create mode 100644 contrib/ufoai/ufoai_level.cpp create mode 100644 contrib/ufoai/ufoai_level.h diff --git a/contrib/ufoai/bitmaps/ufoai_actorclip.bmp b/contrib/ufoai/bitmaps/ufoai_actorclip.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5fbba7f986f3d421dd3376a85f40c1b702bf696f GIT binary patch literal 774 ycmZ?rWn*Rl12Z700mK48%n!tj3=%++f#CuZ1A`DZ1cL=YMB4vRG#UcKCIkQrKT!Gr literal 0 HcmV?d00001 diff --git a/contrib/ufoai/bitmaps/ufoai_level1.bmp b/contrib/ufoai/bitmaps/ufoai_level1.bmp new file mode 100644 index 0000000000000000000000000000000000000000..80a4b2996e9dbcf76cec18e761c746dfb15c3fb2 GIT binary patch literal 198 zcmZ?rJ;ne5en3hChy{R{ABY(lSb!u0Lj@2EaYHa0kPX5h@c;jR1`xCb!Z#vs82--s e3y}bljDlbwfS`eH1V76Jf4u@TV# literal 0 HcmV?d00001 diff --git a/contrib/ufoai/bitmaps/ufoai_level2.bmp b/contrib/ufoai/bitmaps/ufoai_level2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e84e254434fe221653da07189d16146fa36aa9ba GIT binary patch literal 198 zcmYj~!3}^g3&148an7_`^KR!az*Z6{=t-svwbbt&=GG@gU+PRw`2?mC&&Q z7c~!|o^MHEW>9X-vJ}+2MuRm?9{Ho2{CkVc;Dq`zL>ZzCC(Dn%DGO~*`|aQhD#j6R literal 0 HcmV?d00001 diff --git a/contrib/ufoai/bitmaps/ufoai_level3.bmp b/contrib/ufoai/bitmaps/ufoai_level3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..141c32457872bce1579e51417c3b8afa73c0b01f GIT binary patch literal 198 zcmY*Su?>JQ409#K!a##Kf+twm;T~?`Ag<{PRd5n2gd@kbqomt@BXCd_GLs{j(6Iw2 zISs*{Z=*p~VYRZ#Tu`qX1NJ12{3)-B&?jq=HVF}a literal 0 HcmV?d00001 diff --git a/contrib/ufoai/bitmaps/ufoai_level6.bmp b/contrib/ufoai/bitmaps/ufoai_level6.bmp new file mode 100644 index 0000000000000000000000000000000000000000..418fdd280dc849add3cc4d3d307e245e0ef77906 GIT binary patch literal 198 zcmZ?rJ;ne5en3hChy{R{ABY(lSb!u0Lj@2EaYHa0kPX5h@c;jR1`xCb!Z#vs82--s y3y}bljDlbwfJ8Ge2nquE0*qin5XfTy@iAzaJWM^vAcz)_W}q&JIS}(<76Je$4-s1c literal 0 HcmV?d00001 diff --git a/contrib/ufoai/bitmaps/ufoai_level7.bmp b/contrib/ufoai/bitmaps/ufoai_level7.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d82dab61c387a5f974bad9a52dde617aaf298b81 GIT binary patch literal 198 zcmZ?rJ;ne5en3hChy{R{ABY(lSb!u0Lj@2EaYHa0kPX5h@c;jR1`xCb!Z#vs82--s y3y}bljDlbwfJ8F@ML>Lz9EgTvpafVQoMwdZfr4Oh7%j*E;)AS!h=a_7SqK0^mJzT3 literal 0 HcmV?d00001 diff --git a/contrib/ufoai/bitmaps/ufoai_level8.bmp b/contrib/ufoai/bitmaps/ufoai_level8.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c3809538b01aa2cc6b430fa75a63c18c842e401c GIT binary patch literal 198 zcmZ?rJ;ne5en3hChy{R{ABY(lSb!u0Lj@2EaYHa0kPX5h@c;jR1`xCb!Z#vs82--s r3y}bljDlbwfS`ek9m@9Vah`ace(nQf&DBn6^LX-P5eY2E-{{e?iE* z;WM4zuSM^B`ASEXOM)*Le8@kmK3#qUkk7f|@F}JR{{kPfR)pCO8sx;mFl;1y3;h}W zuHTRV!be3sO#ZsBc{Ic=PGOIb@(7~ppY!A5-n}4^4@XJ<8U#Z^LXWV^*93{h2qgCh l7tHw}!FL)6xL1fgjBZQ04+VceYRZqN1I$bRd@BF0egOy(zykmP literal 0 HcmV?d00001 diff --git a/contrib/ufoai/ufoai.cpp b/contrib/ufoai/ufoai.cpp new file mode 100644 index 0000000..81e749f --- /dev/null +++ b/contrib/ufoai/ufoai.cpp @@ -0,0 +1,227 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "ufoai.h" +#include "ufoai_level.h" +#include "ufoai_gtk.h" +#include "ufoai_filters.h" + +#include "debugging/debugging.h" + +#include "iplugin.h" + +#include "version.h" + +#include "string/string.h" +#include "modulesystem/singletonmodule.h" + +#include + +#define PLUGIN_VERSION "0.1" + +#include "ifilter.h" +#include "ibrush.h" +#include "iundo.h" // declaration of undo system +#include "ientity.h" // declaration of entity system +#include "iscenegraph.h" // declaration of datastructure of the map +#include "scenelib.h" // declaration of datastructure of the map +#include "qerplugin.h" // declaration to use other interfaces as a plugin +#include "ieclass.h" + +class UFOAIPluginDependencies : + public GlobalRadiantModuleRef, // basic class for all other module refs + public GlobalUndoModuleRef, // used to say radiant that something has changed and to undo that + public GlobalSceneGraphModuleRef, // necessary to handle data in the mapfile (change, retrieve data) + public GlobalEntityModuleRef, // to access and modify the entities + public GlobalEntityClassManagerModuleRef +{ +public: + UFOAIPluginDependencies(void) : + GlobalEntityModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entities")), + GlobalEntityClassManagerModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("entityclass")) + { + } +}; + +namespace UFOAI +{ + GtkWindow* g_mainwnd; + + const char* init(void* hApp, void* pMainWidget) + { + g_mainwnd = GTK_WINDOW(pMainWidget); + return "Initializing GTKRadiant UFOAI plugin"; + } + const char* getName() + { + return "UFO:AI"; + } + const char* getCommandList() + { + /*GlobalRadiant().getGameName()*/ + return "About;-;Worldspawn reset (day);Worldspawn reset (night);Worldspawn (day);Worldspawn (night);Perform check;-;Level 1;Level 2;Level 3;Level 4;Level 5;Level 6;Level 7;Level 8;-;StepOn;ActorClip"; + } + const char* getCommandTitleList() + { + return ""; + } + void dispatch(const char* command, float* vMin, float* vMax, bool bSingleBrush) + { + char *message = NULL; + if(string_equal(command, "About")) + { + GlobalRadiant().m_pfnMessageBox(GTK_WIDGET(g_mainwnd), + "UFO:AI Plugin (http://www.ufoai.net)\nBuild: " __DATE__ "\nRadiant version: " RADIANT_VERSION "\nPlugin version: " PLUGIN_VERSION "\n", "About", + eMB_OK, eMB_ICONDEFAULT); + } + else if(string_equal(command, "Level 1")) + { + filter_level(CONTENTS_LEVEL1); + } + else if(string_equal(command, "Level 2")) + { + filter_level(CONTENTS_LEVEL2); + } + else if(string_equal(command, "Level 3")) + { + filter_level(CONTENTS_LEVEL3); + } + else if(string_equal(command, "Worldspawn (day)")) + { + assign_default_values_to_worldspawn(false, true, &message); + } + else if(string_equal(command, "Worldspawn (night)")) + { + assign_default_values_to_worldspawn(false, false, &message); + } + else if(string_equal(command, "Worldspawn reset (day)")) + { + assign_default_values_to_worldspawn(true, true, &message); + } + else if(string_equal(command, "Worldspawn reset (night)")) + { + assign_default_values_to_worldspawn(true, false, &message); + } + else if(string_equal(command, "Perform check")) + { + check_map_values(&message); + } + else if(string_equal(command, "Level 4")) + { + filter_level(CONTENTS_LEVEL4); + } + else if(string_equal(command, "Level 5")) + { + filter_level(CONTENTS_LEVEL5); + } + else if(string_equal(command, "Level 6")) + { + filter_level(CONTENTS_LEVEL6); + } + else if(string_equal(command, "Level 7")) + { + filter_level(CONTENTS_LEVEL7); + } + else if(string_equal(command, "Level 8")) + { + filter_level(CONTENTS_LEVEL8); + } + else if(string_equal(command, "StepOn")) + { + filter_stepon(); + } + else if(string_equal(command, "ActorClip")) + { + filter_actorclip(); + } + + if (message != NULL) + { + GlobalRadiant().m_pfnMessageBox(GTK_WIDGET(g_mainwnd), + message, "Note", + eMB_OK, eMB_ICONDEFAULT); + } + SceneChangeNotify(); + } +} // namespace + + +class UFOAIModule : public TypeSystemRef +{ + _QERPluginTable m_plugin; +public: + typedef _QERPluginTable Type; + STRING_CONSTANT(Name, "UFO:AI"); + + UFOAIModule() + { + m_plugin.m_pfnQERPlug_Init = &UFOAI::init; + m_plugin.m_pfnQERPlug_GetName = &UFOAI::getName; + m_plugin.m_pfnQERPlug_GetCommandList = &UFOAI::getCommandList; + m_plugin.m_pfnQERPlug_GetCommandTitleList = &UFOAI::getCommandTitleList; + m_plugin.m_pfnQERPlug_Dispatch = &UFOAI::dispatch; + } + _QERPluginTable* getTable() + { + return &m_plugin; + } +}; + +typedef SingletonModule SingletonUFOAIModule; + +SingletonUFOAIModule g_UFOAIModule; + + +class UFOAIToolbarDependencies : public ModuleRef<_QERPluginTable> +{ +public: + UFOAIToolbarDependencies() : ModuleRef<_QERPluginTable>("UFO:AI") + { + } +}; + +class UFOAIToolbarModule : public TypeSystemRef +{ + _QERPlugToolbarTable m_table; +public: + typedef _QERPlugToolbarTable Type; + STRING_CONSTANT(Name, "UFO:AI"); + + UFOAIToolbarModule() + { + m_table.m_pfnToolbarButtonCount = ToolbarButtonCount; + m_table.m_pfnGetToolbarButton = GetToolbarButton; + } + _QERPlugToolbarTable* getTable() + { + return &m_table; + } +}; + +typedef SingletonModule SingletonUFOAIToolbarModule; + +SingletonUFOAIToolbarModule g_UFOAIToolbarModule; + + +extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server) +{ + initialiseModule(server); + + g_UFOAIModule.selfRegister(); + g_UFOAIToolbarModule.selfRegister(); +} diff --git a/contrib/ufoai/ufoai.def b/contrib/ufoai/ufoai.def new file mode 100644 index 0000000..03e0750 --- /dev/null +++ b/contrib/ufoai/ufoai.def @@ -0,0 +1,7 @@ +; sample.def : Declares the module parameters for the DLL. + +LIBRARY "UFOAI" + +EXPORTS + ; Explicit exports can go here + Radiant_RegisterModules @1 diff --git a/contrib/ufoai/ufoai.h b/contrib/ufoai/ufoai.h new file mode 100644 index 0000000..7193fa0 --- /dev/null +++ b/contrib/ufoai/ufoai.h @@ -0,0 +1,22 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(INCLUDED_UFOAI_H) +#define INCLUDED_UFOAI_H + +#endif diff --git a/contrib/ufoai/ufoai.vcproj b/contrib/ufoai/ufoai.vcproj new file mode 100644 index 0000000..33cf6d6 --- /dev/null +++ b/contrib/ufoai/ufoai.vcproj @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/contrib/ufoai/ufoai_filters.cpp b/contrib/ufoai/ufoai_filters.cpp new file mode 100644 index 0000000..d7fec32 --- /dev/null +++ b/contrib/ufoai/ufoai_filters.cpp @@ -0,0 +1,292 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "ufoai_filters.h" + +#include "ibrush.h" +#include "ientity.h" +#include "iscenegraph.h" + +// believe me, i'm sorry +#include "../../radiant/brush.h" + +#include "generic/callback.h" + +#include + +bool actorclip_active = false; +bool stepon_active = false; +int level_active = 0; + +// TODO: This should be added to ibrush.h +// like already done for Node_getEntity in ientity.h +// FIXME: Doesn't belong here +inline Brush* Node_getBrush(scene::Node& node) +{ + return NodeTypeCast::cast(node); +} + +void hide_node(scene::Node& node, bool hide) +{ + hide + ? node.enable(scene::Node::eHidden) + : node.disable(scene::Node::eHidden); +} + +typedef std::list entitylist_t; + +class EntityFindByName : public scene::Graph::Walker +{ + const char* m_name; + entitylist_t& m_entitylist; + /* this starts at 1 << level */ + int m_flag; + int m_hide; +public: + EntityFindByName(const char* name, entitylist_t& entitylist, int flag, bool hide) + : m_name(name), m_entitylist(entitylist), m_flag(flag), m_hide(hide) + { + } + bool pre(const scene::Path& path, scene::Instance& instance) const + { + int spawnflagsInt; + Entity* entity = Node_getEntity(path.top()); + if (entity != 0) + { + if (string_equal(m_name, entity->getKeyValue("classname"))) + { + const char *spawnflags = entity->getKeyValue("spawnflags"); + globalOutputStream() << "spawnflags for " << m_name << ": " << spawnflags << ".\n"; + + if (!string_empty(spawnflags)) { + spawnflagsInt = atoi(spawnflags); + if (!(spawnflagsInt & m_flag)) + { + hide_node(path.top(), m_hide); // hide/unhide + m_entitylist.push_back(entity); + } + } + else + { + globalOutputStream() << "UFO:AI: Warning: no spawnflags for " << m_name << ".\n"; + } + } + } + return true; + } +}; + +class ForEachFace : public BrushVisitor +{ + Brush &m_brush; +public: + mutable int m_contentFlagsVis; + mutable int m_surfaceFlagsVis; + + ForEachFace(Brush& brush) + : m_brush(brush) + { + m_contentFlagsVis = -1; + m_surfaceFlagsVis = -1; + } + + void visit(Face& face) const + { +#if _DEBUG + if (m_surfaceFlagsVis < 0) + m_surfaceFlagsVis = face.getShader().m_flags.m_surfaceFlags; + else if (m_surfaceFlagsVis >= 0 && m_surfaceFlagsVis != face.getShader().m_flags.m_surfaceFlags) + globalOutputStream() << "Faces with different surfaceflags at brush\n"; + if (m_contentFlagsVis < 0) + m_contentFlagsVis = face.getShader().m_flags.m_contentFlags; + else if (m_contentFlagsVis >= 0 && m_contentFlagsVis != face.getShader().m_flags.m_contentFlags) + globalOutputStream() << "Faces with different contentflags at brush\n"; +#else + m_surfaceFlagsVis = face.getShader().m_flags.m_surfaceFlags; + m_contentFlagsVis = face.getShader().m_flags.m_contentFlags; +#endif + } +}; + +typedef std::list brushlist_t; + +class BrushGetLevel : public scene::Graph::Walker +{ + brushlist_t& m_brushlist; + int m_flag; + bool m_content; // if true - use m_contentFlags - otherwise m_surfaceFlags + mutable bool m_notset; + mutable bool m_hide; +public: + BrushGetLevel(brushlist_t& brushlist, int flag, bool content, bool notset, bool hide) + : m_brushlist(brushlist), m_flag(flag), m_content(content), m_notset(notset), m_hide(hide) + { + } + bool pre(const scene::Path& path, scene::Instance& instance) const + { + Brush* brush = Node_getBrush(path.top()); + if (brush != 0) + { + ForEachFace faces(*brush); + brush->forEachFace(faces); + // contentflags? + if (m_content) + { + // are any flags set? + if (faces.m_contentFlagsVis > 0) + { + // flag should not be set + if (m_notset && (!(faces.m_contentFlagsVis & m_flag))) + { + hide_node(path.top(), m_hide); + m_brushlist.push_back(brush); + } + // check whether flag is set + else if (!m_notset && ((faces.m_contentFlagsVis & m_flag))) + { + hide_node(path.top(), m_hide); + m_brushlist.push_back(brush); + } + } + } + // surfaceflags? + else + { + // are any flags set? + if (faces.m_surfaceFlagsVis > 0) + { + // flag should not be set + if (m_notset && (!(faces.m_surfaceFlagsVis & m_flag))) + { + hide_node(path.top(), m_hide); + m_brushlist.push_back(brush); + } + // check whether flag is set + else if (!m_notset && ((faces.m_surfaceFlagsVis & m_flag))) + { + hide_node(path.top(), m_hide); + m_brushlist.push_back(brush); + } + } + } + + } + return true; + } +}; + +/** + * @brief Activates the level filter for the given level + * @param[in] level Which level to show? + * @todo Entities + */ +void filter_level(int flag) +{ + int level; + brushlist_t brushes; + entitylist_t entities; + + level = (flag >> 8); + + if (level_active) + { + GlobalSceneGraph().traverse(BrushGetLevel(brushes, (level_active << 8), true, true, false)); + GlobalSceneGraph().traverse(EntityFindByName("func_breakable", entities, level_active, false)); + GlobalSceneGraph().traverse(EntityFindByName("misc_model", entities, level_active, false)); + entities.erase(entities.begin(), entities.end()); + brushes.erase(brushes.begin(), brushes.end()); + if (level_active == level) + { + level_active = 0; + // just disabĺe level filter + return; + } + } + level_active = level; + globalOutputStream() << "UFO:AI: level_active: " << level_active << ", flag: " << flag << ".\n"; + + // first all brushes + GlobalSceneGraph().traverse(BrushGetLevel(brushes, flag, true, true, true)); + + // now all entities + GlobalSceneGraph().traverse(EntityFindByName("func_breakable", entities, level, true)); + GlobalSceneGraph().traverse(EntityFindByName("misc_model", entities, level, true)); + +#ifdef _DEBUG + if (brushes.empty()) + { + globalOutputStream() << "UFO:AI: No brushes.\n"; + } + else + { + globalOutputStream() << "UFO:AI: Found " << Unsigned(brushes.size()) << " brushes.\n"; + } + + // now let's filter all entities like misc_model and func_breakable that have the spawnflags set + if (entities.empty()) + { + globalOutputStream() << "UFO:AI: No entities.\n"; + } + else + { + globalOutputStream() << "UFO:AI: Found " << Unsigned(entities.size()) << " entities.\n"; + } +#endif +} + +void filter_stepon (void) +{ + if (stepon_active) { + stepon_active = false; + } else { + stepon_active = true; + } + brushlist_t brushes; + GlobalSceneGraph().traverse(BrushGetLevel(brushes, CONTENTS_STEPON, true, false, stepon_active)); + + if (brushes.empty()) + { + globalOutputStream() << "UFO:AI: No brushes.\n"; + } + else + { + globalOutputStream() << "UFO:AI: Hiding " << Unsigned(brushes.size()) << " stepon brushes.\n"; + } +} + +void filter_actorclip (void) +{ + if (actorclip_active) { + actorclip_active = false; + } else { + actorclip_active = true; + } + brushlist_t brushes; + GlobalSceneGraph().traverse(BrushGetLevel(brushes, CONTENTS_ACTORCLIP, true, false, actorclip_active)); + +#ifdef _DEBUG + if (brushes.empty()) + { + globalOutputStream() << "UFO:AI: No brushes.\n"; + } + else + { + globalOutputStream() << "UFO:AI: Hiding " << Unsigned(brushes.size()) << " actorclip brushes.\n"; + } +#endif +} diff --git a/contrib/ufoai/ufoai_filters.h b/contrib/ufoai/ufoai_filters.h new file mode 100644 index 0000000..bdc40fc --- /dev/null +++ b/contrib/ufoai/ufoai_filters.h @@ -0,0 +1,38 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(INCLUDED_FILTERS_H) +#define INCLUDED_FILTERS_H + +void filter_level(int flag); +void filter_stepon(void); +void filter_actorclip(void); + +#define CONTENTS_LEVEL8 0x8000 +#define CONTENTS_LEVEL7 0x4000 +#define CONTENTS_LEVEL6 0x2000 +#define CONTENTS_LEVEL5 0x1000 +#define CONTENTS_LEVEL4 0x0800 +#define CONTENTS_LEVEL3 0x0400 +#define CONTENTS_LEVEL2 0x0200 +#define CONTENTS_LEVEL1 0x0100 +#define CONTENTS_ACTORCLIP 0x10000 + +#define CONTENTS_STEPON 0x40000000 + +#endif diff --git a/contrib/ufoai/ufoai_gtk.cpp b/contrib/ufoai/ufoai_gtk.cpp new file mode 100644 index 0000000..3fff09b --- /dev/null +++ b/contrib/ufoai/ufoai_gtk.cpp @@ -0,0 +1,181 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "ufoai_gtk.h" +#include "ufoai_filters.h" + +#include "itoolbar.h" +#include "iscenegraph.h" + +#include + +/** + * GTK callback functions + */ + +class UFOAIGtk +{ + GtkWindow* m_gtk_window; +public: + UFOAIGtk(void* gtk_window) : m_gtk_window((GtkWindow*)gtk_window) + { + } +}; + +/** + * @brief If you return FALSE in the "delete_event" signal handler, + * GTK will emit the "destroy" signal. Returning TRUE means + * you don't want the window to be destroyed. + * This is useful for popping up 'are you sure you want to quit?' + * type dialogs. + */ +static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + return FALSE; +} + +/** + * @brief destroy widget if destroy signal is passed to widget + */ +static void destroy(GtkWidget *widget, gpointer data) +{ + gtk_widget_destroy(widget); +} + +/** + * @brief function for close button to destroy the toplevel widget + */ +static void close_window(GtkWidget *widget, gpointer data) +{ + gtk_widget_destroy(gtk_widget_get_toplevel(widget)); +} + +/* =============================== */ + +#define NUM_TOOLBARBUTTONS 10 + +/** + * @brief + */ +std::size_t ToolbarButtonCount(void) +{ + return NUM_TOOLBARBUTTONS; +} + +/** + * @brief + */ +class CUFOAIToolbarButton : public IToolbarButton +{ +public: + virtual const char* getImage() const + { + switch( mIndex ) + { + case 0: return "ufoai_level1.bmp"; + case 1: return "ufoai_level2.bmp"; + case 2: return "ufoai_level3.bmp"; + case 3: return "ufoai_level4.bmp"; + case 4: return "ufoai_level5.bmp"; + case 5: return "ufoai_level6.bmp"; + case 6: return "ufoai_level7.bmp"; + case 7: return "ufoai_level8.bmp"; + case 8: return "ufoai_stepon.bmp"; + case 9: return "ufoai_actorclip.bmp"; + } + return NULL; + } + virtual EType getType() const + { + switch( mIndex ) + { +/* case 3: return eButton;*/ + case 8: return eToggleButton; + case 9: return eToggleButton; + default: return eButton; + } + } + virtual const char* getText() const + { + switch( mIndex ) + { + case 0: return "Level 1"; + case 1: return "Level 2"; + case 2: return "Level 3"; + case 3: return "Level 4"; + case 4: return "Level 5"; + case 5: return "Level 6"; + case 6: return "Level 7"; + case 7: return "Level 8"; + case 8: return "Stepon"; + case 9: return "Actorclip"; + } + return NULL; + } + virtual const char* getTooltip() const + { + switch( mIndex ) + { + case 0: return "Show only level 1"; + case 1: return "Show only level 2"; + case 2: return "Show only level 3"; + case 3: return "Show only level 4"; + case 4: return "Show only level 5"; + case 5: return "Show only level 6"; + case 6: return "Show only level 7"; + case 7: return "Show only level 8"; + case 8: return "Hide stepon brushes"; + case 9: return "Hide actorclip brushes"; + } + return NULL; + } + + virtual void activate() const + { + switch( mIndex ) + { + case 0: filter_level(CONTENTS_LEVEL1); break; + case 1: filter_level(CONTENTS_LEVEL2); break; + case 2: filter_level(CONTENTS_LEVEL3); break; + case 3: filter_level(CONTENTS_LEVEL4); break; + case 4: filter_level(CONTENTS_LEVEL5); break; + case 5: filter_level(CONTENTS_LEVEL6); break; + case 6: filter_level(CONTENTS_LEVEL7); break; + case 7: filter_level(CONTENTS_LEVEL8); break; + case 8: filter_stepon(); break; + case 9: filter_actorclip(); break; + } + SceneChangeNotify(); + } + + std::size_t mIndex; +}; + +/** + * @brief + */ +CUFOAIToolbarButton g_ufoaiToolbarButtons[NUM_TOOLBARBUTTONS]; + +/** + * @brief + */ +const IToolbarButton* GetToolbarButton(std::size_t index) +{ + g_ufoaiToolbarButtons[index].mIndex = index; + return &g_ufoaiToolbarButtons[index]; +} diff --git a/contrib/ufoai/ufoai_gtk.h b/contrib/ufoai/ufoai_gtk.h new file mode 100644 index 0000000..6199bdb --- /dev/null +++ b/contrib/ufoai/ufoai_gtk.h @@ -0,0 +1,28 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(INCLUDED_UFOAI_GTK_H) +#define INCLUDED_UFOAI_GTK_H + +#include "itoolbar.h" +#include + +const IToolbarButton* GetToolbarButton(std::size_t index); +std::size_t ToolbarButtonCount(void); + +#endif diff --git a/contrib/ufoai/ufoai_level.cpp b/contrib/ufoai/ufoai_level.cpp new file mode 100644 index 0000000..71f72a2 --- /dev/null +++ b/contrib/ufoai/ufoai_level.cpp @@ -0,0 +1,300 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "ufoai_level.h" +#include "ufoai_filters.h" + +#include "ibrush.h" +#include "ientity.h" +#include "iscenegraph.h" + +#include "string/string.h" +#include + +class Level; + +/** + * @brief find entities by class + * @note from radiant/map.cpp + */ +class EntityFindByClassname : public scene::Graph::Walker +{ + const char* m_name; + Entity*& m_entity; +public: + EntityFindByClassname(const char* name, Entity*& entity) : m_name(name), m_entity(entity) + { + m_entity = 0; + } + bool pre(const scene::Path& path, scene::Instance& instance) const + { + if(m_entity == 0) + { + Entity* entity = Node_getEntity(path.top()); + if(entity != 0 && string_equal(m_name, entity->getKeyValue("classname"))) + { + m_entity = entity; + } + } + return true; + } +}; + +/** + * @brief + */ +Entity* Scene_FindEntityByClass(const char* name) +{ + Entity* entity = NULL; + GlobalSceneGraph().traverse(EntityFindByClassname(name, entity)); + return entity; +} + +/** + * @brief finds start positions + */ +class EntityFindTeams : public scene::Graph::Walker +{ + const char *m_classname; + int *m_count; + int *m_team; + +public: + EntityFindTeams(const char *classname, int *count, int *team) : m_classname(classname), m_count(count), m_team(team) + { + } + bool pre(const scene::Path& path, scene::Instance& instance) const + { + const char *str; + Entity* entity = Node_getEntity(path.top()); + if(entity != 0 && string_equal(m_classname, entity->getKeyValue("classname"))) + { + if (m_count) + (*m_count)++; + // now get the highest teamnum + if (m_team) + { + str = entity->getKeyValue("team"); + if (!string_empty(str)) + { + if (atoi(str) > *m_team) + (*m_team) = atoi(str); + } + } + } + return true; + } +}; + +/** + * @brief + */ +void get_team_count (const char *classname, int *count, int *team) +{ + GlobalSceneGraph().traverse(EntityFindTeams(classname, count, team)); + globalOutputStream() << "UFO:AI: classname: " << classname << ": #" << (*count) << "\n"; +} + +/** + * @brief Some default values to worldspawn like maxlevel, maxteams and so on + */ +void assign_default_values_to_worldspawn (bool override, bool day, char **returnMsg) +{ + static char message[1024]; + Entity* worldspawn; + int teams = 0; + int count = 0; + char str[64]; + + worldspawn = Scene_FindEntityByClass("worldspawn"); + if (!worldspawn) + { + globalOutputStream() << "UFO:AI: Could not find worldspawn.\n"; + *returnMsg = "Could not find worldspawn"; + return; + } + + *message = '\0'; + *str = '\0'; + + get_team_count("info_player_start", &count, &teams); + + // TODO: Get highest brush - a level has 64 units + worldspawn->setKeyValue("maxlevel", "5"); + + if (string_empty(worldspawn->getKeyValue("maxteams")) + || atoi(worldspawn->getKeyValue("maxteams")) != teams) + { + snprintf(str, sizeof(str) - 1, "%i", teams); + worldspawn->setKeyValue("maxteams", str); + strncat(message, "Worldspawn: Set maxteams to ", sizeof(message) - 1); + strncat(message, str, sizeof(message) - 1); + strncat(message, "\n", sizeof(message) - 1); + } + + if (day) + { + if (override) + { + worldspawn->setKeyValue("light", "160"); + worldspawn->setKeyValue("_color", "1 0.8 0.8"); + worldspawn->setKeyValue("angles", "30 210"); + worldspawn->setKeyValue("ambient", "0.4 0.4 0.4"); + } + else + { + if (string_empty(worldspawn->getKeyValue("light"))) + { + worldspawn->setKeyValue("light", "160"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + if (string_empty(worldspawn->getKeyValue("_color"))) + { + worldspawn->setKeyValue("_color", "1 0.8 0.8"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + if (string_empty(worldspawn->getKeyValue("angles"))) + { + worldspawn->setKeyValue("angles", "30 210"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + if (string_empty(worldspawn->getKeyValue("ambient"))) + { + worldspawn->setKeyValue("ambient", "0.4 0.4 0.4"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + } + } + else + { + if (override) + { + worldspawn->setKeyValue("light", "60"); + worldspawn->setKeyValue("_color", "0.8 0.8 1"); + worldspawn->setKeyValue("angles", "15 60"); + worldspawn->setKeyValue("ambient", "0.25 0.25 0.275"); + } + else + { + if (string_empty(worldspawn->getKeyValue("light"))) + { + worldspawn->setKeyValue("light", "60"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + if (string_empty(worldspawn->getKeyValue("_color"))) + { + worldspawn->setKeyValue("_color", "0.8 0.8 1"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + if (string_empty(worldspawn->getKeyValue("angles"))) + { + worldspawn->setKeyValue("angles", "15 60"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + if (string_empty(worldspawn->getKeyValue("ambient"))) + { + worldspawn->setKeyValue("ambient", "0.25 0.25 0.275"); + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), "Set ambient to: %s", worldspawn->getKeyValue("ambient")); + } + } + } + + if (override) + { + snprintf(&message[strlen(message)], sizeof(message) - 1 - strlen(message), + "Set light to: %s\n" + "Set _color to: %s\n" + "Set angles to: %s\n" + "Set ambient to: %s\n", + worldspawn->getKeyValue("light"), + worldspawn->getKeyValue("_color"), + worldspawn->getKeyValue("angles"), + worldspawn->getKeyValue("ambient") + ); + } + + // no errors - no warnings + if (!strlen(message)) + return; + + *returnMsg = message; +} + +/** + * @brief Will check e.g. the map entities for valid values + * @todo: Check whether all misc_model and func_breakable have spawnflags + * @todo: check for maxlevel + */ +void check_map_values (char **returnMsg) +{ + static char message[1024]; + int count = 0; + int teams = 0; + Entity* worldspawn; + char str[64]; + + worldspawn = Scene_FindEntityByClass("worldspawn"); + if (!worldspawn) + { + globalOutputStream() << "UFO:AI: Could not find worldspawn.\n"; + *returnMsg = "Could not find worldspawn"; + return; + } + + *message = '\0'; + *str = '\0'; + + // multiplayer start positions + get_team_count("info_player_start", &count, &teams); + if (!count) + strncat(message, "No multiplayer start positions (info_player_start)\n", sizeof(message) - 1); + else if (string_empty(worldspawn->getKeyValue("maxteams"))) + { + snprintf(message, sizeof(message) - 1, "Worldspawn: No maxteams defined (#info_player_start) (set to: %i)\n", teams); + snprintf(str, sizeof(str) - 1, "%i", teams); + worldspawn->setKeyValue("maxteams", str); + } + else if (teams != atoi(worldspawn->getKeyValue("maxteams"))) + snprintf(message, sizeof(message) - 1, "Worldspawn: Settings for maxteams (%s) doesn't match team count (%i)\n", worldspawn->getKeyValue("maxteams"), teams); + + // singleplayer map? + count = 0; + get_team_count("info_human_start", &count, NULL); + if (!count) + strncat(message, "No singleplayer start positions (info_human_start)\n", sizeof(message) - 1); + + // search for civilians + count = 0; + get_team_count("info_civilian_start", &count, NULL); + if (!count) + strncat(message, "No civilian start positions (info_civilian_start)\n", sizeof(message) - 1); + + // check maxlevel + if (string_empty(worldspawn->getKeyValue("maxlevel"))) + strncat(message, "Worldspawn: No maxlevel defined\n", sizeof(message) - 1); + else if (atoi(worldspawn->getKeyValue("maxlevel")) > 8) + { + strncat(message, "Worldspawn: Highest maxlevel is 8\n", sizeof(message) - 1); + worldspawn->setKeyValue("maxlevel", "8"); + } + // no errors - no warnings + if (!strlen(message)) + return; + + *returnMsg = message; +} diff --git a/contrib/ufoai/ufoai_level.h b/contrib/ufoai/ufoai_level.h new file mode 100644 index 0000000..b545c20 --- /dev/null +++ b/contrib/ufoai/ufoai_level.h @@ -0,0 +1,26 @@ +/* +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if !defined(INCLUDED_UFOAI_LEVEL_H) +#define INCLUDED_UFOAI_LEVEL_H + +void assign_default_values_to_worldspawn (bool override, bool day, char **returnMsg); +void check_map_values (char **returnMsg); +void get_team_count (const char *classname, int *count, int *team); + +#endif