Design problem bei 'nem Bot.



  • @Nexus

    Hi,

    Erstmal danke für deine Antwort. Zurzeit hab ich den Cooldown part nicht Implementiert, ich dachte aber an sowas, siehe code unten.

    setCastTime wird ausgeführt, wenn ich die "antwort" vom gameserver kriege, dass der skill erfolgreich benutzt wurde. Weiter bin ich aber nicht gekommen, ist vielleicht auch zu spät zum nachdenken, werd morgen weiter darüber grübeln.

    #include "windows.h"
    #include <list>
    #include <string>
    
    struct sSkills
    {
    	DWORD skillId;
    	std::string skillName;
    	int skillCooldown;
    	bool isSkillReady;
    	int lastCastTime;
    
    };
    
    class skillManager
    {
        public:
    
    	std::list < sSkills > playerSkills;
    
    	void AddSkill(sSkills newPlayer);
    	bool isSkillReady(DWORD skillId);
    	void setCastTime(DWORD skillID);
    
    };
    
    bool skillManager::isSkillReady(DWORD skillId)
    {
    	std::list<sSkills>::iterator Itr = playerSkills.begin();
    	std::list<sSkills>::iterator ItrEnd = playerSkills.end();
    
    	while (Itr != ItrEnd)
    	{
    		if (Itr->skillId == skillId)
    		{
    			if ( GetTickCount() - Itr->lastCastTime >= Itr->skillCooldown)
    			{
    				Itr->isSkillReady = true;
    				return true;
    			}
    		}
    		else
    			Itr++;
    	}
    
    	return false;
    }
    
    void skillManager::setCastTime(DWORD skillID)
    {
    	std::list<sSkills>::iterator Itr = playerSkills.begin();
    	std::list<sSkills>::iterator ItrEnd = playerSkills.end();
    
    	while (Itr != ItrEnd)
    	{
    		if (Itr->skillId == skillId)
    		{
    			Itr->lastCastTime = 0;
    			Itr->lastCastTime = GetTickCount();
    			Itr->isSkillReady = false;
    		}
    		else
    			Itr++;
    	}
    
    }
    

    Gruß!



  • skill0r schrieb:

    sind die skills visuell. sichtbar? sind die skills zum anklicken?
    bzw. wie und wann merkt hans, welche skills er hat?

    irgendwo muss ja ein timer die cooldown zeit der skills dekrementieren, dort wäre auch bei t <= 0 ein bool flag angebracht, das den entsprechenden skill aktiviert.
    sortieren fällt flach, weil man in jeden skill 'reingucken' muss. es tut also ein skill array als "container" und ne schleife drum herum.

    Sorry, hab dein post nicht gesehen als ich Nexus geantwortet habe.

    1. ) Beim einloggen shickt der GameServer dem GameClient die verfügbaren Skills.

    2. ) Die verfübaren skills von dem Charakter werden in einer std::list gespeichert, und in der GUI Angezeigt.

    3. ) Es gibt einen "Add" button, mit dem man den gewünschten skill in einer Listbox hinzufügt, die Listbox repräsentiert die Skills die der Bot benutzen wird.

    4. ) Der GameServer sagt dem GameClient leider nicht wann ein skill wieder benutzbar ist, daher muss ich es selber machen, genauso wie der GameClient.

    Gruß



  • @Nexus
    Arg, vergessen zu sagen dass es max 6-7 skills geben wird, wenn es hoch kommt manchmal 10. Sorry für triple post. 😞



  • zu 4)
    aber der sever muss wenigstens die cooldown time liefern? 😕

    wie auch immer,
    die ids für die skills würde ich so vergeben, das man ohne eine schleife indexbasiert direkt zugreifen kann.
    wenn nicht allzu viele player zu verwalten sind, kann man auch beim suchen nach einem skill eines players auf eine schleife verzichten:

    #define SKILL_1 0
    #define SKILL_2 1
    // ...
    #define SKILL_10 9
    #define SKILLS_QUANTITY 10
    
    typedef struct Skill
    {
    	int id;
    	int lastCastTime;
    	int skillCooldown;
    	char* name;
    	// ... 
    }Skills[SKILLS_QUANTITY];
    
    typedef struct Player
    {
    	int id;
    	char* name;
    	Skills skills;
    	// ...
    };
    
    void set_cast_time ( Player* p, int skill_id )
    {
    	p->skills[skill_id].lastCastTime = 0;
    	// ...
    }
    
    bool skill_ready ( Skill* s )
    {
    	return GetTickCount() - s->lastCastTime >= s->skillCooldown;
    }
    
    int main() 
    { 
    	Player p = {0};
    	p.name = "Hans";
    	p.skills[SKILL_2].name = "Hans kanns.";
    
    	set_cast_time (&p, SKILL_2);
    	if ( skill_ready ( &p.skills[SKILL_2] ))
    		cout << "Hello, my name is " << p.name << 
    			" my skill level is " << p.skills[SKILL_2].name << endl;
    	return 0;
    }
    


  • Hi,

    Der server liefert nicht die Cooldown zeit, der Client liest die Cooldown zeit aus den data files, genau wie ich. Irgendwie find ich den code nicht wirklich schön, irgendwie sehe ich da kein c++. Dennoch danke.



  • warum muss der gameserver umbedingt die cooldownzeit liefern?
    die ist ja meist ein vielfaches von 0.5, oder es steht ingame drauf.

    oder halt ne datei.

    @skil0r: blub, C++ forum, define? typedef struct? das C forum ist eins weiter oben

    class Skill
    {
    public:
        Skill(){}
        Skill(const char *pname, float pcooldown)
        : name(pname), cooldown(pcooldown), time_left(0.f)
        {
        }
        void AdvanceTime(float ftime)
        {
            if (time_left > 0.f)
                time_left -= ftime;
        }
        bool SpellReady()
        {
            return time_left <= 0.f;
        }
        bool Reset()
        {
            time_left = cooldown;
        }
        const char *GetName()
        {
            return name;
        }
    private:
        const char *name;
        const float cooldown;
        float time_left;
    };
    class Container
    {
    public:
        void AddSpell(const Spell &s)
        {
            spells.push_back(s);
        }
        void AdvanceTime(float ftime)
        {
            for (unsigned i = 0; i < spells.size(); ++i)
                spells[i].AdvanceTime(ftime);
        }
        Spell *GetReadySpell()
        {
            for (unsigned i = 0; i < spells.size(); ++i)
                if (spells[i].SpellReady())
                    return &spells[i];
            return 0;
        }
    private:
        std::vector<Spell> spells;
    };
    

    so würde ich es machen



  • Hm, nett. Nur wieso fügst du eine referenz zu dem objekt in den vector ein? und wieso char * und nicht std::string ? und ftime is *nix only soweit ich weiß. Dennoch danke. 🙂



  • Um die Skills zu speichern, ist eine map angebracht, die Schleifen zum Finden der Skills fallen damit weg. Zudem sollte diese Funktionalität sowieso in getSkill() o.ä. ausgelagert werden, dann kannst du die Implementierung bei Bedarf bequem austauschen. Die map setzt natürlich voraus, dass es keine zwei Skills mit gleicher ID geben kann.
    sSkills bekommt eine Funktion ready() frei nach skill0rs skill_ready. Der Besitzer der Skills sollte regelmäßig alle Skills pollen und bei Bedarf casten. Ein Flag wie castPending ist hier wohl auch angebracht, damit du denselben Skill nicht noch zwanzig weitere mal zu casten versuchst, bis endlich die Antwort vom Server kommt.
    Wenn der Bot sonst nichts machst, kannst du auch CPU-Zeit sparen, indem du schaust, welcher Cooldown am frühesten abläuft und schläfst dann so lange.



  • dosenkekse schrieb:

    @skil0r: blub, C++ forum, define? typedef struct? das C forum ist eins

    Isch liebe disch schrieb:

    irgendwie sehe ich da kein c++. Dennoch danke.

    Es ging mir um den Zugriff, für den man keine Schleife und auch keine Map braucht, weiter nix.



  • Hatte in den letzen tagen keine zeit, aber danke an alle für die tipps, denk mal das ich es schaffen werde, falls jemand dennoch was übrig zu sagen hat, leg los.

    Gruß


Anmelden zum Antworten