Enforce 4 sec Sneak Attack rule fixes #569

Spells flagged with SNEAK_ATTACK requires you to be hidden for
about 4 seconds before you can cast them
This commit is contained in:
Michael Cook (mackal) 2016-10-25 23:19:20 -04:00
parent 60406ebcc1
commit b9fefc95e8
6 changed files with 26 additions and 17 deletions

View File

@ -1181,6 +1181,11 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
if (!IsCastWhileInvis(rank->spell))
CommonBreakInvisible();
if (spells[rank->spell].sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) {
Message_StringID(13, SNEAK_RESTRICT);
return;
}
// Bards can cast instant cast AAs while they are casting another song
if(spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
if(!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQEmu::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {

View File

@ -7911,6 +7911,7 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app)
}
else
hidden = true;
tmHidden = Timer::GetCurrentTime();
}
if (GetClass() == ROGUE){
auto outapp = new EQApplicationPacket(OP_SimpleMessage, sizeof(SimpleMessage_Struct));

View File

@ -630,17 +630,6 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
if(r == MAX_PP_DISCIPLINES)
return(false); //not found.
//Check the disc timer
pTimerType DiscTimer = pTimerDisciplineReuseStart + spells[spell_id].EndurTimerIndex;
if(!p_timers.Expired(&database, DiscTimer)) {
/*char val1[20]={0};*/ //unused
/*char val2[20]={0};*/ //unused
uint32 remain = p_timers.GetRemainingTime(DiscTimer);
//Message_StringID(0, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2));
Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60));
return(false);
}
//make sure we can use it..
if(!IsValidSpell(spell_id)) {
Message(13, "This tome contains invalid knowledge.");
@ -667,6 +656,23 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
return(false);
}
// sneak attack discs require you to be hidden for 4 seconds before use
if (spell.sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) {
Message_StringID(13, SNEAK_RESTRICT);
return false;
}
//Check the disc timer
pTimerType DiscTimer = pTimerDisciplineReuseStart + spell.EndurTimerIndex;
if(!p_timers.Expired(&database, DiscTimer)) {
/*char val1[20]={0};*/ //unused
/*char val2[20]={0};*/ //unused
uint32 remain = p_timers.GetRemainingTime(DiscTimer);
//Message_StringID(0, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2));
Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60));
return(false);
}
if(spell.recast_time > 0)
{
uint32 reduced_recast = spell.recast_time / 1000;

View File

@ -108,7 +108,8 @@ Mob::Mob(const char* in_name,
m_TargetLocation(glm::vec3()),
m_TargetV(glm::vec3()),
flee_timer(FLEE_CHECK_TIMER),
m_Position(position)
m_Position(position),
tmHidden(-1)
{
targeted = 0;
tar_ndx=0;

View File

@ -762,6 +762,7 @@ public:
inline const bodyType GetOrigBodyType() const { return orig_bodytype; }
void SetBodyType(bodyType new_body, bool overwrite_orig);
uint32 tmHidden; // timestamp of hide, only valid while hidden == true
uint8 invisible, see_invis;
bool invulnerable, invisible_undead, invisible_animals, sneaking, hidden, improved_hidden;
bool see_invis_undead, see_hide, see_improved_hide;

View File

@ -3392,11 +3392,6 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
if(spelltar->IsClient() && spelltar->CastToClient()->IsHoveringForRespawn())
return false;
if (spells[spell_id].sneak && IsClient() && !CastToClient()->sneaking){
Message_StringID(13, SNEAK_RESTRICT);
return false;//Fail Safe, this can cause a zone crash certain situations if you try to apply sneak effects when not sneaking.
}
if(IsDetrimentalSpell(spell_id) && !IsAttackAllowed(spelltar) && !IsResurrectionEffects(spell_id)) {
if(!IsClient() || !CastToClient()->GetGM()) {
Message_StringID(MT_SpellFailure, SPELL_NO_HOLD);