mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 01:11:29 +00:00
[Feature] Add opcodes for Cast and Scribe book buttons (#3578)
This is just the packet framework for the Scribe button on recipe books and the Cast Spell button on books that allow casting spells on targets. It will need to be hooked up to a content implementation
This commit is contained in:
parent
bab16771aa
commit
604c7ad4ab
@ -62,6 +62,7 @@ N(OP_BeginCast),
|
|||||||
N(OP_Bind_Wound),
|
N(OP_Bind_Wound),
|
||||||
N(OP_BlockedBuffs),
|
N(OP_BlockedBuffs),
|
||||||
N(OP_BoardBoat),
|
N(OP_BoardBoat),
|
||||||
|
N(OP_BookButton),
|
||||||
N(OP_Buff),
|
N(OP_Buff),
|
||||||
N(OP_BuffCreate),
|
N(OP_BuffCreate),
|
||||||
N(OP_BuffRemoveRequest),
|
N(OP_BuffRemoveRequest),
|
||||||
|
|||||||
@ -2559,7 +2559,10 @@ struct GMEmoteZone_Struct {
|
|||||||
struct BookText_Struct {
|
struct BookText_Struct {
|
||||||
uint8 window; // where to display the text (0xFF means new window)
|
uint8 window; // where to display the text (0xFF means new window)
|
||||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||||
uint32 invslot; // Only used in SoF and later clients.
|
int16 invslot; // Only used in SoF and later clients.
|
||||||
|
int32 target_id;
|
||||||
|
int8 can_cast;
|
||||||
|
int8 can_scribe;
|
||||||
char booktext[1]; // Variable Length
|
char booktext[1]; // Variable Length
|
||||||
};
|
};
|
||||||
// This is the request to read a book.
|
// This is the request to read a book.
|
||||||
@ -2568,11 +2571,18 @@ struct BookText_Struct {
|
|||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
uint8 window; // where to display the text (0xFF means new window)
|
uint8 window; // where to display the text (0xFF means new window)
|
||||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||||
uint32 invslot; // Only used in Sof and later clients;
|
int16 invslot; // Only used in Sof and later clients;
|
||||||
int16 subslot; // The subslot inside of a bag if it is inside one.
|
int32 target_id;
|
||||||
char txtfile[20];
|
char txtfile[20];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
int16 invslot; // server slot
|
||||||
|
int32 target_id;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Object/Ground Spawn struct
|
** Object/Ground Spawn struct
|
||||||
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
|
||||||
|
|||||||
@ -2785,7 +2785,10 @@ namespace RoF2
|
|||||||
else
|
else
|
||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(invslot);
|
eq->invslot = ServerToRoF2TypelessSlot(emu->invslot, invtype::typePossessions);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -4411,6 +4414,17 @@ namespace RoF2
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->slot, invtype::typePossessions));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@ -5117,8 +5131,8 @@ namespace RoF2
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
IN(invslot);
|
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->invslot, invtype::typePossessions));
|
||||||
IN(subslot);
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
|
|||||||
@ -150,6 +150,7 @@ D(OP_AugmentInfo)
|
|||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
D(OP_BlockedBuffs)
|
D(OP_BlockedBuffs)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_BuffRemoveRequest)
|
D(OP_BuffRemoveRequest)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
|
|||||||
@ -2868,15 +2868,23 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint16 invslot; // Is the slot, but the RoF2 conversion causes it to fail. Turned to 0 since it isnt required anyway.
|
/*0004*/ TypelessInventorySlot_Struct invslot; // book ItemIndex (with int16_t alignment padding)
|
||||||
/*0006*/ int16 subslot; // Inventory sub-slot (0-x)
|
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0008*/ uint16 unknown006; // Seen FFFF
|
/*0016*/ uint32 target_id; // client's target when using the book
|
||||||
/*0010*/ uint16 unknown008; // seen 0000
|
/*0020*/ uint8 can_cast; // show Cast Spell button in book window
|
||||||
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0021*/ uint8 can_scribe; // show Scribe button in book window
|
||||||
/*0016*/ uint32 unknown0012;
|
/*0022*/ char txtfile[8194];
|
||||||
/*0020*/ uint16 unknown0016;
|
/*8216*/
|
||||||
/*0022*/ char txtfile[8194];
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ TypelessInventorySlot_Struct slot; // book ItemIndex (with int16_t alignment padding)
|
||||||
|
/*0008*/ int32 target_id; // client's target when using the book button
|
||||||
|
/*0012*/ int32 unused; // always 0 from button packets
|
||||||
|
/*0016*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -1782,6 +1782,9 @@ namespace SoD
|
|||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->invslot = ServerToSoDSlot(emu->invslot);
|
eq->invslot = ServerToSoDSlot(emu->invslot);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -2817,6 +2820,17 @@ namespace SoD
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@ -3364,7 +3378,8 @@ namespace SoD
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
emu->invslot = SoDToServerSlot(eq->invslot);
|
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
|
|||||||
@ -103,6 +103,7 @@ D(OP_ApplyPoison)
|
|||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_ChannelMessage)
|
D(OP_ChannelMessage)
|
||||||
|
|||||||
@ -2351,12 +2351,21 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0012*/ uint32 unknown0012;
|
/*0012*/ uint32 target_id;
|
||||||
/*0016*/ uint16 unknown0016;
|
/*0016*/ uint8 can_cast;
|
||||||
/*0018*/ char txtfile[8194];
|
/*0017*/ uint8 can_scribe;
|
||||||
|
/*0018*/ char txtfile[8194];
|
||||||
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ int32 invslot;
|
||||||
|
/*0004*/ int32 target_id; // client's target when using the book
|
||||||
|
/*0008*/ int32 unused; // always 0 from button packets
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -1452,6 +1452,9 @@ namespace SoF
|
|||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->invslot = ServerToSoFSlot(emu->invslot);
|
eq->invslot = ServerToSoFSlot(emu->invslot);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -2261,6 +2264,17 @@ namespace SoF
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@ -2769,7 +2783,8 @@ namespace SoF
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
emu->invslot = SoFToServerSlot(eq->invslot);
|
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
|
|||||||
@ -94,6 +94,7 @@ D(OP_AltCurrencySellSelection)
|
|||||||
D(OP_ApplyPoison)
|
D(OP_ApplyPoison)
|
||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_Bug)
|
D(OP_Bug)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
|
|||||||
@ -2321,12 +2321,21 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0012*/ uint32 unknown0012;
|
/*0012*/ uint32 target_id;
|
||||||
/*0016*/ uint16 unknown0016;
|
/*0016*/ uint8 can_cast;
|
||||||
/*0018*/ char txtfile[8194];
|
/*0017*/ uint8 can_scribe;
|
||||||
|
/*0018*/ char txtfile[8194];
|
||||||
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ int32 invslot;
|
||||||
|
/*0004*/ int32 target_id; // client's target when using the book
|
||||||
|
/*0008*/ int32 unused; // always 0 from button packets
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -2027,6 +2027,9 @@ namespace UF
|
|||||||
eq->window = emu->window;
|
eq->window = emu->window;
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->invslot = ServerToUFSlot(emu->invslot);
|
eq->invslot = ServerToUFSlot(emu->invslot);
|
||||||
|
OUT(target_id);
|
||||||
|
OUT(can_cast);
|
||||||
|
OUT(can_scribe);
|
||||||
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -3105,6 +3108,17 @@ namespace UF
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_BookButton)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
|
||||||
|
|
||||||
|
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_Buff)
|
DECODE(OP_Buff)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
|
||||||
@ -3664,7 +3678,8 @@ namespace UF
|
|||||||
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
|
||||||
|
|
||||||
IN(type);
|
IN(type);
|
||||||
emu->invslot = UFToServerSlot(eq->invslot);
|
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
|
||||||
|
IN(target_id);
|
||||||
emu->window = (uint8)eq->window;
|
emu->window = (uint8)eq->window;
|
||||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||||
|
|
||||||
|
|||||||
@ -110,6 +110,7 @@ D(OP_ApplyPoison)
|
|||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
|
D(OP_BookButton)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_BuffRemoveRequest)
|
D(OP_BuffRemoveRequest)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
|
|||||||
@ -2400,12 +2400,21 @@ struct BookText_Struct {
|
|||||||
// This is just a "text file" on the server
|
// This is just a "text file" on the server
|
||||||
// or in our case, the 'name' column in our books table.
|
// or in our case, the 'name' column in our books table.
|
||||||
struct BookRequest_Struct {
|
struct BookRequest_Struct {
|
||||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||||
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
|
/*0004*/ uint32 invslot; // The inventory slot the book is in
|
||||||
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||||
/*0012*/ uint32 unknown0012;
|
/*0012*/ uint32 target_id;
|
||||||
/*0016*/ uint16 unknown0016;
|
/*0016*/ uint8 can_cast;
|
||||||
/*0018*/ char txtfile[8194];
|
/*0017*/ uint8 can_scribe;
|
||||||
|
/*0018*/ char txtfile[8194];
|
||||||
|
};
|
||||||
|
|
||||||
|
// used by Scribe and CastSpell book buttons
|
||||||
|
struct BookButton_Struct
|
||||||
|
{
|
||||||
|
/*0000*/ int32 invslot;
|
||||||
|
/*0004*/ int32 target_id; // client's target when using the book
|
||||||
|
/*0008*/ int32 unused; // always 0 from button packets
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -370,6 +370,7 @@ OP_AggroMeterTargetInfo=0x16bc
|
|||||||
OP_AggroMeterUpdate=0x1781
|
OP_AggroMeterUpdate=0x1781
|
||||||
OP_UnderWorld=0x2eb3 # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
OP_UnderWorld=0x2eb3 # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
||||||
OP_KickPlayers=0x6770
|
OP_KickPlayers=0x6770
|
||||||
|
OP_BookButton=0x6146
|
||||||
|
|
||||||
# Expeditions
|
# Expeditions
|
||||||
OP_DzQuit=0xb2e3
|
OP_DzQuit=0xb2e3
|
||||||
|
|||||||
@ -360,6 +360,7 @@ OP_Marquee=0x7dc9
|
|||||||
OP_Fling=0x2b88
|
OP_Fling=0x2b88
|
||||||
OP_CancelSneakHide=0x7705
|
OP_CancelSneakHide=0x7705
|
||||||
OP_UnderWorld=0x51ae # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
OP_UnderWorld=0x51ae # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
||||||
|
OP_BookButton=0x4348
|
||||||
|
|
||||||
# Expedition
|
# Expedition
|
||||||
OP_DzQuit=0x054e
|
OP_DzQuit=0x054e
|
||||||
|
|||||||
@ -341,6 +341,7 @@ OP_Marquee=0x2f75
|
|||||||
OP_Untargetable=0x3e36
|
OP_Untargetable=0x3e36
|
||||||
OP_CancelSneakHide=0x5335
|
OP_CancelSneakHide=0x5335
|
||||||
OP_UnderWorld=0x7580 # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
OP_UnderWorld=0x7580 # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
||||||
|
OP_BookButton=0x4eee
|
||||||
|
|
||||||
#expedition
|
#expedition
|
||||||
OP_DzQuit=0x20d6
|
OP_DzQuit=0x20d6
|
||||||
|
|||||||
@ -371,6 +371,7 @@ OP_Marquee=0x3675
|
|||||||
OP_Fling=0x51b1
|
OP_Fling=0x51b1
|
||||||
OP_CancelSneakHide=0x7686
|
OP_CancelSneakHide=0x7686
|
||||||
OP_UnderWorld=0x2d9d # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
OP_UnderWorld=0x2d9d # clients sends up when they detect an underworld issue, might be useful for cheat detection
|
||||||
|
OP_BookButton=0x018e
|
||||||
|
|
||||||
OP_DzQuit=0x1539
|
OP_DzQuit=0x1539
|
||||||
OP_DzListTimers=0x21e9
|
OP_DzListTimers=0x21e9
|
||||||
|
|||||||
@ -2211,25 +2211,13 @@ void Client::ReadBook(BookRequest_Struct *book) {
|
|||||||
|
|
||||||
|
|
||||||
if (ClientVersion() >= EQ::versions::ClientVersion::SoF) {
|
if (ClientVersion() >= EQ::versions::ClientVersion::SoF) {
|
||||||
// Find out what slot the book was read from.
|
|
||||||
// SoF+ need to look up book type for the output message.
|
// SoF+ need to look up book type for the output message.
|
||||||
int16 read_from_slot;
|
|
||||||
|
|
||||||
if (book->subslot >= 0) {
|
|
||||||
uint16 offset;
|
|
||||||
offset = (book->invslot-23) * 10; // How many packs to skip.
|
|
||||||
read_from_slot = 251 + offset + book->subslot;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
read_from_slot = book->invslot -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EQ::ItemInstance *inst = nullptr;
|
const EQ::ItemInstance *inst = nullptr;
|
||||||
|
|
||||||
if (read_from_slot <= EQ::invbag::GENERAL_BAGS_END)
|
if (book->invslot <= EQ::invbag::GENERAL_BAGS_END)
|
||||||
{
|
{
|
||||||
inst = m_inv[read_from_slot];
|
inst = m_inv[book->invslot];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(inst)
|
if(inst)
|
||||||
out->type = inst->GetItem()->Book;
|
out->type = inst->GetItem()->Book;
|
||||||
@ -2240,6 +2228,9 @@ void Client::ReadBook(BookRequest_Struct *book) {
|
|||||||
out->type = book->type;
|
out->type = book->type;
|
||||||
}
|
}
|
||||||
out->invslot = book->invslot;
|
out->invslot = book->invslot;
|
||||||
|
out->target_id = book->target_id;
|
||||||
|
out->can_cast = 0; // todo: implement
|
||||||
|
out->can_scribe = 0; // todo: implement
|
||||||
|
|
||||||
memcpy(out->booktext, booktxt2.c_str(), length);
|
memcpy(out->booktext, booktxt2.c_str(), length);
|
||||||
|
|
||||||
|
|||||||
@ -145,6 +145,7 @@ void MapOpcodes()
|
|||||||
ConnectedOpcodes[OP_Bind_Wound] = &Client::Handle_OP_Bind_Wound;
|
ConnectedOpcodes[OP_Bind_Wound] = &Client::Handle_OP_Bind_Wound;
|
||||||
ConnectedOpcodes[OP_BlockedBuffs] = &Client::Handle_OP_BlockedBuffs;
|
ConnectedOpcodes[OP_BlockedBuffs] = &Client::Handle_OP_BlockedBuffs;
|
||||||
ConnectedOpcodes[OP_BoardBoat] = &Client::Handle_OP_BoardBoat;
|
ConnectedOpcodes[OP_BoardBoat] = &Client::Handle_OP_BoardBoat;
|
||||||
|
ConnectedOpcodes[OP_BookButton] = &Client::Handle_OP_BookButton;
|
||||||
ConnectedOpcodes[OP_Buff] = &Client::Handle_OP_Buff;
|
ConnectedOpcodes[OP_Buff] = &Client::Handle_OP_Buff;
|
||||||
ConnectedOpcodes[OP_BuffRemoveRequest] = &Client::Handle_OP_BuffRemoveRequest;
|
ConnectedOpcodes[OP_BuffRemoveRequest] = &Client::Handle_OP_BuffRemoveRequest;
|
||||||
ConnectedOpcodes[OP_Bug] = &Client::Handle_OP_Bug;
|
ConnectedOpcodes[OP_Bug] = &Client::Handle_OP_Bug;
|
||||||
@ -4130,6 +4131,28 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::Handle_OP_BookButton(const EQApplicationPacket* app)
|
||||||
|
{
|
||||||
|
if (app->size != sizeof(BookButton_Struct))
|
||||||
|
{
|
||||||
|
LogError("Size mismatch in OP_BookButton. expected [{}] got [{}]", sizeof(BookButton_Struct), app->size);
|
||||||
|
DumpPacket(app);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BookButton_Struct* book = reinterpret_cast<BookButton_Struct*>(app->pBuffer);
|
||||||
|
|
||||||
|
const EQ::ItemInstance* const inst = GetInv().GetItem(book->invslot);
|
||||||
|
if (inst && inst->GetItem()->Book)
|
||||||
|
{
|
||||||
|
// todo: if scribe book learn recipes and delete book from inventory
|
||||||
|
// todo: if cast book use its spell on target and delete book from inventory (unless reusable?)
|
||||||
|
}
|
||||||
|
|
||||||
|
EQApplicationPacket outapp(OP_FinishWindow, 0);
|
||||||
|
QueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_Buff(const EQApplicationPacket *app)
|
void Client::Handle_OP_Buff(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -56,6 +56,7 @@
|
|||||||
void Handle_OP_Bind_Wound(const EQApplicationPacket *app);
|
void Handle_OP_Bind_Wound(const EQApplicationPacket *app);
|
||||||
void Handle_OP_BlockedBuffs(const EQApplicationPacket *app);
|
void Handle_OP_BlockedBuffs(const EQApplicationPacket *app);
|
||||||
void Handle_OP_BoardBoat(const EQApplicationPacket *app);
|
void Handle_OP_BoardBoat(const EQApplicationPacket *app);
|
||||||
|
void Handle_OP_BookButton(const EQApplicationPacket *app);
|
||||||
void Handle_OP_Buff(const EQApplicationPacket *app);
|
void Handle_OP_Buff(const EQApplicationPacket *app);
|
||||||
void Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app);
|
void Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app);
|
||||||
void Handle_OP_Bug(const EQApplicationPacket *app);
|
void Handle_OP_Bug(const EQApplicationPacket *app);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user