Skip to content

Commit

Permalink
[z1186] Imporvments gameevent creature morphing.
Browse files Browse the repository at this point in the history
* This is allow have more clean logic in feature work.
* Prevent modify static creature data.
* Table `game_event_model_equip` renamed to `game_event_creature_data`
* Table allow now store same creatures for different events, BUT
  expected that related events no active in same time.
* Added possibility switch entry at gameevent time.
  This let have diff factions/loot and etc for creatures.
* Added possibility cast spells at gameevent start/end.
  Exist some spells that expected casted to creature at gameevent start
  for model replace, and for animation in other cases.

Note: `game_event_creature_data`.`modelid` field posisble will removed soon in fowor related spell use.
      Ofc, when spells will implemented in core.

(based on master commit cedf1d2)
(based on master commit 36c0e42)
(based on master commit af25119)

(based on commit 43e4343)
  • Loading branch information
VladimirMangos committed Dec 31, 2010
1 parent 2cfff2f commit aa8b61d
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 143 deletions.
51 changes: 26 additions & 25 deletions sql/mangos.sql
Expand Up @@ -24,7 +24,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`required_z1159_s0566_01_mangos_mangos_string` bit(1) default NULL
`required_z1186_s0600_01_mangos_game_event_creature_data` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
/*!40101 SET character_set_client = @saved_cs_client */;

Expand Down Expand Up @@ -1579,51 +1579,52 @@ LOCK TABLES `game_event_creature` WRITE;
UNLOCK TABLES;

--
-- Table structure for table `game_event_gameobject`
-- Table structure for table `game_event_creature_data`
--

DROP TABLE IF EXISTS `game_event_gameobject`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `game_event_gameobject` (
`guid` int(10) unsigned NOT NULL,
`event` smallint(6) NOT NULL default '0' COMMENT 'Negatives value to remove during event and ignore pool grouping, positive value for spawn during event and if guid is part of pool then al pool memebers must be listed as part of event spawn.',
PRIMARY KEY (`guid`)
DROP TABLE IF EXISTS `game_event_creature_data`;
CREATE TABLE `game_event_creature_data` (
`guid` int(10) unsigned NOT NULL default '0',
`entry_id` mediumint(8) unsigned NOT NULL default '0',
`modelid` mediumint(8) unsigned NOT NULL default '0',
`equipment_id` mediumint(8) unsigned NOT NULL default '0',
`spell_start` mediumint(8) unsigned NOT NULL default '0',
`spell_end` mediumint(8) unsigned NOT NULL default '0',
`event` smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (`guid`,`event`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `game_event_gameobject`
-- Dumping data for table `game_event_creature_data`
--

LOCK TABLES `game_event_gameobject` WRITE;
/*!40000 ALTER TABLE `game_event_gameobject` DISABLE KEYS */;
/*!40000 ALTER TABLE `game_event_gameobject` ENABLE KEYS */;
LOCK TABLES `game_event_creature_data` WRITE;
/*!40000 ALTER TABLE `game_event_creature_data` DISABLE KEYS */;
/*!40000 ALTER TABLE `game_event_creature_data` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `game_event_model_equip`
-- Table structure for table `game_event_gameobject`
--

DROP TABLE IF EXISTS `game_event_model_equip`;
DROP TABLE IF EXISTS `game_event_gameobject`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `game_event_model_equip` (
`guid` int(10) unsigned NOT NULL DEFAULT '0',
`modelid` mediumint(8) unsigned NOT NULL DEFAULT '0',
`equipment_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
`event` smallint(5) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`guid`)
CREATE TABLE `game_event_gameobject` (
`guid` int(10) unsigned NOT NULL,
`event` smallint(6) NOT NULL default '0' COMMENT 'Negatives value to remove during event and ignore pool grouping, positive value for spawn during event and if guid is part of pool then al pool memebers must be listed as part of event spawn.',
PRIMARY KEY (`guid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `game_event_model_equip`
-- Dumping data for table `game_event_gameobject`
--

LOCK TABLES `game_event_model_equip` WRITE;
/*!40000 ALTER TABLE `game_event_model_equip` DISABLE KEYS */;
/*!40000 ALTER TABLE `game_event_model_equip` ENABLE KEYS */;
LOCK TABLES `game_event_gameobject` WRITE;
/*!40000 ALTER TABLE `game_event_gameobject` DISABLE KEYS */;
/*!40000 ALTER TABLE `game_event_gameobject` ENABLE KEYS */;
UNLOCK TABLES;

--
Expand Down
6 changes: 4 additions & 2 deletions sql/updates/Makefile.am
Expand Up @@ -188,7 +188,8 @@ pkgdata_DATA = \
z1135_s0540_02_characters_character_spell.sql \
z1135_xxxxx_03_mangos_playercreateinfo_spell.sql \
z1142_s0531_01_characters_bugreport.sql \
z1159_s0566_01_mangos_mangos_string.sql
z1159_s0566_01_mangos_mangos_string.sql \
z1186_s0600_01_mangos_game_event_creature_data.sql

## Additional files to include when running 'make dist'
# SQL update files, to upgrade database schema from older revisions
Expand Down Expand Up @@ -355,4 +356,5 @@ EXTRA_DIST = \
z1135_s0540_02_characters_character_spell.sql \
z1135_xxxxx_03_mangos_playercreateinfo_spell.sql \
z1142_s0531_01_characters_bugreport.sql \
z1159_s0566_01_mangos_mangos_string.sql
z1159_s0566_01_mangos_mangos_string.sql \
z1186_s0600_01_mangos_game_event_creature_data.sql
14 changes: 14 additions & 0 deletions sql/updates/z1186_s0600_01_mangos_game_event_creature_data.sql
@@ -0,0 +1,14 @@
ALTER TABLE db_version CHANGE COLUMN required_z1159_s0566_01_mangos_mangos_string required_z1186_s0600_01_mangos_game_event_creature_data bit;


DROP TABLE IF EXISTS game_event_creature_data;
RENAME TABLE game_event_model_equip TO game_event_creature_data;

ALTER TABLE game_event_creature_data
ADD COLUMN entry_id mediumint(8) unsigned NOT NULL default '0' AFTER guid,
ADD COLUMN spell_start mediumint(8) unsigned NOT NULL default '0' AFTER equipment_id,
ADD COLUMN spell_end mediumint(8) unsigned NOT NULL default '0' AFTER spell_start;

ALTER TABLE game_event_creature_data
DROP PRIMARY KEY,
ADD PRIMARY KEY (`guid`,`event`);
64 changes: 50 additions & 14 deletions src/game/Creature.cpp
Expand Up @@ -28,6 +28,7 @@
#include "QuestDef.h"
#include "GossipDef.h"
#include "Player.h"
#include "GameEventMgr.h"
#include "PoolManager.h"
#include "Opcodes.h"
#include "Log.h"
Expand Down Expand Up @@ -201,8 +202,12 @@ void Creature::RemoveCorpse()
/**
* change the entry of creature until respawn
*/
bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
bool Creature::InitEntry(uint32 Entry, uint32 team, CreatureData const* data /*=NULL*/, GameEventCreatureData const* eventData /*=NULL*/ )
{
// use game event entry if any instead default suggested
if (eventData && eventData->entry_id)
Entry = eventData->entry_id;

CreatureInfo const *normalInfo = ObjectMgr::GetCreatureTemplate(Entry);
if(!normalInfo)
{
Expand All @@ -223,7 +228,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
// known valid are: CLASS_WARRIOR,CLASS_PALADIN,CLASS_ROGUE,CLASS_MAGE
SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class));

uint32 display_id = ChooseDisplayId(GetCreatureInfo(), data);
uint32 display_id = ChooseDisplayId(GetCreatureInfo(), data, eventData);
if (!display_id) // Cancel load if no display id
{
sLog.outErrorDb("Creature (Entry: %u) has no model defined in table `creature_template`, can't load.", Entry);
Expand Down Expand Up @@ -254,7 +259,11 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);

// Load creature equipment
if(!data || data->equipmentId == 0)
if (eventData && eventData->equipment_id)
{
LoadEquipment(eventData->equipment_id); // use event equipment if any for active event
}
else if (!data || data->equipmentId == 0)
{ // use default from the template
LoadEquipment(cinfo->equipmentId);
}
Expand All @@ -277,9 +286,9 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data )
return true;
}

bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data, bool preserveHPAndPower)
bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data /*=NULL*/, GameEventCreatureData const* eventData /*=NULL*/, bool preserveHPAndPower /*=true*/)
{
if (!InitEntry(Entry, team, data))
if (!InitEntry(Entry, team, data, eventData))
return false;

m_regenHealth = GetCreatureInfo()->RegenHealth;
Expand Down Expand Up @@ -337,11 +346,19 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data,
for(int i = 0; i < CREATURE_MAX_SPELLS; ++i)
m_spells[i] = GetCreatureInfo()->spells[i];

// if eventData set then event active and need apply spell_start
if (eventData)
ApplyGameEventSpells(eventData, true);

return true;
}

uint32 Creature::ChooseDisplayId(const CreatureInfo *cinfo, const CreatureData *data /*= NULL*/)
uint32 Creature::ChooseDisplayId(const CreatureInfo *cinfo, const CreatureData *data /*= NULL*/, GameEventCreatureData const* eventData /*=NULL*/)
{
// Use creature event model explicit, override any other static models
if (eventData && eventData->modelid)
return eventData->modelid;

// Use creature model explicit, override template (creature.modelid)
if (data && data->modelid_override)
return data->modelid_override;
Expand Down Expand Up @@ -401,7 +418,11 @@ void Creature::Update(uint32 diff)
lootForSkin = false;

if(m_originalEntry != GetEntry())
UpdateEntry(m_originalEntry);
{
// need preserver gameevent state
GameEventCreatureData const* eventData = sGameEventMgr.GetCreatureUpdateDataForActiveEvent(GetDBTableGUIDLow());
UpdateEntry(m_originalEntry, 0, NULL, eventData);
}

CreatureInfo const *cinfo = GetCreatureInfo();

Expand Down Expand Up @@ -652,13 +673,13 @@ bool Creature::AIM_Initialize()
return true;
}

bool Creature::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data)
bool Creature::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data /*= NULL*/, GameEventCreatureData const* eventData /*= NULL*/)
{
MANGOS_ASSERT(map);
SetMap(map);

//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
const bool bResult = CreateFromProto(guidlow, Entry, team, data);
const bool bResult = CreateFromProto(guidlow, Entry, team, data, eventData);

if (bResult)
{
Expand Down Expand Up @@ -1126,7 +1147,7 @@ float Creature::GetSpellDamageMod(int32 Rank)
}
}

bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const CreatureData *data)
bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const CreatureData *data /*=NULL*/, GameEventCreatureData const* eventData /*=NULL*/)
{
CreatureInfo const *cinfo = ObjectMgr::GetCreatureTemplate(Entry);
if(!cinfo)
Expand All @@ -1138,7 +1159,7 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const

Object::_Create(guidlow, Entry, HIGHGUID_UNIT);

if (!UpdateEntry(Entry, team, data, false))
if (!UpdateEntry(Entry, team, data, eventData, false))
return false;

return true;
Expand All @@ -1154,6 +1175,8 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map)
return false;
}

GameEventCreatureData const* eventData = sGameEventMgr.GetCreatureUpdateDataForActiveEvent(guidlow);

m_DBTableGuid = guidlow;
if (map->GetInstanceId() == 0)
{
Expand All @@ -1167,8 +1190,7 @@ bool Creature::LoadFromDB(uint32 guidlow, Map *map)
else
guidlow = sObjectMgr.GenerateLowGuid(HIGHGUID_UNIT);

uint16 team = 0;
if (!Create(guidlow, map, data->id, team, data))
if (!Create(guidlow, map, data->id, 0, data, eventData))
return false;

Relocate(data->posX, data->posY, data->posZ, data->orientation);
Expand Down Expand Up @@ -1290,7 +1312,7 @@ void Creature::DeleteFromDB()
WorldDatabase.PExecuteLog("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM creature_movement WHERE id = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM game_event_creature_data WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecuteLog("DELETE FROM creature_battleground WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.CommitTransaction();
}
Expand Down Expand Up @@ -2261,3 +2283,17 @@ void Creature::RelocationNotify()
float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO);
Cell::VisitAllObjects(this, relocationNotifier, radius);
}

void Creature::ApplyGameEventSpells(GameEventCreatureData const* eventData, bool activated)
{
uint32 cast_spell = activated ? eventData->spell_id_start : eventData->spell_id_end;
uint32 remove_spell = activated ? eventData->spell_id_end : eventData->spell_id_start;

if (remove_spell)
if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(remove_spell))
if (IsSpellAppliesAura(spellEntry))
RemoveAurasDueToSpell(remove_spell);

if (cast_spell)
CastSpell(this, cast_spell, true);
}
14 changes: 9 additions & 5 deletions src/game/Creature.h
Expand Up @@ -39,6 +39,8 @@ class Quest;
class Player;
class WorldSession;

struct GameEventCreatureData;

enum CreatureFlagsExtra
{
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
Expand Down Expand Up @@ -367,7 +369,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
void AddToWorld();
void RemoveFromWorld();

bool Create(uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data = NULL);
bool Create(uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data = NULL, GameEventCreatureData const* eventData = NULL);
bool LoadCreatureAddon(bool reload = false);
void SelectLevel(const CreatureInfo *cinfo, float percentHealth = 100.0f, float percentMana = 100.0f);
void LoadEquipment(uint32 equip_entry, bool force=false);
Expand Down Expand Up @@ -468,7 +470,9 @@ class MANGOS_DLL_SPEC Creature : public Unit

bool HasSpell(uint32 spellID) const;

bool UpdateEntry(uint32 entry, uint32 team = ALLIANCE, const CreatureData* data = NULL, bool preserveHPAndPower = true);
bool UpdateEntry(uint32 entry, uint32 team = ALLIANCE, const CreatureData* data = NULL, GameEventCreatureData const* eventData = NULL, bool preserveHPAndPower = true);

void ApplyGameEventSpells(GameEventCreatureData const* eventData, bool activated);
bool UpdateStats(Stats stat);
bool UpdateAllStats();
void UpdateResistances(uint32 school);
Expand All @@ -491,7 +495,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
CreatureDataAddon const* GetCreatureAddon() const;

static uint32 ChooseDisplayId(const CreatureInfo *cinfo, const CreatureData *data = NULL);
static uint32 ChooseDisplayId(const CreatureInfo *cinfo, const CreatureData *data = NULL, GameEventCreatureData const* eventData = NULL);

std::string GetAIName() const;
std::string GetScriptName() const;
Expand Down Expand Up @@ -608,8 +612,8 @@ class MANGOS_DLL_SPEC Creature : public Unit
void SendAreaSpiritHealerQueryOpcode(Player *pl);

protected:
bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL, GameEventCreatureData const* eventData =NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data = NULL, GameEventCreatureData const* eventData = NULL);
void RelocationNotify();

uint32 m_groupLootTimer; // (msecs)timer used for group loot
Expand Down

0 comments on commit aa8b61d

Please sign in to comment.