Another release.
With this class, you'll be able to add stages to creatures, specific to players.
For example you could write a gossip script and integrate this class with it.
You can update creatures' stages after an event e.g: killed something, talked to some other npc.., development in own gossip; use your creativity.
The stages are saved in the database, so if a player develops in a npcs stage it stays, whether the server crashes or restarts.
This makes it possible for npcs to react differently on players.
- CreatureStage.cpp:
Code:
#include "CreatureStage.h"
#include "StdAfx.h"
void CreatureStage::UpdateStage(uint32 value, uint32 entry, uint32 guid)
{
if(entry && guid)
{
std::stringstream ss;
ss << "UPDATE creature_phases SET phase = '" << value << "' WHERE entry = '" << entry << "' AND guid = '" << guid << "';";
WorldDatabase.Execute(ss.str().c_str());
list->second = value;
}
}
void CreatureStage::DeleteRow(uint32 entry, uint32 guid)
{
if(entry && guid)
{
std::stringstream ss;
ss << "DELETE FROM creature_phases WHERE entry='" << entry << "' AND guid='" << guid << "';";
WorldDatabase.Execute(ss.str().c_str());
players.erase(list);
}
}
void CreatureStage::AddNewPlayer(uint32 entry, uint32 guid, uint32 phase)
{
if(entry && guid)
{
std::stringstream ss;
ss << "INSERT INTO creature_phases (entry, guid, phase) VALUES ('" << entry << "' , " << guid << ", " << phase << ");";
WorldDatabase.Execute(ss.str().c_str());
players.insert(make_pair(guid, phase));
}
}
void CreatureStage::GetCreatureStages(uint32 entry)
{
std::stringstream ss;
ss << "SELECT * FROM creature_phases WHERE entry='" << entry << "';";
QueryResult *result = WorldDatabase.Query(ss.str().c_str());
if(result)
{
do
{
Field* field = result->Fetch();
uint32 low_guid = field[1].GetUInt32();
uint32 phase = field[2].GetUInt32();
players.insert(make_pair(low_guid, phase));
} while(result->NextRow());
}
}
bool CreatureStage::FindPlayer(uint32 guid)
{
bool found = true;
list = players.find(guid);
if(list == players.end())
found = false;
return found;
}
uint32 CreatureStage::GetStage()
{
uint32 phase = 0;
if(list != players.end())
phase = list->second;
return phase;
}
- CreatureStage.h:
Code:
#include "StdAfx.h"
#pragma once
class CreatureStage
{
public:
map<uint32, uint32> players;
map<uint32,uint32>::iterator list;
void UpdateStage(uint32 value, uint32 entry, uint32 guid);
void DeleteRow(uint32 entry, uint32 guid);
void AddNewPlayer(uint32 entry, uint32 guid, uint32 phase);
void GetCreatureStages(uint32 entry);
bool FindPlayer(uint32 guid);
uint32 GetStage();
};
- CreatureStage.sql(execute on world database):
Code:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `creature_phases`
-- ----------------------------
DROP TABLE IF EXISTS `creature_phases`;
CREATE TABLE `creature_phases` (
`entry` int(11) NOT NULL,
`guid` int(11) NOT NULL,
`phase` int(11) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `creature_phases`
-- ----------------------------
- Example code:
Code:
class SERVER_DECL Example_Gossip : public GossipScript
{
public:
CreatureStage* Example;
void GossipHello(Object* object, Player* player, bool AutoSend)
{
GossipMenu *Menu;
uint32 entry = object->GetEntry();
uint32 guid = player->GetLowGUID();
Example->GetCreatureStages(entry);
if(Example->FindPlayer(guid))
{
switch(Example->GetStage())
{
case 0: {
// Stage 1.
} break;
case 1: {
// Stage 2.
} break;
case 2: {
// stage 3.
} break;
// And go on..
}
}
else
{
// Not staged yet.
}
Menu->SendTo(player);
};
void GossipSelectOption(Object* object, Player* player, uint32 Id, uint32 IntId, const char * Code)
{
GossipMenu *Menu;
uint32 stage = 0;
uint32 entry = object->GetEntry();
uint32 guid = player->GetLowGUID();
switch(IntId)
{
case 0: {
// IntId 0, put something here..
} break;
case 1: {
// IntId 1, to end the gossip.
GossipEnd(object, player);
} break;
case 2:
{
// Well.. Let's add the player, if he isn't in the table yet..
if(!Example->FindPlayer(guid))
{
stage = 1;
Example->AddNewPlayer(entry, guid, stage);
}
GossipEnd(object, player);
} break;
case 3:
{
// Well to show how to delete a player from his list ;)
if(Example->FindPlayer(guid))
Example->DeleteRow(entry, guid);
GossipHello(object, player, true);
} break;
case 4:
{
// Let's update the creatures' (- player) stage. :)
stage = 2;
{
if(Example->FindPlayer(guid))
Example->UpdateStage(stage, entry, guid);
}
} break;
}
};
void GossipEnd(Object * object, Player* player)
{
player->GetSession()->OutPacket(SMSG_GOSSIP_COMPLETE, 0, NULL);
}
void Destroy()
{
delete this;
};
};
Have fun.