* corrected MyCharacter & related
* implemented basic spellcasting, more to come. * new conf option: "disablespellcheck" * reactivated DefScript command "castspell" * added selfheal.def for GMs * misc stuff
This commit is contained in:
parent
17e6692007
commit
242e9cafcd
@ -176,10 +176,7 @@ bool DefScriptPackage::SCcastspell(CmdSet Set)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 spellId = 0;// = atoi(Set.defaultarg.c_str());
|
uint32 spellId = atoi(Set.defaultarg.c_str());
|
||||||
uint64 spellTarget = 0;// atoi(Set.arg[0]);
|
|
||||||
|
|
||||||
spellId = atoi(Set.defaultarg.c_str());
|
|
||||||
|
|
||||||
if (spellId <= 0)
|
if (spellId <= 0)
|
||||||
{
|
{
|
||||||
@ -187,12 +184,7 @@ bool DefScriptPackage::SCcastspell(CmdSet Set)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spellTarget <= 0)
|
((PseuInstance*)parentMethod)->GetWSession()->SendCastSpell(spellId);
|
||||||
{
|
|
||||||
spellTarget = ((PseuInstance*)parentMethod)->GetWSession()->GetGuid();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ((PseuInstance*)parentMethod)->GetWSession()->GetPlayerSettings()->CastSpell(spellId, spellTarget);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -271,6 +271,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v)
|
|||||||
enablechatai=(bool)atoi(v.Get("ENABLECHATAI").c_str());
|
enablechatai=(bool)atoi(v.Get("ENABLECHATAI").c_str());
|
||||||
notifyping=(bool)atoi(v.Get("NOTIFYPING").c_str());
|
notifyping=(bool)atoi(v.Get("NOTIFYPING").c_str());
|
||||||
showmyopcodes=(bool)atoi(v.Get("SHOWMYOPCODES").c_str());
|
showmyopcodes=(bool)atoi(v.Get("SHOWMYOPCODES").c_str());
|
||||||
|
disablespellcheck=(bool)atoi(v.Get("DISABLESPELLCHECK").c_str());
|
||||||
|
|
||||||
// clientversion is a bit more complicated to add
|
// clientversion is a bit more complicated to add
|
||||||
{
|
{
|
||||||
|
|||||||
@ -47,6 +47,7 @@ class PseuInstanceConf
|
|||||||
bool enablechatai;
|
bool enablechatai;
|
||||||
bool notifyping;
|
bool notifyping;
|
||||||
bool showmyopcodes;
|
bool showmyopcodes;
|
||||||
|
bool disablespellcheck;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -76,9 +76,12 @@ void WorldSession::SendQueryItem(uint32 id, uint64 guid) // is it a guid? not su
|
|||||||
SendWorldPacket(packet);
|
SendWorldPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// use ONLY this function to target objects and notify the server about it.
|
||||||
|
// (server & client need to stay synced)
|
||||||
void WorldSession::SendSetSelection(uint64 guid)
|
void WorldSession::SendSetSelection(uint64 guid)
|
||||||
{
|
{
|
||||||
// TODO: MyCharacter.SetTarget(guid);
|
ASSERT(GetMyChar()) // we need to be logged in to select something
|
||||||
|
GetMyChar()->SetTarget(guid);
|
||||||
logdebug("SetSelection GUID="I64FMT,guid);
|
logdebug("SetSelection GUID="I64FMT,guid);
|
||||||
WorldPacket packet;
|
WorldPacket packet;
|
||||||
packet << guid;
|
packet << guid;
|
||||||
@ -86,5 +89,54 @@ void WorldSession::SendSetSelection(uint64 guid)
|
|||||||
SendWorldPacket(packet);
|
SendWorldPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldSession::SendCastSpell(uint32 spellid)
|
||||||
|
{
|
||||||
|
if(!spellid)
|
||||||
|
return;
|
||||||
|
MyCharacter *my = GetMyChar();
|
||||||
|
bool known = my->HasSpell(spellid);
|
||||||
|
if( (!known) && (!GetInstance()->GetConf()->disablespellcheck) )
|
||||||
|
{
|
||||||
|
logerror("Attempt to cast not-known spell %u",spellid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *target = objmgr.GetObj(my->GetTarget());
|
||||||
|
|
||||||
|
if(!target) // this is wrong, some spells dont require a target (areaspells, self-only spells)
|
||||||
|
return; // but for now, this should be ok, until a db is used that provides spell info
|
||||||
|
|
||||||
|
WorldPacket packet;
|
||||||
|
ByteBuffer temp;
|
||||||
|
uint16 flags=TARGET_FLAG_SELF; // target mask. spellcast implementeation needs to be changed if TARGET_MASK_SELF is != 0
|
||||||
|
packet << spellid;
|
||||||
|
if(my->GetTarget() != GetGuid()) // self cast?
|
||||||
|
{
|
||||||
|
if(target->GetTypeId() == TYPEID_PLAYER || target->GetTypeId() == TYPEID_UNIT)
|
||||||
|
{
|
||||||
|
flags |= TARGET_FLAG_UNIT;
|
||||||
|
temp << (uint8)0xFF << my->GetTarget(); // need to send packed guid?
|
||||||
|
}
|
||||||
|
if(target->GetTypeId() == TYPEID_OBJECT)
|
||||||
|
{
|
||||||
|
flags |= TARGET_FLAG_OBJECT;
|
||||||
|
temp << (uint8)0xFF <<my->GetTarget(); // need to send packed guid?
|
||||||
|
}
|
||||||
|
// TODO: need implementation of areaspells & item targets (enchant) here (temp << itemGUID)!
|
||||||
|
// TODO: append floats x,y,z according to target type srcloc & dstloc to temp
|
||||||
|
// TODO: append string to temp if TARGET_FLAG_STRING is set. what string for what purpose??
|
||||||
|
// and whats with TARGET_CORPSE?
|
||||||
|
}
|
||||||
|
packet << flags;
|
||||||
|
packet.append(temp);
|
||||||
|
|
||||||
|
// cast it
|
||||||
|
packet.SetOpcode(CMSG_CAST_SPELL);
|
||||||
|
SendWorldPacket(packet);
|
||||||
|
logdetail("Casting spell %u on target "I64FMT,spellid,my->GetTarget());
|
||||||
|
if(!known)
|
||||||
|
logerror(" - WARNING: spell is NOT known!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -398,13 +398,13 @@ public:
|
|||||||
uint8 GetSlot(void) { return _slot; }
|
uint8 GetSlot(void) { return _slot; }
|
||||||
void SetSlot(uint8 nr) { _slot = nr; }
|
void SetSlot(uint8 nr) { _slot = nr; }
|
||||||
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
|
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
|
||||||
uint32 GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT); }
|
uint32 GetCount() const { return GetUInt32Value(ITEM_FIELD_STACK_COUNT); }
|
||||||
Bag *GetBag(void) { return _bag; }
|
Bag *GetBag(void) { return _bag; }
|
||||||
bool IsInBag() const { return _bag != NULL; }
|
bool IsInBag() const { return _bag != NULL; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8 _slot;
|
uint8 _slot;
|
||||||
Bag *_bag; // not yet implemented
|
Bag *_bag;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
#include "ObjMgr.h"
|
#include "ObjMgr.h"
|
||||||
|
|
||||||
ObjMgr::~ObjMgr()
|
ObjMgr::~ObjMgr()
|
||||||
|
{
|
||||||
|
RemoveAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjMgr::RemoveAll(void)
|
||||||
{
|
{
|
||||||
for(ItemProtoList::iterator i = _iproto.begin(); i!=_iproto.end(); i++)
|
for(ItemProtoList::iterator i = _iproto.begin(); i!=_iproto.end(); i++)
|
||||||
{
|
{
|
||||||
@ -31,6 +36,8 @@ void ObjMgr::Add(Object *o)
|
|||||||
|
|
||||||
Object *ObjMgr::GetObj(uint64 guid)
|
Object *ObjMgr::GetObj(uint64 guid)
|
||||||
{
|
{
|
||||||
|
if(!guid)
|
||||||
|
return NULL;
|
||||||
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
||||||
if((*i)->GetGUID() == guid)
|
if((*i)->GetGUID() == guid)
|
||||||
return (*i);
|
return (*i);
|
||||||
|
|||||||
@ -13,6 +13,7 @@ class ObjMgr
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~ObjMgr();
|
~ObjMgr();
|
||||||
|
void RemoveAll(void); // TODO: this needs to be called on SMSG_LOGOUT_COMPLETE once implemented.
|
||||||
|
|
||||||
// Item Prototype functions
|
// Item Prototype functions
|
||||||
uint32 GetItemProtoCount(void) { return _iproto.size(); }
|
uint32 GetItemProtoCount(void) { return _iproto.size(); }
|
||||||
|
|||||||
@ -22,9 +22,9 @@ void Player::Create(uint64 guid)
|
|||||||
Object::Create(guid);
|
Object::Create(guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
MyCharacter::MyCharacter()
|
MyCharacter::MyCharacter() : Player()
|
||||||
{
|
{
|
||||||
_castingSpell = false;
|
SetTarget(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyCharacter::SetActionButtons(WorldPacket &data)
|
void MyCharacter::SetActionButtons(WorldPacket &data)
|
||||||
@ -43,53 +43,20 @@ void MyCharacter::SetSpells(WorldPacket &data)
|
|||||||
data >> spellid >> spellslot;
|
data >> spellid >> spellslot;
|
||||||
logdebug("Initial Spell: id=%u slot=%u",spellid,spellslot);
|
logdebug("Initial Spell: id=%u slot=%u",spellid,spellslot);
|
||||||
|
|
||||||
spell _spell;
|
SpellBookEntry _spell;
|
||||||
_spell.spellId = spellid;
|
_spell.id = spellid;
|
||||||
_spell.spellSlot = spellslot;
|
_spell.slot = spellslot;
|
||||||
|
|
||||||
_spells.push_back(_spell);
|
_spells.push_back(_spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyCharacter::CastSpell(uint32 spellId, uint64 target)
|
uint16 MyCharacter::GetSpellSlot(uint32 spellid)
|
||||||
{
|
{
|
||||||
/*
|
for(std::vector<SpellBookEntry>::iterator i=_spells.begin(); i != _spells.end(); i++)
|
||||||
if (_castingSpell)
|
if(i->id == spellid)
|
||||||
return;
|
return i->slot;
|
||||||
|
return 0;
|
||||||
_castingSpell = !_castingSpell;
|
|
||||||
|
|
||||||
WorldPacket packet;
|
|
||||||
packet.SetOpcode(CMSG_CAST_SPELL);
|
|
||||||
packet << spellId << (uint16)2 << (uint8)1 << (uint8)target; // 2 = TARGET_FLAG_UNIT
|
|
||||||
// Can be bugged, not fully tested, probably doesn't work when the guid is high
|
|
||||||
// Damn packed guid stuff! xD
|
|
||||||
|
|
||||||
_worldSession->SendWorldPacket(packet);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyCharacter::HandleCastResultOpcode(WorldPacket &packet)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
uint32 spellId;
|
|
||||||
uint8 statusFail;
|
|
||||||
uint8 failProblem;
|
|
||||||
char l[150];
|
|
||||||
|
|
||||||
packet >> spellId >> statusFail;
|
|
||||||
|
|
||||||
_castingSpell = false;
|
|
||||||
|
|
||||||
sprintf(l, "Received cast result opcode. Spell = %d, statusFail = %d", spellId, statusFail);
|
|
||||||
|
|
||||||
if (statusFail == 2) // Spell cast failed
|
|
||||||
{
|
|
||||||
packet >> failProblem;
|
|
||||||
sprintf(l, "%s, failProblem = %d", l, failProblem);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//logdetail(l);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
@ -175,6 +175,12 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SpellBookEntry
|
||||||
|
{
|
||||||
|
uint32 id;
|
||||||
|
uint16 slot;
|
||||||
|
};
|
||||||
|
|
||||||
class Player : public Unit
|
class Player : public Unit
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -197,19 +203,18 @@ public:
|
|||||||
|
|
||||||
void SetActionButtons(WorldPacket &data);
|
void SetActionButtons(WorldPacket &data);
|
||||||
void SetSpells(WorldPacket &data);
|
void SetSpells(WorldPacket &data);
|
||||||
void CastSpell(uint32 spellId, uint64 target);
|
uint64 GetTarget(void) { return _target; }
|
||||||
void HandleCastResultOpcode(WorldPacket &packet);
|
void SetTarget(uint64 guid) { _target = guid; } // should only be called by WorldSession::SendSetSelection() !!
|
||||||
|
bool HasSpell(uint32 spellid) { return GetSpellSlot(spellid) != 0; }
|
||||||
|
uint16 GetSpellSlot(uint32 spellid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _castingSpell;
|
// bool _castingSpell; // this is something we dont really need for now
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16 spellId;
|
|
||||||
uint16 spellSlot;
|
|
||||||
} spell;
|
|
||||||
|
|
||||||
std::vector<spell> _spells;
|
|
||||||
|
std::vector<SpellBookEntry> _spells;
|
||||||
|
uint64 _target; // currently targeted object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -988,4 +988,15 @@ enum ChatMsg
|
|||||||
CHAT_MSG_LOOT = 0x18,
|
CHAT_MSG_LOOT = 0x18,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SpellCastTargetFlags
|
||||||
|
{
|
||||||
|
TARGET_FLAG_SELF = 0x0000,
|
||||||
|
TARGET_FLAG_UNIT = 0x0002,
|
||||||
|
TARGET_FLAG_OBJECT = 0x0800,
|
||||||
|
TARGET_FLAG_ITEM = 0x1010,
|
||||||
|
TARGET_FLAG_SOURCE_LOCATION = 0x0020,
|
||||||
|
TARGET_FLAG_DEST_LOCATION = 0x0040,
|
||||||
|
TARGET_FLAG_STRING = 0x2000
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -24,10 +24,8 @@ WorldSession::WorldSession(PseuInstance *in)
|
|||||||
_myGUID=0; // i dont have a guid yet
|
_myGUID=0; // i dont have a guid yet
|
||||||
plrNameCache.ReadFromFile(); // load names/guids of known players
|
plrNameCache.ReadFromFile(); // load names/guids of known players
|
||||||
ItemProtoCache_InsertDataToSession(this);
|
ItemProtoCache_InsertDataToSession(this);
|
||||||
myCharacter = new MyCharacter();
|
|
||||||
_deleteme = false;
|
_deleteme = false;
|
||||||
_channels = new Channel(this);
|
_channels = new Channel(this);
|
||||||
// _playerSettings->Init(this);
|
|
||||||
//...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,13 +364,14 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
log("Entering World with Character \"%s\"...",GetInstance()->GetConf()->charname.c_str());
|
log("Entering World with Character \"%s\"...",GetInstance()->GetConf()->charname.c_str());
|
||||||
// _player->Init(plr[i]);
|
// create the character and add it to the objmgr.
|
||||||
|
MyCharacter *my = new MyCharacter();
|
||||||
|
my->Create(_myGUID);
|
||||||
|
objmgr.Add(my);
|
||||||
|
|
||||||
WorldPacket pkt;
|
WorldPacket pkt;
|
||||||
pkt.SetOpcode(CMSG_PLAYER_LOGIN);
|
pkt.SetOpcode(CMSG_PLAYER_LOGIN);
|
||||||
pkt << _myGUID;
|
pkt << _myGUID;
|
||||||
_targetGUID=0;
|
|
||||||
_followGUID=0;
|
|
||||||
SendWorldPacket(pkt);
|
SendWorldPacket(pkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -632,11 +631,23 @@ void WorldSession::_HandleChannelNotifyOpcode(WorldPacket& recvPacket)
|
|||||||
|
|
||||||
void WorldSession::_HandleCastResultOpcode(WorldPacket& recvPacket)
|
void WorldSession::_HandleCastResultOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
// _playerSettings->HandleCastResultOpcode(recvPacket);
|
uint32 spellid;
|
||||||
|
uint8 flag,result;
|
||||||
|
recvPacket >> spellid >> flag;
|
||||||
|
if(flag)
|
||||||
|
{
|
||||||
|
recvPacket >> result;
|
||||||
|
logdetail("Cast of spell %u failed. flag=%u, result=%u",spellid,flag,result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logdetail("Cast of spell %u successful.",spellid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::_HandleInitialSpellsOpcode(WorldPacket& recvPacket)
|
void WorldSession::_HandleInitialSpellsOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
myCharacter->SetSpells(recvPacket);
|
// suggestion for later: what about MyCharacter->AddSpellBookEntry() ?
|
||||||
|
GetMyChar()->SetSpells(recvPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,8 +50,7 @@ public:
|
|||||||
uint64 GetFollowTarget(void) { return _followGUID; }
|
uint64 GetFollowTarget(void) { return _followGUID; }
|
||||||
uint64 GetGuid(void) { return _myGUID; }
|
uint64 GetGuid(void) { return _myGUID; }
|
||||||
Channel *GetChannels(void) { return _channels; }
|
Channel *GetChannels(void) { return _channels; }
|
||||||
// Player *GetPlayer(void) { return _player; }
|
MyCharacter *GetMyChar(void) { ASSERT(_myGUID > 0); return (MyCharacter*)objmgr.GetObj(_myGUID); }
|
||||||
// PlayerSettings *GetPlayerSettings(void) { return _playerSettings; }
|
|
||||||
|
|
||||||
|
|
||||||
// CMSGConstructor
|
// CMSGConstructor
|
||||||
@ -61,9 +60,9 @@ public:
|
|||||||
void SendEmote(uint32);
|
void SendEmote(uint32);
|
||||||
void SendQueryItem(uint32, uint64);
|
void SendQueryItem(uint32, uint64);
|
||||||
void SendSetSelection(uint64);
|
void SendSetSelection(uint64);
|
||||||
|
void SendCastSpell(uint32);
|
||||||
|
|
||||||
PlayerNameCache plrNameCache;
|
PlayerNameCache plrNameCache;
|
||||||
MyCharacter *myCharacter;
|
|
||||||
ObjMgr objmgr;
|
ObjMgr objmgr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user