Core/Auras: Update AuraState enum and implement missing new ones
This commit is contained in:
@@ -508,9 +508,12 @@ void Unit::Update(uint32 p_time)
|
||||
|
||||
if (IsAlive())
|
||||
{
|
||||
ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, HealthBelowPct(20));
|
||||
ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, HealthBelowPct(35));
|
||||
ModifyAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, HealthAbovePct(75));
|
||||
ModifyAuraState(AURA_STATE_WOUNDED_20_PERCENT, HealthBelowPct(20));
|
||||
ModifyAuraState(AURA_STATE_WOUNDED_25_PERCENT, HealthBelowPct(25));
|
||||
ModifyAuraState(AURA_STATE_WOUNDED_35_PERCENT, HealthBelowPct(35));
|
||||
ModifyAuraState(AURA_STATE_WOUND_HEALTH_20_80, HealthBelowPct(20) || HealthAbovePct(80));
|
||||
ModifyAuraState(AURA_STATE_HEALTHY_75_PERCENT, HealthAbovePct(75));
|
||||
ModifyAuraState(AURA_STATE_WOUND_HEALTH_35_80, HealthBelowPct(35) || HealthAbovePct(80));
|
||||
}
|
||||
|
||||
UpdateSplineMovement(p_time);
|
||||
@@ -5934,7 +5937,7 @@ void Unit::ModifyAuraState(AuraStateType flag, bool apply)
|
||||
for (Unit::AuraApplicationMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
|
||||
{
|
||||
SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo();
|
||||
if (itr->second->GetBase()->GetCasterGUID() == GetGUID() && spellProto->CasterAuraState == uint32(flag) && (spellProto->IsPassive() || flag != AURA_STATE_ENRAGE))
|
||||
if (itr->second->GetBase()->GetCasterGUID() == GetGUID() && spellProto->CasterAuraState == uint32(flag) && (spellProto->IsPassive() || flag != AURA_STATE_ENRAGED))
|
||||
RemoveAura(itr);
|
||||
else
|
||||
++itr;
|
||||
@@ -6812,7 +6815,7 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage
|
||||
|
||||
// Drain Soul - increased damage for targets under 20% HP
|
||||
if (spellProto->Id == 198590)
|
||||
if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))
|
||||
if (HasAuraState(AURA_STATE_WOUNDED_20_PERCENT))
|
||||
DoneTotalMod *= 2;
|
||||
break;
|
||||
}
|
||||
@@ -10616,41 +10619,23 @@ void Unit::ProcSkillsAndReactives(bool isVictim, Unit* procTarget, uint32 typeMa
|
||||
// Update AURA_STATE on dodge
|
||||
if (getClass() != CLASS_ROGUE) // skip Rogue Riposte
|
||||
{
|
||||
ModifyAuraState(AURA_STATE_DEFENSE, true);
|
||||
ModifyAuraState(AURA_STATE_DEFENSIVE, true);
|
||||
StartReactiveTimer(REACTIVE_DEFENSE);
|
||||
}
|
||||
}
|
||||
// if victim and parry attack
|
||||
if (hitMask & PROC_HIT_PARRY)
|
||||
{
|
||||
// For Hunters only Counterattack (skip Mongoose bite)
|
||||
if (getClass() == CLASS_HUNTER)
|
||||
{
|
||||
ModifyAuraState(AURA_STATE_HUNTER_PARRY, true);
|
||||
StartReactiveTimer(REACTIVE_HUNTER_PARRY);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyAuraState(AURA_STATE_DEFENSE, true);
|
||||
StartReactiveTimer(REACTIVE_DEFENSE);
|
||||
}
|
||||
ModifyAuraState(AURA_STATE_DEFENSIVE, true);
|
||||
StartReactiveTimer(REACTIVE_DEFENSE);
|
||||
}
|
||||
// if and victim block attack
|
||||
if (hitMask & PROC_HIT_BLOCK)
|
||||
{
|
||||
ModifyAuraState(AURA_STATE_DEFENSE, true);
|
||||
ModifyAuraState(AURA_STATE_DEFENSIVE, true);
|
||||
StartReactiveTimer(REACTIVE_DEFENSE);
|
||||
}
|
||||
}
|
||||
else // For attacker
|
||||
{
|
||||
// Overpower on victim dodge
|
||||
if ((hitMask & PROC_HIT_DODGE) && GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR)
|
||||
{
|
||||
ToPlayer()->AddComboPoints(1);
|
||||
StartReactiveTimer(REACTIVE_OVERPOWER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10995,12 +10980,10 @@ void Unit::ClearAllReactives()
|
||||
for (uint8 i = 0; i < MAX_REACTIVE; ++i)
|
||||
m_reactiveTimer[i] = 0;
|
||||
|
||||
if (HasAuraState(AURA_STATE_DEFENSE))
|
||||
ModifyAuraState(AURA_STATE_DEFENSE, false);
|
||||
if (getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY))
|
||||
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
|
||||
if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
|
||||
ToPlayer()->ClearComboPoints();
|
||||
if (HasAuraState(AURA_STATE_DEFENSIVE))
|
||||
ModifyAuraState(AURA_STATE_DEFENSIVE, false);
|
||||
if (HasAuraState(AURA_STATE_DEFENSIVE_2))
|
||||
ModifyAuraState(AURA_STATE_DEFENSIVE_2, false);
|
||||
}
|
||||
|
||||
void Unit::UpdateReactives(uint32 p_time)
|
||||
@@ -11019,16 +11002,12 @@ void Unit::UpdateReactives(uint32 p_time)
|
||||
switch (reactive)
|
||||
{
|
||||
case REACTIVE_DEFENSE:
|
||||
if (HasAuraState(AURA_STATE_DEFENSE))
|
||||
ModifyAuraState(AURA_STATE_DEFENSE, false);
|
||||
if (HasAuraState(AURA_STATE_DEFENSIVE))
|
||||
ModifyAuraState(AURA_STATE_DEFENSIVE, false);
|
||||
break;
|
||||
case REACTIVE_HUNTER_PARRY:
|
||||
if (getClass() == CLASS_HUNTER && HasAuraState(AURA_STATE_HUNTER_PARRY))
|
||||
ModifyAuraState(AURA_STATE_HUNTER_PARRY, false);
|
||||
break;
|
||||
case REACTIVE_OVERPOWER:
|
||||
if (getClass() == CLASS_WARRIOR && GetTypeId() == TYPEID_PLAYER)
|
||||
ToPlayer()->ClearComboPoints();
|
||||
case REACTIVE_DEFENSE_2:
|
||||
if (HasAuraState(AURA_STATE_DEFENSIVE_2))
|
||||
ModifyAuraState(AURA_STATE_DEFENSIVE_2, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -893,11 +893,10 @@ struct TC_GAME_API CharmInfo
|
||||
enum ReactiveType
|
||||
{
|
||||
REACTIVE_DEFENSE = 0,
|
||||
REACTIVE_HUNTER_PARRY = 1,
|
||||
REACTIVE_OVERPOWER = 2
|
||||
REACTIVE_DEFENSE_2 = 1
|
||||
};
|
||||
|
||||
#define MAX_REACTIVE 3
|
||||
#define MAX_REACTIVE 2
|
||||
#define SUMMON_SLOT_PET 0
|
||||
#define SUMMON_SLOT_TOTEM 1
|
||||
#define MAX_TOTEM_SLOT 5
|
||||
|
||||
@@ -2254,34 +2254,34 @@ enum AuraStateType
|
||||
{ // (C) used in caster aura state (T) used in target aura state
|
||||
// (c) used in caster aura state-not (t) used in target aura state-not
|
||||
AURA_STATE_NONE = 0, // C |
|
||||
AURA_STATE_DEFENSE = 1, // C |
|
||||
AURA_STATE_HEALTHLESS_20_PERCENT = 2, // CcT |
|
||||
AURA_STATE_BERSERKING = 3, // C T |
|
||||
AURA_STATE_FROZEN = 4, // c t| frozen target
|
||||
AURA_STATE_JUDGEMENT = 5, // C |
|
||||
//AURA_STATE_UNKNOWN6 = 6, // | not used
|
||||
AURA_STATE_HUNTER_PARRY = 7, // C |
|
||||
//AURA_STATE_UNKNOWN7 = 7, // c | creature cheap shot / focused bursts spells
|
||||
//AURA_STATE_UNKNOWN8 = 8, // t| test spells
|
||||
//AURA_STATE_UNKNOWN9 = 9, // |
|
||||
AURA_STATE_WARRIOR_VICTORY_RUSH = 10, // C | warrior victory rush
|
||||
//AURA_STATE_UNKNOWN11 = 11, // C t| 60348 - Maelstrom Ready!, test spells
|
||||
AURA_STATE_DEFENSIVE = 1, // CcTt|
|
||||
AURA_STATE_WOUNDED_20_PERCENT = 2, // CcT |
|
||||
AURA_STATE_UNBALANCED = 3, // CcT | NYI
|
||||
AURA_STATE_FROZEN = 4, // c t|
|
||||
AURA_STATE_MARKED = 5, // C t| NYI
|
||||
AURA_STATE_WOUNDED_25_PERCENT = 6, // T |
|
||||
AURA_STATE_DEFENSIVE_2 = 7, // Cc | NYI
|
||||
AURA_STATE_BANISHED = 8, // c | NYI
|
||||
AURA_STATE_DAZED = 9, // t|
|
||||
AURA_STATE_VICTORIOUS = 10, // C |
|
||||
AURA_STATE_RAMPAGE = 11, // | NYI
|
||||
AURA_STATE_FAERIE_FIRE = 12, // c t|
|
||||
AURA_STATE_HEALTHLESS_35_PERCENT = 13, // C T |
|
||||
AURA_STATE_CONFLAGRATE = 14, // T |
|
||||
AURA_STATE_SWIFTMEND = 15, // T |
|
||||
AURA_STATE_DEADLY_POISON = 16, // T |
|
||||
AURA_STATE_ENRAGE = 17, // C |
|
||||
AURA_STATE_BLEEDING = 18, // T|
|
||||
AURA_STATE_UNKNOWN19 = 19, // |
|
||||
//AURA_STATE_UNKNOWN20 = 20, // c | only (45317 Suicide)
|
||||
//AURA_STATE_UNKNOWN21 = 21, // | not used
|
||||
AURA_STATE_UNKNOWN22 = 22, // C t| varius spells (63884, 50240)
|
||||
AURA_STATE_HEALTH_ABOVE_75_PERCENT = 23 // C |
|
||||
AURA_STATE_WOUNDED_35_PERCENT = 13, // CcT |
|
||||
AURA_STATE_RAID_ENCOUNTER_2 = 14, // cT |
|
||||
AURA_STATE_DRUID_PERIODIC_HEAL = 15, // T |
|
||||
AURA_STATE_ROGUE_POISONED = 16, // |
|
||||
AURA_STATE_ENRAGED = 17, // C |
|
||||
AURA_STATE_BLEED = 18, // T |
|
||||
AURA_STATE_VULNERABLE = 19, // | NYI
|
||||
AURA_STATE_ARENA_PREPARATION = 20, // c |
|
||||
AURA_STATE_WOUND_HEALTH_20_80 = 21, // T |
|
||||
AURA_STATE_RAID_ENCOUNTER = 22, // CcTt|
|
||||
AURA_STATE_HEALTHY_75_PERCENT = 23, // C |
|
||||
AURA_STATE_WOUND_HEALTH_35_80 = 24 // T |
|
||||
};
|
||||
|
||||
#define PER_CASTER_AURA_STATE_MASK (\
|
||||
(1<<(AURA_STATE_CONFLAGRATE-1))|(1<<(AURA_STATE_DEADLY_POISON-1)))
|
||||
(1<<(AURA_STATE_RAID_ENCOUNTER_2-1))|(1<<(AURA_STATE_ROGUE_POISONED-1)))
|
||||
|
||||
// Spell mechanics
|
||||
enum Mechanics
|
||||
|
||||
@@ -4312,6 +4312,8 @@ void AuraEffect::HandleArenaPreparation(AuraApplication const* aurApp, uint8 mod
|
||||
return;
|
||||
target->RemoveUnitFlag(UNIT_FLAG_PREPARATION);
|
||||
}
|
||||
|
||||
target->ModifyAuraState(AURA_STATE_ARENA_PREPARATION, apply);
|
||||
}
|
||||
|
||||
void AuraEffect::HandleNoReagentUseAura(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
|
||||
|
||||
@@ -2423,45 +2423,25 @@ void SpellInfo::_LoadAuraState()
|
||||
{
|
||||
_auraState = [this]()->AuraStateType
|
||||
{
|
||||
// Seals
|
||||
if (GetSpellSpecific() == SPELL_SPECIFIC_SEAL)
|
||||
return AURA_STATE_JUDGEMENT;
|
||||
|
||||
// Conflagrate aura state on Immolate and Shadowflame
|
||||
if (SpellFamilyName == SPELLFAMILY_WARLOCK &&
|
||||
// Immolate
|
||||
((SpellFamilyFlags[0] & 4) ||
|
||||
// Shadowflame
|
||||
(SpellFamilyFlags[2] & 2)))
|
||||
return AURA_STATE_CONFLAGRATE;
|
||||
|
||||
// Faerie Fire (druid versions)
|
||||
if (SpellFamilyName == SPELLFAMILY_DRUID && SpellFamilyFlags[0] & 0x400)
|
||||
return AURA_STATE_FAERIE_FIRE;
|
||||
|
||||
// Sting (hunter's pet ability)
|
||||
// Faerie Fire (Feral)
|
||||
if (GetCategory() == 1133)
|
||||
return AURA_STATE_FAERIE_FIRE;
|
||||
|
||||
// Victorious
|
||||
if (SpellFamilyName == SPELLFAMILY_WARRIOR && SpellFamilyFlags[1] & 0x00040000)
|
||||
return AURA_STATE_WARRIOR_VICTORY_RUSH;
|
||||
|
||||
// Swiftmend state on Regrowth & Rejuvenation
|
||||
if (SpellFamilyName == SPELLFAMILY_DRUID && SpellFamilyFlags[0] & 0x50)
|
||||
return AURA_STATE_SWIFTMEND;
|
||||
// Swiftmend state on Regrowth, Rejuvenation, Wild Growth
|
||||
if (SpellFamilyName == SPELLFAMILY_DRUID && (SpellFamilyFlags[0] & 0x50 || SpellFamilyFlags[1] & 0x4000000))
|
||||
return AURA_STATE_DRUID_PERIODIC_HEAL;
|
||||
|
||||
// Deadly poison aura state
|
||||
if (SpellFamilyName == SPELLFAMILY_ROGUE && SpellFamilyFlags[0] & 0x10000)
|
||||
return AURA_STATE_DEADLY_POISON;
|
||||
return AURA_STATE_ROGUE_POISONED;
|
||||
|
||||
// Enrage aura state
|
||||
if (Dispel == DISPEL_ENRAGE)
|
||||
return AURA_STATE_ENRAGE;
|
||||
return AURA_STATE_ENRAGED;
|
||||
|
||||
// Bleeding aura state
|
||||
if (GetAllEffectsMechanicMask() & 1<<MECHANIC_BLEED)
|
||||
return AURA_STATE_BLEEDING;
|
||||
return AURA_STATE_BLEED;
|
||||
|
||||
if (GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)
|
||||
for (SpellEffectInfo const* effect : _effects)
|
||||
@@ -2470,15 +2450,46 @@ void SpellInfo::_LoadAuraState()
|
||||
|
||||
switch (Id)
|
||||
{
|
||||
case 1064: // Dazed
|
||||
return AURA_STATE_DAZED;
|
||||
case 32216: // Victorious
|
||||
return AURA_STATE_VICTORIOUS;
|
||||
case 71465: // Divine Surge
|
||||
case 50241: // Evasive Charges
|
||||
return AURA_STATE_UNKNOWN22;
|
||||
case 9991: // Touch of Zanzil
|
||||
case 35325: // Glowing Blood
|
||||
case 35328: // Lambent Blood
|
||||
case 35329: // Vibrant Blood
|
||||
case 35331: // Black Blood
|
||||
case 49163: // Perpetual Instability
|
||||
return AURA_STATE_RAID_ENCOUNTER;
|
||||
case 6950: // Faerie Fire
|
||||
case 9806: // Phantom Strike
|
||||
case 9991: // Touch of Zanzil
|
||||
case 13424: // Faerie Fire
|
||||
case 13752: // Faerie Fire
|
||||
case 16432: // Plague Mist
|
||||
case 20656: // Faerie Fire
|
||||
case 25602: // Faerie Fire
|
||||
case 32129: // Faerie Fire
|
||||
case 35325: // Glowing Blood
|
||||
case 35328: // Lambent Blood
|
||||
case 35329: // Vibrant Blood
|
||||
case 35331: // Black Blood
|
||||
case 49163: // Perpetual Instability
|
||||
case 65863: // Faerie Fire
|
||||
case 79559: // Luxscale Light
|
||||
case 82855: // Dazzling
|
||||
case 102953: // In the Rumpus
|
||||
case 127907: // Phosphorescence
|
||||
case 127913: // Phosphorescence
|
||||
case 129007: // Zijin Sting
|
||||
case 130159: // Fae Touch
|
||||
case 142537: // Spotter Smoke
|
||||
case 168455: // Spotted!
|
||||
case 176905: // Super Sticky Glitter Bomb
|
||||
case 189502: // Marked
|
||||
case 201785: // Intruder Alert!
|
||||
case 201786: // Intruder Alert!
|
||||
case 201935: // Spotted!
|
||||
case 239233: // Smoke Bomb
|
||||
case 319400: // Glitter Burst
|
||||
case 321470: // Dimensional Shifter Mishap
|
||||
case 331134: // Spotted
|
||||
return AURA_STATE_FAERIE_FIRE;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -534,8 +534,10 @@ public:
|
||||
me->SetHealth(0);
|
||||
me->StopMoving();
|
||||
me->RemoveAllAurasOnDeath();
|
||||
me->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUNDED_20_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUNDED_25_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUNDED_35_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUND_HEALTH_20_80, false);
|
||||
me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->ClearAllReactives();
|
||||
me->SetTarget(ObjectGuid::Empty);
|
||||
|
||||
+2
-2
@@ -367,7 +367,7 @@ class boss_fjola : public CreatureScript
|
||||
{
|
||||
SetEquipmentSlots(false, EQUIP_MAIN_1, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
Weapon = EQUIP_MAIN_1;
|
||||
AuraState = AURA_STATE_UNKNOWN22;
|
||||
AuraState = AURA_STATE_RAID_ENCOUNTER;
|
||||
SisterNpcId = NPC_EYDIS_DARKBANE;
|
||||
MyEmphatySpellId = SPELL_TWIN_EMPATHY_DARK;
|
||||
OtherEssenceSpellId = SPELL_DARK_ESSENCE;
|
||||
@@ -475,7 +475,7 @@ class boss_eydis : public CreatureScript
|
||||
{
|
||||
SetEquipmentSlots(false, EQUIP_MAIN_2, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
Weapon = EQUIP_MAIN_2;
|
||||
AuraState = AURA_STATE_UNKNOWN19;
|
||||
AuraState = AURA_STATE_VULNERABLE;
|
||||
SisterNpcId = NPC_FJOLA_LIGHTBANE;
|
||||
MyEmphatySpellId = SPELL_TWIN_EMPATHY_LIGHT;
|
||||
OtherEssenceSpellId = SPELL_LIGHT_ESSENCE;
|
||||
|
||||
@@ -322,12 +322,12 @@ class boss_professor_putricide : public CreatureScript
|
||||
break;
|
||||
case NPC_GAS_CLOUD:
|
||||
// no possible aura seen in sniff adding the aurastate
|
||||
summon->ModifyAuraState(AURA_STATE_UNKNOWN22, true);
|
||||
summon->ModifyAuraState(AURA_STATE_RAID_ENCOUNTER, true);
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
break;
|
||||
case NPC_VOLATILE_OOZE:
|
||||
// no possible aura seen in sniff adding the aurastate
|
||||
summon->ModifyAuraState(AURA_STATE_UNKNOWN19, true);
|
||||
summon->ModifyAuraState(AURA_STATE_VULNERABLE, true);
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
break;
|
||||
case NPC_CHOKING_GAS_BOMB:
|
||||
|
||||
@@ -379,8 +379,10 @@ struct advisorbase_ai : public ScriptedAI
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->SetHealth(0);
|
||||
me->RemoveAllAurasOnDeath();
|
||||
me->ModifyAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUNDED_20_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUNDED_25_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUNDED_35_PERCENT, false);
|
||||
me->ModifyAuraState(AURA_STATE_WOUND_HEALTH_20_80, false);
|
||||
me->AddUnitFlag(UnitFlags(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED));
|
||||
me->SetTarget(ObjectGuid::Empty);
|
||||
me->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
|
||||
@@ -682,7 +682,7 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader
|
||||
if (DamageInfo* damageInfo = eventInfo.GetDamageInfo())
|
||||
{
|
||||
SpellInfo const* spellInfo = damageInfo->GetSpellInfo();
|
||||
if (spellInfo && (spellInfo->Id == SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND || (spellInfo->Id == SPELL_WARRIOR_EXECUTE && !_procTarget->HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT))))
|
||||
if (spellInfo && (spellInfo->Id == SPELL_WARRIOR_BLADESTORM_PERIODIC_WHIRLWIND || (spellInfo->Id == SPELL_WARRIOR_EXECUTE && !_procTarget->HasAuraState(AURA_STATE_WOUNDED_20_PERCENT))))
|
||||
{
|
||||
// If triggered by Execute (while target is not under 20% hp) or Bladestorm deals normalized weapon damage
|
||||
GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2, true, nullptr, aurEff);
|
||||
|
||||
Reference in New Issue
Block a user