mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 01:01:30 +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 LaurionToServerConvertLinks(std::string& message_out, const std::string& message_in);
|
||||
|
||||
//SpawnAppearance
|
||||
// SpawnAppearance
|
||||
static inline uint32 ServerToLaurionSpawnAppearanceType(uint32 server_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 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)
|
||||
{
|
||||
@ -1163,7 +1172,8 @@ namespace Laurion
|
||||
u8 status;
|
||||
*/
|
||||
|
||||
out.WriteUInt64(0);
|
||||
out.WriteInt32(emu->guild_id);
|
||||
out.WriteUInt32(0);
|
||||
out.WriteUInt8(0);
|
||||
out.WriteUInt8(5);
|
||||
|
||||
@ -1262,7 +1272,7 @@ namespace Laurion
|
||||
out.WriteUInt32(emu->careerEbonCrystals);
|
||||
|
||||
/*
|
||||
u32 momentum_balance;
|
||||
u32 momentum_balance;
|
||||
u32 loyalty_reward_balance;
|
||||
u32 parcel_status;
|
||||
*/
|
||||
@ -2926,6 +2936,104 @@ namespace Laurion
|
||||
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(OP_EnterWorld)
|
||||
@ -3124,6 +3232,23 @@ namespace Laurion
|
||||
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
|
||||
int ExtractIDFile(const std::string& input) {
|
||||
std::string number;
|
||||
@ -4481,7 +4606,7 @@ namespace Laurion
|
||||
return ServerSlot;
|
||||
}
|
||||
|
||||
item::ItemPacketType ServerToLaurionItemPacketType(ItemPacketType server_type) {
|
||||
static item::ItemPacketType ServerToLaurionItemPacketType(ItemPacketType server_type) {
|
||||
switch (server_type) {
|
||||
case ItemPacketType::ItemPacketMerchant:
|
||||
return item::ItemPacketType::ItemPacketMerchant;
|
||||
@ -4507,4 +4632,108 @@ namespace Laurion
|
||||
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*/
|
||||
|
||||
@ -341,10 +341,10 @@ namespace Laurion
|
||||
const int SPELL_GEM_RECAST_TIMER = 15;
|
||||
|
||||
const int LONG_BUFFS = 42;
|
||||
const int SHORT_BUFFS = 20;
|
||||
const int SHORT_BUFFS = 30;
|
||||
const int DISC_BUFFS = 1;
|
||||
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 MERC_BUFFS = LONG_BUFFS;
|
||||
|
||||
|
||||
@ -35,6 +35,9 @@ E(OP_ExpUpdate)
|
||||
E(OP_SendAATable)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_BeginCast)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_Buff)
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_EnterWorld)
|
||||
D(OP_ZoneEntry)
|
||||
@ -49,6 +52,7 @@ D(OP_ClickDoor)
|
||||
D(OP_SpawnAppearance)
|
||||
D(OP_MoveItem)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_CastSpell)
|
||||
|
||||
#undef E
|
||||
#undef D
|
||||
|
||||
@ -621,6 +621,65 @@ namespace Laurion {
|
||||
/*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()
|
||||
|
||||
}; //end namespace structs
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user