Kasten der Ameisen besser darstellen (Plugin?)

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Kasten der Ameisen besser darstellen (Plugin?)

      Hallo,



      ich versuche meine Ameisen möglichst dynamisch Kästen zuzuweisen, wenn
      sie "geboren" werden. Allerdings ist das stets schwer im laufenden Spiel
      zu debuggen. Gibt es vielleicht eine Möglichkeit, relativ einfach
      einzusehen, wie viele Ameisen z.Z. in welcher Kaste sind? Entweder als
      Plugin, oder in den Statistiken, oder als farbliche Hervorhebung der
      Ameisen (ich habe leider keine Möglichkeit gefunden, die Ameisen selber
      "einzufärben"). Hat damit jemand Erfahrung gemacht? Ich bin erst seit
      heute hier, würde mich aber wirklich brennend interessieren :)



      Liebe Grüße und im Vorhinein danke für die Hilfe,

      Felix
    • Bmeise schrieb:

      Willst du das über den Quellcode von AntMe machen, oder bei der einfachen Version. Da dürfte es etwas schwieriger werden.

      Hallo,

      ich muss gestehen, ich weiß nicht genau, was du meinst. Prinzipiell hätte ich nichts dagegen, auch ein Plugin zu schreiben, allerdings habe ich mir den Quellcode für AntMe heruntergeladen, und der ist ziemlich komplex. Da werde ich wohl nicht genug durchsteigen, obwohl ich bereits die Stelle gefunden habe, wo jedem Team eine bestimmte Farbe zugeordnet wird - das aber abzuändern in Z.B. kastenspezifische Farben, da wäre ich nicht in der Lage zu ;) Ein Plugin schreiben würde ich auch prinzipiell, habe aber nirgends eine Anleitung oder Schnittstellenbeschreibung gefunden, das wird sicherlich so auch über meine Kompetenzen hinaus gehen :(
    • Hey Felix,

      habe jetzt eine Möglichkeit gefunden, die aber noch nicht sehr ausgereift ist. Es funktioniert leider nur mit der Profi-Version:

      Wenn du in der Profiversion in dem Projekt "MdxPlugin" in das Dokument "RenderForm.cs" gehst (Codeansicht), dann findest du dort die Methode "form_closing", die immer dann aufgerufen wird, wenn das Simulationsfenster geschlossen wird. Darunter kannst du meine folgende Methode einfügen:

      Quellcode

      1. private void showKastes()
      2. {
      3. string text = "Kasten: \n";
      4. int index = 0;
      5. for (int i = 0; i < simulationState.ColonyStates.Count; i++)
      6. {
      7. for (int j = 0; j < simulationState.ColonyStates.AntStates.Count; j++)
      8. {
      9. text += simulationState.ColonyStates.AntStates[j].CasteId + " ";
      10. index++;
      11. if (index > 10)
      12. {
      13. index = 0;
      14. text += "\n";
      15. }
      16. }
      17. }
      18. MessageBox.Show(text);
      19. }
      Alles anzeigen



      Die Methode musst du dann nur noch in form_closing aufrufen:

      Quellcode

      1. private void form_closing(object sender, FormClosingEventArgs e)
      2. {
      3. e.Cancel = true;
      4. Hide();
      5. showKastes();
      6. }


      Leider geht das nur, wenn du die Simulation vor dem Ende abbrichst, aber ich versuche, noch einen anderen Weg zu finden.


      Liebe Grüße,
      Bmeise

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von Bmeise ()

    • Leider bin ich gerade nicht in der Lage das Profipacket zu starten. Erst wurden die Plugins nicht geladen, da die AssemblyInfos anscheinend nicht korrekt waren. Jetzt habe ich jede AssemblyInfo.cs kopiert und damit vereinheitlicht, das Programm läuft, aber sobald ich das Spiel mit Ameisenvölkern starten will oder neue Hinzufügen will, kommt der Hinweis

      "Eine nicht behandelte Ausnahme des Typs "System.Security.SecurityException" ist in mscorlib.dll aufgetreten.

      Zusätzliche Informationen: Die Assembly lässt keine Aufrufer zu, die nicht voll vertrauenswürdig sind."

      Und das wars, er macht dann nicht weiter. Gibt es eine Anleitung für die Profiversion?

      Da könnte ich eventuell auch eine gute Möglichkeit finden :) Z.B. gibt es in der Renderform.cs die Zeilen

      Quellcode

      1. switch (selectedItem.SelectionType) {
      2. case SelectionType.Ant:
      3. AntState ameise = (AntState) selectedItem.Item;
      4. string name;
      5. if (!antNames.ContainsKey(ameise.Id)) {
      6. name = names[random.Next(names.Length)];
      7. antNames.Add(ameise.Id, name);
      8. }
      9. else {
      10. name = antNames[ameise.Id];
      11. }
      12. line1 = string.Format(Resource.HovertextAntLine1, name, selectedItem.AdditionalInfo);
      13. line2 = string.Format(Resource.HovertextAntLine2, ameise.Vitality);
      14. break;
      Alles anzeigen

      zum anzeigen des Mouseovers über eine Ameise. Wenn man da

      Quellcode

      1. line2 = string.Format(Resource.HovertextAntLine2, ameise.Vitality);
      2. // in folgendes
      3. line2 = string.Format(Resource.HovertextAntLine2, ameise.ColonyId);

      umändert, sieht man auf jeden Fall die Zugehörigkeit für die Ameise bei einem Mouseover (denke ich, praktisch kann ich es ja nicht testen) :)
    • Gute Idee! Habe das gleich mal ausprobiert und es klappt super!
      Zunächst habe ich die Variablen in ein Array umgewandelt und dann auch die Methode "RenderInfoTag" in "ModelManager.cs" angepasst:

      Quellcode

      1. /* In: private void render(object sender, PaintEventArgs e) */
      2. // Render Info-Tag at selected item
      3. if (selectedItem.SelectionType != SelectionType.Nothing) {
      4. string[] lines = new string[3];
      5. switch (selectedItem.SelectionType) {
      6. case SelectionType.Ant:
      7. AntState ameise = (AntState) selectedItem.Item;
      8. string name;
      9. if (!antNames.ContainsKey(ameise.Id)) {
      10. name = names[random.Next(names.Length)];
      11. antNames.Add(ameise.Id, name);
      12. }
      13. else {
      14. name = antNames[ameise.Id];
      15. }
      16. lines[0] = string.Format(Resource.HovertextAntLine1, name, selectedItem.AdditionalInfo);
      17. lines[1] = string.Format(Resource.HovertextAntLine2, ameise.Vitality);
      18. lines[2] = string.Format("Kaste: {0}", ameise.CasteId); // Siehe unten
      19. break;
      20. case SelectionType.Anthill:
      21. lines[0] = Resource.HovertextAnthillLine1;
      22. lines[1] = string.Format(Resource.HovertextAnthillLine2, selectedItem.AdditionalInfo);
      23. break;
      24. case SelectionType.Bug:
      25. BugState bugState = (BugState) selectedItem.Item;
      26. lines[0] = Resource.HovertextBugLine1;
      27. lines[1] = string.Format(Resource.HovertextBugLine2, bugState.Vitality);
      28. break;
      29. case SelectionType.Fruit:
      30. FruitState fruitState = (FruitState) selectedItem.Item;
      31. lines[0] = Resource.HovertextFruitLine1;
      32. lines[1] = string.Format(Resource.HovertextFruitLine2, fruitState.Amount);
      33. break;
      34. case SelectionType.Sugar:
      35. SugarState sugar = (SugarState) selectedItem.Item;
      36. lines[0] = Resource.HovertextSugarLine1;
      37. lines[1] = string.Format(Resource.HovertextSugarLine2, sugar.Amount);
      38. break;
      39. default:
      40. lines[0] = String.Empty;
      41. lines[1] = String.Empty;
      42. break;
      43. }
      44. // Text an Mausposition ausgeben
      45. if (lines[0] != String.Empty || lines[1] != String.Empty) {
      46. modelManager.RenderInfoTag(mousePosition, lines);
      47. }
      48. }
      Alles anzeigen


      Quellcode

      1. public void RenderInfoTag(Point position, String[] lines) {
      2. int height = lines.Length * ROWHEIGHT + 10;
      3. int positionY = (height/2) + position.Y + 5;
      4. line.Width = height;
      5. line.Begin();
      6. line.Draw (
      7. new Vector2[] {new Vector2(position.X, positionY), new Vector2(position.X + 200, positionY)},
      8. Color.FromArgb(100, Color.White).ToArgb());
      9. line.End();
      10. int YPosition = position.Y + 10;
      11. foreach (string l in lines) {
      12. if (!(l == null)) {
      13. fontNormal.DrawText(null, l, position.X + 10, YPosition, Color.Black);
      14. YPosition += ROWHEIGHT;
      15. }
      16. else
      17. break;
      18. }
      19. }
      Alles anzeigen


      Allerdings habe ich ein Problem: Mit ameise.CasteID bekomme ich nur den Index der Kaste, aber nicht den Namen. Wie komme ich an den Namen der Kaste? Wäre echt cool, wenn das jemand wüsste!!! 8)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Bmeise ()

    • Bmeise schrieb:

      Hab's schon herausgefunden:
      "SimulationState.ColonyStates[x].CasteStates[y].Name" gibt den Namen der Kaste im Volk x mit dem Index y zurück.
      ARRRGH, das wollte ich auch gerade schreiben :pinch:
      SimulationState.ColonyStates[ameise.ColonyId].CasteStates[ameise.CasteId].Name

      Leider kann ich es nur immer noch nicht testen :( Hast du eine Ahnung, was ich da falsch mache?
    • Versuch es doch einfach, indem du das Profi-Packet nochmal runterlädst. Sonst schau mal in den Eigenschaften vom Projekt AntMe unter Sicherheit nach, dass das Kästchen "ClickOnce-Sicherheitseinstellungen aktivieren" nicht gedrückt ist. Das könnte die System.Security.SecurityException auslösen.

      P.S. Zu dem Namen der Kaste: War ja auch zu offensichtlich!!! :rolleyes:
    • Versuch
      es doch einfach, indem du das Profi-Packet nochmal runterlädst. Sonst
      schau mal in den Eigenschaften vom Projekt AntMe unter Sicherheit nach,
      dass das Kästchen "ClickOnce-Sicherheitseinstellungen aktivieren" nicht
      gedrückt ist. Das könnte die System.Security.SecurityException auslösen.


      Hah, super Sache. Es lag zwar nicht an den MVS Einstellungen, aber das
      neue Herunterladen hat es tatsächlich erklärt. Mit den ganzen Hokuspokus
      des AssemblyInfo.cs verändern hatte ich mir mein Programm zerschossen. Der einzige Schritt der mir nicht klar war ist, dass ich alle Unterprojekte gleichzeitig neu erstellen muss, damit es funktioniert :)

      Mein

      Quellcode

      1. SimulationState.ColonyStates[ameise.ColonyId].CasteStates[ameise.CasteId].Name


      funktioniert anscheinend doch nicht so wirklich... Kurioser weise, muss
      die ColonyId, CasteId noch um eins dekrementiert werden. Und wenn die
      Standardkaste ausgewählt ist, wird die gar nicht erst mit in den
      CasteStates gelistet... Ich habe es jetzt folgendermaßen gelöst
      (funktioniert bei mir):



      Quellcode

      1. string casteName;
      2. try{
      3. casteName =
      4. SimulationState.ColonyStates[ameise.ColonyId -
      5. 1].CasteStates[ameise.CasteId - 1].Name;
      6. }catch(Exception){
      7. casteName = "Standard";
      8. }
      9. lines[2] = string.Format("Kaste: {0}", casteName);
      Alles anzeigen


      Ich muss dir noch mal ein super fettes Dankeschön geben, ohne dich hätte
      ich das nie hinbekommen :) Mit der Sache kann man das Skript bestimmt
      noch sehr schön erweitern.



      Übrigens: Deine Änderung an der RenderInfoTag() Methode finde ich sogar
      so gut, dass ich finde, das sollten wir gleich den Entwicklern
      einschicken :D
    • Ich hab mal eine Methode geschrieben, mit der sich leicht prüfen lässt, welchen Namen die Kaste hat:

      Quellcode

      1. private string getCasteName(SimulationState simulationState, int ColonyId, int CasteId)
      2. {
      3. if (CasteId > 0)
      4. return simulationState.ColonyStates[ColonyId - 1].CasteStates[CasteId - 1].Name;
      5. else
      6. return "Standard";
      7. }


      Diese Methode könnte man wie folgt einsetzen:

      Quellcode

      1. // Zeile 20
      2. lines[2] = string.Format(Resource.HovertextAntLine3, getCasteName(simulationState, ameise.ColonyId, ameise.CasteId));
      3. //
    • Bmeise schrieb:

      Einfacher noch:

      Quellcode

      1. private string getCasteName(SimulationState simulationState, AntState antState)
      2. {
      3. return getCasteName(simulationState, antState.ColonyId, antState.CasteId);
      4. }


      und dann:

      Quellcode

      1. // Zeile 20
      2. lines[2] = string.Format(Resource.HovertextAntLine3, getCasteName(simulationState, ameise));
      3. //
      Die Simulationstate-Variable musst du gar nicht übergeben, du kannst direkt auf SimulationState zugreifen (SimulationState.ColonyStates...). Das SimulationState wird in der RenderForm fast ganz unten definiert und liefert die aktuelle Membervariable simulationState zurück.
    • Habe gerade noch einen Fehler entdeckt. Das mit Resource.HovertextAntLine3 funktioniert nur, wenn man HovertextAntLine3 definiert hat (habe ich nämlich zwischendurch). Man muss erst im Projekt MdxPlugin in Resource.resx und Resource.de.resx einen neuen Eintrag mit dem Namen HovertextAntLine3 eingeben (jeweils englisch und deutsch) --> "Caste: {0}" / "Kaste : {0}". Dann kann man je nach Culture-Einstellungen beide Versionen abrufen. :)