Code:
#include "StdAfx.h"
#include "Setup.h"
#include <iostream>
#include <vector>
using namespace std;
#ifdef WIN32
#pragma warning(disable:4305) // warning C4305: 'argument' : truncation from 'double' to 'float'
#endif
#define SendQuickMenu(textid) objmgr.CreateGossipMenuForPlayer(&Menu, pObject->GetGUID(), textid, Plr); Menu->SendTo(Plr);
// GossipScript only supports 15 items (client side)
#define MAX_ENTRIES 13
class SCRIPT_DECL VotingRewards : public GossipScript
{
public:
void GossipHello(Object * pObject, Player* Plr, bool AutoSend);
void DisplayPage(Object * pObject, Player* Plr, uint8 page);
void GossipSelectOption(Object * pObject, Player* Plr, uint32 Id, uint32 IntId, const char * Code);
void GossipEnd(Object * pObject, Player* Plr);
private:
void GetRewards(uint32 team,uint32 page,std::vector<vr_item*> &items);
void GetReward(uint32 id,vr_item &item);
bool GiveReward(uint32 item,Player * Plr);
bool CanDisplay(vr_item item, Player * Plr);
uint32 GetPoints(Player * Plr);
void UpdatePoints(Player * Plr,uint32 points);
bool GiveReward(Player * Plr,uint32 item);
};
void VotingRewards::GossipHello(Object * pObject, Player* Plr, bool AutoSend)
{
Creature * pCreature = (pObject->GetTypeId()==TYPEID_UNIT)?((Creature*)pObject):NULL;
if(pCreature==NULL)
return;
uint32 points = GetPoints(Plr);
std::stringstream msg;
if(points > 0)
{
msg << "Welcome " << Plr->GetName() << ". You have " << points << " Voting Points to spend.";
pCreature->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,msg.str().c_str());
DisplayPage(pObject,Plr,1);
return;
}
msg << "Welcome " << Plr->GetName() << ". Sorry but you have no Voting Points to spend. GO VOTE!";
pCreature->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,msg.str().c_str());
GossipScript::GossipEnd(pObject, Plr);
return;
}
void VotingRewards::DisplayPage(Object * pObject, Player * Plr, uint8 page)
{
uint32 next = page+1;
uint32 prev = page > 1 ? page-1 : 0;
Creature * pCreature = (pObject->GetTypeId()==TYPEID_UNIT)?((Creature*)pObject):NULL;
if(pCreature==NULL)
return;
GossipMenu *Menu;
objmgr.CreateGossipMenuForPlayer(&Menu, pObject->GetGUID(), 1, Plr);
std::vector<vr_item*> items;
GetRewards(Plr->GetTeam(),page,items);
uint32 index = 0;
for(std::vector<vr_item*>::iterator itItem = items.begin(); itItem != items.end(); itItem++)
{
if(index++ >= MAX_ENTRIES)
{
Menu->AddItem(7,"[Next]",next);
break;
}
vr_item *item = *(itItem);
if(CanDisplay(*(item),Plr))
{
std::stringstream msg;
msg << item->name << " (" << item->cost << " pts)";
Menu->AddItem(1,msg.str().c_str(),item->id);
}
delete item;
}
if(page > 1)
Menu->AddItem(7,"[Prev]",prev);
Menu->SendTo(Plr);
}
void VotingRewards::GossipSelectOption(Object * pObject, Player* Plr, uint32 Id, uint32 IntId, const char * Code)
{
Creature * pCreature = (pObject->GetTypeId()==TYPEID_UNIT)?((Creature*)pObject):NULL;
if(pCreature==NULL)
return;
if (IntId < 10)
{
DisplayPage(pObject,Plr,IntId);
return;
}
uint32 points = GetPoints(Plr);
vr_item item;
GetReward(IntId,item);
std::stringstream msg;
if (points > item.cost)
{
if (GiveReward(Plr,item.id))
{
msg << "Thank You " << Plr->GetName() << ". Enjoy your reward.";
pCreature->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,msg.str().c_str());
UpdatePoints(Plr,item.cost);
}
else
{
msg << "Sorry " << Plr->GetName() << ", but your inventory is full.";
pCreature->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,msg.str().c_str());
}
DisplayPage(pObject,Plr,1);
}
else
{
msg << "Sorry " << Plr->GetName() << ", but you do not have enough points for that item.";
pCreature->SendChatMessage(CHAT_MSG_MONSTER_SAY,LANG_UNIVERSAL,msg.str().c_str());
DisplayPage(pObject,Plr,1);
}
}
void VotingRewards::GossipEnd(Object * pObject, Player* Plr)
{
GossipScript::GossipEnd(pObject, Plr);
}
void VotingRewards::GetRewards(uint32 team,uint32 page,std::vector<vr_item*> &items)
{
uint32 start = (page > 0) ? (page-1) * MAX_ENTRIES : 0;
QueryResult * res;
res = WorldDatabase.Query("SELECT v.item,i.name1,v.cost,v.team,v.minlevel,v.maxlevel FROM votingrewards AS v LEFT JOIN items AS i ON (i.entry=v.item) WHERE (v
.team=-1 OR v.team=%u) ORDER BY i.name1 LIMIT %u,100",team,start);
if(res)
{
do {
vr_item *item = new vr_item;
item->id = res->Fetch()[0].GetUInt32();
item->name = res->Fetch()[1].GetString();
item->cost = res->Fetch()[2].GetUInt32();
item->team = res->Fetch()[3].GetUInt32();
item->maxlevel = res->Fetch()[4].GetUInt32();
item->minlevel = res->Fetch()[5].GetUInt32();
if ((item->id > 0) && (item->name != 0))
items.push_back(item);
} while(res->NextRow());
}
delete res;
}
void VotingRewards::GetReward(uint32 id,vr_item &item)
{
QueryResult * res;
res = WorldDatabase.Query("SELECT v.item,i.name1,v.cost,v.team,v.minlevel,v.maxlevel FROM votingrewards AS v LEFT JOIN items AS i ON (i.entry=v.item) WHERE v.
item='%u'",id);
if(res)
{
item.id = res->Fetch()[0].GetUInt32();
item.name = res->Fetch()[1].GetString();
item.cost = res->Fetch()[2].GetUInt32();
item.team = res->Fetch()[3].GetUInt32();
item.maxlevel = res->Fetch()[4].GetUInt32();
item.minlevel = res->Fetch()[5].GetUInt32();
}
delete res;
}
bool VotingRewards::CanDisplay(vr_item item, Player * Plr)
{
if ((item.team != -1) && (item.team != Plr->GetTeam())) return false;
if ((item.minlevel > 0) && (Plr->getLevel() < item.minlevel)) return false;
if ((item.maxlevel > 0) && (Plr->getLevel() > item.maxlevel)) return false;
return true;
}
uint32 VotingRewards::GetPoints(Player * Plr)
{
QueryResult * res = VoteDatabase.Query("SELECT points FROM users WHERE username='%s'",Plr->GetSession()->GetAccountName().c_str());
if(res)
{
uint32 points = res->Fetch()[0].GetUInt32();
delete res;
return points;
}
delete res;
return 0;
}
bool VotingRewards::GiveReward(uint32 item,Player * Plr)
{
Item * pItem = objmgr.CreateItem(item,Plr);
return Plr->GetItemInterface()->AddItemToFreeSlot(pItem);
}
void VotingRewards::UpdatePoints(Player * Plr,uint32 points)
{
QueryResult * res = VoteDatabase.Query("UPDATE users SET points=points-%u WHERE username='%s'",points,Plr->GetSession()->GetAccountName().c_str());
delete res;
}
bool VotingRewards::GiveReward(Player * Plr,uint32 item)
{
ItemPrototype *proto = ItemPrototypeStorage.LookupEntry(item);
SlotResult slotresult;
slotresult = Plr->GetItemInterface()->FindFreeInventorySlot(proto);
if(!slotresult.Result)
{
Plr->GetItemInterface()->BuildInventoryChangeError(NULL, NULL, INV_ERR_INVENTORY_FULL);
return false;
}
else
{
Item *itm = objmgr.CreateItem(item, Plr);
itm->SetUInt32Value(ITEM_FIELD_STACK_COUNT, 1);
Plr->GetItemInterface()->SafeAddItem(itm,slotresult.ContainerSlot, slotresult.Slot);
return true;
}
}
void SetupVotingRewards(ScriptMgr * mgr)
{
GossipScript * gs = (GossipScript*) new VotingRewards();
mgr->register_gossip_script(2, gs);
}
Setup.cpp