mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
Implement Linked Spell Reuse Timers
They started linked spells at OoW launch (I think) At least canni was linked then. This is rather user unfriendly, but that's live like. Ex. the spells aren't actually put on cool down so you can attempt to cast them still but you will be interrupted. Titanium is particularly unfriendly with large differences in reuse times
This commit is contained in:
parent
ed5715ccd9
commit
e894e96404
@ -1,5 +1,11 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 08/14/2016 ==
|
||||
mackal: Implement Linked Spell Reuse Timers
|
||||
- For whatever reason this is a bit unfriendly, but that's how it is on live.
|
||||
- Titanium is especially unfriendly with large differences in reuse times (ex higher canni and the first 4)
|
||||
- Unsure when this went live for spells, but canni was at least linked at OoW launch
|
||||
|
||||
== 08/13/2016 ==
|
||||
Kinglykrab: Implemented optional avoidance cap rules.
|
||||
- Serves to eliminate God-like characters on custom servers with high item stats
|
||||
|
||||
@ -289,6 +289,7 @@ N(OP_LFGuild),
|
||||
N(OP_LFPCommand),
|
||||
N(OP_LFPGetMatchesRequest),
|
||||
N(OP_LFPGetMatchesResponse),
|
||||
N(OP_LinkedReuse),
|
||||
N(OP_LoadSpellSet),
|
||||
N(OP_LocInfo),
|
||||
N(OP_LockoutTimerInfo),
|
||||
|
||||
@ -390,6 +390,18 @@ uint32 scribing; // 1 if memorizing a spell, set to 0 if scribing to book, 2 if
|
||||
uint32 reduction; // lower reuse
|
||||
};
|
||||
|
||||
/*
|
||||
** Linked Spell Reuse Timer
|
||||
** Length: 12
|
||||
** Comes before the OP_Memorize
|
||||
** Live (maybe TDS steam) has an extra DWORD after timer_id
|
||||
*/
|
||||
struct LinkedSpellReuseTimer_Struct {
|
||||
uint32 timer_id; // Timer ID of the spell
|
||||
uint32 end_time; // timestamp of when it will be ready
|
||||
uint32 start_time; // timestamp of when it started
|
||||
};
|
||||
|
||||
/*
|
||||
** Make Charmed Pet
|
||||
** Length: 12 Bytes
|
||||
|
||||
@ -37,10 +37,12 @@ enum { //values for pTimerType
|
||||
pTimerSenseTraps = 12,
|
||||
pTimerDisarmTraps = 13,
|
||||
pTimerDisciplineReuseStart = 14,
|
||||
pTimerDisciplineReuseEnd = 24,
|
||||
pTimerDisciplineReuseEnd = 24, // client actually has 20 ids, but still no disc go that high even on live
|
||||
pTimerCombatAbility = 25,
|
||||
pTimerCombatAbility2 = 26, // RoF2+ Tiger Claw is unlinked from other monk skills, generic in case other classes ever need it
|
||||
pTimerBeggingPickPocket = 27,
|
||||
pTimerLinkedSpellReuseStart = 28,
|
||||
pTimerLinkedSpellReuseEnd = 48,
|
||||
|
||||
pTimerLayHands = 87, //these IDs are used by client too
|
||||
pTimerHarmTouch = 89, //so dont change them
|
||||
|
||||
@ -172,6 +172,7 @@ OP_BeginCast=0x17ff
|
||||
OP_ColoredText=0x41cb
|
||||
OP_ConsentResponse=0x183d
|
||||
OP_MemorizeSpell=0x2fac
|
||||
OP_LinkedReuse=0x3ac0
|
||||
OP_SwapSpell=0x4736
|
||||
OP_CastSpell=0x1cb5
|
||||
OP_Consider=0x4d8d
|
||||
|
||||
@ -171,6 +171,7 @@ OP_BeginCast=0x318f
|
||||
OP_ColoredText=0x43af
|
||||
OP_ConsentResponse=0x384a
|
||||
OP_MemorizeSpell=0x217c
|
||||
OP_LinkedReuse=0x1619
|
||||
OP_SwapSpell=0x0efa
|
||||
OP_CastSpell=0x1287
|
||||
OP_Consider=0x742b
|
||||
|
||||
@ -171,6 +171,7 @@ OP_BeginCast=0x0d5a # C
|
||||
OP_ColoredText=0x569a # C
|
||||
OP_ConsentResponse=0x6e47 # C
|
||||
OP_MemorizeSpell=0x8543 # C
|
||||
OP_LinkedReuse=0x6ef9
|
||||
OP_SwapSpell=0x3fd2 # C
|
||||
OP_CastSpell=0x3582 # C
|
||||
OP_Consider=0x6024 # C
|
||||
|
||||
@ -169,6 +169,7 @@ OP_BeginCast=0x5A50 #SEQ 12/04/08
|
||||
OP_ColoredText=0x3BC7 #SEQ 12/04/08
|
||||
OP_ConsentResponse=0x4D30 #SEQ 12/04/08
|
||||
OP_MemorizeSpell=0x6A93 #SEQ 12/04/08
|
||||
OP_LinkedReuse=0x2c26
|
||||
OP_SwapSpell=0x1418 #SEQ 12/04/08
|
||||
OP_CastSpell=0x7F5D #SEQ 12/04/08
|
||||
OP_Consider=0x32E1 #SEQ 12/04/08
|
||||
|
||||
@ -170,6 +170,7 @@ OP_Save=0x736b # ShowEQ 10/27/05
|
||||
OP_Camp=0x78c1 # ShowEQ 10/27/05
|
||||
OP_EndLootRequest=0x2316 # ShowEQ 10/27/05
|
||||
OP_MemorizeSpell=0x308e # ShowEQ 10/27/05
|
||||
OP_LinkedReuse=0x6a00
|
||||
OP_SwapSpell=0x2126 # ShowEQ 10/27/05
|
||||
OP_CastSpell=0x304b # ShowEQ 10/27/05
|
||||
OP_DeleteSpell=0x4f37
|
||||
|
||||
@ -173,6 +173,7 @@ OP_BeginCast=0x0d5a # C
|
||||
OP_ColoredText=0x71bf # C
|
||||
OP_ConsentResponse=0x0e87 # C
|
||||
OP_MemorizeSpell=0x3887 # C
|
||||
OP_LinkedReuse=0x1b26
|
||||
OP_SwapSpell=0x5805 # C
|
||||
OP_CastSpell=0x50c2 # C
|
||||
OP_Consider=0x3c2d # C
|
||||
|
||||
@ -894,6 +894,9 @@ public:
|
||||
void SendDisciplineTimer(uint32 timer_id, uint32 duration);
|
||||
bool UseDiscipline(uint32 spell_id, uint32 target);
|
||||
|
||||
void SetLinkedSpellReuseTimer(uint32 timer_id, uint32 duration);
|
||||
bool IsLinkedSpellReuseTimerReady(uint32 timer_id);
|
||||
|
||||
bool CheckTitle(int titleset);
|
||||
void EnableTitle(int titleset);
|
||||
void RemoveTitle(int titleset);
|
||||
|
||||
@ -552,6 +552,10 @@ bool Mob::DoCastingChecks()
|
||||
}
|
||||
}
|
||||
|
||||
if (IsClient() && spells[spell_id].EndurTimerIndex > 0 && casting_spell_slot < CastingSlot::MaxGems)
|
||||
if (!CastToClient()->IsLinkedSpellReuseTimerReady(spells[spell_id].EndurTimerIndex))
|
||||
return false;
|
||||
|
||||
casting_spell_checks = true;
|
||||
return true;
|
||||
}
|
||||
@ -1308,8 +1312,11 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
||||
{
|
||||
if(IsClient())
|
||||
{
|
||||
this->CastToClient()->CheckSongSkillIncrease(spell_id);
|
||||
this->CastToClient()->MemorizeSpell(static_cast<uint32>(slot), spell_id, memSpellSpellbar);
|
||||
Client *c = CastToClient();
|
||||
c->CheckSongSkillIncrease(spell_id);
|
||||
if (spells[spell_id].EndurTimerIndex > 0 && slot < CastingSlot::MaxGems)
|
||||
c->SetLinkedSpellReuseTimer(spells[spell_id].EndurTimerIndex, spells[spell_id].recast_time / 1000);
|
||||
c->MemorizeSpell(static_cast<uint32>(slot), spell_id, memSpellSpellbar);
|
||||
}
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Bard song %d should be started", spell_id);
|
||||
}
|
||||
@ -1321,6 +1328,8 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
||||
SendSpellBarEnable(spell_id);
|
||||
|
||||
// this causes the delayed refresh of the spell bar gems
|
||||
if (spells[spell_id].EndurTimerIndex > 0 && slot < CastingSlot::MaxGems)
|
||||
c->SetLinkedSpellReuseTimer(spells[spell_id].EndurTimerIndex, spells[spell_id].recast_time / 1000);
|
||||
c->MemorizeSpell(static_cast<uint32>(slot), spell_id, memSpellSpellbar);
|
||||
|
||||
// this tells the client that casting may happen again
|
||||
@ -5680,3 +5689,25 @@ void Mob::ConeDirectional(uint16 spell_id, int16 resist_adjust)
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
// duration in seconds
|
||||
void Client::SetLinkedSpellReuseTimer(uint32 timer_id, uint32 duration)
|
||||
{
|
||||
if (timer_id > 19)
|
||||
return;
|
||||
GetPTimers().Start(pTimerLinkedSpellReuseStart + timer_id, duration);
|
||||
auto outapp = new EQApplicationPacket(OP_LinkedReuse, sizeof(LinkedSpellReuseTimer_Struct));
|
||||
auto lr = (LinkedSpellReuseTimer_Struct *)outapp->pBuffer;
|
||||
lr->timer_id = timer_id;
|
||||
lr->start_time = Timer::GetCurrentTime() / 1000;
|
||||
lr->end_time = lr->start_time + duration;
|
||||
FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
bool Client::IsLinkedSpellReuseTimerReady(uint32 timer_id)
|
||||
{
|
||||
if (timer_id > 19)
|
||||
return true;
|
||||
return GetPTimers().Expired(&database, pTimerLinkedSpellReuseStart + timer_id);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user