* 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;
|
||||
}
|
||||
|
||||
uint32 spellId = 0;// = atoi(Set.defaultarg.c_str());
|
||||
uint64 spellTarget = 0;// atoi(Set.arg[0]);
|
||||
|
||||
spellId = atoi(Set.defaultarg.c_str());
|
||||
uint32 spellId = atoi(Set.defaultarg.c_str());
|
||||
|
||||
if (spellId <= 0)
|
||||
{
|
||||
@ -187,12 +184,7 @@ bool DefScriptPackage::SCcastspell(CmdSet Set)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (spellTarget <= 0)
|
||||
{
|
||||
spellTarget = ((PseuInstance*)parentMethod)->GetWSession()->GetGuid();
|
||||
}
|
||||
|
||||
// ((PseuInstance*)parentMethod)->GetWSession()->GetPlayerSettings()->CastSpell(spellId, spellTarget);
|
||||
((PseuInstance*)parentMethod)->GetWSession()->SendCastSpell(spellId);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -271,6 +271,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v)
|
||||
enablechatai=(bool)atoi(v.Get("ENABLECHATAI").c_str());
|
||||
notifyping=(bool)atoi(v.Get("NOTIFYPING").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
|
||||
{
|
||||
|
||||
@ -47,6 +47,7 @@ class PseuInstanceConf
|
||||
bool enablechatai;
|
||||
bool notifyping;
|
||||
bool showmyopcodes;
|
||||
bool disablespellcheck;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -76,9 +76,12 @@ void WorldSession::SendQueryItem(uint32 id, uint64 guid) // is it a guid? not su
|
||||
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)
|
||||
{
|
||||
// TODO: MyCharacter.SetTarget(guid);
|
||||
ASSERT(GetMyChar()) // we need to be logged in to select something
|
||||
GetMyChar()->SetTarget(guid);
|
||||
logdebug("SetSelection GUID="I64FMT,guid);
|
||||
WorldPacket packet;
|
||||
packet << guid;
|
||||
@ -86,5 +89,54 @@ void WorldSession::SendSetSelection(uint64 guid)
|
||||
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; }
|
||||
void SetSlot(uint8 nr) { _slot = nr; }
|
||||
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; }
|
||||
bool IsInBag() const { return _bag != NULL; }
|
||||
|
||||
protected:
|
||||
uint8 _slot;
|
||||
Bag *_bag; // not yet implemented
|
||||
Bag *_bag;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
#include "ObjMgr.h"
|
||||
|
||||
ObjMgr::~ObjMgr()
|
||||
{
|
||||
RemoveAll();
|
||||
}
|
||||
|
||||
void ObjMgr::RemoveAll(void)
|
||||
{
|
||||
for(ItemProtoList::iterator i = _iproto.begin(); i!=_iproto.end(); i++)
|
||||
{
|
||||
@ -31,6 +36,8 @@ void ObjMgr::Add(Object *o)
|
||||
|
||||
Object *ObjMgr::GetObj(uint64 guid)
|
||||
{
|
||||
if(!guid)
|
||||
return NULL;
|
||||
for(ObjectList::iterator i = _obj.begin(); i!=_obj.end(); i++)
|
||||
if((*i)->GetGUID() == guid)
|
||||
return (*i);
|
||||
|
||||
@ -13,6 +13,7 @@ class ObjMgr
|
||||
{
|
||||
public:
|
||||
~ObjMgr();
|
||||
void RemoveAll(void); // TODO: this needs to be called on SMSG_LOGOUT_COMPLETE once implemented.
|
||||
|
||||
// Item Prototype functions
|
||||
uint32 GetItemProtoCount(void) { return _iproto.size(); }
|
||||
|
||||
@ -22,9 +22,9 @@ void Player::Create(uint64 guid)
|
||||
Object::Create(guid);
|
||||
}
|
||||
|
||||
MyCharacter::MyCharacter()
|
||||
MyCharacter::MyCharacter() : Player()
|
||||
{
|
||||
_castingSpell = false;
|
||||
SetTarget(0);
|
||||
}
|
||||
|
||||
void MyCharacter::SetActionButtons(WorldPacket &data)
|
||||
@ -43,53 +43,20 @@ void MyCharacter::SetSpells(WorldPacket &data)
|
||||
data >> spellid >> spellslot;
|
||||
logdebug("Initial Spell: id=%u slot=%u",spellid,spellslot);
|
||||
|
||||
spell _spell;
|
||||
_spell.spellId = spellid;
|
||||
_spell.spellSlot = spellslot;
|
||||
SpellBookEntry _spell;
|
||||
_spell.id = spellid;
|
||||
_spell.slot = spellslot;
|
||||
|
||||
_spells.push_back(_spell);
|
||||
}
|
||||
}
|
||||
|
||||
void MyCharacter::CastSpell(uint32 spellId, uint64 target)
|
||||
uint16 MyCharacter::GetSpellSlot(uint32 spellid)
|
||||
{
|
||||
/*
|
||||
if (_castingSpell)
|
||||
return;
|
||||
|
||||
_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);
|
||||
*/
|
||||
for(std::vector<SpellBookEntry>::iterator i=_spells.begin(); i != _spells.end(); i++)
|
||||
if(i->id == spellid)
|
||||
return i->slot;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
@ -197,19 +203,18 @@ public:
|
||||
|
||||
void SetActionButtons(WorldPacket &data);
|
||||
void SetSpells(WorldPacket &data);
|
||||
void CastSpell(uint32 spellId, uint64 target);
|
||||
void HandleCastResultOpcode(WorldPacket &packet);
|
||||
uint64 GetTarget(void) { return _target; }
|
||||
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:
|
||||
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,
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
@ -24,10 +24,8 @@ WorldSession::WorldSession(PseuInstance *in)
|
||||
_myGUID=0; // i dont have a guid yet
|
||||
plrNameCache.ReadFromFile(); // load names/guids of known players
|
||||
ItemProtoCache_InsertDataToSession(this);
|
||||
myCharacter = new MyCharacter();
|
||||
_deleteme = false;
|
||||
_channels = new Channel(this);
|
||||
// _playerSettings->Init(this);
|
||||
//...
|
||||
}
|
||||
|
||||
@ -366,13 +364,14 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
return;
|
||||
} else {
|
||||
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;
|
||||
pkt.SetOpcode(CMSG_PLAYER_LOGIN);
|
||||
pkt << _myGUID;
|
||||
_targetGUID=0;
|
||||
_followGUID=0;
|
||||
SendWorldPacket(pkt);
|
||||
}
|
||||
}
|
||||
@ -632,11 +631,23 @@ void WorldSession::_HandleChannelNotifyOpcode(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)
|
||||
{
|
||||
myCharacter->SetSpells(recvPacket);
|
||||
// suggestion for later: what about MyCharacter->AddSpellBookEntry() ?
|
||||
GetMyChar()->SetSpells(recvPacket);
|
||||
}
|
||||
|
||||
|
||||
@ -50,8 +50,7 @@ public:
|
||||
uint64 GetFollowTarget(void) { return _followGUID; }
|
||||
uint64 GetGuid(void) { return _myGUID; }
|
||||
Channel *GetChannels(void) { return _channels; }
|
||||
// Player *GetPlayer(void) { return _player; }
|
||||
// PlayerSettings *GetPlayerSettings(void) { return _playerSettings; }
|
||||
MyCharacter *GetMyChar(void) { ASSERT(_myGUID > 0); return (MyCharacter*)objmgr.GetObj(_myGUID); }
|
||||
|
||||
|
||||
// CMSGConstructor
|
||||
@ -61,9 +60,9 @@ public:
|
||||
void SendEmote(uint32);
|
||||
void SendQueryItem(uint32, uint64);
|
||||
void SendSetSelection(uint64);
|
||||
void SendCastSpell(uint32);
|
||||
|
||||
PlayerNameCache plrNameCache;
|
||||
MyCharacter *myCharacter;
|
||||
ObjMgr objmgr;
|
||||
|
||||
private:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user