Arrays in verschiedenen Klassen

amorent

Grünschnabel
Hallo zusammen,

ich habe frisch angefangen mich mit c++ auseinander zu setzen. Ich bin gerade aber an einem Punkt an dem ich nicht weiter komme und ich bräuchte einmal ein Beispiel anhand meiner Dateien um endlich weiter zu kommen.
Um das ganze euch so gut wie möglich zu erklären, hier einmal grob umschrieben:

Wenn eine Kreatur stirbt, soll man eine zurätzliche auwahlmöglichkeit in einem Textfeld haben. Ja ich weiß das ist ziemlich schwamming, darum werde ich einmal konkreter.

Ich habe die Klasse "Kreatur".
Eine Kreatur kann entweder tot oder lebendig sein.
Ich habe die Klasse "Textfeld".

Wenn eine kreatur stirbt, wird in der Klasse "Kreatur" das void OnCreatureDeath aufgerufen.
Darin geht es über einen switch in einen case ( das funktioniert auch soaweit alles.)

Jetzt kommt das Problem:
In der Klasse "Textfeld" soll geprüft werden, ob die kreatur tot ist. Wenn die Creatur tot ist, wird ein text ausgegeben. Wenn die Kreature nicht tot ist, wird der text nicht ausgegeben.

C++:
class Kreatur : public Instanz{
void OnCreatureDeath(Kreatur)
{
    switch(Kreatur->KreaturID)
    {
        case: KreaturID1
        {  
             kreatur1 = tot
         } break;

        case: KreaturID2
        {
             kreatur2 = tot
         } break;
    }
};


C++:
class Textfeld : public Gossip{
void Ausgabe(Kreatur)
{
    if(kreature1 = tot)
        nachricht: Kreatur 1 ist tot;

    if(kreature2 = tot)
        nachricht: Kreatur 2 ist tot;
}
};

Ich hoffe es ist verständlich was mein Problem ist. Ich weiß nicht wie ich die Information aus Klasse "Kreatur" in der Klasse "Textfeld" wiederverwenden kann. Spätestens wenn ich in der Klasse "Textfeld" den wert ausgeben will, erscheint immer "kreatur1 nicht definiert" aber ich will es ja nicht neu definieren, sondern nur prüfen...

Immer wieder bin ich über "Arrays" gestolpert, jedoch habe ich nach vier Tutorials immer noch keine Ahnung ob und wie ich das bei mir anwenden kann.

Darum meine Bitte. kann mir jemand einmal mit einem Beispiel erklären, wie ich die Information "kreatur1 = tot" aus der Klasse "Kreatur", in meiner Klasse "Textfeld" zum prüfen übergeben kann?

Währe echt super.

Grüße
 
Moin,

auch wenn Dein Code ein wenig seltsam anmutet (hast Du ihn nur für den Post hier verkürzt?) :

Scheinbar übergibst Du doch ein Objekt von Typ "Kreatur" :
C++:
class Textfeld : public Gossip
{
void Ausgabe(Kreatur)
{
    if(kreature1 = tot)
        nachricht: Kreatur 1 ist tot;

    if(kreature2 = tot)
        nachricht: Kreatur 2 ist tot;
}
};
also:
C++:
class Textfeld : public Gossip
{
void Ausgabe(Kreatur myCreature)
{
    if(myCreature.kreature1 == tot)  // oder auch als Zeiger
        nachricht: Kreatur 1 ist tot;

    if(myCreature.kreature2 == tot)  // oder auch als Zeiger
        nachricht: Kreatur 2 ist tot;
}
};
Trotzdem mutet das Ganz etwas seltsam an! Warum gibst Du denn bspw. die Nachricht nicht direkt in "OnCreatureDeath" aus ??

Gruß
Klaus
 
Hallo,

für mein Verständnis von Klassen und sauberer Trennung sollte das Textfeld auch nichts mit einer anderen Klasse zu tun haben, dann entfällt vorallem auch die Prüfung. vfl_freak hat es bereits angedeutet. Die Nachricht wer tot ist kannst du bereits in OnCreatureDeath bestimmen und den String dazu nur noch an das Textfeld übergeben.

Das hat auch den Vorteil, dass dein Textfeld mehrfach, auch von anderen Klassen, benutzt werden kann ohne Textfeld jeweils ändern zu müssen.

Arrays lohnen sich m.M.n erst bei einer höheren Anzahl an Objekten, also bei 5+ Objekten. In diesem Fall bietet sich allerdings auch schon ein std::vector durch höhere Funktionalität an. Der Vorteil von Arrays kommt vorallem dann zu tragen wenn für alle Objekte periodisch die gleichen/ähnlichen Abfragen nötig sind.

Beste Grüße,
Jennesta
 
Hallo,

vielen Dank erst einmal an Jennesta und vfl_freak.

Cromon hat den Nagel auf dem Kopf getroffen. (Dass ich deinen Namen noch einmal lesen darf, freut mich.) Genau darum geht es, nur leider nicht für Mangos, sondern Arcemu, was die Sache wohl nicht unbedingt leichter macht.

Ich dachte immer, dass dies simpel übergeben werden kann, aber ich wurde eines besseren belehrt.

Über einen Ansatz würde ich mich bereits freuen.
Grüße
Amorent
 
Moin,

Ich dachte immer, dass dies simpel übergeben werden kann, aber ich wurde eines besseren belehrt.
Im Grunde übergibst Du doch schon ein entsprechendes Objekt - Du musst es nur erichtig machen (siehe mein erster Post).
Da wir die aufrufende Stelle allerdings nicht kennen, können wir nicht beurteilen, ob Du dort schon ein solches Objekt erzeugt hast ....

Gruß
Klaus
 
Hallo amorent

In deinem Falle ist bereits eine Schnittstelle vorhanden, nämlich die Map auf der die beiden Entities leben.
C++:
class Textfeld : public Gossip{
   void Ausgabe(Kreatur)
   {
      MapMgr* mgr = cr->GetMapMgr();
      if(mgr == nullptr) { return; }

      Kreatur* kr = dynamic_cast<Kreature*>(mgr->GetScript());
      if(kr == nullptr) { return; }

      if(kr->kreature1 = tot)
         nachricht: Kreatur 1 ist tot;
      if(kr->kreature2 = tot)
         nachricht: Kreatur 2 ist tot;
   }
}
 
Hi,
mir scheint sich da doch ein Fehler eingeschlichen zu haben (In meinem Beispliel). Darum hier einmal das komplette Script.

ICCGossip.cpp
C++:
#include "Raid_ICC.h"

///////////////////////////////////////////////////////
// ICC Teleporter
class ICCTeleporterAI : public GameObjectAIScript
{
public:

    ICCTeleporterAI(GameObject* go) : GameObjectAIScript(go) {}

    ~ICCTeleporterAI(){}

    static GameObjectAIScript* Create(GameObject* go) { return new ICCTeleporterAI(go); }

    void OnActivate(Player* player)
    {
        GossipMenu* menu = NULL;
        objmgr.CreateGossipMenuForPlayer(&menu, _gameobject->GetGUID(), 1/*Its not one need to be checked*/, player);
        menu->AddItem(Arcemu::Gossip::ICON_CHAT, "Teleport to Light's Hammer.", 0);
    
        //Check if boss is dead, then add the menu item
        //if (!mMarrowisDead->isAlive)
            menu->AddItem(Arcemu::Gossip::ICON_CHAT, "Teleport to Oratory of The Damned.", 1);

        //if(GetInstanceData(mDeathwhisperGUID) = State_Finished)
            menu->AddItem(Arcemu::Gossip::ICON_CHAT, "Teleport to Rampart of Skulls.", 2);

        // GunshipBattle has to be finished...
        //menu->AddItem(Arcemu::Gossip::ICON_CHAT, "Teleport to Deathbringer's Rise.", 3);

        //if(GetInstanceData(mDreamwalkerGUID) = State_Finished)
            menu->AddItem(Arcemu::Gossip::ICON_CHAT, "Teleport to the Upper Spire.", 4);

        //if(GetInstanceData(mColdflameGUID) = State_Finished)
            menu->AddItem(Arcemu::Gossip::ICON_CHAT, "Teleport to Sindragosa's Lair.", 5);

        menu->SendTo(player);
    }
};

class ICCTeleporterGossip : public GossipScript
{
public:
    ICCTeleporterGossip() : GossipScript(){}

    void OnSelectOption(Object* object, Player* player, uint32 Id, const char* enteredcode)
    {
        Arcemu::Gossip::Menu::Complete(player);

        if(Id >= 7)
            return;
        else
            player->SafeTeleport(ICCTeleCoords[Id][0], player->GetInstanceID(), ICCTeleCoords[Id][1], ICCTeleCoords[Id][2], ICCTeleCoords[Id][3], ICCTeleCoords[Id][4]);
    }
};

void SetupICC_Tele(ScriptMgr* mgr)
{
    //Teleporters
    mgr->register_gameobject_script(202242, &ICCTeleporterAI::Create);
    mgr->register_go_gossip_script(202242, new ICCTeleporterGossip());

    mgr->register_gameobject_script(202243, &ICCTeleporterAI::Create);
    mgr->register_go_gossip_script(202243, new ICCTeleporterGossip());

    mgr->register_gameobject_script(202244, &ICCTeleporterAI::Create);
    mgr->register_go_gossip_script(202244, new ICCTeleporterGossip());

    mgr->register_gameobject_script(202245, &ICCTeleporterAI::Create);
    mgr->register_go_gossip_script(202245, new ICCTeleporterGossip());

    mgr->register_gameobject_script(202246, &ICCTeleporterAI::Create);
    mgr->register_go_gossip_script(202246, new ICCTeleporterGossip());
};

ICC.h
C++:
#define MAP_ICECROWNCITADEL 631

/////////////////ICC GOs managed by script//////////////////////

enum IceCrownCitadelGOs{
    GO_MARROWGAR_ICEWALL_1 = 201911,
    GO_MARROWGAR_ICEWALL_2 = 201910,
    GO_MARROWGAR_DOOR = 201563
};

/////////////////ICC CNs managed by script//////////////////////
enum IceCrownCitadelCNentry{
   CN_LORD_MARROWGAR = 36612,
   CN_COLDFLAME = 36672,
   CN_LADY_DEATHWHISPER = 36855,
   CN_VALITHRIA_DREAMWALKER = 36789,
};

// CN ids for Encounter State ?!?
enum IceCrownCitadelCNid{
   CNID_LORD_MARROWGAR         = 0,
   CNID_COLDFLAME              = 1,
   CNID_LADY_DEATHWHISPER      = 2,
   CNID_VALITHRIA_DREAMWALKER  = 3,
   CNID_END
};

static Location Doors[] =
{
    { -407.35f, 2147.88f, 42.85f, 0 },         //IceWall1
    { -412.97f, 2285.24f, 42.01f, 0 },       //IceWall2
    { -520.44f, 2211.47f, 63.14f, 0 },       //Door behinde ice
};

/////////////////Teleport Coords//////////////////////
static float ICCTeleCoords[6][5] =
{    // Maybe moving this to a clean mysql table with all teleports in it... maybe as spell or event?
    { MAP_ICECROWNCITADEL, -17.856115f, 2211.640137f, 30.115812f, 0.0f },     //1   Teleport to Light's Hammer
    { MAP_ICECROWNCITADEL, -503.632599f, 2211.219971f, 62.823246f, 0.0f },    //2   Teleport to Oratory of The Damned
    { MAP_ICECROWNCITADEL, -615.098267f, 2211.509766f, 199.973083f, 0.0f },   //3   Teleport to Rampart of Skulls
    { MAP_ICECROWNCITADEL, -549.151001f, 2211.463967f, 539.290222f, 0.0f },   //4   Teleport to Deathbringer's Rise
    { MAP_ICECROWNCITADEL, 4356.780273f, 2863.636230f, 349.337982f, 0.0f },   //5   Teleport to the Upper Spire.
    { MAP_ICECROWNCITADEL, 4453.248535f, 2769.325684f, 349.347473f, 0.0f }    //6   Teleport to Sindragosa's Lair
};


void SetupICC(ScriptMgr* mgr);

Und Raid_ICC.cpp
C++:
#include "Raid_ICC.h"

class IceCrownCitadelScript : public MoonInstanceScript
{
    friend class ICCTeleporterAI; // Friendship forever ;-)
public:
    MOONSCRIPT_INSTANCE_FACTORY_FUNCTION(IceCrownCitadelScript, MoonInstanceScript);

    uint32 mMarrowgarGUID;
    uint32 mColdflameGUID;
    uint32 mDeathwhisperGUID;
    uint32 mDreamwalkerGUID;

    IceCrownCitadelScript(MapMgr* pMapMgr) : MoonInstanceScript(pMapMgr)
    {
    
        //GO states
        mMarrowIceDoor1_GUID = 0;
        mMarrowIceDoor2_GUID = 0;
        mMarrowDoor_GUID = 0;
    }

    void OnPlayerEnter(Player* pPlayer){
        if (!InstanceTeam)
            InstanceTeam = pPlayer->GetTeam();
    }

    void OnGameObjectPushToWorld(GameObject* pGameObject)
    {
        switch (pGameObject->GetEntry())
        {
        case GO_MARROWGAR_ICEWALL_1:    mMarrowIceDoor1_GUID = pGameObject->GetGUID(); break;
        case GO_MARROWGAR_ICEWALL_2:    mMarrowIceDoor2_GUID = pGameObject->GetGUID(); break;
        case GO_MARROWGAR_DOOR:         mMarrowDoor_GUID = pGameObject->GetGUID(); break;
        }
    }
void OnCreatureDeath(Creature* pCreature, Unit* pUnit)
    {
        switch (pCreature->GetEntry())
        {
            //Need check if killed set state 2
            case CN_LORD_MARROWGAR:
            {
                GameObject* pMarrowIceDoor1 = FindClosestGameObjectOnMap(GO_MARROWGAR_ICEWALL_1, Doors[0].x, Doors[0].y, Doors[0].z);
                if (pMarrowIceDoor1 != NULL)
                    pMarrowIceDoor1->SetState(GAMEOBJECT_STATE_OPEN);

                GameObject* pMarrowIceDoor2 = FindClosestGameObjectOnMap(GO_MARROWGAR_ICEWALL_2, Doors[1].x, Doors[1].y, Doors[1].z);
                if (pMarrowIceDoor2 != NULL)
                    pMarrowIceDoor2->SetState(GAMEOBJECT_STATE_OPEN);

                GameObject* pMarrowDoor = FindClosestGameObjectOnMap(GO_MARROWGAR_DOOR, Doors[2].x, Doors[2].y, Doors[2].z);
                if (pMarrowDoor != NULL)
                    pMarrowDoor->SetState(GAMEOBJECT_STATE_OPEN);
            }break;

            case CN_LADY_DEATHWHISPER:
                SetInstanceData(Data_EncounterState, CN_LADY_DEATHWHISPER, State_Finished);
                break;

            case CN_VALITHRIA_DREAMWALKER:
                SetInstanceData(Data_EncounterState, CN_VALITHRIA_DREAMWALKER, State_Finished);
                break;

            case CN_COLDFLAME:
                SetInstanceData(Data_EncounterState, CN_COLDFLAME, State_Finished);
                break;

            default:
                break;
        }
        return;
    }

protected:
    uint32 mMarrowIceDoor1_GUID;
    uint32 mMarrowIceDoor2_GUID;
    uint32 mMarrowDoor_GUID;
};

void SetupICC(ScriptMgr* mgr)
{
    //Bosses
    mgr->register_instance_script(MAP_ICECROWNCITADEL, &IceCrownCitadelScript::Create);
}


Weiterführende Links:
https://github.com/arcemu/arcemu/blob/master/src/arcemu-world/ScriptMgr.h

Ich habe einiges ausprobiert wie das funktionieren soll, also bitte lasst euch nicht irritieren.
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück