[11316] Implement a basic system to restore default faction for creatures after changes

A new specialized function SetFactionTemporary for creatures are added. It work just like setFaction but has in addition option to set flags.
The flags determine if default faction should be restored and when; most commonly just before respawn and when reaching home after evade.

SCRIPT_COMMAND_SET_FACTION for DB scripts and ACTION_T_SET_FACTION for creature_ai_scripts are now capable of using the system (documentation updated)

The intention of the system is to be able to solve basic events that include faction changes, with the use of database only and in easier ways.

It is advised that DB devs revise current database scripts to check if changes should be made. The same goes for EventAI devs regarding ACTION_T_SET_FACTION.

Signed-off-by: NoFantasy <nofantasy@nf.no>
This commit is contained in:
NoFantasy 2011-04-05 15:03:25 +02:00
parent 0ceb42ff9a
commit 889ce13264
11 changed files with 71 additions and 16 deletions

View file

@ -105,7 +105,7 @@ For all ACTION_T_RANDOM, When a Particular Param is selected for the Event... Th
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 ACTION_T_NONE No Action Does nothing. 0 ACTION_T_NONE No Action Does nothing.
1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Simply displays the specified -TextId. When -TextId2 and -TextId3 are specified, the selection will be randomized. Text types are defined, along with other options for the text, in a table below. All values needs to be negative. 1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Simply displays the specified -TextId. When -TextId2 and -TextId3 are specified, the selection will be randomized. Text types are defined, along with other options for the text, in a table below. All values needs to be negative.
2 ACTION_T_SET_FACTION FactionId Changes faction for a creature. When param1 is zero, creature will revert to it's default faction. 2 ACTION_T_SET_FACTION FactionId, Flags Changes faction for a creature. When param1 is zero, creature will revert to it's default faction. Flags will determine when faction is restored to default (evade, respawn etc)
3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set either model from creature_template.entry (Param1) OR explicit modelId (Param2). If (Param1) AND (Param2) are both 0, demorph and revert to the default model. 3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set either model from creature_template.entry (Param1) OR explicit modelId (Param2). If (Param1) AND (Param2) are both 0, demorph and revert to the default model.
4 ACTION_T_SOUND SoundId Plays a sound 4 ACTION_T_SOUND SoundId Plays a sound
5 ACTION_T_EMOTE EmoteId Does an emote 5 ACTION_T_EMOTE EmoteId Does an emote
@ -430,6 +430,11 @@ Read at bottom for documentation of creature_ai_texts-table.
2 = ACTION_T_SET_FACTION: 2 = ACTION_T_SET_FACTION:
------------------ ------------------
Parameter 1: FactionId from Faction.dbc OR 0. Changes faction for creature. If 0, creature will revert to it's default faction if previously changed. Parameter 1: FactionId from Faction.dbc OR 0. Changes faction for creature. If 0, creature will revert to it's default faction if previously changed.
Parameter 2: When Parameter 1 is not 0, flags can be used to restore default faction at certain events. Current supported, from enum TemporaryFactionFlags:
TEMPFACTION_NONE = 0x00, // A persistent faction change and will require manual change to default/another faction when changed once
TEMPFACTION_RESTORE_RESPAWN = 0x01, // Default faction will be restored at respawn
TEMPFACTION_RESTORE_COMBAT_STOP = 0x02, // ... at CombatStop() (happens at creature death, at evade or custom scripte among others)
TEMPFACTION_RESTORE_REACH_HOME = 0x04, // ... at reaching home in home movement (evade), if not already done at CombatStop()
----------------------- -----------------------
3 = ACTION_T_MORPH_TO_ENTRY_OR_MODEL: 3 = ACTION_T_MORPH_TO_ENTRY_OR_MODEL:

View file

@ -190,6 +190,11 @@ spell_scripts
* datalong=factionId OR 0 to restore original faction from creature_template * datalong=factionId OR 0 to restore original faction from creature_template
* datalong2=creature entry * datalong2=creature entry
* datalong3=search radius * datalong3=search radius
* data_flags = enum TemporaryFactionFlags
TEMPFACTION_NONE = 0x00, // When no flag is used in temporary faction change, faction will be persistent. It will then require manual change back to default/another faction when changed once
TEMPFACTION_RESTORE_RESPAWN = 0x01, // Default faction will be restored at respawn
TEMPFACTION_RESTORE_COMBAT_STOP = 0x02, // ... at CombatStop() (happens at creature death, at evade or custom scripte among others)
TEMPFACTION_RESTORE_REACH_HOME = 0x04, // ... at reaching home in home movement (evade), if not already done at CombatStop()
23 SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL source=worldobject, target=creature 23 SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL source=worldobject, target=creature
* datalong=creature entry/modelid (depend on data_flags) OR 0 to demorph * datalong=creature entry/modelid (depend on data_flags) OR 0 to demorph

View file

@ -155,7 +155,7 @@ m_corpseDecayTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60),
m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0), m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_temporaryFactionFlags(TEMPFACTION_NONE),
m_creatureInfo(NULL), m_splineFlags(SPLINEFLAG_WALKMODE) m_creatureInfo(NULL), m_splineFlags(SPLINEFLAG_WALKMODE)
{ {
m_regenTimer = 200; m_regenTimer = 200;
@ -1477,7 +1477,12 @@ void Creature::SetDeathState(DeathState s)
RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
AddSplineFlag(SPLINEFLAG_WALKMODE); AddSplineFlag(SPLINEFLAG_WALKMODE);
SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag); SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag);
if (GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_RESPAWN)
ClearTemporaryFaction();
Unit::SetDeathState(ALIVE); Unit::SetDeathState(ALIVE);
clearUnitState(UNIT_STAT_ALL_STATE); clearUnitState(UNIT_STAT_ALL_STATE);
i_motionMaster.Clear(); i_motionMaster.Clear();
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
@ -2316,6 +2321,24 @@ const char* Creature::GetNameForLocaleIdx(int32 loc_idx) const
return GetName(); return GetName();
} }
void Creature::SetFactionTemporary(uint32 factionId, uint32 tempFactionFlags)
{
m_temporaryFactionFlags = tempFactionFlags;
setFaction(factionId);
}
void Creature::ClearTemporaryFaction()
{
// No restore if creature is charmed/possessed.
// For later we may consider extend to restore to charmer faction where charmer is creature.
// This can also be done by update any pet/charmed of creature at any faction change to charmer.
if (isCharmed())
return;
m_temporaryFactionFlags = TEMPFACTION_NONE;
setFaction(GetCreatureInfo()->faction_A);
}
void Creature::SetActiveObjectState( bool on ) void Creature::SetActiveObjectState( bool on )
{ {
if(m_isActiveObject==on) if(m_isActiveObject==on)

View file

@ -422,6 +422,15 @@ enum CreatureSubtype
CREATURE_SUBTYPE_TEMPORARY_SUMMON, // new TemporarySummon CREATURE_SUBTYPE_TEMPORARY_SUMMON, // new TemporarySummon
}; };
enum TemporaryFactionFlags // Used at real faction changes
{
TEMPFACTION_NONE = 0x00, // When no flag is used in temporary faction change, faction will be persistent. It will then require manual change back to default/another faction when changed once
TEMPFACTION_RESTORE_RESPAWN = 0x01, // Default faction will be restored at respawn
TEMPFACTION_RESTORE_COMBAT_STOP = 0x02, // ... at CombatStop() (happens at creature death, at evade or custom scripte among others)
TEMPFACTION_RESTORE_REACH_HOME = 0x04, // ... at reaching home in home movement (evade), if not already done at CombatStop()
TEMPFACTION_ALL,
};
class MANGOS_DLL_SPEC Creature : public Unit class MANGOS_DLL_SPEC Creature : public Unit
{ {
CreatureAI *i_AI; CreatureAI *i_AI;
@ -681,6 +690,10 @@ class MANGOS_DLL_SPEC Creature : public Unit
void SetActiveObjectState(bool on); void SetActiveObjectState(bool on);
void SetFactionTemporary(uint32 factionId, uint32 tempFactionFlags = TEMPFACTION_ALL);
void ClearTemporaryFaction();
uint32 GetTemporaryFactionFlags() { return m_temporaryFactionFlags; }
void SendAreaSpiritHealerQueryOpcode(Player *pl); void SendAreaSpiritHealerQueryOpcode(Player *pl);
void SetVirtualItem(VirtualItemSlot slot, uint32 item_id) { SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot, item_id); } void SetVirtualItem(VirtualItemSlot slot, uint32 item_id) { SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + slot, item_id); }
@ -719,11 +732,13 @@ class MANGOS_DLL_SPEC Creature : public Unit
Cell m_currentCell; // store current cell where creature listed Cell m_currentCell; // store current cell where creature listed
uint32 m_equipmentId; uint32 m_equipmentId;
// below fields has potential for optimization
bool m_AlreadyCallAssistance; bool m_AlreadyCallAssistance;
bool m_AlreadySearchedAssistance; bool m_AlreadySearchedAssistance;
bool m_regenHealth; bool m_regenHealth;
bool m_AI_locked; bool m_AI_locked;
bool m_isDeadByDefault; bool m_isDeadByDefault;
uint32 m_temporaryFactionFlags; // used for real faction changes (not auras etc)
SpellSchoolMask m_meleeDamageSchoolMask; SpellSchoolMask m_meleeDamageSchoolMask;
uint32 m_originalEntry; uint32 m_originalEntry;

View file

@ -457,16 +457,10 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
case ACTION_T_SET_FACTION: case ACTION_T_SET_FACTION:
{ {
if (action.set_faction.factionId) if (action.set_faction.factionId)
m_creature->setFaction(action.set_faction.factionId); m_creature->SetFactionTemporary(action.set_faction.factionId, action.set_faction.factionFlags);
else else // no id provided, assume reset and then use default
{ m_creature->ClearTemporaryFaction();
if (CreatureInfo const* ci = ObjectMgr::GetCreatureTemplate(m_creature->GetEntry()))
{
//if no id provided, assume reset and then use default
if (m_creature->getFaction() != ci->faction_A)
m_creature->setFaction(ci->faction_A);
}
}
break; break;
} }
case ACTION_T_MORPH_TO_ENTRY_OR_MODEL: case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:

View file

@ -187,7 +187,8 @@ struct CreatureEventAI_Action
// ACTION_T_SET_FACTION = 2 // ACTION_T_SET_FACTION = 2
struct struct
{ {
uint32 factionId; // faction or 0 for default) uint32 factionId; // faction id or 0 to restore default faction
uint32 factionFlags; // flags will restore default faction at evade and/or respawn
} set_faction; } set_faction;
// ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3 // ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3
struct struct

View file

@ -80,6 +80,9 @@ HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff
} }
} }
if (owner.GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_REACH_HOME)
owner.ClearTemporaryFaction();
owner.LoadCreatureAddon(true); owner.LoadCreatureAddon(true);
owner.AI()->JustReachedHome(); owner.AI()->JustReachedHome();
return false; return false;

View file

@ -2683,9 +2683,9 @@ void Map::ScriptsProcess()
} }
if (step.script->faction.factionId) if (step.script->faction.factionId)
pOwner->setFaction(step.script->faction.factionId); pOwner->SetFactionTemporary(step.script->faction.factionId, step.script->faction.flags);
else else
pOwner->setFaction(pOwner->GetCreatureInfo()->faction_A); pOwner->ClearTemporaryFaction();
break; break;
} }

View file

@ -246,6 +246,8 @@ struct ScriptInfo
uint32 factionId; // datalong uint32 factionId; // datalong
uint32 creatureEntry; // datalong2 uint32 creatureEntry; // datalong2
uint32 searchRadius; // datalong3 uint32 searchRadius; // datalong3
uint32 empty1; // datalong4
uint32 flags; // data_flags
} faction; } faction;
struct // SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL (23) struct // SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL (23)

View file

@ -5713,8 +5713,15 @@ void Unit::CombatStop(bool includingCast)
AttackStop(); AttackStop();
RemoveAllAttackers(); RemoveAllAttackers();
if( GetTypeId()==TYPEID_PLAYER ) if( GetTypeId()==TYPEID_PLAYER )
((Player*)this)->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel ((Player*)this)->SendAttackSwingCancelAttack(); // melee and ranged forced attack cancel
else if (GetTypeId() == TYPEID_UNIT)
{
if (((Creature*)this)->GetTemporaryFactionFlags() & TEMPFACTION_RESTORE_COMBAT_STOP)
((Creature*)this)->ClearTemporaryFaction();
}
ClearInCombat(); ClearInCombat();
} }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11315" #define REVISION_NR "11316"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__