AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
npc_echo_of_medivh Struct Reference
Inheritance diagram for npc_echo_of_medivh:
ScriptedAI CreatureAI UnitAI

Public Member Functions

 npc_echo_of_medivh (Creature *creature)
 
void Reset () override
 
void JustSummoned (Creature *summon) override
 
void SummonedCreatureDespawn (Creature *summon) override
 
void RemoveCheats ()
 
void SetupBoard ()
 
void HandleCellInitialData (uint8 row, uint8 col, Creature *trigger, BoardCell &cell)
 
bool IsMedivhPiece (uint32 entry) const
 
CreatureGetHostileTargetForChangeFacing (Creature *piece, KarazhanChessOrientationType orientation)
 
void HandlePieceJustDied (Creature *piece)
 
int8 HandlePieceRotate (Creature *piece, ObjectGuid const &triggerGUID)
 
int8 HandlePieceMove (Creature *piece, ObjectGuid const &triggerGUID, bool moveByAI)
 
void CastChangeFacing (Creature *piece, Creature *trigger)
 
bool HandlePieceMoveByAI (Creature *piece, KarazhanChessOrientationType orientation)
 
void HandleCheat ()
 
CreatureGetPiece (Creature *sourcePiece, uint8 searchType, float distance, bool hostile, uint32 minHPDiff, bool checkFront)
 
void UpdateAI (uint32 diff) override
 
void sGossipHello (Player *player) override
 
void sGossipSelect (Player *player, uint32, uint32 gossipListId) override
 
- Public Member Functions inherited from ScriptedAI
 ScriptedAI (Creature *creature)
 
 ~ScriptedAI () override
 
void AttackStartNoMove (Unit *target)
 
void DamageTaken (Unit *, uint32 &, DamageEffectType, SpellSchoolMask) override
 
void UpdateAI (uint32 diff) override
 
void JustDied (Unit *) override
 
void KilledUnit (Unit *) override
 
void JustSummoned (Creature *) override
 
void SummonedCreatureDespawn (Creature *) override
 
void SpellHit (Unit *, SpellInfo const *) override
 
void SpellHitTarget (Unit *, SpellInfo const *) override
 
void MovementInform (uint32, uint32) override
 
void OnPossess (bool)
 
bool IsInRoom (const Position *pos, Axis axis, bool above)
 
void Reset () override
 
void JustEngagedWith (Unit *) override
 Called for reaction when initially engaged.
 
void AttackStart (Unit *) override
 
void DoStartMovement (Unit *target, float distance=0.0f, float angle=0.0f)
 
void DoStartNoMovement (Unit *target)
 
void DoStopAttack ()
 
void DoCastSpell (Unit *target, SpellInfo const *spellInfo, bool triggered=false)
 
void DoPlaySoundToSet (WorldObject *source, uint32 soundId)
 
void DoPlayMusic (uint32 soundId, bool zone)
 
void DoAddThreat (Unit *unit, float amount)
 
void DoModifyThreatByPercent (Unit *unit, int32 pct)
 
void DoResetThreat (Unit *unit)
 
void DoResetThreatList ()
 
float DoGetThreat (Unit *unit)
 
void DoTeleportPlayer (Unit *unit, float x, float y, float z, float o)
 
void DoTeleportAll (float x, float y, float z, float o)
 
UnitDoSelectLowestHpFriendly (float range, uint32 minHPDiff=1)
 
std::list< Creature * > DoFindFriendlyCC (float range)
 
std::list< Creature * > DoFindFriendlyMissingBuff (float range, uint32 spellId)
 
PlayerGetPlayerAtMinimumRange (float minRange)
 
CreatureDoSpawnCreature (uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, uint32 despawntime)
 
bool HealthBelowPct (uint32 pct) const
 
bool HealthAbovePct (uint32 pct) const
 
SpellInfo const * SelectSpell (Unit *target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effect)
 
void SetEquipmentSlots (bool loadDefault, int32 mainHand=EQUIP_NO_CHANGE, int32 offHand=EQUIP_NO_CHANGE, int32 ranged=EQUIP_NO_CHANGE)
 
void SetCombatMovement (bool allowMovement)
 
bool IsCombatMovementAllowed () const
 
virtual bool CheckEvadeIfOutOfCombatArea () const
 
bool IsHeroic () const
 
Difficulty GetDifficulty () const
 
bool Is25ManRaid () const
 
template<class T >
const T & DUNGEON_MODE (const T &normal5, const T &heroic10) const
 
template<class T >
const T & RAID_MODE (const T &normal10, const T &normal25) const
 
template<class T >
const T & RAID_MODE (const T &normal10, const T &normal25, const T &heroic10, const T &heroic25) const
 
PlayerSelectTargetFromPlayerList (float maxdist, uint32 excludeAura=0, bool mustBeInLOS=false) const
 
- Public Member Functions inherited from CreatureAI
void Talk (uint8 id, WorldObject const *whisperTarget=nullptr, Milliseconds delay=0s)
 Causes the creature to talk/say the text assigned to their entry in the creature_text database table.
 
void Talk (uint8 id, Milliseconds delay)
 
 CreatureAI (Creature *creature)
 
 ~CreatureAI () override
 
void MoveCircleChecks ()
 
void MoveBackwardsChecks ()
 
void MoveInLineOfSight_Safe (Unit *who)
 == Reactions At =================================
 
void TriggerAlert (Unit const *who) const
 
virtual bool CanRespawn ()
 
virtual void EnterEvadeMode (EvadeReason why=EVADE_REASON_OTHER)
 
virtual void JustEngagedWith (Unit *)
 Called for reaction when initially engaged.
 
virtual void JustDied (Unit *)
 
virtual void KilledUnit (Unit *)
 
virtual void JustSummoned (Creature *)
 
virtual void IsSummonedBy (WorldObject *)
 
virtual void SummonedCreatureDespawn (Creature *)
 
virtual void SummonedCreatureDies (Creature *, Unit *)
 
virtual void SummonedCreatureDespawnAll ()
 
virtual void SpellHit (Unit *, SpellInfo const *)
 
virtual void SpellHitTarget (Unit *, SpellInfo const *)
 
virtual void AttackedBy (Unit *)
 
virtual bool IsEscorted ()
 
virtual void JustRespawned ()
 
virtual void MovementInform (uint32, uint32)
 
virtual void PathEndReached (uint32)
 
void OnCharmed (bool apply) override
 
virtual void JustReachedHome ()
 
void DoZoneInCombat (Creature *creature=nullptr, float maxRangeToNearestTarget=250.0f)
 
virtual void ReceiveEmote (Player *, uint32)
 
virtual void OwnerAttackedBy (Unit *)
 
virtual void OwnerAttacked (Unit *)
 
virtual void CorpseRemoved (uint32 &)
 == Triggered Actions Requested ==================
 
virtual void PassengerBoarded (Unit *, int8, bool)
 == Fields =======================================
 
virtual bool BeforeSpellClick (Unit *)
 
virtual void OnSpellClick (Unit *, bool &)
 
virtual bool CanSeeAlways (WorldObject const *)
 
virtual bool CanBeSeen (Player const *)
 
virtual bool CanAlwaysBeDetectable (WorldObject const *)
 
virtual void PetStopAttack ()
 
virtual bool CheckInRoom ()
 
CreatureBoundary const * GetBoundary () const
 
void SetBoundary (CreatureBoundary const *boundary, bool negativeBoundaries=false)
 
bool IsInBoundary (Position const *who=nullptr) const
 
virtual void CalculateThreat (Unit *, float &, SpellInfo const *)
 
virtual bool OnTeleportUnreacheablePlayer (Player *)
 
- Public Member Functions inherited from UnitAI
 UnitAI (Unit *unit)
 
virtual ~UnitAI ()
 
virtual bool CanAIAttack (Unit const *) const
 
virtual void AttackStart (Unit *)
 
virtual void UpdateAI (uint32)=0
 
virtual void InitializeAI ()
 
virtual void Reset ()
 
virtual void OnCharmed (bool apply)=0
 
virtual void DoAction (int32)
 
virtual uint32 GetData (uint32) const
 
virtual void SetData (uint32, uint32)
 
virtual void SetGUID (ObjectGuid, int32=0)
 
virtual ObjectGuid GetGUID (int32=0) const
 
UnitSelectTarget (SelectTargetMethod targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
 
template<class PREDICATE >
UnitSelectTarget (SelectTargetMethod targetType, uint32 position, PREDICATE const &predicate)
 
void SelectTargetList (std::list< Unit * > &targetList, uint32 num, SelectTargetMethod targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
 
template<class PREDICATE >
void SelectTargetList (std::list< Unit * > &targetList, uint32 num, SelectTargetMethod targetType, uint32 position, PREDICATE const &predicate)
 
virtual void JustEnteredCombat (Unit *)
 Called when the unit enters combat (NOTE: Creature engage logic should NOT be here, but in JustEngagedWith, which happens once threat is established!)
 
virtual void JustExitedCombat ()
 Called when the unit leaves combat.
 
virtual void DamageDealt (Unit *, uint32 &, DamageEffectType)
 
virtual void DamageTaken (Unit *, uint32 &, DamageEffectType, SpellSchoolMask)
 
virtual void HealReceived (Unit *, uint32 &)
 
virtual void HealDone (Unit *, uint32 &)
 
void AttackStartCaster (Unit *victim, float dist)
 
SpellCastResult DoAddAuraToAllHostilePlayers (uint32 spellid)
 
SpellCastResult DoCast (uint32 spellId)
 
SpellCastResult DoCast (Unit *victim, uint32 spellId, bool triggered=false)
 
SpellCastResult DoCastSelf (uint32 spellId, bool triggered=false)
 
SpellCastResult DoCastToAllHostilePlayers (uint32 spellid, bool triggered=false)
 
SpellCastResult DoCastVictim (uint32 spellId, bool triggered=false)
 
SpellCastResult DoCastAOE (uint32 spellId, bool triggered=false)
 
SpellCastResult DoCastRandomTarget (uint32 spellId, uint32 threatTablePosition=0, float dist=0.0f, bool playerOnly=true, bool triggered=false)
 
SpellCastResult DoCastMaxThreat (uint32 spellId, uint32 threatTablePosition=0, float dist=0.0f, bool playerOnly=true, bool triggered=false)
 Cast spell on the max threat target, which may not always be the current victim.
 
float DoGetSpellMaxRange (uint32 spellId, bool positive=false)
 
void DoMeleeAttackIfReady ()
 
bool DoSpellAttackIfReady (uint32 spell)
 
void DoSpellAttackToRandomTargetIfReady (uint32 spell, uint32 threatTablePosition=0, float dist=0.f, bool playerOnly=true)
 
virtual void SummonMovementInform (Creature *, uint32, uint32)
 
virtual void sGossipHello (Player *)
 
virtual void sGossipSelect (Player *, uint32, uint32)
 
virtual void sGossipSelectCode (Player *, uint32, uint32, char const *)
 
virtual void sQuestAccept (Player *, Quest const *)
 
virtual void sQuestSelect (Player *, Quest const *)
 
virtual void sQuestComplete (Player *, Quest const *)
 
virtual void sQuestReward (Player *, Quest const *, uint32)
 
virtual void sOnGameEvent (bool, uint16)
 
virtual std::string GetDebugInfo () const
 

Private Attributes

InstanceScript_instance
 
SummonList _summons
 
std::array< std::array< BoardCell, MAX_COL >, MAX_ROW_boards
 
std::array< uint32, 2 > _deadCount
 
uint32 _cheatTimer
 

Additional Inherited Members

- Public Types inherited from ScriptedAI
enum class  Axis {
  AXIS_X ,
  AXIS_Y
}
 
- Public Types inherited from CreatureAI
enum  EvadeReason {
  EVADE_REASON_NO_HOSTILES ,
  EVADE_REASON_BOUNDARY ,
  EVADE_REASON_SEQUENCE_BREAK ,
  EVADE_REASON_NO_PATH ,
  EVADE_REASON_OTHER
}
 
- Static Public Member Functions inherited from CreatureAI
static bool IsInBounds (CreatureBoundary const &boundary, Position const *who)
 
- Static Public Member Functions inherited from UnitAI
static void FillAISpellInfo ()
 
- Public Attributes inherited from ScriptedAI
Creatureme
 
bool IsFleeing
 
- Static Public Attributes inherited from UnitAI
static AISpellInfoTypeAISpellInfo
 
- Protected Member Functions inherited from CreatureAI
bool UpdateVictim ()
 
bool UpdateVictimWithGaze ()
 
void SetGazeOn (Unit *target)
 
CreatureDoSummon (uint32 entry, Position const &pos, uint32 despawnTime=30000, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
 
CreatureDoSummon (uint32 entry, WorldObject *obj, float radius=5.0f, uint32 despawnTime=30000, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
 
CreatureDoSummonFlyer (uint32 entry, WorldObject *obj, float flightZ, float radius=5.0f, uint32 despawnTime=30000, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
 
virtual void MoveInLineOfSight (Unit *)
 
bool _EnterEvadeMode (EvadeReason why=EVADE_REASON_OTHER)
 
- Protected Attributes inherited from CreatureAI
Creature *const me
 
EventMap events
 
CreatureBoundary const * _boundary
 
bool _negateBoundary
 
- Protected Attributes inherited from UnitAI
Unit *const me
 

Detailed Description

Constructor & Destructor Documentation

◆ npc_echo_of_medivh()

npc_echo_of_medivh::npc_echo_of_medivh ( Creature creature)
inline
194 : ScriptedAI(creature), _summons(me)
195 {
196 _instance = creature->GetInstanceScript();
197 }
Definition: ScriptedCreature.h:192
Creature * me
Definition: ScriptedCreature.h:282
InstanceScript * GetInstanceScript() const
Definition: Object.cpp:1192
InstanceScript * _instance
Definition: boss_chess_event.cpp:1417
SummonList _summons
Definition: boss_chess_event.cpp:1418

References _instance, and WorldObject::GetInstanceScript().

Member Function Documentation

◆ CastChangeFacing()

void npc_echo_of_medivh::CastChangeFacing ( Creature piece,
Creature trigger 
)
inline
973 {
974 piece->CastSpell(trigger, SPELL_CHANGE_FACING, true);
975 }
@ SPELL_CHANGE_FACING
Definition: boss_chess_event.cpp:52
SpellCastResult CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=nullptr, AuraEffect const *triggeredByAura=nullptr, ObjectGuid originalCaster=ObjectGuid::Empty)
Definition: Unit.cpp:1169

References Unit::CastSpell(), and SPELL_CHANGE_FACING.

Referenced by HandlePieceMoveByAI().

◆ GetHostileTargetForChangeFacing()

Creature * npc_echo_of_medivh::GetHostileTargetForChangeFacing ( Creature piece,
KarazhanChessOrientationType  orientation 
)
inline
395 {
396 for (uint8 row = 0; row < MAX_ROW; ++row)
397 {
398 for (uint8 col = 0; col < MAX_COL; ++col)
399 {
400 BoardCell const& cell = _boards[row][col];
401 if (cell.pieceGUID == piece->GetGUID())
402 {
403 std::vector<KarazhanChessOrientationType> orientations;
404 switch (orientation)
405 {
406 case ORI_SE:
408 break;
409 case ORI_S:
411 break;
412 case ORI_SW:
414 break;
415 case ORI_W:
417 break;
418 case ORI_NW:
420 break;
421 case ORI_N:
423 break;
424 case ORI_NE:
426 break;
427 case ORI_E:
429 break;
430 default:
431 break;
432 }
433
435 {
436 uint8 newRow = row;
437 uint8 newCol = col;
438 switch (orient)
439 {
440 case ORI_SE:
441 newRow -= 1;
442 break;
443 case ORI_S:
444 newRow -= 1;
445 newCol -= 1;
446 break;
447 case ORI_SW:
448 newCol -= 1;
449 break;
450 case ORI_W:
451 newRow += 1;
452 newCol -= 1;
453 break;
454 case ORI_NW:
455 newRow += 1;
456 break;
457 case ORI_N:
458 newRow += 1;
459 newCol += 1;
460 break;
461 case ORI_NE:
462 newCol += 1;
463 break;
464 case ORI_E:
465 newRow -= 1;
466 newCol += 1;
467 break;
468 default:
469 break;
470 }
471
472 if (Creature* targetPiece = ObjectAccessor::GetCreature(*me, _boards[newRow][newCol].pieceGUID))
473 {
474 if (!IsFriendly(piece, targetPiece))
475 {
476 return targetPiece;
477 }
478 }
479 }
480
481 return nullptr;
482 }
483 }
484 }
485
486 return nullptr;
487 }
std::uint8_t uint8
Definition: Define.h:110
static std::array< float, MAX_ORI > orientations
Definition: boss_chess_event.cpp:179
static constexpr uint8 MAX_ROW
Definition: boss_chess_event.cpp:145
KarazhanChessOrientationType
Definition: boss_chess_event.cpp:76
@ ORI_NE
Definition: boss_chess_event.cpp:83
@ ORI_W
Definition: boss_chess_event.cpp:80
@ ORI_E
Definition: boss_chess_event.cpp:84
@ ORI_S
Definition: boss_chess_event.cpp:78
@ ORI_NW
Definition: boss_chess_event.cpp:81
@ ORI_N
Definition: boss_chess_event.cpp:82
@ ORI_SE
Definition: boss_chess_event.cpp:77
@ ORI_SW
Definition: boss_chess_event.cpp:79
static constexpr uint8 MAX_COL
Definition: boss_chess_event.cpp:146
static bool IsFriendly(Creature *piece, Creature *target)
Definition: boss_chess_event.cpp:181
Creature * GetCreature(WorldObject const &u, ObjectGuid const guid)
Definition: ObjectAccessor.cpp:215
Definition: Creature.h:46
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
Definition: boss_chess_event.cpp:149
ObjectGuid pieceGUID
Definition: boss_chess_event.cpp:153
std::array< std::array< BoardCell, MAX_COL >, MAX_ROW > _boards
Definition: boss_chess_event.cpp:1419

References _boards, ObjectAccessor::GetCreature(), Object::GetGUID(), IsFriendly(), MAX_COL, MAX_ROW, ScriptedAI::me, ORI_E, ORI_N, ORI_NE, ORI_NW, ORI_S, ORI_SE, ORI_SW, ORI_W, orientations, and BoardCell::pieceGUID.

Referenced by HandlePieceMoveByAI().

◆ GetPiece()

Creature * npc_echo_of_medivh::GetPiece ( Creature sourcePiece,
uint8  searchType,
float  distance,
bool  hostile,
uint32  minHPDiff,
bool  checkFront 
)
inline
1273 {
1274 if (!sourcePiece)
1275 {
1276 return nullptr;
1277 }
1278
1279 Creature* target = nullptr;
1280 std::vector<Creature*> targets;
1281
1282 for (uint8 row = 0; row < MAX_ROW; ++row)
1283 {
1284 for (uint8 col = 0; col < MAX_COL; ++col)
1285 {
1286 if (Creature* piece = ObjectAccessor::GetCreature(*me, _boards[row][col].pieceGUID))
1287 {
1288 if (IsFriendly(piece, sourcePiece) == hostile)
1289 {
1290 continue;
1291 }
1292
1293 if (checkFront && !sourcePiece->HasInArc(float(M_PI) / 3.0f, piece))
1294 {
1295 continue;
1296 }
1297
1298 if (minHPDiff)
1299 {
1300 if (piece->GetMaxHealth() - piece->GetHealth() <= minHPDiff)
1301 {
1302 continue;
1303 }
1304
1305 minHPDiff = piece->GetMaxHealth() - piece->GetHealth();
1306 }
1307
1308 float dist = sourcePiece->GetExactDist2d(piece);
1309 if (dist < distance)
1310 {
1311 if (searchType == CHESS_PIECE_SEARCH_TYPE_CLOSEST)
1312 {
1313 distance = dist;
1314 target = piece;
1315 }
1316 else
1317 {
1318 targets.push_back(piece);
1319 }
1320 }
1321 }
1322 }
1323 }
1324
1325 if (!targets.empty())
1326 {
1328 }
1329
1330 return target;
1331 }
@ CHESS_PIECE_SEARCH_TYPE_CLOSEST
Definition: boss_chess_event.cpp:188
auto SelectRandomContainerElement(C const &container) -> typename std::add_const< decltype(*std::begin(container))>::type &
Definition: Containers.h:135
float GetExactDist2d(const float x, const float y) const
Definition: Position.h:166
bool HasInArc(float arcangle, const Position *pos, float targetRadius=0.0f) const
Definition: Position.cpp:140
uint32 GetMaxHealth() const
Definition: Unit.h:1441

References _boards, CHESS_PIECE_SEARCH_TYPE_CLOSEST, ObjectAccessor::GetCreature(), Position::GetExactDist2d(), Unit::GetMaxHealth(), Position::HasInArc(), IsFriendly(), MAX_COL, MAX_ROW, ScriptedAI::me, and Acore::Containers::SelectRandomContainerElement().

◆ HandleCellInitialData()

void npc_echo_of_medivh::HandleCellInitialData ( uint8  row,
uint8  col,
Creature trigger,
BoardCell cell 
)
inline
266 {
267 switch (row)
268 {
269 case 0: // Alliance first row
270 {
271 switch (col)
272 {
273 case 0:
274 case 7: // Rook
275 if (Creature* rook = trigger->FindNearestCreature(NPC_ROOK_A, 4.0f, true))
276 {
277 cell.SetPiece(rook);
278 }
279 break;
280 case 1:
281 case 6: // Knight
282 if (Creature* knight = trigger->FindNearestCreature(NPC_KNIGHT_A, 4.0f, true))
283 {
284 cell.SetPiece(knight);
285 }
286 break;
287 case 2:
288 case 5: // Bishop
289 if (Creature* bishop = trigger->FindNearestCreature(NPC_BISHOP_A, 4.0f, true))
290 {
291 cell.SetPiece(bishop);
292 }
293 break;
294 case 3: // Queen
295 if (Creature* queen = trigger->FindNearestCreature(NPC_QUEEN_A, 4.0f, true))
296 {
297 cell.SetPiece(queen);
298 }
299 break;
300 case 4: // King
301 if (Creature* king = trigger->FindNearestCreature(NPC_KING_A, 4.0f, true))
302 {
303 cell.SetPiece(king);
304 }
305 break;
306 }
307 break;
308 }
309 case 1: // Alliance second row
310 // All pawns
311 if (Creature* pawn = trigger->FindNearestCreature(NPC_PAWN_A, 4.0f, true))
312 {
313 cell.SetPiece(pawn);
314 }
315 break;
316 case 6: // Horde second row
317 // All pawns
318 if (Creature* pawn = trigger->FindNearestCreature(NPC_PAWN_H, 4.0f, true))
319 {
320 cell.SetPiece(pawn);
321 }
322 break;
323 case 7: // Horde first row
324 {
325 switch (col)
326 {
327 case 0:
328 case 7: // Rook
329 if (Creature* rook = trigger->FindNearestCreature(NPC_ROOK_H, 4.0f, true))
330 {
331 cell.SetPiece(rook);
332 }
333 break;
334 case 1:
335 case 6: // Knight
336 if (Creature* knight = trigger->FindNearestCreature(NPC_KNIGHT_H, 4.0f, true))
337 {
338 cell.SetPiece(knight);
339 }
340 break;
341 case 2:
342 case 5: // Bishop
343 if (Creature* bishop = trigger->FindNearestCreature(NPC_BISHOP_H, 4.0f, true))
344 {
345 cell.SetPiece(bishop);
346 }
347 break;
348 case 3: // Queen
349 if (Creature* queen = trigger->FindNearestCreature(NPC_QUEEN_H, 4.0f, true))
350 {
351 cell.SetPiece(queen);
352 }
353 break;
354 case 4: // King
355 if (Creature* king = trigger->FindNearestCreature(NPC_KING_H, 4.0f, true))
356 {
357 cell.SetPiece(king);
358 }
359 break;
360 default:
361 break;
362 }
363 break;
364 }
365 default:
366 cell.Reset();
367 break;
368 }
369 }
@ NPC_QUEEN_H
Definition: karazhan.h:111
@ NPC_ROOK_A
Definition: karazhan.h:116
@ NPC_KNIGHT_H
Definition: karazhan.h:109
@ NPC_KING_A
Definition: karazhan.h:118
@ NPC_PAWN_H
Definition: karazhan.h:107
@ NPC_PAWN_A
Definition: karazhan.h:108
@ NPC_ROOK_H
Definition: karazhan.h:115
@ NPC_KING_H
Definition: karazhan.h:117
@ NPC_QUEEN_A
Definition: karazhan.h:112
@ NPC_BISHOP_H
Definition: karazhan.h:113
@ NPC_BISHOP_A
Definition: karazhan.h:114
@ NPC_KNIGHT_A
Definition: karazhan.h:110
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2409
void Reset()
Definition: boss_chess_event.cpp:165
void SetPiece(Creature *piece)
Definition: boss_chess_event.cpp:171

References WorldObject::FindNearestCreature(), NPC_BISHOP_A, NPC_BISHOP_H, NPC_KING_A, NPC_KING_H, NPC_KNIGHT_A, NPC_KNIGHT_H, NPC_PAWN_A, NPC_PAWN_H, NPC_QUEEN_A, NPC_QUEEN_H, NPC_ROOK_A, NPC_ROOK_H, BoardCell::Reset(), and BoardCell::SetPiece().

Referenced by SetupBoard().

◆ HandleCheat()

void npc_echo_of_medivh::HandleCheat ( )
inline
1178 {
1180
1181 switch (urand(0, 2))
1182 {
1183 case 0: // Heal king
1184 {
1186 {
1187 if (Creature* king = me->FindNearestCreature(NPC_KING_H, 80.0f, true))
1188 {
1189 king->SetHealth(king->GetMaxHealth());
1190 }
1191 }
1193 {
1194 if (Creature* king = me->FindNearestCreature(NPC_KING_A, 80.0f, true))
1195 {
1196 king->SetHealth(king->GetMaxHealth());
1197 }
1198 }
1199
1200 break;
1201 }
1202 case 1: // Fire
1203 {
1204 std::list<Creature*> targetList;
1205 for (uint8 row = 0; row < MAX_ROW; ++row)
1206 {
1207 for (uint8 col = 0; col < MAX_COL; ++col)
1208 {
1209 BoardCell const& cell = _boards[row][col];
1210 if (!cell.pieceGUID || IsMedivhPiece(cell.pieceEntry))
1211 {
1212 continue;
1213 }
1214
1215 if (Creature* trigger = ObjectAccessor::GetCreature(*me, cell.triggerGUID))
1216 {
1217 targetList.push_back(trigger);
1218 }
1219 }
1220 }
1221
1222 if (targetList.size() > 3)
1223 {
1224 Acore::Containers::RandomResize(targetList, 3);
1225 }
1226
1227 for (Creature* target : targetList)
1228 {
1229 DoCast(target, SPELL_FURY_OF_MEDIVH_FIRE, true);
1230 }
1231
1232 break;
1233 }
1234 case 2: // Buff
1235 {
1236 std::list<Creature*> targetList;
1237 for (uint8 row = 0; row < MAX_ROW; ++row)
1238 {
1239 for (uint8 col = 0; col < MAX_COL; ++col)
1240 {
1241 BoardCell const& cell = _boards[row][col];
1242 if (!cell.pieceGUID || !IsMedivhPiece(cell.pieceEntry))
1243 {
1244 continue;
1245 }
1246
1247 if (Creature* piece = ObjectAccessor::GetCreature(*me, cell.pieceGUID))
1248 {
1249 targetList.push_back(piece);
1250 }
1251 }
1252 }
1253
1254 uint8 resizeMax = urand(1, 4);
1255 if (targetList.size() > resizeMax)
1256 {
1257 Acore::Containers::RandomResize(targetList, resizeMax);
1258 }
1259
1260 for (Creature* target : targetList)
1261 {
1262 DoCast(target, SPELL_HAND_OF_MEDIVH, true);
1263 }
1264
1265 break;
1266 }
1267 }
1268
1270 }
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:44
@ TALK_MEDIHV_CHEAT_EMOTE
Definition: boss_chess_event.cpp:125
@ TALK_MEDIHV_CHEAT
Definition: boss_chess_event.cpp:124
@ SPELL_FURY_OF_MEDIVH_FIRE
Definition: boss_chess_event.cpp:58
@ SPELL_HAND_OF_MEDIVH
Definition: karazhan.h:163
@ CHESS_EVENT_TEAM
Definition: karazhan.h:66
Talk
Definition: boss_fathomlord_karathress.cpp:23
@ TEAM_ALLIANCE
Definition: SharedDefines.h:732
@ TEAM_HORDE
Definition: SharedDefines.h:733
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:81
SpellCastResult DoCast(uint32 spellId)
Definition: UnitAI.cpp:178
virtual uint32 GetData(uint32) const
Definition: ZoneScript.h:52
uint32 pieceEntry
Definition: boss_chess_event.cpp:154
ObjectGuid triggerGUID
Definition: boss_chess_event.cpp:152
bool IsMedivhPiece(uint32 entry) const
Definition: boss_chess_event.cpp:371

References _boards, _instance, CHESS_EVENT_TEAM, UnitAI::DoCast(), WorldObject::FindNearestCreature(), ObjectAccessor::GetCreature(), ZoneScript::GetData(), IsMedivhPiece(), MAX_COL, MAX_ROW, ScriptedAI::me, NPC_KING_A, NPC_KING_H, BoardCell::pieceEntry, BoardCell::pieceGUID, Acore::Containers::RandomResize(), SPELL_FURY_OF_MEDIVH_FIRE, SPELL_HAND_OF_MEDIVH, TALK_MEDIHV_CHEAT, TALK_MEDIHV_CHEAT_EMOTE, TEAM_ALLIANCE, TEAM_HORDE, BoardCell::triggerGUID, and urand().

Referenced by UpdateAI().

◆ HandlePieceJustDied()

void npc_echo_of_medivh::HandlePieceJustDied ( Creature piece)
inline
490 {
491 switch (piece->GetFaction())
492 {
494 {
495 float baseX = -11078.116211f;
496 float baseY = -1908.443115f;
497 float deltaX = 2.148438f;
498 float deltaY = 1.723755f;
499 float extraX = 2.416992f;
500 float extraY = -2.889649f;
501 float offset = 1.3f * (_deadCount[DEAD_ALLIANCE] % MAX_ROW);
502 float finalX = baseX + offset * deltaX + (_deadCount[DEAD_ALLIANCE] >= MAX_ROW ? 1 : 0) * extraX;
503 float finalY = baseY + offset * deltaY + (_deadCount[DEAD_ALLIANCE] >= MAX_ROW ? 1 : 0) * extraY;
504 piece->NearTeleportTo(finalX, finalY, 221.0f, orientations[ORI_SW]);
506
507 piece->CombatStop();
510 piece->SetHealth(piece->GetMaxHealth());
511 break;
512 }
514 {
515 float baseX = -11081.393555f;
516 float baseY = -1844.194092f;
517 float deltaX = -2.148438f;
518 float deltaY = -1.723755f;
519 float extraX = -2.416992f;
520 float extraY = 2.889649f;
521
522 float offset = 1.3f * (_deadCount[DEAD_HORDE] % MAX_ROW);
523
524 float finalX = baseX + offset * deltaX + (_deadCount[DEAD_HORDE] >= MAX_ROW ? 1 : 0) * extraX;
525 float finalY = baseY + offset * deltaY + (_deadCount[DEAD_HORDE] >= MAX_ROW ? 1 : 0) * extraY;
526 piece->NearTeleportTo(finalX, finalY, 221.0f, orientations[ORI_NE]);
528
529 piece->CombatStop();
532 piece->SetHealth(piece->GetMaxHealth());
533 break;
534 }
535 }
536
537 for (uint8 row = 0; row < MAX_ROW; ++row)
538 {
539 for (uint8 col = 0; col < MAX_COL; ++col)
540 {
541 if (_boards[row][col].pieceGUID == piece->GetGUID())
542 {
543 _boards[row][col].Reset();
544 }
545 }
546 }
547
549 {
550 bool ended = false;
551 switch (piece->GetEntry())
552 {
553 case NPC_KING_H:
557 break;
558 case NPC_KING_A:
560 {
566 ended = true;
568 }
570 {
574 ended = true;
576 }
577 break;
578 default:
579 break;
580 }
581
582 if (!ended)
583 {
584 uint8 talkIndex = TALK_PLAYER_LOOSE_PAWN;
585 if (piece->GetFaction() == CHESS_FACTION_ALLIANCE)
586 {
587 talkIndex = TALK_MEDIVH_LOOSE_PAWN;
588 }
589
590 switch (piece->GetEntry())
591 {
592 case NPC_ROOK_A:
593 case NPC_ROOK_H:
594 talkIndex += 1;
595 break;
596 case NPC_KNIGHT_A:
597 case NPC_KNIGHT_H:
598 talkIndex += 2;
599 break;
600 case NPC_BISHOP_A:
601 case NPC_BISHOP_H:
602 talkIndex += 3;
603 break;
604 case NPC_QUEEN_A:
605 case NPC_QUEEN_H:
606 talkIndex += 4;
607 break;
608 case NPC_KING_H:
609 case NPC_KING_A:
610 talkIndex += 5;
611 break;
612 }
613
614 Talk(talkIndex);
615 }
616 }
618 {
619 bool ended = false;
620 switch (piece->GetEntry())
621 {
622 case NPC_KING_A:
626 break;
627 case NPC_KING_H:
629 {
635 ended = true;
637 }
639 {
644 ended = true;
645 }
646 break;
647 default:
648 break;
649 }
650
651 if (!ended)
652 {
653 uint8 talkIndex = TALK_PLAYER_LOOSE_PAWN;
654 if (piece->GetFaction() == CHESS_FACTION_HORDE)
655 {
656 talkIndex = TALK_MEDIVH_LOOSE_PAWN;
657 }
658
659 switch (piece->GetEntry())
660 {
661 case NPC_ROOK_A:
662 case NPC_ROOK_H:
663 talkIndex += 1;
664 break;
665 case NPC_KNIGHT_A:
666 case NPC_KNIGHT_H:
667 talkIndex += 2;
668 break;
669 case NPC_BISHOP_A:
670 case NPC_BISHOP_H:
671 talkIndex += 3;
672 break;
673 case NPC_QUEEN_A:
674 case NPC_QUEEN_H:
675 talkIndex += 4;
676 break;
677 case NPC_KING_H:
678 case NPC_KING_A:
679 talkIndex += 5;
680 break;
681 }
682
683 Talk(talkIndex);
684 }
685 }
686 else
687 {
688 switch (piece->GetEntry())
689 {
690 case NPC_KING_H:
691 case NPC_KING_A:
696 break;
697 }
698
699 uint8 talkIndex = TALK_PLAYER_LOOSE_PAWN;
700 if (piece->GetFaction() == CHESS_FACTION_HORDE)
701 {
702 talkIndex = TALK_MEDIVH_LOOSE_PAWN;
703 }
704
705 switch (piece->GetEntry())
706 {
707 case NPC_ROOK_A:
708 case NPC_ROOK_H:
709 talkIndex += 1;
710 break;
711 case NPC_KNIGHT_A:
712 case NPC_KNIGHT_H:
713 talkIndex += 2;
714 break;
715 case NPC_BISHOP_A:
716 case NPC_BISHOP_H:
717 talkIndex += 3;
718 break;
719 case NPC_QUEEN_A:
720 case NPC_QUEEN_H:
721 talkIndex += 4;
722 break;
723 case NPC_KING_H:
724 case NPC_KING_A:
725 talkIndex += 5;
726 break;
727 }
728
729 Talk(talkIndex);
730 }
731 }
constexpr auto DAY
Definition: Common.h:58
@ JUST_RESPAWNED
Definition: Unit.h:320
@ UNIT_FLAG_NOT_SELECTABLE
Definition: Unit.h:473
@ IN_PROGRESS
Definition: InstanceScript.h:57
@ DONE
Definition: InstanceScript.h:59
@ SPECIAL
Definition: InstanceScript.h:60
@ NOT_STARTED
Definition: InstanceScript.h:56
@ TALK_EVENT_ENDED
Definition: boss_chess_event.cpp:142
@ TALK_MEDIVH_LOOSE_PAWN
Definition: boss_chess_event.cpp:134
@ TALK_PLAYER_LOOSE_PAWN
Definition: boss_chess_event.cpp:127
@ DEAD_ALLIANCE
Definition: boss_chess_event.cpp:71
@ DEAD_HORDE
Definition: boss_chess_event.cpp:72
@ CHESS_FACTION_HORDE
Definition: karazhan.h:180
@ CHESS_FACTION_ALLIANCE
Definition: karazhan.h:181
@ CHESS_PHASE_NOT_STARTED
Definition: karazhan.h:169
@ CHESS_PHASE_PVE_FINISHED
Definition: karazhan.h:173
@ SPELL_GAME_IN_SESSION
Definition: karazhan.h:162
@ DATA_CHESS_GAME_PHASE
Definition: karazhan.h:68
@ DATA_DUST_COVERED_CHEST
Definition: karazhan.h:70
@ DATA_CHESS_EVENT
Definition: karazhan.h:39
@ DATA_CHESS_REINIT_PIECES
Definition: karazhan.h:67
void setDeathState(DeathState s, bool despawn=false) override
Definition: Creature.cpp:1934
uint32 GetEntry() const
Definition: Object.h:109
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:10401
void SetHealth(uint32 val)
Definition: Unit.cpp:15370
uint32 GetFaction() const
Definition: Unit.h:1495
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition: Unit.cpp:20148
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:1481
ObjectGuid GetGuidData(uint32 type) const override
Definition: InstanceScript.cpp:94
void DoRemoveAurasDueToSpellOnPlayers(uint32 spell)
Definition: InstanceScript.cpp:587
void DoRespawnGameObject(ObjectGuid guid, uint32 timeToDespawn=MINUTE)
Definition: InstanceScript.cpp:487
virtual void SetData(uint32, uint32)
Definition: ZoneScript.h:53
std::array< uint32, 2 > _deadCount
Definition: boss_chess_event.cpp:1420

References _boards, _deadCount, _instance, CHESS_EVENT_TEAM, CHESS_FACTION_ALLIANCE, CHESS_FACTION_HORDE, CHESS_PHASE_NOT_STARTED, CHESS_PHASE_PVE_FINISHED, Unit::CombatStop(), DATA_CHESS_EVENT, DATA_CHESS_GAME_PHASE, DATA_CHESS_REINIT_PIECES, DATA_DUST_COVERED_CHEST, DAY, DEAD_ALLIANCE, DEAD_HORDE, DONE, InstanceScript::DoRemoveAurasDueToSpellOnPlayers(), InstanceScript::DoRespawnGameObject(), ZoneScript::GetData(), Object::GetEntry(), Unit::GetFaction(), Object::GetGUID(), InstanceScript::GetGuidData(), Unit::GetMaxHealth(), IN_PROGRESS, JUST_RESPAWNED, MAX_COL, MAX_ROW, Unit::NearTeleportTo(), NOT_STARTED, NPC_BISHOP_A, NPC_BISHOP_H, NPC_KING_A, NPC_KING_H, NPC_KNIGHT_A, NPC_KNIGHT_H, NPC_QUEEN_A, NPC_QUEEN_H, NPC_ROOK_A, NPC_ROOK_H, ORI_NE, ORI_SW, orientations, ZoneScript::SetData(), Creature::setDeathState(), Unit::SetHealth(), Unit::SetUnitFlag(), SPECIAL, SPELL_GAME_IN_SESSION, TALK_EVENT_ENDED, TALK_MEDIVH_LOOSE_PAWN, TALK_PLAYER_LOOSE_PAWN, TEAM_ALLIANCE, TEAM_HORDE, and UNIT_FLAG_NOT_SELECTABLE.

◆ HandlePieceMove()

int8 npc_echo_of_medivh::HandlePieceMove ( Creature piece,
ObjectGuid const &  triggerGUID,
bool  moveByAI 
)
inline
855 {
856 bool foundProperCell = false;
857 bool foundOld = false;
858 bool foundNew = false;
859 int8 oldRow = MAX_ROW;
860 int8 oldCol = MAX_COL;
861 int8 newRow = -1;
862 int8 newCol = -1;
863
864 for (uint8 row = 0; row < MAX_ROW; ++row)
865 {
866 for (uint8 col = 0; col < MAX_COL; ++col)
867 {
868 BoardCell const& cell = _boards[row][col];
869 if (!foundNew)
870 {
871 if (cell.triggerGUID == triggerGUID)
872 {
873 //is there already a piece on this cell ?
874 if (cell.pieceGUID)
875 {
876 return -1;
877 }
878
879 newCol = col;
880 newRow = row;
881 foundProperCell = true;
882 foundNew = true;
883 }
884 }
885
886 if (!foundOld)
887 {
888 if (cell.pieceGUID == piece->GetGUID())
889 {
890 oldCol = col;
891 oldRow = row;
892 foundOld = true;
893 }
894 }
895
896 if (foundNew && foundOld)
897 {
898 break;
899 }
900 }
901
902 if (foundNew && foundOld)
903 {
904 break;
905 }
906 }
907
908 if (newCol == -1 || newRow == -1)
909 {
910 return -1;
911 }
912
913 if (!moveByAI && foundProperCell)
914 {
915 uint8 deltaRow = abs(oldRow - newRow);
916 uint8 deltaCol = abs(oldCol - newCol);
917
918 switch (piece->GetEntry())
919 {
920 case NPC_PAWN_H:
921 case NPC_PAWN_A:
922 case NPC_BISHOP_H:
923 case NPC_BISHOP_A:
924 case NPC_ROOK_H:
925 case NPC_ROOK_A:
926 case NPC_KING_H:
927 case NPC_KING_A:
928 if (deltaRow > 1 || deltaCol > 1)
929 {
930 foundProperCell = false;
931 }
932 break;
933 case NPC_QUEEN_H:
934 case NPC_QUEEN_A:
935 if (deltaRow > 3 || deltaCol > 3)
936 {
937 foundProperCell = false;
938 }
939 break;
940 case NPC_KNIGHT_H:
941 case NPC_KNIGHT_A:
942 if (deltaRow > 2 || deltaCol > 2)
943 {
944 foundProperCell = false;
945 }
946 break;
947 default:
948 break;
949 }
950 }
951
952 if (foundProperCell || moveByAI)
953 {
954 int8 orientation = HandlePieceRotate(piece, triggerGUID);
955 if (orientation != -1)
956 {
957 _boards[newRow][newCol].triggerGUID = triggerGUID;
958 _boards[newRow][newCol].SetPiece(piece);
959
960 if (oldRow != MAX_ROW && oldCol != MAX_COL)
961 {
962 _boards[oldRow][oldCol].Reset();
963 }
964 }
965
966 return orientation;
967 }
968
969 return -1;
970 }
std::int8_t int8
Definition: Define.h:106
int8 HandlePieceRotate(Creature *piece, ObjectGuid const &triggerGUID)
Definition: boss_chess_event.cpp:733

References _boards, Object::GetEntry(), Object::GetGUID(), HandlePieceRotate(), MAX_COL, MAX_ROW, NPC_BISHOP_A, NPC_BISHOP_H, NPC_KING_A, NPC_KING_H, NPC_KNIGHT_A, NPC_KNIGHT_H, NPC_PAWN_A, NPC_PAWN_H, NPC_QUEEN_A, NPC_QUEEN_H, NPC_ROOK_A, NPC_ROOK_H, BoardCell::pieceGUID, and BoardCell::triggerGUID.

◆ HandlePieceMoveByAI()

bool npc_echo_of_medivh::HandlePieceMoveByAI ( Creature piece,
KarazhanChessOrientationType  orientation 
)
inline

Change orientation at edges

Here we shouldn't be facing the edges of the board, check in the 4 first if statements

978 {
979 uint8 pieceRow = 0;
980 uint8 pieceCol = 0;
981 bool found = false;
982
983 for (uint8 row = 0; row < MAX_ROW; ++row)
984 {
985 for (uint8 col = 0; col < MAX_COL; ++col)
986 {
987 if (_boards[row][col].pieceGUID == piece->GetGUID())
988 {
989 pieceRow = row;
990 pieceCol = col;
991 found = true;
992 break;
993 }
994 }
995
996 if (found)
997 {
998 break;
999 }
1000 }
1001
1003 if (orientation == ORI_SE && pieceRow == 0)
1004 {
1005 if (Creature* trigger = ObjectAccessor::GetCreature(*me, _boards[pieceRow + 1][pieceCol].triggerGUID))
1006 {
1007 CastChangeFacing(piece, trigger);
1008 }
1009
1010 return true;
1011 }
1012 else if (orientation == ORI_NW && pieceRow == 7)
1013 {
1014 if (Creature* trigger = ObjectAccessor::GetCreature(*me, _boards[pieceRow - 1][pieceCol].triggerGUID))
1015 {
1016 CastChangeFacing(piece, trigger);
1017 }
1018
1019 return true;
1020 }
1021 else if (orientation == ORI_SW && pieceCol == 0)
1022 {
1023 if (Creature* trigger = ObjectAccessor::GetCreature(*me, _boards[pieceRow][pieceCol + 1].triggerGUID))
1024 {
1025 CastChangeFacing(piece, trigger);
1026 }
1027
1028 return true;
1029 }
1030 else if (orientation == ORI_NE && pieceCol == 7)
1031 {
1032 if (Creature* trigger = ObjectAccessor::GetCreature(*me, _boards[pieceRow][pieceCol - 1].triggerGUID))
1033 {
1034 CastChangeFacing(piece, trigger);
1035 }
1036
1037 return true;
1038 }
1039 else if (urand(0, 1)) // 50% chance to check for nearby enemies
1040 {
1041 if (Creature* target = GetHostileTargetForChangeFacing(piece, orientation))
1042 {
1043 CastChangeFacing(me, target);
1044 return true;
1045 }
1046 }
1047
1048 switch (orientation)
1049 {
1050 case ORI_W:
1051 case ORI_N:
1052 orientation = ORI_NW;
1053 break;
1054 case ORI_S:
1055 case ORI_E:
1056 orientation = ORI_SE;
1057 break;
1058 default:
1059 break;
1060 }
1061
1062 switch (orientation)
1063 {
1064 case ORI_SE:
1065 case ORI_NW:
1066 {
1067 int32 randomRow = (orientation == ORI_SE) ? pieceRow - 1 : pieceRow + 1;
1068 int32 randomCol = pieceCol;
1069 switch (urand(0, 2))
1070 {
1071 case 0:
1072 if ((me->GetEntry() == NPC_QUEEN_A || me->GetEntry() == NPC_QUEEN_H))
1073 {
1074 randomCol -= irand(1, 2);
1075 }
1076 else
1077 {
1078 randomCol -= 1;
1079 }
1080 break;
1081 case 1:
1082 if ((me->GetEntry() == NPC_QUEEN_A || me->GetEntry() == NPC_QUEEN_H))
1083 {
1084 randomCol += irand(1, 2);
1085 }
1086 else
1087 {
1088 randomCol += 1;
1089 }
1090 break;
1091 case 2:
1092 if ((me->GetEntry() == NPC_QUEEN_A || me->GetEntry() == NPC_QUEEN_H))
1093 {
1094 randomRow += (orientation == ORI_SE) ? irand(-2, 0) : irand(0, 2);
1095 }
1096 else if ((me->GetEntry() == NPC_KNIGHT_A || me->GetEntry() == NPC_KNIGHT_H) && urand(0, 1))
1097 {
1098 randomRow += (orientation == ORI_SE) ? -1 : 1;
1099 }
1100 break;
1101 }
1102
1103 randomRow = RoundToInterval(randomRow, 0, 7);
1104 randomCol = RoundToInterval(randomCol, 0, 7);
1105
1106 BoardCell const& cell = _boards[randomRow][randomCol];
1107 if (Creature* trigger = ObjectAccessor::GetCreature(*me, cell.triggerGUID))
1108 {
1109 if (!cell.pieceGUID)
1110 {
1111 piece->CastSpell(trigger, SPELL_MOVE_GENERIC, false);
1112 return true;
1113 }
1114 }
1115 break;
1116 }
1117 case ORI_SW:
1118 case ORI_NE:
1119 {
1120 int32 randomRow = pieceRow;
1121 int32 randomCol = orientation == ORI_SW ? pieceCol - 1 : pieceCol + 1;
1122 switch (urand(0, 2))
1123 {
1124 case 0:
1125 if ((me->GetEntry() == NPC_QUEEN_A || me->GetEntry() == NPC_QUEEN_H))
1126 {
1127 randomRow -= irand(1, 2);
1128 }
1129 else
1130 {
1131 randomRow -= 1;
1132 }
1133 break;
1134 case 1:
1135 if ((me->GetEntry() == NPC_QUEEN_A || me->GetEntry() == NPC_QUEEN_H))
1136 {
1137 randomRow += irand(1, 2);
1138 }
1139 else
1140 {
1141 randomRow += 1;
1142 }
1143 break;
1144 case 2:
1145 if ((me->GetEntry() == NPC_QUEEN_A || me->GetEntry() == NPC_QUEEN_H))
1146 {
1147 randomCol += (orientation == ORI_SW) ? irand(-2, 0) : irand(0, 2);
1148 }
1149 else if ((me->GetEntry() == NPC_KNIGHT_A || me->GetEntry() == NPC_KNIGHT_H) && urand(0, 1))
1150 {
1151 randomCol += (orientation == ORI_SW) ? -1 : 1;
1152 }
1153 break;
1154 }
1155
1156 randomRow = RoundToInterval(randomRow, 0, 7);
1157 randomCol = RoundToInterval(randomCol, 0, 7);
1158
1159 BoardCell const& cell = _boards[randomRow][randomCol];
1160 if (Creature* trigger = ObjectAccessor::GetCreature(*me, cell.triggerGUID))
1161 {
1162 if (!cell.pieceGUID)
1163 {
1164 piece->CastSpell(trigger, SPELL_MOVE_GENERIC, false);
1165 return true;
1166 }
1167 }
1168 break;
1169 }
1170 default:
1171 break;
1172 }
1173
1174 return false;
1175 }
std::int32_t int32
Definition: Define.h:104
int32 irand(int32 min, int32 max)
Definition: Random.cpp:37
T RoundToInterval(T &num, T floor, T ceil)
Definition: Util.h:79
@ SPELL_MOVE_GENERIC
Definition: boss_chess_event.cpp:50
void CastChangeFacing(Creature *piece, Creature *trigger)
Definition: boss_chess_event.cpp:972
Creature * GetHostileTargetForChangeFacing(Creature *piece, KarazhanChessOrientationType orientation)
Definition: boss_chess_event.cpp:394

References _boards, CastChangeFacing(), Unit::CastSpell(), ObjectAccessor::GetCreature(), Object::GetEntry(), Object::GetGUID(), GetHostileTargetForChangeFacing(), irand(), MAX_COL, MAX_ROW, ScriptedAI::me, NPC_KNIGHT_A, NPC_KNIGHT_H, NPC_QUEEN_A, NPC_QUEEN_H, ORI_E, ORI_N, ORI_NE, ORI_NW, ORI_S, ORI_SE, ORI_SW, ORI_W, BoardCell::pieceGUID, RoundToInterval(), SPELL_MOVE_GENERIC, BoardCell::triggerGUID, and urand().

◆ HandlePieceRotate()

int8 npc_echo_of_medivh::HandlePieceRotate ( Creature piece,
ObjectGuid const &  triggerGUID 
)
inline
734 {
735 bool foundOld = false;
736 bool foundNew = false;
737 int8 pieceRow = MAX_ROW;
738 int8 pieceCol = MAX_COL;
739 int8 targetRow = -1;
740 int8 targetCol = -1;
741
742 for (uint8 row = 0; row < MAX_ROW; ++row)
743 {
744 for (uint8 col = 0; col < MAX_COL; ++col)
745 {
746 BoardCell const& cell = _boards[row][col];
747 if (!foundNew && cell.triggerGUID == triggerGUID)
748 {
749 targetRow = row;
750 targetCol = col;
751 foundNew = true;
752 }
753
754 if (!foundOld && cell.pieceGUID == piece->GetGUID())
755 {
756 pieceRow = row;
757 pieceCol = col;
758 foundOld = true;
759 }
760
761 if (foundNew && foundOld)
762 {
763 break;
764 }
765 }
766
767 if (foundNew && foundOld)
768 {
769 break;
770 }
771 }
772
773 if (targetRow == -1 || targetCol == -1)
774 {
775 return -1;
776 }
777
778 int8 deltaRow = targetRow - pieceRow;
779 int8 deltaCol = targetCol - pieceCol;
780
781 if (!deltaRow && !deltaCol)
782 {
783 return -1;
784 }
785
786 switch (deltaRow)
787 {
788 case -3:
789 case -2:
790 case -1:
791 {
792 switch (deltaCol)
793 {
794 case -3:
795 case -2:
796 case -1:
797 return ORI_S;
798 case 0:
799 return ORI_SE;
800 case 1:
801 case 2:
802 case 3:
803 return ORI_E;
804 default:
805 break;
806 }
807 break;
808 }
809 case 0:
810 {
811 switch (deltaCol)
812 {
813 case -3:
814 case -2:
815 case -1:
816 return ORI_SW;
817 case 1:
818 case 2:
819 case 3:
820 return ORI_NE;
821 default:
822 break;
823 }
824 break;
825 }
826 case 1:
827 case 2:
828 case 3:
829 {
830 switch (deltaCol)
831 {
832 case -3:
833 case -2:
834 case -1:
835 return ORI_W;
836 case 0:
837 return ORI_NW;
838 case 1:
839 case 2:
840 case 3:
841 return ORI_N;
842 default:
843 break;
844 }
845 break;
846 }
847 default:
848 break;
849 }
850
851 return -1;
852 }

References _boards, Object::GetGUID(), MAX_COL, MAX_ROW, ORI_E, ORI_N, ORI_NE, ORI_NW, ORI_S, ORI_SE, ORI_SW, ORI_W, BoardCell::pieceGUID, and BoardCell::triggerGUID.

Referenced by HandlePieceMove().

◆ IsMedivhPiece()

bool npc_echo_of_medivh::IsMedivhPiece ( uint32  entry) const
inline
372 {
373 switch (entry)
374 {
375 case NPC_PAWN_H:
376 case NPC_KNIGHT_H:
377 case NPC_QUEEN_H:
378 case NPC_BISHOP_H:
379 case NPC_ROOK_H:
380 case NPC_KING_H:
382 case NPC_PAWN_A:
383 case NPC_KNIGHT_A:
384 case NPC_QUEEN_A:
385 case NPC_BISHOP_A:
386 case NPC_ROOK_A:
387 case NPC_KING_A:
389 }
390
391 return false;
392 }

References _instance, CHESS_EVENT_TEAM, ZoneScript::GetData(), NPC_BISHOP_A, NPC_BISHOP_H, NPC_KING_A, NPC_KING_H, NPC_KNIGHT_A, NPC_KNIGHT_H, NPC_PAWN_A, NPC_PAWN_H, NPC_QUEEN_A, NPC_QUEEN_H, NPC_ROOK_A, NPC_ROOK_H, TEAM_ALLIANCE, and TEAM_HORDE.

Referenced by HandleCheat().

◆ JustSummoned()

void npc_echo_of_medivh::JustSummoned ( Creature summon)
inlineoverridevirtual

Reimplemented from ScriptedAI.

215 {
216 _summons.Summon(summon);
217 }
void Summon(Creature const *summon)
Definition: ScriptedCreature.h:90

References _summons, and SummonList::Summon().

◆ RemoveCheats()

void npc_echo_of_medivh::RemoveCheats ( )
inline
225 {
226 // Buffs
227 for (uint8 row = 0; row < MAX_ROW; ++row)
228 {
229 for (uint8 col = 0; col < MAX_COL; ++col)
230 {
231 if (ObjectGuid guid = _boards[row][col].pieceGUID)
232 {
233 if (Creature* piece = ObjectAccessor::GetCreature(*me, guid))
234 {
235 piece->RemoveAurasDueToSpell(SPELL_HAND_OF_MEDIVH);
236 }
237 }
238 }
239 }
240 }
Definition: ObjectGuid.h:120

References _boards, ObjectAccessor::GetCreature(), MAX_COL, MAX_ROW, ScriptedAI::me, and SPELL_HAND_OF_MEDIVH.

◆ Reset()

void npc_echo_of_medivh::Reset ( )
inlineoverridevirtual

Reimplemented from ScriptedAI.

200 {
201 for (uint8 row = 0; row < MAX_ROW; ++row)
202 {
203 for (uint8 col = 0; col < MAX_COL; ++col)
204 {
205 _boards[row][col].Reset();
206 }
207 }
208
210
212 }
constexpr auto IN_MILLISECONDS
Definition: Common.h:62
void DespawnAll(uint32 delay=0)
Definition: ScriptedCreature.cpp:67
uint32 _cheatTimer
Definition: boss_chess_event.cpp:1421

References _boards, _cheatTimer, _summons, SummonList::DespawnAll(), IN_MILLISECONDS, MAX_COL, MAX_ROW, and urand().

◆ SetupBoard()

void npc_echo_of_medivh::SetupBoard ( )
inline
243 {
245
247
248 for (uint8 row = 0; row < MAX_ROW; ++row)
249 {
250 for (uint8 col = 0; col < MAX_COL; ++col)
251 {
252 BoardCell& cell = _boards[row][col];
253
254 if (Creature* trigger = me->SummonCreature(NPC_CHESS_MOVE_TRIGGER, (-11108.099609f + (3.49f * col) + (4.4f * row)), (-1872.910034f - (4.4f * col) + (3.45f * row)), 220.667f, 0, TEMPSUMMON_MANUAL_DESPAWN, 0))
255 {
256 cell.SetData(trigger->GetGUID(), row, col);
257 HandleCellInitialData(row, col, trigger, cell);
258 }
259 }
260 }
261
262 _deadCount.fill(0);
263 }
@ TEMPSUMMON_MANUAL_DESPAWN
Definition: Object.h:49
@ NPC_CHESS_MOVE_TRIGGER
Definition: boss_chess_event.cpp:66
TempSummon * SummonCreature(uint32 id, const Position &pos, TempSummonType spwtype=TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime=0, uint32 vehId=0, SummonPropertiesEntry const *properties=nullptr, bool visibleBySummonerOnly=false) const
Definition: Object.cpp:2318
void SetData(ObjectGuid _triggerGUID, uint8 _row, uint8 _col)
Definition: boss_chess_event.cpp:158
void HandleCellInitialData(uint8 row, uint8 col, Creature *trigger, BoardCell &cell)
Definition: boss_chess_event.cpp:265

References _boards, _deadCount, _instance, _summons, DATA_CHESS_REINIT_PIECES, SummonList::DespawnAll(), HandleCellInitialData(), MAX_COL, MAX_ROW, ScriptedAI::me, NPC_CHESS_MOVE_TRIGGER, BoardCell::SetData(), ZoneScript::SetData(), WorldObject::SummonCreature(), and TEMPSUMMON_MANUAL_DESPAWN.

Referenced by sGossipSelect().

◆ sGossipHello()

void npc_echo_of_medivh::sGossipHello ( Player player)
inlineoverridevirtual

Reimplemented from UnitAI.

1354 {
1356 switch (chessPhase)
1357 {
1359 AddGossipItemFor(player, GOSSIP_ICON_CHAT, "We want to play a game against you!", GOSSIP_SENDER_MAIN, MEDIVH_GOSSIP_START_PVE);
1360 break;
1363 AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Restart", GOSSIP_SENDER_MAIN, MEDIVH_GOSSIP_RESTART); // We want to player another game against you
1364 break;
1366 AddGossipItemFor(player, GOSSIP_ICON_CHAT, "PvP", GOSSIP_SENDER_MAIN, MEDIVH_GOSSIP_START_PVP); // We'd like to fight each other
1367 break;
1368 }
1369
1370 SendGossipMenuFor(player, player->GetGossipTextId(me), me->GetGUID());
1371 }
std::uint32_t uint32
Definition: Define.h:108
void SendGossipMenuFor(Player *player, uint32 npcTextID, ObjectGuid const guid)
Definition: ScriptedGossip.cpp:45
void AddGossipItemFor(Player *player, uint32 icon, std::string const &text, uint32 sender, uint32 action)
Definition: ScriptedGossip.cpp:28
@ GOSSIP_SENDER_MAIN
Definition: ScriptedGossip.h:70
@ GOSSIP_ICON_CHAT
Definition: GossipDef.h:60
@ MEDIVH_GOSSIP_RESTART
Definition: boss_chess_event.cpp:37
@ MEDIVH_GOSSIP_START_PVP
Definition: boss_chess_event.cpp:38
@ MEDIVH_GOSSIP_START_PVE
Definition: boss_chess_event.cpp:36
@ CHESS_PHASE_INPROGRESS_PVP
Definition: karazhan.h:175
@ CHESS_PHASE_INPROGRESS_PVE
Definition: karazhan.h:171
uint32 GetGossipTextId(uint32 menuId, WorldObject *source)
Definition: PlayerGossip.cpp:405

References _instance, AddGossipItemFor(), CHESS_PHASE_INPROGRESS_PVE, CHESS_PHASE_INPROGRESS_PVP, CHESS_PHASE_NOT_STARTED, CHESS_PHASE_PVE_FINISHED, DATA_CHESS_GAME_PHASE, ZoneScript::GetData(), Player::GetGossipTextId(), Object::GetGUID(), GOSSIP_ICON_CHAT, GOSSIP_SENDER_MAIN, ScriptedAI::me, MEDIVH_GOSSIP_RESTART, MEDIVH_GOSSIP_START_PVE, MEDIVH_GOSSIP_START_PVP, and SendGossipMenuFor().

◆ sGossipSelect()

void npc_echo_of_medivh::sGossipSelect ( Player player,
uint32  ,
uint32  gossipListId 
)
inlineoverridevirtual

Reimplemented from UnitAI.

1374 {
1376 _instance->SetData(CHESS_EVENT_TEAM, chessPhase < CHESS_PHASE_PVE_FINISHED ? player->GetTeamId() : TEAM_NEUTRAL);
1377
1378 CloseGossipMenuFor(player);
1379
1380 uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
1381 switch (action)
1382 {
1385 SetupBoard();
1388 break;
1392 _deadCount.fill(0);
1394 {
1397 }
1399 {
1402 }
1404 break;
1407 SetupBoard();
1410 break;
1411 default:
1412 break;
1413 }
1414 }
void CloseGossipMenuFor(Player *player)
Definition: ScriptedGossip.cpp:56
@ TALK_EVENT_BEGIN
Definition: boss_chess_event.cpp:122
@ CHESS_PHASE_FAILED
Definition: karazhan.h:172
@ CHESS_PHASE_PVE_WARMUP
Definition: karazhan.h:170
@ CHESS_PHASE_PVP_WARMUP
Definition: karazhan.h:174
@ TEAM_NEUTRAL
Definition: SharedDefines.h:734
TeamId GetTeamId(PvPTeamId teamId)
Definition: SharedDefines.h:3434
uint32 GetGossipOptionAction(uint32 selection) const
Definition: GossipDef.h:270
PlayerMenu * PlayerTalkClass
Definition: Player.h:2188
void SetupBoard()
Definition: boss_chess_event.cpp:242

References _deadCount, _instance, CHESS_EVENT_TEAM, CHESS_PHASE_FAILED, CHESS_PHASE_NOT_STARTED, CHESS_PHASE_PVE_FINISHED, CHESS_PHASE_PVE_WARMUP, CHESS_PHASE_PVP_WARMUP, CloseGossipMenuFor(), DATA_CHESS_EVENT, DATA_CHESS_GAME_PHASE, DATA_CHESS_REINIT_PIECES, DONE, InstanceScript::DoRemoveAurasDueToSpellOnPlayers(), ZoneScript::GetData(), PlayerMenu::GetGossipOptionAction(), GetTeamId(), IN_PROGRESS, MEDIVH_GOSSIP_RESTART, MEDIVH_GOSSIP_START_PVE, MEDIVH_GOSSIP_START_PVP, NOT_STARTED, Player::PlayerTalkClass, ZoneScript::SetData(), SetupBoard(), SPECIAL, SPELL_GAME_IN_SESSION, TALK_EVENT_BEGIN, and TEAM_NEUTRAL.

◆ SummonedCreatureDespawn()

void npc_echo_of_medivh::SummonedCreatureDespawn ( Creature summon)
inlineoverridevirtual

Reimplemented from ScriptedAI.

220 {
221 _summons.Despawn(summon);
222 }
void Despawn(Creature const *summon)
Definition: ScriptedCreature.h:91

References _summons, and SummonList::Despawn().

◆ UpdateAI()

void npc_echo_of_medivh::UpdateAI ( uint32  diff)
inlineoverridevirtual

Reimplemented from ScriptedAI.

1334 {
1336 if (chessPhase != CHESS_PHASE_INPROGRESS_PVE && chessPhase != CHESS_PHASE_INPROGRESS_PVP)
1337 return;
1338
1339 if (chessPhase == CHESS_PHASE_INPROGRESS_PVE)
1340 {
1341 if (_cheatTimer <= diff)
1342 {
1343 HandleCheat();
1344 _cheatTimer = urand(45000, 100000);
1345 }
1346 else
1347 {
1348 _cheatTimer -= diff;
1349 }
1350 }
1351 }
void HandleCheat()
Definition: boss_chess_event.cpp:1177

References _cheatTimer, _instance, CHESS_PHASE_INPROGRESS_PVE, CHESS_PHASE_INPROGRESS_PVP, DATA_CHESS_GAME_PHASE, ZoneScript::GetData(), HandleCheat(), and urand().

Member Data Documentation

◆ _boards

◆ _cheatTimer

uint32 npc_echo_of_medivh::_cheatTimer
private

Referenced by Reset(), and UpdateAI().

◆ _deadCount

std::array<uint32, 2> npc_echo_of_medivh::_deadCount
private

◆ _instance

◆ _summons

SummonList npc_echo_of_medivh::_summons
private