]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/entity.cpp
support misc_*model as misc_model in the radiant editor (way more convenient)
[xonotic/netradiant.git] / radiant / entity.cpp
index c2a31091b1b07556d12b5ea21102444a597eb23a..055de6362f10b58b6204326a3f25cc6a08f7df30 100644 (file)
@@ -156,6 +156,101 @@ void Entity_ungroupSelected()
 }
 
 
+class EntityFindSelected : public scene::Graph::Walker
+{
+public:
+  mutable const scene::Path *groupPath;
+  mutable scene::Instance *groupInstance;
+  EntityFindSelected(): groupPath(0), groupInstance(0)
+  {
+  }
+  bool pre(const scene::Path& path, scene::Instance& instance) const
+  {
+    return true;
+  }
+  void post(const scene::Path& path, scene::Instance& instance) const
+  {
+    Entity* entity = Node_getEntity(path.top());
+    if(entity != 0
+      && Instance_getSelectable(instance)->isSelected()
+         && node_is_group(path.top())
+         && !groupPath)
+    { 
+         groupPath = &path;
+         groupInstance = &instance;
+    }
+  }
+};
+
+class EntityGroupSelected : public scene::Graph::Walker
+{
+       NodeSmartReference group;
+       //typedef std::pair<NodeSmartReference, NodeSmartReference> DeletionPair;
+       //Stack<DeletionPair> deleteme;
+       public:
+       EntityGroupSelected(const scene::Path &p): group(p.top().get())
+       {
+       }
+       bool pre(const scene::Path& path, scene::Instance& instance) const
+       {
+               return true;
+       }
+       void post(const scene::Path& path, scene::Instance& instance) const
+       {
+               Selectable *selectable = Instance_getSelectable(instance);
+               if(selectable && selectable->isSelected())
+               { 
+                       Entity* entity = Node_getEntity(path.top());
+                       if(entity == 0 && Node_isPrimitive(path.top()))
+                       {
+                               NodeSmartReference child(path.top().get());
+                               NodeSmartReference parent(path.parent().get());
+
+                               if(path.size() >= 3 && parent != Map_FindOrInsertWorldspawn(g_map))
+                               {
+                                       NodeSmartReference parentparent(path[path.size() - 3].get());
+
+                                       Node_getTraversable(parent)->erase(child);
+                                       Node_getTraversable(group)->insert(child);
+
+                                       if(Node_getTraversable(parent)->empty())
+                                       {
+                                               //deleteme.push(DeletionPair(parentparent, parent));
+                                               Node_getTraversable(parentparent)->erase(parent);
+                                       }
+                               }
+                               else
+                               {
+                                       Node_getTraversable(parent)->erase(child);
+                                       Node_getTraversable(group)->insert(child);
+                               }
+                       }
+               }
+       }
+};
+
+void Entity_groupSelected()
+{
+  if (GlobalSelectionSystem().countSelected() < 1) return;
+
+  UndoableCommand undo("groupSelectedEntities");
+
+  scene::Path world_path(makeReference(GlobalSceneGraph().root()));
+  world_path.push(makeReference(Map_FindOrInsertWorldspawn(g_map)));
+
+  EntityFindSelected fse;
+  GlobalSceneGraph().traverse(fse);
+  if(fse.groupPath)
+  {
+         GlobalSceneGraph().traverse(EntityGroupSelected(*fse.groupPath));
+  }
+  else
+  {
+         GlobalSceneGraph().traverse(EntityGroupSelected(world_path));
+  }
+}
+
+
 
 void Entity_connectSelected()
 {
@@ -163,7 +258,8 @@ void Entity_connectSelected()
   {
     GlobalEntityCreator().connectEntities(
       GlobalSelectionSystem().penultimateSelected().path(),
-      GlobalSelectionSystem().ultimateSelected().path()
+      GlobalSelectionSystem().ultimateSelected().path(),
+      0
     );
   }
   else
@@ -172,6 +268,22 @@ void Entity_connectSelected()
   }
 }
 
+void Entity_killconnectSelected()
+{
+  if(GlobalSelectionSystem().countSelected() == 2)
+  {
+    GlobalEntityCreator().connectEntities(
+      GlobalSelectionSystem().penultimateSelected().path(),
+      GlobalSelectionSystem().ultimateSelected().path(),
+      1
+    );
+  }
+  else
+  {
+    globalErrorStream() << "entityKillConnectSelected: exactly two instances must be selected\n";
+  }
+}
+
 AABB Doom3Light_getBounds(const AABB& workzone)
 {
   AABB aabb(workzone);
@@ -216,8 +328,7 @@ void Entity_createFromSelection(const char* name, const Vector3& origin)
 
   EntityClass* entityClass = GlobalEntityClassManager().findOrInsert(name, true);
 
-  bool isModel = string_equal_nocase(name, "misc_model")
-    || string_equal_nocase(name, "misc_gamemodel")
+  bool isModel = (string_compare_nocase_n(name, "misc_", 5) == 0 && string_equal_nocase(name + string_length(name) - 5, "model")) // misc_*model (also misc_model)
     || string_equal_nocase(name, "model_static")
     || (GlobalSelectionSystem().countSelected() == 0 && string_equal_nocase(name, "func_static"));
 
@@ -324,7 +435,7 @@ void Entity_createFromSelection(const char* name, const Vector3& origin)
   }
 }
 
-
+#if 0
 bool DoNormalisedColor(Vector3& color)
 {
   if(!color_dialog(GTK_WIDGET(MainFrame_getWindow()), color))
@@ -359,13 +470,75 @@ bool DoNormalisedColor(Vector3& color)
 
   return true;
 }
+#endif 
+
+void NormalizeColor(Vector3& color)
+{
+  // scale colors so that at least one component is at 1.0F 
+
+  float largest = 0.0F;
+
+  if ( color[0] > largest )
+    largest = color[0];
+  if ( color[1] > largest )
+    largest = color[1];
+  if ( color[2] > largest )
+    largest = color[2];
+
+  if ( largest == 0.0F )
+  {
+    color[0] = 1.0F;
+    color[1] = 1.0F;
+    color[2] = 1.0F;
+  }
+  else
+  {
+    float scaler = 1.0F / largest;
+
+    color[0] *= scaler;
+    color[1] *= scaler;
+    color[2] *= scaler;
+  }
+}
+
+void Entity_normalizeColor()
+{
+       if(GlobalSelectionSystem().countSelected() != 0)
+       {
+               const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path();
+               Entity* entity = Node_getEntity(path.top());
+
+               if(entity != 0)
+               {
+                       const char* strColor = entity->getKeyValue("_color");
+                       if(!string_empty(strColor))
+                       {
+                               Vector3 rgb;
+                               if (string_parse_vector3(strColor, rgb))
+                               {
+                                       g_entity_globals.color_entity = rgb;
+                                       NormalizeColor(g_entity_globals.color_entity);
+
+                                       char buffer[128];
+                                       sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0],
+                                               g_entity_globals.color_entity[1],
+                                               g_entity_globals.color_entity[2]);
+
+                                       Scene_EntitySetKeyValue_Selected("_color", buffer);
+                               }
+                       }
+               }
+       }
+}
 
 void Entity_setColour()
 {
   if(GlobalSelectionSystem().countSelected() != 0)
   {
+       bool normalize = false;
     const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path();
     Entity* entity = Node_getEntity(path.top());
+
     if(entity != 0)
     {
       const char* strColor = entity->getKeyValue("_color");
@@ -378,17 +551,21 @@ void Entity_setColour()
         }
       }
 
-      if(g_pGameDescription->mGameType == "doom3"
-        ? color_dialog(GTK_WIDGET(MainFrame_getWindow()), g_entity_globals.color_entity)
-        : DoNormalisedColor(g_entity_globals.color_entity))
-      {
-        char buffer[128];
-        sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0],
-                g_entity_globals.color_entity[1],
-                g_entity_globals.color_entity[2]);
+         if( g_pGameDescription->mGameType == "doom3" )
+                 normalize = false;
 
-        Scene_EntitySetKeyValue_Selected("_color", buffer);
-      }
+         if(color_dialog(GTK_WIDGET(MainFrame_getWindow()), g_entity_globals.color_entity))
+         {
+                 if( normalize )
+                         NormalizeColor(g_entity_globals.color_entity);
+
+                 char buffer[128];
+                 sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0],
+                         g_entity_globals.color_entity[1],
+                         g_entity_globals.color_entity[2]);
+
+                 Scene_EntitySetKeyValue_Selected("_color", buffer);
+         }
     }
   }
 }
@@ -454,9 +631,12 @@ void Entity_registerPreferencesPage()
 
 void Entity_constructMenu(GtkMenu* menu)
 {
+  create_menu_item_with_mnemonic(menu, "_Regroup", "GroupSelection");
   create_menu_item_with_mnemonic(menu, "_Ungroup", "UngroupSelection");
   create_menu_item_with_mnemonic(menu, "_Connect", "ConnectSelection");
+  create_menu_item_with_mnemonic(menu, "_KillConnect", "KillConnectSelection");
   create_menu_item_with_mnemonic(menu, "_Select Color...", "EntityColor");
+  create_menu_item_with_mnemonic(menu, "_Normalize Color...", "NormalizeColor");
 }
 
 
@@ -467,7 +647,10 @@ void Entity_constructMenu(GtkMenu* menu)
 void Entity_Construct()
 {
   GlobalCommands_insert("EntityColor", FreeCaller<Entity_setColour>(), Accelerator('K'));
+  GlobalCommands_insert("NormalizeColor", FreeCaller<Entity_normalizeColor>());
   GlobalCommands_insert("ConnectSelection", FreeCaller<Entity_connectSelected>(), Accelerator('K', (GdkModifierType)GDK_CONTROL_MASK));
+  GlobalCommands_insert("KillConnectSelection", FreeCaller<Entity_killconnectSelected>(), Accelerator('K', (GdkModifierType)(GDK_SHIFT_MASK)));
+  GlobalCommands_insert("GroupSelection", FreeCaller<Entity_groupSelected>());
   GlobalCommands_insert("UngroupSelection", FreeCaller<Entity_ungroupSelected>());
 
   GlobalPreferenceSystem().registerPreference("SI_Colors5", Vector3ImportStringCaller(g_entity_globals.color_entity), Vector3ExportStringCaller(g_entity_globals.color_entity));