Implemented spell Target Type (45) 'Target Rings' on Underfoot.

Thanks to Lecht for figuring out op code side of it.
This commit is contained in:
KayenEQ 2014-11-09 22:37:12 -05:00
parent d8a8b8e6dc
commit d656db843a
11 changed files with 62 additions and 6 deletions

View File

@ -1,5 +1,10 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50) 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.
== 11/06/2014 == == 11/06/2014 ==
demonstar55: Tracking default sort will now be correct order demonstar55: Tracking default sort will now be correct order
Trevius: Fixed dynamic merchant list loading. Allows any merchant to be used in any zone. Trevius: Fixed dynamic merchant list loading. Allows any merchant to be used in any zone.

View File

@ -478,7 +478,11 @@ struct CastSpell_Struct
uint32 spell_id; uint32 spell_id;
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
uint32 target_id; uint32 target_id;
uint8 cs_unknown[4]; uint32 cs_unknown1;
uint32 cs_unknown2;
float y_pos;
float x_pos;
float z_pos;
}; };
struct SpellEffect_Struct struct SpellEffect_Struct

View File

@ -2994,6 +2994,11 @@ namespace Underfoot
IN(spell_id); IN(spell_id);
emu->inventoryslot = UnderfootToServerSlot(eq->inventoryslot); emu->inventoryslot = UnderfootToServerSlot(eq->inventoryslot);
IN(target_id); IN(target_id);
IN(cs_unknown1);
IN(cs_unknown2);
IN(y_pos);
IN(x_pos);
IN(z_pos);
FINISH_DIRECT_DECODE(); FINISH_DIRECT_DECODE();
} }

View File

@ -519,7 +519,11 @@ struct CastSpell_Struct
uint32 spell_id; uint32 spell_id;
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
uint32 target_id; uint32 target_id;
uint32 cs_unknown[5]; uint32 cs_unknown1;
uint32 cs_unknown2;
float y_pos;
float x_pos;
float z_pos;
}; };
/* /*

View File

@ -132,7 +132,7 @@ typedef enum {
/* 42 */ ST_Directional = 0x2a, //ae around this target between two angles /* 42 */ ST_Directional = 0x2a, //ae around this target between two angles
/* 43 */ ST_GroupClientAndPet = 0x2b, /* 43 */ ST_GroupClientAndPet = 0x2b,
/* 44 */ //ST_Beam = 0x2c, //like directional but facing in front of you always /* 44 */ //ST_Beam = 0x2c, //like directional but facing in front of you always
/* 45 */ //ST_Ring = 0x2d, // Like a mix of PB ae + rain spell(has ae duration) /* 45 */ ST_Ring = 0x2d,
/* 46 */ ST_TargetsTarget = 0x2e, // uses the target of your target /* 46 */ ST_TargetsTarget = 0x2e, // uses the target of your target
/* 47 */ ST_PetMaster = 0x2f, // uses the master as target /* 47 */ ST_PetMaster = 0x2f, // uses the master as target
} SpellTargetType; } SpellTargetType;

View File

@ -4034,6 +4034,10 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
return; return;
} }
targetring_x = castspell->x_pos;
targetring_y = castspell->y_pos;
targetring_z = castspell->z_pos;
CastSpell(spell_to_cast, castspell->target_id, castspell->slot); CastSpell(spell_to_cast, castspell->target_id, castspell->slot);
} }
/* Spell Slot or Potion Belt Slot */ /* Spell Slot or Potion Belt Slot */

View File

@ -494,6 +494,7 @@ typedef enum {
GroupSpell, // causes effect to caster + target's group GroupSpell, // causes effect to caster + target's group
CAHateList, // causes effect to all people on caster's hate list within some range CAHateList, // causes effect to all people on caster's hate list within some range
DirectionalAE, DirectionalAE,
TargetRing,
CastActUnknown CastActUnknown
} CastAction_type; } CastAction_type;

View File

@ -765,7 +765,13 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
if (curmob == caster && !affect_caster) //watch for caster too if (curmob == caster && !affect_caster) //watch for caster too
continue; continue;
if (spells[spell_id].targettype == ST_Ring){
dist_targ = curmob->DistNoRoot(caster->GetTargetRingX(), caster->GetTargetRingY(),caster->GetTargetRingZ());
}
else if (center){
dist_targ = center->DistNoRoot(*curmob); dist_targ = center->DistNoRoot(*curmob);
}
if (dist_targ > dist2) //make sure they are in range if (dist_targ > dist2) //make sure they are in range
continue; continue;
if (dist_targ < min_range2) //make sure they are in range if (dist_targ < min_range2) //make sure they are in range
@ -787,7 +793,9 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
if (bad) { if (bad) {
if (!caster->IsAttackAllowed(curmob, true)) if (!caster->IsAttackAllowed(curmob, true))
continue; continue;
if (!center->CheckLosFN(curmob)) if (center && !center->CheckLosFN(curmob))
continue;
if (!center && !caster->CheckLosFN(caster->GetTargetRingX(), caster->GetTargetRingY(),caster->GetTargetRingZ(), curmob->GetSize()))
continue; continue;
} else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies... } else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// This does not check faction for beneficial AE buffs..only agro and attackable. // This does not check faction for beneficial AE buffs..only agro and attackable.

View File

@ -369,6 +369,10 @@ Mob::Mob(const char* in_name,
nimbus_effect3 = 0; nimbus_effect3 = 0;
m_targetable = true; m_targetable = true;
targetring_x = 0.0f;
targetring_y = 0.0f;
targetring_z = 0.0f;
flymode = FlyMode3; flymode = FlyMode3;
// Pathing // Pathing
PathingLOSState = UnknownLOS; PathingLOSState = UnknownLOS;

View File

@ -287,6 +287,9 @@ public:
inline virtual uint32 GetNimbusEffect2() const { return nimbus_effect2; } inline virtual uint32 GetNimbusEffect2() const { return nimbus_effect2; }
inline virtual uint32 GetNimbusEffect3() const { return nimbus_effect3; } inline virtual uint32 GetNimbusEffect3() const { return nimbus_effect3; }
void RemoveNimbusEffect(int effectid); void RemoveNimbusEffect(int effectid);
inline float GetTargetRingX() const { return targetring_x; }
inline float GetTargetRingY() const { return targetring_y; }
inline float GetTargetRingZ() const { return targetring_z; }
//Basic Stats/Inventory //Basic Stats/Inventory
virtual void SetLevel(uint8 in_level, bool command = false) { level = in_level; } virtual void SetLevel(uint8 in_level, bool command = false) { level = in_level; }
@ -1231,6 +1234,10 @@ protected:
float tar_vz; float tar_vz;
float test_vector; float test_vector;
float targetring_x;
float targetring_y;
float targetring_z;
uint32 m_spellHitsLeft[38]; // Used to track which spells will have their numhits incremented when spell finishes casting, 38 Buffslots uint32 m_spellHitsLeft[38]; // Used to track which spells will have their numhits incremented when spell finishes casting, 38 Buffslots
int flymode; int flymode;
bool m_targetable; bool m_targetable;

View File

@ -368,6 +368,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
if((IsGroupSpell(spell_id) || if((IsGroupSpell(spell_id) ||
spell.targettype == ST_Self || spell.targettype == ST_Self ||
spell.targettype == ST_AECaster || spell.targettype == ST_AECaster ||
spell.targettype == ST_Ring ||
spell.targettype == ST_TargetOptional) && target_id == 0) spell.targettype == ST_TargetOptional) && target_id == 0)
{ {
mlog(SPELLS__CASTING, "Spell %d auto-targeted the caster. Group? %d, target type %d", spell_id, IsGroupSpell(spell_id), spell.targettype); mlog(SPELLS__CASTING, "Spell %d auto-targeted the caster. Group? %d, target type %d", spell_id, IsGroupSpell(spell_id), spell.targettype);
@ -1802,6 +1803,14 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
break; break;
} }
case ST_Ring:
{
CastAction = TargetRing;
spell_target = nullptr;
ae_center = nullptr;
break;
}
default: default:
{ {
mlog(SPELLS__CASTING_ERR, "I dont know Target Type: %d Spell: (%d) %s", spells[spell_id].targettype, spell_id, spells[spell_id].name); mlog(SPELLS__CASTING_ERR, "I dont know Target Type: %d Spell: (%d) %s", spells[spell_id].targettype, spell_id, spells[spell_id].name);
@ -2165,6 +2174,11 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
} }
break; break;
} }
case TargetRing:{
entity_list.AESpell(this, nullptr, spell_id, false, resist_adjust);
break;
}
} }
DoAnim(spells[spell_id].CastingAnim, 0, true, IsClient() ? FilterPCSpells : FilterNPCSpells); DoAnim(spells[spell_id].CastingAnim, 0, true, IsClient() ? FilterPCSpells : FilterNPCSpells);