mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 18:36:31 +01:00
Scripts/Deadmines: implement "Captain" Cookie encounter
This commit is contained in:
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Player.h"
|
||||
#include "deadmines.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// "Captain" Cookie
|
||||
SPELL_WHOS_THAT = 89339,
|
||||
SPELL_COOKIES_HAT = 88873,
|
||||
SPELL_COOKIES_CAULDRON = 89250,
|
||||
SPELL_CAULDRON_FIRE = 89252,
|
||||
SPELL_COOKIE_ACHIEVEMENT_AURA = 95650,
|
||||
SPELL_THROW_FOOD_TARGETING_CORN = 89268,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_CORN = 89740,
|
||||
SPELL_THROW_FOOD_TARGETING_MELON = 90561,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_MELON = 90582,
|
||||
SPELL_THROW_FOOD_TARGETING_STEAK = 90562,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_STEAK = 90583,
|
||||
SPELL_THROW_FOOD_TARGETING_MYSTERY_MEAT = 90563,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_MYSTERY_MEAT = 90584,
|
||||
SPELL_THROW_FOOD_TARGETING_LOAF = 90564,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_LOAF = 90585,
|
||||
SPELL_THROW_FOOD_TARGETING_BUN = 90565,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_BUN = 90586,
|
||||
|
||||
// Player
|
||||
SPELL_NAUSEATED = 89732,
|
||||
SPELL_NAUSEATED_HC = 92066
|
||||
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_MOVE_TO_SUMMON_POS = 1,
|
||||
EVENT_SUMMON_CAULDRON,
|
||||
EVENT_JUMP_INTO_CAULDRON,
|
||||
EVENT_CAULDRON_FIRE,
|
||||
EVENT_THROW_FOOD,
|
||||
};
|
||||
|
||||
enum Points
|
||||
{
|
||||
POINT_CAULDRON_SUMMON = 1
|
||||
};
|
||||
|
||||
enum FoodTypes
|
||||
{
|
||||
FOOD_CORN = 0,
|
||||
FOOD_MELON,
|
||||
FOOD_STEAK,
|
||||
FOOD_MYSTERY_MEAT,
|
||||
FOOD_LOAF,
|
||||
FOOD_BUN,
|
||||
};
|
||||
|
||||
enum FoodStates
|
||||
{
|
||||
FOOD_STATE_DELICIOUS = 0,
|
||||
FOOD_STATE_ROTTEN,
|
||||
};
|
||||
|
||||
uint32 cornSpells[] =
|
||||
{
|
||||
SPELL_THROW_FOOD_TARGETING_CORN,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_CORN
|
||||
};
|
||||
|
||||
uint32 melonSpells[] =
|
||||
{
|
||||
SPELL_THROW_FOOD_TARGETING_MELON,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_MELON
|
||||
};
|
||||
|
||||
uint32 steakSpells[] =
|
||||
{
|
||||
SPELL_THROW_FOOD_TARGETING_STEAK,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_STEAK
|
||||
};
|
||||
|
||||
uint32 mysteryMeatSpells[] =
|
||||
{
|
||||
SPELL_THROW_FOOD_TARGETING_MYSTERY_MEAT,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_MYSTERY_MEAT
|
||||
};
|
||||
|
||||
uint32 loafSpells[] =
|
||||
{
|
||||
SPELL_THROW_FOOD_TARGETING_MYSTERY_MEAT,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_MYSTERY_MEAT
|
||||
};
|
||||
|
||||
uint32 bunSpells[] =
|
||||
{
|
||||
SPELL_THROW_FOOD_TARGETING_BUN,
|
||||
SPELL_THROW_FOOD_TARGETING_ROTTEN_BUN
|
||||
};
|
||||
|
||||
Position const cookieIntroPos = { -66.23547f, -820.1689f, 40.98766f };
|
||||
|
||||
class boss_captain_cookie : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_captain_cookie() : CreatureScript("boss_captain_cookie") { }
|
||||
|
||||
struct boss_captain_cookieAI : public BossAI
|
||||
{
|
||||
boss_captain_cookieAI(Creature* creature) : BossAI(creature, DATA_CAPTAIN_COOKIE)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_foodState = FOOD_STATE_DELICIOUS;
|
||||
_foodType = RAND(FOOD_CORN, FOOD_BUN);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
Initialize();
|
||||
DoCastSelf(SPELL_WHOS_THAT, true);
|
||||
DoCastSelf(SPELL_COOKIES_HAT, true);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_JustEngagedWith();
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
|
||||
me->RemoveAurasDueToSpell(SPELL_WHOS_THAT);
|
||||
me->AttackStop();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_SUMMON_POS, Milliseconds(1));
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
{
|
||||
_EnterEvadeMode();
|
||||
summons.DespawnAll();
|
||||
instance->SetBossState(DATA_CAPTAIN_COOKIE, FAIL);
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_DespawnAtEvade();
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
switch (point)
|
||||
{
|
||||
case POINT_CAULDRON_SUMMON:
|
||||
DoCastAOE(SPELL_COOKIES_CAULDRON);
|
||||
events.ScheduleEvent(EVENT_JUMP_INTO_CAULDRON, Seconds(1) + Milliseconds(500));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MOVE_TO_SUMMON_POS:
|
||||
me->GetMotionMaster()->MovePoint(POINT_CAULDRON_SUMMON, cookieIntroPos, false);
|
||||
break;
|
||||
case EVENT_JUMP_INTO_CAULDRON:
|
||||
if (Creature* cauldron = me->FindNearestCreature(NPC_COOKIES_CAULDRON, 15.0f, true))
|
||||
{
|
||||
me->CastSpell(cauldron, VEHICLE_SPELL_RIDE_HARDCODED);
|
||||
events.ScheduleEvent(EVENT_CAULDRON_FIRE, Seconds(2) + Milliseconds(400));
|
||||
}
|
||||
break;
|
||||
case EVENT_CAULDRON_FIRE:
|
||||
DoCastSelf(SPELL_CAULDRON_FIRE, true);
|
||||
DoCastAOE(SPELL_COOKIE_ACHIEVEMENT_AURA, true);
|
||||
events.ScheduleEvent(EVENT_THROW_FOOD, Milliseconds(1));
|
||||
break;
|
||||
case EVENT_THROW_FOOD:
|
||||
{
|
||||
switch (_foodType)
|
||||
{
|
||||
case FOOD_CORN:
|
||||
DoCastAOE(cornSpells[_foodState], true);
|
||||
break;
|
||||
case FOOD_MELON:
|
||||
DoCastAOE(melonSpells[_foodState], true);
|
||||
break;
|
||||
case FOOD_STEAK:
|
||||
DoCastAOE(steakSpells[_foodState], true);
|
||||
break;
|
||||
case FOOD_MYSTERY_MEAT:
|
||||
DoCastAOE(mysteryMeatSpells[_foodState], true);
|
||||
break;
|
||||
case FOOD_LOAF:
|
||||
DoCastAOE(loafSpells[_foodState], true);
|
||||
break;
|
||||
case FOOD_BUN:
|
||||
DoCastAOE(bunSpells[_foodState], true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Select food when rotten and delicious versions has been thrown
|
||||
if (_foodState == FOOD_STATE_ROTTEN)
|
||||
{
|
||||
// Select next random food and make sure that we will
|
||||
// never get the same food twice
|
||||
uint8 oldFoodType = _foodType;
|
||||
_foodType = RAND(FOOD_CORN, FOOD_BUN);
|
||||
if (_foodType == oldFoodType)
|
||||
_foodType++;
|
||||
if (_foodType > FOOD_BUN)
|
||||
_foodType = FOOD_CORN;
|
||||
}
|
||||
|
||||
_foodState = _foodState == FOOD_STATE_DELICIOUS ? FOOD_STATE_ROTTEN : FOOD_STATE_DELICIOUS;
|
||||
events.Repeat(Seconds(1) + Milliseconds(200), Seconds(2));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
uint8 _foodState;
|
||||
uint8 _foodType;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature *creature) const override
|
||||
{
|
||||
return GetDeadminesAI<boss_captain_cookieAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_cookie_throw_food_targeting : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_cookie_throw_food_targeting() : SpellScriptLoader("spell_cookie_throw_food_targeting") { }
|
||||
|
||||
class spell_cookie_throw_food_targeting_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_cookie_throw_food_targeting_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
Trinity::Containers::RandomResize(targets, 1);
|
||||
}
|
||||
|
||||
void HandleHit(SpellEffIndex effIndex)
|
||||
{
|
||||
GetCaster()->CastSpell(GetHitUnit(), GetSpellInfo()->Effects[effIndex].BasePoints);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_cookie_throw_food_targeting_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_cookie_throw_food_targeting_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_cookie_throw_food_targeting_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_cookie_satiated : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_cookie_satiated() : SpellScriptLoader("spell_cookie_satiated") { }
|
||||
|
||||
class spell_cookie_satiated_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_cookie_satiated_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo(
|
||||
{
|
||||
SPELL_NAUSEATED,
|
||||
SPELL_NAUSEATED_HC
|
||||
});
|
||||
}
|
||||
|
||||
void HandleHit(SpellEffIndex effIndex)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Aura* nauseatedAura = caster->GetAura(GetSpellInfo()->Effects[effIndex].BasePoints))
|
||||
nauseatedAura->ModStackAmount(-1, AURA_REMOVE_BY_DEFAULT, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_cookie_satiated_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_cookie_satiated_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_captain_cookie()
|
||||
{
|
||||
new boss_captain_cookie();
|
||||
new spell_cookie_throw_food_targeting();
|
||||
new spell_cookie_satiated();
|
||||
}
|
||||
@@ -51,6 +51,7 @@ enum DMCreatures
|
||||
BOSS_HELIX_GEARBREAKER = 47296,
|
||||
BOSS_FOE_REAPER_5000 = 43778,
|
||||
BOSS_ADMIRAL_RIPSNARL = 47626,
|
||||
BOSS_CAPTAIN_COOKIE = 47739,
|
||||
|
||||
// Horde Creatures
|
||||
NPC_SLINKY_SHARPSHIV = 46906,
|
||||
@@ -86,7 +87,20 @@ enum DMCreatures
|
||||
NPC_FOE_REAPER_TARGETING_BUNNY = 47468,
|
||||
NPC_PROTOTYPE_REAPER = 49208,
|
||||
NPC_MOLTEN_SLAG = 49229,
|
||||
NPC_VAPOR = 47714
|
||||
NPC_VAPOR = 47714,
|
||||
NPC_COOKIES_CAULDRON = 47754,
|
||||
NPC_CORN = 48006,
|
||||
NPC_ROTTEN_CORN = 48276,
|
||||
NPC_MELON = 48294,
|
||||
NPC_ROTTEN_MELON = 48293,
|
||||
NPC_STEAK = 48296,
|
||||
NPC_ROTTEN_STEAK = 48295,
|
||||
NPC_MYSTERY_MEAT = 48297,
|
||||
NPC_ROTTEN_MYSTERY_MEAT = 48298,
|
||||
NPC_LOAF = 48300,
|
||||
NPC_ROTTEN_LOAF = 48299,
|
||||
NPC_BUN = 48301,
|
||||
NPC_ROTTEN_BUN = 48302,
|
||||
};
|
||||
|
||||
enum DMGameObjects
|
||||
@@ -105,6 +119,8 @@ enum DMSpells
|
||||
SPELL_FOG = 88768
|
||||
};
|
||||
|
||||
Position const captainCookieSpawnPos = { -88.13194f, -819.3299f, 39.23453f };
|
||||
|
||||
template<class AI>
|
||||
AI* GetDeadminesAI(Creature* creature)
|
||||
{
|
||||
|
||||
@@ -22,12 +22,25 @@
|
||||
#include "TemporarySummon.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
enum EventIds
|
||||
{
|
||||
EVENT_SUMMON_CAPTAIN_COOKIE = 1
|
||||
};
|
||||
|
||||
enum TextsIds
|
||||
{
|
||||
// Id's 0 - 1 used by Foe Reaper 5000
|
||||
// Id 2 used by Defias Cannon
|
||||
SAY_ANNOUNCE_SHADOWY_FIGURE = 3
|
||||
};
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ BOSS_GLUBTOK, DATA_GLUBTOK },
|
||||
{ BOSS_HELIX_GEARBREAKER, DATA_HELIX_GEARBREAKER },
|
||||
{ BOSS_FOE_REAPER_5000, DATA_FOE_REAPER_5000 },
|
||||
{ BOSS_ADMIRAL_RIPSNARL, DATA_ADMIRAL_RIPSNARL },
|
||||
{ BOSS_CAPTAIN_COOKIE, DATA_CAPTAIN_COOKIE },
|
||||
{ NPC_LUMBERING_OAF, DATA_LUMBERING_OAF },
|
||||
{ NPC_FOE_REAPER_TARGETING_BUNNY, DATA_FOE_REAPER_BUNNY },
|
||||
{ NPC_PROTOTYPE_REAPER, DATA_PROTOTYPE_REAPER },
|
||||
@@ -65,6 +78,7 @@ class instance_deadmines : public InstanceMapScript
|
||||
_teamInInstance = 0;
|
||||
_foeReaper5000Intro = 0;
|
||||
_IronCladDoorState = 0;
|
||||
_firstCookieSpawn = true;
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* player) override
|
||||
@@ -134,6 +148,21 @@ class instance_deadmines : public InstanceMapScript
|
||||
if (Creature* ripsnarl = GetCreature(DATA_ADMIRAL_RIPSNARL))
|
||||
ripsnarl->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_CORN:
|
||||
case NPC_ROTTEN_CORN:
|
||||
case NPC_MELON:
|
||||
case NPC_ROTTEN_MELON:
|
||||
case NPC_STEAK:
|
||||
case NPC_ROTTEN_STEAK:
|
||||
case NPC_MYSTERY_MEAT:
|
||||
case NPC_ROTTEN_MYSTERY_MEAT:
|
||||
case NPC_LOAF:
|
||||
case NPC_ROTTEN_LOAF:
|
||||
case NPC_BUN:
|
||||
case NPC_ROTTEN_BUN:
|
||||
if (Creature* cookie = GetCreature(DATA_CAPTAIN_COOKIE))
|
||||
cookie->AI()->JustSummoned(creature);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -154,6 +183,27 @@ class instance_deadmines : public InstanceMapScript
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
{
|
||||
if (!InstanceScript::SetBossState(type, state))
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DATA_ADMIRAL_RIPSNARL:
|
||||
if (state == DONE)
|
||||
events.ScheduleEvent(EVENT_SUMMON_CAPTAIN_COOKIE, Seconds(10));
|
||||
break;
|
||||
case DATA_CAPTAIN_COOKIE:
|
||||
if (state == FAIL)
|
||||
events.ScheduleEvent(EVENT_SUMMON_CAPTAIN_COOKIE, Seconds(30));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
switch (type)
|
||||
@@ -221,14 +271,38 @@ class instance_deadmines : public InstanceMapScript
|
||||
|
||||
}
|
||||
|
||||
void Update(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SUMMON_CAPTAIN_COOKIE:
|
||||
if (Creature* cookie = instance->SummonCreature(BOSS_CAPTAIN_COOKIE, captainCookieSpawnPos))
|
||||
if (_firstCookieSpawn)
|
||||
{
|
||||
if (Creature* bunny = cookie->FindNearestCreature(NPC_GENERAL_PURPOSE_DUMMY_JMF, 30.0f, true))
|
||||
bunny->AI()->Talk(SAY_ANNOUNCE_SHADOWY_FIGURE);
|
||||
_firstCookieSpawn = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
EventMap events;
|
||||
uint32 _teamInInstance;
|
||||
uint32 _foeReaper5000Intro;
|
||||
uint32 _IronCladDoorState;
|
||||
GuidSet _generalPurposeBunnyJMF2GuidSet;
|
||||
bool _firstCookieSpawn;
|
||||
};
|
||||
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
{
|
||||
return new instance_deadmines_InstanceMapScript(map);
|
||||
|
||||
@@ -73,6 +73,7 @@ void AddSC_boss_glubtok();
|
||||
void AddSC_boss_helix_gearbreaker();
|
||||
void AddSC_boss_foe_reaper_5000();
|
||||
void AddSC_boss_admiral_ripsnarl();
|
||||
void AddSC_boss_captain_cookie();
|
||||
void AddSC_gilneas_c1(); //Gilneas
|
||||
void AddSC_gnomeregan(); //Gnomeregan
|
||||
void AddSC_instance_gnomeregan();
|
||||
@@ -278,6 +279,7 @@ void AddEasternKingdomsScripts()
|
||||
AddSC_boss_helix_gearbreaker();
|
||||
AddSC_boss_foe_reaper_5000();
|
||||
AddSC_boss_admiral_ripsnarl();
|
||||
AddSC_boss_captain_cookie();
|
||||
AddSC_gilneas_c1(); //Gilneas
|
||||
AddSC_gnomeregan(); //Gnomeregan
|
||||
AddSC_instance_gnomeregan();
|
||||
|
||||
Reference in New Issue
Block a user