diff --git a/changelog.txt b/changelog.txt index fb47deba4..03aa3bc32 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,7 +1,10 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- + == 11/09/2014 == -Kayen: Implemented support for spell target type (45) 'Target Rings' on Underfoot (does work earlier expansions). Thanks to Lecht for figuring out the op_code side. +Kayen: Implemented support for spell target type (45) 'Target Rings' on Underfoot (does work earlier expansions) +Thanks to Lecht for figuring out the op_code side. +Implement new Live-like faction adjustment message using rule Client:UseLiveFactionMessage. JJ: Implement new Live-like faction adjustment message using rule Client:UseLiveFactionMessage. Optional SQL: utils/sql/git/optional/2014_11_09_LiveFactionMessages.sql diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 20bd7603e..0630ce293 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -478,11 +478,11 @@ struct CastSpell_Struct uint32 spell_id; uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast uint32 target_id; - uint32 cs_unknown1; - uint32 cs_unknown2; - float y_pos; - float x_pos; - float z_pos; + uint32 cs_unknown1; + uint32 cs_unknown2; + float y_pos; + float x_pos; + float z_pos; }; struct SpellEffect_Struct diff --git a/common/patches/underfoot_structs.h b/common/patches/underfoot_structs.h index 6620f6a0a..ebad98678 100644 --- a/common/patches/underfoot_structs.h +++ b/common/patches/underfoot_structs.h @@ -519,11 +519,11 @@ struct CastSpell_Struct uint32 spell_id; uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast uint32 target_id; - uint32 cs_unknown1; - uint32 cs_unknown2; - float y_pos; - float x_pos; - float z_pos; + uint32 cs_unknown1; + uint32 cs_unknown2; + float y_pos; + float x_pos; + float z_pos; }; /* diff --git a/common/spdat.h b/common/spdat.h index 4668cabde..feaddaf84 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -132,7 +132,7 @@ typedef enum { /* 42 */ ST_Directional = 0x2a, //ae around this target between two angles /* 43 */ ST_GroupClientAndPet = 0x2b, /* 44 */ //ST_Beam = 0x2c, //like directional but facing in front of you always -/* 45 */ ST_Ring = 0x2d, +/* 45 */ ST_Ring = 0x2d, /* 46 */ ST_TargetsTarget = 0x2e, // uses the target of your target /* 47 */ ST_PetMaster = 0x2f, // uses the master as target } SpellTargetType; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 73a5c79c9..7bc91f0f5 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4004,6 +4004,10 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) CastSpell_Struct* castspell = (CastSpell_Struct*)app->pBuffer; + targetring_x = castspell->x_pos; + targetring_y = castspell->y_pos; + targetring_z = castspell->z_pos; + #ifdef _EQDEBUG LogFile->write(EQEMuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[0], castspell->cs_unknown[0]); LogFile->write(EQEMuLog::Debug, "cs_unknown2: %u %i", (uint8)castspell->cs_unknown[1], castspell->cs_unknown[1]); @@ -4041,7 +4045,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) CastSpell(spell_to_cast, castspell->target_id, castspell->slot); } /* Spell Slot or Potion Belt Slot */ - else if ((castspell->slot == USE_ITEM_SPELL_SLOT) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // ITEM or POTION cast + else if ((castspell->slot == USE_ITEM_SPELL_SLOT) || (castspell->slot == POTION_BELT_SPELL_SLOT)|| (castspell->slot == TARGET_RING_SPELL_SLOT)) // ITEM or POTION cast { //discipline, using the item spell slot if (castspell->inventoryslot == INVALID_INDEX) { @@ -4051,7 +4055,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) } return; } - else if (m_inv.SupportsClickCasting(castspell->inventoryslot) || (castspell->slot == POTION_BELT_SPELL_SLOT)) // sanity check + else if (m_inv.SupportsClickCasting(castspell->inventoryslot) || (castspell->slot == POTION_BELT_SPELL_SLOT) || (castspell->slot == TARGET_RING_SPELL_SLOT)) // sanity check { // packet field types will be reviewed as packet transistions occur -U const ItemInst* inst = m_inv[castspell->inventoryslot]; //slot values are int16, need to check packet on this field @@ -8646,6 +8650,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) IsFeared() || IsMezzed() || DivineAura() || + (spells[spell_id].targettype == ST_Ring) || (IsSilenced() && !IsDiscipline(spell_id)) || (IsAmnesiad() && IsDiscipline(spell_id)) || (IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()) diff --git a/zone/common.h b/zone/common.h index 8b6464268..fb89dfe77 100644 --- a/zone/common.h +++ b/zone/common.h @@ -19,6 +19,7 @@ #define USE_ITEM_SPELL_SLOT 10 #define POTION_BELT_SPELL_SLOT 11 +#define TARGET_RING_SPELL_SLOT 12 #define DISCIPLINE_SPELL_SLOT 10 #define ABILITY_SPELL_SLOT 9 diff --git a/zone/effects.cpp b/zone/effects.cpp index 4aa972480..02060c10b 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -764,7 +764,7 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_ continue; if (curmob == caster && !affect_caster) //watch for caster too continue; - + if (spells[spell_id].targettype == ST_Ring) { dist_targ = curmob->DistNoRoot(caster->GetTargetRingX(), caster->GetTargetRingY(), caster->GetTargetRingZ()); } diff --git a/zone/mob.cpp b/zone/mob.cpp index 0c561acc5..d0f973a5a 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -370,7 +370,7 @@ Mob::Mob(const char* in_name, m_targetable = true; targetring_x = 0.0f; - targetring_y = 0.0f; + targetring_y = 0.0f; targetring_z = 0.0f; flymode = FlyMode3; diff --git a/zone/spells.cpp b/zone/spells.cpp index ab3d06510..2e5e16f46 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -254,7 +254,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, } //Added to prevent MQ2 exploitation of equipping normally-unequippable/clickable items with effects and clicking them for benefits. - if(item_slot && IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT))) + if(item_slot && IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT) || (slot == TARGET_RING_SPELL_SLOT))) { ItemInst *itm = CastToClient()->GetInv().GetItem(item_slot); int bitmask = 1; @@ -885,7 +885,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, { bool IsFromItem = false; - if(IsClient() && slot != USE_ITEM_SPELL_SLOT && slot != POTION_BELT_SPELL_SLOT && spells[spell_id].recast_time > 1000) { // 10 is item + if(IsClient() && slot != USE_ITEM_SPELL_SLOT && slot != POTION_BELT_SPELL_SLOT && slot != TARGET_RING_SPELL_SLOT && spells[spell_id].recast_time > 1000) { // 10 is item if(!CastToClient()->GetPTimers().Expired(&database, pTimerSpellStart + spell_id, false)) { //should we issue a message or send them a spell gem packet? Message_StringID(13, SPELL_RECAST); @@ -895,7 +895,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, } } - if(IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT))) + if(IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT) || (slot == TARGET_RING_SPELL_SLOT))) { IsFromItem = true; ItemInst *itm = CastToClient()->GetInv().GetItem(inventory_slot); @@ -1191,7 +1191,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, int16 DeleteChargeFromSlot = -1; - if(IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT)) + if(IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT) || (slot == TARGET_RING_SPELL_SLOT)) && inventory_slot != 0xFFFFFFFF) // 10 is an item { bool fromaug = false; @@ -2194,7 +2194,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 // if this was a spell slot or an ability use up the mana for it // CastSpell already reduced the cost for it if we're a client with focus - if(slot != USE_ITEM_SPELL_SLOT && slot != POTION_BELT_SPELL_SLOT && mana_used > 0) + if(slot != USE_ITEM_SPELL_SLOT && slot != POTION_BELT_SPELL_SLOT && slot != TARGET_RING_SPELL_SLOT && mana_used > 0) { mlog(SPELLS__CASTING, "Spell %d: consuming %d mana", spell_id, mana_used); if (!DoHPToManaCovert(mana_used)) @@ -2229,7 +2229,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 } } - if(IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT))) + if(IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT) || (slot == TARGET_RING_SPELL_SLOT))) { ItemInst *itm = CastToClient()->GetInv().GetItem(inventory_slot); if(itm && itm->GetItem()->RecastDelay > 0){