[NPC] Gossip additem

Hallo,

ich wollte einmal fragen, ob es möglich ist mit c++ einen NPC zu erstellen der den Spielern das Gewünschte Item addet. Also so zu sagen ein .add Befehl Ersatz aber das ganze nur mit einem kleinen Unterschied.

Dieser Unterschied ist, dass wenn ich die Spieler die id 400001 eingeben der NPC ihnen dieses Item einfach nicht gibt. Ich möchte das sich die Spieler alles andere adden können außer dieses Item.

Könnte mir jemand bei diesem Script helfen ?

Du willst wahrscheinlich ne Codebox nutzen (siehe examples seitens Trinity), bei der man ne ID eingeben kann. Welche ID’s akzeptiert und welche nicht akzeptiert werden, kannst du auf verschiedene Arten lösen. Ambesten machst du dir ne Blacklist. Dann brauchst du nur zu überprüfen, ob die übergebene ID in der Blacklist vorhanden ist, und kannst den Vorgang abbrechen.

Das Item adden funktioniert genau wie bei .add. Guck dir einfach mal .add an um zu sehen, welche Anfragen und Aufträge du benötigst (CanStoreItem, …) um das ganze zu realisieren

Je nach dem was du machen willst wäre es vielleicht ratsam, einen eigenen Chatbefehl zu implementieren, was dank CommandScript so leicht ist, wie einen NPC zu scripten

Danke sehr für deine Hilfe, doch ich hatte so etwas ähnliches vor.

Mein eigentliches Problem ist aber das Skripten von diesen Code.

Naja ich wollte erst einmal versuchen etwas von etwas von diesem “Geschenk NPC” zu lernen. Da ist ja auch eine add Funktion und eine art Blacklist bzw eine Whitelist beinhalten.

Doch leider ist der Download link Offline =/

Die Funktion “Additem();” sollte für dein Vorhaben reichen.

So ich hab nun den Code gefunden, das Problem ist nur noch das er beim erstellen folgende Fehler raus gibt.

Log

[CODE]1>------ Erstellen gestartet: Projekt: revision.h, Konfiguration: Release x64 ------

1>

1>

1>

1> – WARNING - Missing or outdated git - did you forget to install a recent version?

1> – WARNING - Observe that for revision ID/hash to work you need at least version 1.7

1> – WARNING - Continuing anyway, but setting the revision-ID and hash to Rev:0 Hash: Archive

1> – WARNING - Missing repository tags - you may need to pull tags with git fetch -t

1> – WARNING - Continuing, but the hash will be set to ‘Archive’

2>------ Erstellen gestartet: Projekt: scripts, Konfiguration: Release x64 ------

2> npc_add.cpp

2>…......\TrinityCore\src\server\scripts\Custom\npc_add.cpp(22): error C2590: “npc_add”: Nur ein Konstruktor kann eine Basis-/Member-Initialisiererliste enthalten.

2>…......\TrinityCore\src\server\scripts\Custom\npc_add.cpp(28): error C2664: ‘GossipMenu::AddMenuItem’: Konvertierung des Parameters 2 von ‘const char [15]’ in ‘uint8’ nicht möglich

2> Es gibt keinen Kontext, in dem diese Konvertierung möglich ist

2>…......\TrinityCore\src\server\scripts\Custom\npc_add.cpp(128): error C2061: Syntaxfehler: Bezeichner ‘npc_add’

3>------ Erstellen gestartet: Projekt: worldserver, Konfiguration: Release x64 ------

3> Bibliothek “C:/Trinity/Git/Win/src/server/worldserver/Release/worldserver.lib” und Objekt “C:/Trinity/Git/Win/src/server/worldserver/Release/worldserver.exp” werden erstellt.

3>game.lib(ScriptLoader.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ““void __cdecl AddSC_npc_add(void)” (?AddSC_npc_add@@YAXXZ)” in Funktion ““void __cdecl AddCustomScripts(void)” (?AddCustomScripts@@YAXXZ)”.

3>C:\Trinity\Git\Win\bin\Release\worldserver.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.

4>------ Erstellen übersprungen: Projekt: INSTALL, Konfiguration: Release x64 ------

4>Für diese Projektmappenkonfiguration wurde kein zu erstellendes Projekt ausgewählt.

========== Erstellen: 1 erfolgreich, Fehler bei 2, 11 aktuell, 1 übersprungen ==========[/CODE]

Code

[CODE]/*

made by Hanfer

for IDK? god? education? your mom? this guy from wow studio?

*/

#include “ScriptPCH.h”

#include

std::string sqlcode;

int used;

int id;

bool gotit = true;

#define ITEM_GIFT 44050 //item id of gift

//the crapy code:

class gift_code_npc : public CreatureScript

{

public:

        npc_add()

        : CreatureScript("npc_add")

    {

    }


    bool OnGossipHello(Player* player, Creature* creature)

    {

                            player->PlayerTalkClass->GetGossipMenu().AddMenuItem(5,"Code eingeben!",GOSSIP_SENDER_MAIN, 10, "", 0, true);

                            player->ADD_GOSSIP_ITEM(0, "Schoenen Tag noch", GOSSIP_SENDER_MAIN, 99);

                            player->PlayerTalkClass->SendGossipMenu(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());

    return true;

    }





    bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)

    {

            if (sender == GOSSIP_SENDER_MAIN)

            {

            player->PlayerTalkClass->ClearMenus();


                    switch(action)

                    {


                    case 99:

                        player->CLOSE_GOSSIP_MENU();

                        player->GetSession()->SendNotification("Schoenen Tag noch.");

                    break;



                    }

                }


    return true;

    }



    bool OnGossipSelectCode(Player* player, Creature* /*creature*/, uint32 sender, uint32 action, const char* code)

    {

        player->PlayerTalkClass->ClearMenus();

        if (sender == GOSSIP_SENDER_MAIN)

        {

            switch (action)

            {

            case 10:


                QueryResult result;


                result = WorldDatabase.Query("SELECT `code`, `used`, `id` FROM `codes`"); //get codes from sql


                if(result)

                {

                    do

                    {


                            Field *fields = result->Fetch();

                            sqlcode = fields[0].GetString();

                            used = fields[1].GetInt32();

                            id = fields[2].GetInt32();


                            if(sqlcode == code){

                                //gotit = false; has to be in if (?!? donno)

                                if(used == 0)

                                {

                                    gotit = false;

                                    QueryResult exec;

                                    exec = WorldDatabase.PQuery("UPDATE codes SET used = '1' WHERE id = %u", id); //set code to used

                                    player->AddItem(ITEM_GIFT, 1);                                                //get your present

                                    player->GetSession()->SendNotification("Glückwunsch!");

                                    player->CLOSE_GOSSIP_MENU();


                                }else{

                                    gotit = false;

                                    player->GetSession()->SendNotification("dieser Code wurde schon eingeloest!");//ha! got you! don't use it twice!

                                    player->CLOSE_GOSSIP_MENU();


                                }


                            }


                    } while (result->NextRow());

                    if(gotit){

                        player->GetSession()->SendNotification("Code nicht gefunden!");                            //Are you kidding me?

                        player->CLOSE_GOSSIP_MENU();                                                               // Sometimes i want to punch people over TCP!

                    }


                    return true;


                }




                player->CLOSE_GOSSIP_MENU();


                return true;

            }

        }


        return false;

    }

};

void AddSC_npc_add()

{

    new npc_add();

}[/CODE]

Ok das Problem hab ich nun auch gelöst, mein letztes Problem wäre, den Code der eingegeben wurde runter in nach unten bis zu der stelle

[CODE]if(gotit){

                        player->GetSession()->SendNotification("Code nicht gefunden!");                            //Are you kidding me?

                        player->CLOSE_GOSSIP_MENU();                                                               // Sometimes i want to punch people over TCP!

                    }[/CODE]

zu bringen und dort adden zu lassen.

Könnt ihr mir einfach nur sagen wie ich oben den String definiere und ihn dann mit dem Code fülle der eingegeben wunde und unten dann in der Funktion “player->AddItem(itemid, 1);” wieder ausgebe ?

Und das ganze noch mal kurz und knapp zusammen gefasst.

Ich möchte das der eingefügte Code den Spieler geaddet wird wenn er diesen nicht in der Datenbank findet.

Super Idee kann man den script bekommen ?

Es wäre gut wen er die Erbstücke adden könnte als start pack

Sobald mir jemand mein kleines Problem mit der ID löst stell ich den fertigen Script sofort hoch.

uint32 itemid = (uint32)atol(code);

atol() interpretiert einen C-String als LongInt und das Resultat castest du auf uint32

Falls du die ItemID aus der DB holst und code irgend nen Zufallscode ist (wonach das in deinem Script aussieht), brauchst du ja nur id nehmen - ist ja schon passend)


Oder meinst du nen String zusammensetzen wo der Kram drin vorkommt um quasi ne Bestätigungsnachricht zu schicken?

[CODE]char buff[2048];

sprintf(buff, “Du hast Code %s eingeloest und item %u bekommen.”, code, id);

//buff enthält z.B. Du hast Code 1324657 eingeloest und Item 15244 bekommen[/CODE]

Er Zeigt zwar keine Fehler beim Erstellen, aber er erstellt die Items auch nicht.


/*

made by Hanfer

for IDK? god? education? your mom? this guy from wow studio?

*/

#include "ScriptPCH.h"

#include <cstring>

std::string sqlcode;

int used;

int id;

bool gotit = true;


//the crapy code:

class gift_code_npc : public CreatureScript

{

public:

        	gift_code_npc()

        	: CreatureScript("gift_code_npc")

    	{

    	}

    	bool OnGossipHello(Player* player, Creature* creature)

    	{

                            	player->PlayerTalkClass->GetGossipMenu().AddMenuItem(0,5,"ItemID eingeben!",GOSSIP_SENDER_MAIN, 10, "", 0, true);

                            	player->ADD_GOSSIP_ITEM(0, "Schoenen Tag noch", GOSSIP_SENDER_MAIN, 99);

                            	player->PlayerTalkClass->SendGossipMenu(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());

    	return true;

    	}



    	bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)

    	{

            	if (sender == GOSSIP_SENDER_MAIN)

            	{

            	player->PlayerTalkClass->ClearMenus();

                    	switch(action)

                    	{

                    	case 99:

                        	player->CLOSE_GOSSIP_MENU();

                        	player->GetSession()->SendNotification("Schoenen Tag noch.");

                    	break;


                    	}

                	}

    	return true;

    	}


    	bool OnGossipSelectCode(Player* player, Creature* /*creature*/, uint32 sender, uint32 action, const char* code)

    	{

   uint32 itemid = (uint32)atol(code);

        	player->PlayerTalkClass->ClearMenus();

        	if (sender == GOSSIP_SENDER_MAIN)

        	{

            	switch (action)

            	{

            	case 10:

                	QueryResult result;

                	result = WorldDatabase.Query("SELECT `code`, `used`, `id` FROM `codes`"); //get codes from sql

                	if(result)

                	{

                    	do

                    	{

                            	Field *fields = result->Fetch();

                            	sqlcode = fields[0].GetString();

                            	used = fields[1].GetInt32();

                            	id = fields[2].GetInt32();

                            	if(sqlcode == code){

                                	//gotit = false; has to be in if (?!? donno)

                                	if(used == 0)

                                	{

                                    	gotit = false;

                                    	QueryResult exec;

                                    	exec = WorldDatabase.PQuery("UPDATE codes SET used = '1' WHERE id = %u", id); //set code to used

                                    	//player->AddItem(ITEM_GIFT, 1);                                          	//get your present

                                    	player->GetSession()->SendNotification("Na na na na...du darfst dir kein Gold adden.");

                                    	player->CLOSE_GOSSIP_MENU();

                                	}else{

                                    	gotit = false;

                                    	player->GetSession()->SendNotification("Na na na na...du darfst dir kein Gold adden.");//ha! got you! don't use it twice!

                                    	player->CLOSE_GOSSIP_MENU();

                                	}

                            	}

                    	} while (result->NextRow());

                    	if(gotit){

                        	player->AddItem(itemid, 1);           	// Additem

   	player->GetSession()->SendNotification("Vergesse nicht mit: Mit gro&#223;en leuchte R&#252;stungen solltest du nicht nach Stillbrunn");                           

                        	player->CLOSE_GOSSIP_MENU();                                                               

                    	}

                    	return true;

                	}


                	player->CLOSE_GOSSIP_MENU();

                	return true;

            	}

        	}

        	return false;

    	}


};

void AddSC_gift_code_npc()

{

    	new gift_code_npc();

}

wäre das was ich nun umgeschrieben hab.

Hast du da einfach was zusammenkopiert? Das was du jetzt gemacht hast ergibt kontextmäßig nämlich keinen Sinn.

Das Skript in der aktuellen Fassung macht einen Zugriff auf die SQL-Tabelle “codes”, wo jeweils ein Code, eine ItemID und ein Feld, das besagt ob der Code benutzt wurde oder nicht, enthält. Du hättest in der Tabelle z.B. ItemID 12345 mit dem Code 4a2fga99ZUg und used = 0.

→ User kann 4a2fga99ZUg eingeben und erhält Item 12345. Danach wird used auf 1 gesetzt und der Code ist nicht mehr verwendbar

(Dafür müsste halt “id” geaddet werden)

Deswegen habe ich nachgefragt was du da genau machen willst…

Wenn du einfach nur die eingegebene ID geaddet haben willst, brauchst du den ganzen SQL-Kram nicht.

Da müsstest du im Switch-Case nur das Item (“itemid” nutzen) adden, die Nachricht versenden und das GossipMenü schliessen

Ich will die Code Liste als eine Blacklist verwenden, und wenn ein Spieler kommt und eine Item ID in die Box eingibt und diese nicht auf der Blacklist gefunden wird, wird sie ihn geaddet wenn sie gefunden wird wird sie nicht geaddet.

Ich hab dein Script nen bissle angepasst:

http://paste2.org/p/1541773 (habs mal hier gepostet, da das Forum die Einrückung momentan zerstört)

Die Blacklist befindet sich in der Tabelle “script_gift_blacklist” (WorldDB) und hat die Felder id (EntryID des Items) & allowed (Blacklist Eintrag aktuell gültig (0) oder nicht (1)?)

SQL dürfte ungefähr so aussehen:


CREATE TABLE IF NOT EXISTS `script_gift_blacklist` (

  `id` int(11) NOT NULL,

  `allowed` tinyint(1) DEFAULT '0',

  PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Hab ich nicht getested, grad keinen Source hier ums zu compilen…

Ich teste es Sofort danke sehr schon mal im vor raus /emoticons/default_smile.png

#include "ScriptPCH.h"[/CODE]

Hab ich oben vergessen, musst du wieder reinpacken

Der Code lässt sich perfekt compilen.

Der Code läuft 1a Danke sehr /emoticons/default_smile.png

super ich lade es mir auch mal runter

PS: gute Idee mit der Blacklist sicher ist sicher

Es geht nicht um die Sicherheit /emoticons/default_wink.png

Es ging mir dabei das ich nicht bei jedem neuen Item den Core neu aufsetzen muss^^

ach so /emoticons/default_blink.png auch gut