mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-28 03:12:28 +00:00
WIP spell casting for laurion
This commit is contained in:
parent
d3ac751dd1
commit
7083a74b31
@ -55,7 +55,7 @@ namespace Laurion
|
|||||||
static inline void ServerToLaurionConvertLinks(std::string& message_out, const std::string& message_in);
|
static inline void ServerToLaurionConvertLinks(std::string& message_out, const std::string& message_in);
|
||||||
static inline void LaurionToServerConvertLinks(std::string& message_out, const std::string& message_in);
|
static inline void LaurionToServerConvertLinks(std::string& message_out, const std::string& message_in);
|
||||||
|
|
||||||
//SpawnAppearance
|
// SpawnAppearance
|
||||||
static inline uint32 ServerToLaurionSpawnAppearanceType(uint32 server_type);
|
static inline uint32 ServerToLaurionSpawnAppearanceType(uint32 server_type);
|
||||||
static inline uint32 LaurionToServerSpawnAppearanceType(uint32 laurion_type);
|
static inline uint32 LaurionToServerSpawnAppearanceType(uint32 laurion_type);
|
||||||
|
|
||||||
@ -71,7 +71,16 @@ namespace Laurion
|
|||||||
static inline uint32 LaurionToServerCorpseMainSlot(uint32 laurion_corpse_slot);
|
static inline uint32 LaurionToServerCorpseMainSlot(uint32 laurion_corpse_slot);
|
||||||
static inline uint32 LaurionToServerTypelessSlot(structs::TypelessInventorySlot_Struct laurion_slot, int16 laurion_type);
|
static inline uint32 LaurionToServerTypelessSlot(structs::TypelessInventorySlot_Struct laurion_slot, int16 laurion_type);
|
||||||
|
|
||||||
item::ItemPacketType ServerToLaurionItemPacketType(ItemPacketType laurion_type);
|
// Item packet types
|
||||||
|
static item::ItemPacketType ServerToLaurionItemPacketType(ItemPacketType laurion_type);
|
||||||
|
|
||||||
|
// casting slots
|
||||||
|
static inline spells::CastingSlot ServerToLaurionCastingSlot(EQ::spells::CastingSlot slot);
|
||||||
|
static inline EQ::spells::CastingSlot LaurionToServerCastingSlot(spells::CastingSlot slot);
|
||||||
|
|
||||||
|
// buff slots
|
||||||
|
static inline int ServerToLaurionBuffSlot(int index);
|
||||||
|
static inline int LaurionToServerBuffSlot(int index);
|
||||||
|
|
||||||
void Register(EQStreamIdentifier& into)
|
void Register(EQStreamIdentifier& into)
|
||||||
{
|
{
|
||||||
@ -1163,7 +1172,8 @@ namespace Laurion
|
|||||||
u8 status;
|
u8 status;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
out.WriteUInt64(0);
|
out.WriteInt32(emu->guild_id);
|
||||||
|
out.WriteUInt32(0);
|
||||||
out.WriteUInt8(0);
|
out.WriteUInt8(0);
|
||||||
out.WriteUInt8(5);
|
out.WriteUInt8(5);
|
||||||
|
|
||||||
@ -1262,7 +1272,7 @@ namespace Laurion
|
|||||||
out.WriteUInt32(emu->careerEbonCrystals);
|
out.WriteUInt32(emu->careerEbonCrystals);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
u32 momentum_balance;
|
u32 momentum_balance;
|
||||||
u32 loyalty_reward_balance;
|
u32 loyalty_reward_balance;
|
||||||
u32 parcel_status;
|
u32 parcel_status;
|
||||||
*/
|
*/
|
||||||
@ -2926,6 +2936,104 @@ namespace Laurion
|
|||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_BeginCast)
|
||||||
|
{
|
||||||
|
SETUP_DIRECT_ENCODE(BeginCast_Struct, structs::BeginCast_Struct);
|
||||||
|
|
||||||
|
OUT(spell_id);
|
||||||
|
OUT(caster_id);
|
||||||
|
OUT(cast_time);
|
||||||
|
eq->unknown0e = 1; //not sure what this is; but its usually 1 on live
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_BuffCreate)
|
||||||
|
{
|
||||||
|
SETUP_VAR_ENCODE(BuffIcon_Struct);
|
||||||
|
|
||||||
|
//Laurion has one extra 0x00 byte before the end byte
|
||||||
|
uint32 sz = 13 + (17 * emu->count) + emu->name_lengths; // 17 includes nullterm
|
||||||
|
__packet->size = sz;
|
||||||
|
__packet->pBuffer = new unsigned char[sz];
|
||||||
|
memset(__packet->pBuffer, 0, sz);
|
||||||
|
|
||||||
|
__packet->WriteUInt32(emu->entity_id);
|
||||||
|
__packet->WriteUInt32(emu->tic_timer);
|
||||||
|
__packet->WriteUInt8(emu->all_buffs); // 1 indicates all buffs on the player (0 to add or remove a single buff)
|
||||||
|
__packet->WriteUInt16(emu->count);
|
||||||
|
|
||||||
|
for (int i = 0; i < emu->count; ++i)
|
||||||
|
{
|
||||||
|
__packet->WriteUInt32(emu->type == 0 ? ServerToLaurionBuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot);
|
||||||
|
__packet->WriteUInt32(emu->entries[i].spell_id);
|
||||||
|
__packet->WriteUInt32(emu->entries[i].tics_remaining);
|
||||||
|
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
|
||||||
|
__packet->WriteString(emu->entries[i].caster);
|
||||||
|
}
|
||||||
|
__packet->WriteUInt8(0); // Unknown1
|
||||||
|
__packet->WriteUInt8(emu->type); // Unknown2
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ENCODE(OP_Buff)
|
||||||
|
{
|
||||||
|
ENCODE_LENGTH_EXACT(SpellBuffPacket_Struct);
|
||||||
|
SETUP_DIRECT_ENCODE(SpellBuffPacket_Struct, structs::EQAffectPacket_Struct);
|
||||||
|
|
||||||
|
eq->entity_id = emu->entityid;
|
||||||
|
eq->unknown004 = 0;
|
||||||
|
|
||||||
|
//fill in affect info
|
||||||
|
eq->affect.caster_id.Id = emu->buff.player_id;
|
||||||
|
eq->affect.flags = 0;
|
||||||
|
eq->affect.spell_id = emu->buff.spellid;
|
||||||
|
eq->affect.duration = emu->buff.duration;
|
||||||
|
eq->affect.initial_duration = emu->buff.duration;
|
||||||
|
eq->affect.hit_count = emu->buff.num_hits;
|
||||||
|
eq->affect.viral_timer = 0;
|
||||||
|
eq->affect.modifier = emu->buff.bard_modifier == 10 ? 1.0f : emu->buff.bard_modifier / 10.0f;
|
||||||
|
eq->affect.y = emu->buff.y;
|
||||||
|
eq->affect.x = emu->buff.x;
|
||||||
|
eq->affect.z = emu->buff.z;
|
||||||
|
eq->affect.level = emu->buff.level;
|
||||||
|
|
||||||
|
eq->slot_id = ServerToLaurionBuffSlot(emu->slotid);
|
||||||
|
if (emu->bufffade == 1)
|
||||||
|
{
|
||||||
|
eq->buff_fade = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eq->buff_fade = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
EQApplicationPacket* outapp = nullptr;
|
||||||
|
if (emu->bufffade == 1)
|
||||||
|
{
|
||||||
|
// Bit of a hack. OP_Buff appears to add/remove the buff while OP_BuffCreate adds/removes the actual buff icon
|
||||||
|
outapp = new EQApplicationPacket(OP_BuffCreate, 30);
|
||||||
|
outapp->WriteUInt32(emu->entityid);
|
||||||
|
outapp->WriteUInt32(0); // tic timer
|
||||||
|
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
|
||||||
|
outapp->WriteUInt16(1); // 1 buff in this packet
|
||||||
|
outapp->WriteUInt32(ServerToLaurionBuffSlot(emu->slotid));
|
||||||
|
outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove)
|
||||||
|
outapp->WriteUInt32(0); // Duration
|
||||||
|
outapp->WriteUInt32(0); // numhits
|
||||||
|
outapp->WriteUInt8(0); // Caster name
|
||||||
|
outapp->WriteUInt8(0); // Type
|
||||||
|
outapp->WriteUInt8(0); // Type
|
||||||
|
}
|
||||||
|
|
||||||
|
FINISH_ENCODE();
|
||||||
|
|
||||||
|
if (outapp) {
|
||||||
|
dest->FastQueuePacket(&outapp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DECODE methods
|
// DECODE methods
|
||||||
|
|
||||||
DECODE(OP_EnterWorld)
|
DECODE(OP_EnterWorld)
|
||||||
@ -3124,6 +3232,23 @@ namespace Laurion
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_CastSpell)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(CastSpell_Struct, structs::CastSpell_Struct);
|
||||||
|
|
||||||
|
emu->slot = static_cast<uint32>(LaurionToServerCastingSlot(static_cast<spells::CastingSlot>(eq->slot)));
|
||||||
|
|
||||||
|
//We need to figure out the x y z position stuff
|
||||||
|
IN(spell_id);
|
||||||
|
emu->inventoryslot = LaurionToServerSlot(eq->inventory_slot);
|
||||||
|
IN(target_id);
|
||||||
|
//IN(y_pos);
|
||||||
|
//IN(x_pos);
|
||||||
|
//IN(z_pos);
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
//Naive version but should work well enough for now
|
//Naive version but should work well enough for now
|
||||||
int ExtractIDFile(const std::string& input) {
|
int ExtractIDFile(const std::string& input) {
|
||||||
std::string number;
|
std::string number;
|
||||||
@ -4481,7 +4606,7 @@ namespace Laurion
|
|||||||
return ServerSlot;
|
return ServerSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
item::ItemPacketType ServerToLaurionItemPacketType(ItemPacketType server_type) {
|
static item::ItemPacketType ServerToLaurionItemPacketType(ItemPacketType server_type) {
|
||||||
switch (server_type) {
|
switch (server_type) {
|
||||||
case ItemPacketType::ItemPacketMerchant:
|
case ItemPacketType::ItemPacketMerchant:
|
||||||
return item::ItemPacketType::ItemPacketMerchant;
|
return item::ItemPacketType::ItemPacketMerchant;
|
||||||
@ -4507,4 +4632,108 @@ namespace Laurion
|
|||||||
return item::ItemPacketType::ItemPacketInvalid;
|
return item::ItemPacketType::ItemPacketInvalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//This stuff isn't right because they for one removed potion belt
|
||||||
|
//This will probably be enough to get casting working for now though
|
||||||
|
static inline spells::CastingSlot ServerToLaurionCastingSlot(EQ::spells::CastingSlot slot) {
|
||||||
|
switch (slot) {
|
||||||
|
case EQ::spells::CastingSlot::Gem1:
|
||||||
|
return spells::CastingSlot::Gem1;
|
||||||
|
case EQ::spells::CastingSlot::Gem2:
|
||||||
|
return spells::CastingSlot::Gem2;
|
||||||
|
case EQ::spells::CastingSlot::Gem3:
|
||||||
|
return spells::CastingSlot::Gem3;
|
||||||
|
case EQ::spells::CastingSlot::Gem4:
|
||||||
|
return spells::CastingSlot::Gem4;
|
||||||
|
case EQ::spells::CastingSlot::Gem5:
|
||||||
|
return spells::CastingSlot::Gem5;
|
||||||
|
case EQ::spells::CastingSlot::Gem6:
|
||||||
|
return spells::CastingSlot::Gem6;
|
||||||
|
case EQ::spells::CastingSlot::Gem7:
|
||||||
|
return spells::CastingSlot::Gem7;
|
||||||
|
case EQ::spells::CastingSlot::Gem8:
|
||||||
|
return spells::CastingSlot::Gem8;
|
||||||
|
case EQ::spells::CastingSlot::Gem9:
|
||||||
|
return spells::CastingSlot::Gem9;
|
||||||
|
case EQ::spells::CastingSlot::Gem10:
|
||||||
|
return spells::CastingSlot::Gem10;
|
||||||
|
case EQ::spells::CastingSlot::Gem11:
|
||||||
|
return spells::CastingSlot::Gem11;
|
||||||
|
case EQ::spells::CastingSlot::Gem12:
|
||||||
|
return spells::CastingSlot::Gem12;
|
||||||
|
case EQ::spells::CastingSlot::Item:
|
||||||
|
case EQ::spells::CastingSlot::PotionBelt:
|
||||||
|
return spells::CastingSlot::Item;
|
||||||
|
case EQ::spells::CastingSlot::Discipline:
|
||||||
|
return spells::CastingSlot::Discipline;
|
||||||
|
case EQ::spells::CastingSlot::AltAbility:
|
||||||
|
return spells::CastingSlot::AltAbility;
|
||||||
|
default: // we shouldn't have any issues with other slots ... just return something
|
||||||
|
return spells::CastingSlot::Discipline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline EQ::spells::CastingSlot LaurionToServerCastingSlot(spells::CastingSlot slot) {
|
||||||
|
switch (slot) {
|
||||||
|
case spells::CastingSlot::Gem1:
|
||||||
|
return EQ::spells::CastingSlot::Gem1;
|
||||||
|
case spells::CastingSlot::Gem2:
|
||||||
|
return EQ::spells::CastingSlot::Gem2;
|
||||||
|
case spells::CastingSlot::Gem3:
|
||||||
|
return EQ::spells::CastingSlot::Gem3;
|
||||||
|
case spells::CastingSlot::Gem4:
|
||||||
|
return EQ::spells::CastingSlot::Gem4;
|
||||||
|
case spells::CastingSlot::Gem5:
|
||||||
|
return EQ::spells::CastingSlot::Gem5;
|
||||||
|
case spells::CastingSlot::Gem6:
|
||||||
|
return EQ::spells::CastingSlot::Gem6;
|
||||||
|
case spells::CastingSlot::Gem7:
|
||||||
|
return EQ::spells::CastingSlot::Gem7;
|
||||||
|
case spells::CastingSlot::Gem8:
|
||||||
|
return EQ::spells::CastingSlot::Gem8;
|
||||||
|
case spells::CastingSlot::Gem9:
|
||||||
|
return EQ::spells::CastingSlot::Gem9;
|
||||||
|
case spells::CastingSlot::Gem10:
|
||||||
|
return EQ::spells::CastingSlot::Gem10;
|
||||||
|
case spells::CastingSlot::Gem11:
|
||||||
|
return EQ::spells::CastingSlot::Gem11;
|
||||||
|
case spells::CastingSlot::Gem12:
|
||||||
|
return EQ::spells::CastingSlot::Gem12;
|
||||||
|
case spells::CastingSlot::Discipline:
|
||||||
|
return EQ::spells::CastingSlot::Discipline;
|
||||||
|
case spells::CastingSlot::Item:
|
||||||
|
return EQ::spells::CastingSlot::Item;
|
||||||
|
case spells::CastingSlot::AltAbility:
|
||||||
|
return EQ::spells::CastingSlot::AltAbility;
|
||||||
|
default: // we shouldn't have any issues with other slots ... just return something
|
||||||
|
return EQ::spells::CastingSlot::Discipline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Laurion has the same # of long buffs as rof2, but 10 more short buffs
|
||||||
|
static inline int ServerToLaurionBuffSlot(int index)
|
||||||
|
{
|
||||||
|
// we're a disc
|
||||||
|
if (index >= EQ::spells::LONG_BUFFS + EQ::spells::SHORT_BUFFS)
|
||||||
|
return index - EQ::spells::LONG_BUFFS - EQ::spells::SHORT_BUFFS +
|
||||||
|
spells::LONG_BUFFS + spells::SHORT_BUFFS;
|
||||||
|
// we're a song
|
||||||
|
if (index >= EQ::spells::LONG_BUFFS)
|
||||||
|
return index - EQ::spells::LONG_BUFFS + spells::LONG_BUFFS;
|
||||||
|
// we're a normal buff
|
||||||
|
return index; // as long as we guard against bad slots server side, we should be fine
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int LaurionToServerBuffSlot(int index)
|
||||||
|
{
|
||||||
|
// we're a disc
|
||||||
|
if (index >= spells::LONG_BUFFS + spells::SHORT_BUFFS)
|
||||||
|
return index - spells::LONG_BUFFS - spells::SHORT_BUFFS + EQ::spells::LONG_BUFFS +
|
||||||
|
EQ::spells::SHORT_BUFFS;
|
||||||
|
// we're a song
|
||||||
|
if (index >= spells::LONG_BUFFS)
|
||||||
|
return index - spells::LONG_BUFFS + EQ::spells::LONG_BUFFS;
|
||||||
|
// we're a normal buff
|
||||||
|
return index; // as long as we guard against bad slots server side, we should be fine
|
||||||
|
}
|
||||||
} /*Laurion*/
|
} /*Laurion*/
|
||||||
|
|||||||
@ -341,10 +341,10 @@ namespace Laurion
|
|||||||
const int SPELL_GEM_RECAST_TIMER = 15;
|
const int SPELL_GEM_RECAST_TIMER = 15;
|
||||||
|
|
||||||
const int LONG_BUFFS = 42;
|
const int LONG_BUFFS = 42;
|
||||||
const int SHORT_BUFFS = 20;
|
const int SHORT_BUFFS = 30;
|
||||||
const int DISC_BUFFS = 1;
|
const int DISC_BUFFS = 1;
|
||||||
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
|
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
|
||||||
const int NPC_BUFFS = 97;
|
const int NPC_BUFFS = 400;
|
||||||
const int PET_BUFFS = NPC_BUFFS;
|
const int PET_BUFFS = NPC_BUFFS;
|
||||||
const int MERC_BUFFS = LONG_BUFFS;
|
const int MERC_BUFFS = LONG_BUFFS;
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,9 @@ E(OP_ExpUpdate)
|
|||||||
E(OP_SendAATable)
|
E(OP_SendAATable)
|
||||||
E(OP_ItemPacket)
|
E(OP_ItemPacket)
|
||||||
E(OP_ShopRequest)
|
E(OP_ShopRequest)
|
||||||
|
E(OP_BeginCast)
|
||||||
|
E(OP_BuffCreate)
|
||||||
|
E(OP_Buff)
|
||||||
//list of packets we need to decode on the way in:
|
//list of packets we need to decode on the way in:
|
||||||
D(OP_EnterWorld)
|
D(OP_EnterWorld)
|
||||||
D(OP_ZoneEntry)
|
D(OP_ZoneEntry)
|
||||||
@ -49,6 +52,7 @@ D(OP_ClickDoor)
|
|||||||
D(OP_SpawnAppearance)
|
D(OP_SpawnAppearance)
|
||||||
D(OP_MoveItem)
|
D(OP_MoveItem)
|
||||||
D(OP_ShopRequest)
|
D(OP_ShopRequest)
|
||||||
|
D(OP_CastSpell)
|
||||||
|
|
||||||
#undef E
|
#undef E
|
||||||
#undef D
|
#undef D
|
||||||
|
|||||||
@ -621,6 +621,65 @@ namespace Laurion {
|
|||||||
/*032*/
|
/*032*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BeginCast_Struct
|
||||||
|
{
|
||||||
|
/*000*/ uint32 spell_id;
|
||||||
|
/*004*/ uint16 caster_id;
|
||||||
|
/*006*/ uint32 cast_time; // in miliseconds
|
||||||
|
/*010*/ uint32 unknown0a; // I think this is caster effective level but im not sure. live always sends 0
|
||||||
|
/*014*/ uint8 unknown0e; // 0 will short circuit the cast, seen 1 from live usually, maybe related to interrupts or particles or something
|
||||||
|
/*015*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CastSpell_Struct
|
||||||
|
{
|
||||||
|
/*00*/ uint32 slot;
|
||||||
|
/*04*/ uint32 spell_id;
|
||||||
|
/*08*/ InventorySlot_Struct inventory_slot; // slot for clicky item, Seen unknown of 131 = normal cast
|
||||||
|
/*20*/ uint32 spell_crc; // this is pinstSpellManager_x->SpellsCrc[spell_id]
|
||||||
|
/*24*/ uint32 target_id;
|
||||||
|
/*28*/ uint8 unknown2[11];
|
||||||
|
/*39*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EQAffectSlot_Struct {
|
||||||
|
/*00*/ int32 slot;
|
||||||
|
/*04*/ int32 padding;
|
||||||
|
/*08*/ int64 value;
|
||||||
|
/*16*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EQAffect_Struct
|
||||||
|
{
|
||||||
|
/*000*/ EQAffectSlot_Struct slots[6];
|
||||||
|
/*096*/ EqGuid caster_id;
|
||||||
|
/*104*/ uint32 flags;
|
||||||
|
/*108*/ uint32 spell_id;
|
||||||
|
/*112*/ uint32 duration;
|
||||||
|
/*116*/ uint32 initial_duration;
|
||||||
|
/*120*/ uint32 hit_count;
|
||||||
|
/*124*/ uint32 viral_timer;
|
||||||
|
/*128*/ float modifier;
|
||||||
|
/*132*/ float y;
|
||||||
|
/*136*/ float x;
|
||||||
|
/*140*/ float z;
|
||||||
|
/*144*/ uint8 level;
|
||||||
|
/*145*/ uint8 type;
|
||||||
|
/*146*/ uint8 charges; //no idea if these are right; eqlib doesn't seem to know either
|
||||||
|
/*147*/ uint8 activatable;
|
||||||
|
/*148*/ uint32 unknown1; //might be some timer, not sure though
|
||||||
|
/*152*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EQAffectPacket_Struct {
|
||||||
|
/*000*/ uint32 entity_id;
|
||||||
|
/*004*/ int32 unknown004;
|
||||||
|
/*008*/ EQAffect_Struct affect;
|
||||||
|
/*160*/ uint32 slot_id;
|
||||||
|
/*164*/ uint32 buff_fade;
|
||||||
|
/*168*/
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
}; //end namespace structs
|
}; //end namespace structs
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user