From e56b671979623570acd358a9b99aa169be22ffba Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 31 Oct 2008 20:45:22 +0300 Subject: [PATCH] [2008_10_31_01_mangos_creature_template.sql] Creature related code and DB cleanups. * Rename 2 creature_template fields to more clean names and related code update also. * Use enum values instead raw values for type_flags, use halper functions instead code repeating. * Move tamed pet creating code to new function. --- sql/mangos.sql | 4 +- .../2008_10_31_01_mangos_creature_template.sql | 5 ++ sql/updates/Makefile.am | 2 + src/game/Creature.cpp | 2 +- src/game/Creature.h | 24 ++++++-- src/game/QueryHandler.cpp | 2 +- src/game/SharedDefines.h | 7 +++ src/game/Spell.cpp | 14 +---- src/game/SpellEffects.cpp | 72 +++++++--------------- src/game/Unit.cpp | 31 ++++++++++ src/game/Unit.h | 2 + 11 files changed, 96 insertions(+), 69 deletions(-) create mode 100644 sql/updates/2008_10_31_01_mangos_creature_template.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index c2331be..96ccd89 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -711,7 +711,7 @@ CREATE TABLE `creature_template` ( `attackpower` int(10) unsigned NOT NULL default '0', `baseattacktime` int(10) unsigned NOT NULL default '0', `rangeattacktime` int(10) unsigned NOT NULL default '0', - `flags` int(10) unsigned NOT NULL default '0', + `unit_flags` int(10) unsigned NOT NULL default '0', `dynamicflags` int(10) unsigned NOT NULL default '0', `family` tinyint(4) NOT NULL default '0', `trainer_type` tinyint(4) NOT NULL default '0', @@ -722,7 +722,7 @@ CREATE TABLE `creature_template` ( `maxrangedmg` float NOT NULL default '0', `rangedattackpower` smallint(5) unsigned NOT NULL default '0', `type` tinyint(3) unsigned NOT NULL default '0', - `flag1` int(10) unsigned NOT NULL default '0', + `type_flags` int(10) unsigned NOT NULL default '0', `lootid` mediumint(8) unsigned NOT NULL default '0', `pickpocketloot` mediumint(8) unsigned NOT NULL default '0', `skinloot` mediumint(8) unsigned NOT NULL default '0', diff --git a/sql/updates/2008_10_31_01_mangos_creature_template.sql b/sql/updates/2008_10_31_01_mangos_creature_template.sql new file mode 100644 index 0000000..fb51f3e --- /dev/null +++ b/sql/updates/2008_10_31_01_mangos_creature_template.sql @@ -0,0 +1,5 @@ +ALTER TABLE db_version CHANGE COLUMN required_2008_10_29_05_mangos_command required_2008_10_31_01_mangos_creature_template bit; + +ALTER TABLE `creature_template` + CHANGE COLUMN `flags` `unit_flags` int(10) unsigned NOT NULL default '0', + CHANGE COLUMN `flag1` `type_flags` int(10) unsigned NOT NULL default '0'; diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 519b150..55dec2c 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -118,6 +118,7 @@ pkgdata_DATA = \ 2008_10_29_03_mangos_db_version.sql \ 2008_10_29_04_mangos_mangos_string.sql \ 2008_10_29_05_mangos_command.sql \ + 2008_10_31_01_mangos_creature_template.sql \ README ## Additional files to include when running 'make dist' @@ -217,4 +218,5 @@ EXTRA_DIST = \ 2008_10_29_03_mangos_db_version.sql \ 2008_10_29_04_mangos_mangos_string.sql \ 2008_10_29_05_mangos_command.sql \ + 2008_10_31_01_mangos_creature_template.sql \ README diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 0700077..ce5d9f7 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -258,7 +258,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) SetAttackTime(OFF_ATTACK, GetCreatureInfo()->baseattacktime); SetAttackTime(RANGED_ATTACK,GetCreatureInfo()->rangeattacktime); - SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->Flags); + SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->unit_flags); SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor)); diff --git a/src/game/Creature.h b/src/game/Creature.h index f8b9a96..eae23ff 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -165,9 +165,9 @@ struct CreatureInfo uint32 attackpower; uint32 baseattacktime; uint32 rangeattacktime; - uint32 Flags; + uint32 unit_flags; // enum UnitFlags mask values uint32 dynamicflags; - uint32 family; + uint32 family; // enum CreatureFamily values for type==CREATURE_TYPE_BEAST, or 0 in another cases uint32 trainer_type; uint32 trainer_spell; uint32 classNum; @@ -175,8 +175,8 @@ struct CreatureInfo float minrangedmg; float maxrangedmg; uint32 rangedattackpower; - uint32 type; - uint32 flag1; + uint32 type; // enum CreatureType values + uint32 type_flags; // enum CreatureTypeFlags mask values uint32 lootid; uint32 pickpocketLootId; uint32 SkinLootId; @@ -202,6 +202,22 @@ struct CreatureInfo uint32 MechanicImmuneMask; uint32 flags_extra; char const* ScriptName; + + // helpers + SkillType GetRequiredLootSkill() const + { + if(type_flags & CREATURE_TYPEFLAGS_HERBLOOT) + return SKILL_HERBALISM; + else if(type_flags & CREATURE_TYPEFLAGS_MININGLOOT) + return SKILL_MINING; + else + return SKILL_SKINNING; // normal case + } + + bool isTameable() const + { + return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEBLE); + } }; struct CreatureLocale diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp index 9dc17bc..713338c 100644 --- a/src/game/QueryHandler.cpp +++ b/src/game/QueryHandler.cpp @@ -179,7 +179,7 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 - data << (uint32)ci->flag1; // flags wdbFeild7=wad flags1 + data << (uint32)ci->type_flags; // flags wdbFeild7=wad flags1 data << (uint32)ci->type; data << (uint32)ci->family; // family wdbFeild9 data << (uint32)ci->rank; // rank wdbFeild10 diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 34e3eb1..817ae81 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1531,6 +1531,13 @@ enum CreatureFamily CREATURE_FAMILY_SEA_LION = 36 }; +enum CreatureTypeFlags +{ + CREATURE_TYPEFLAGS_TAMEBLE = 0x0001, + CREATURE_TYPEFLAGS_HERBLOOT = 0x0100, + CREATURE_TYPEFLAGS_MININGLOOT = 0x0200, +}; + enum CreatureEliteType { CREATURE_ELITE_NORMAL = 0, diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 544432d..982d5b0 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3517,12 +3517,8 @@ uint8 Spell::CanCast(bool strict) if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel()) return SPELL_FAILED_HIGHLEVEL; - CreatureInfo const *cinfo = ((Creature*)m_targets.getUnitTarget())->GetCreatureInfo(); - if( cinfo->type != CREATURE_TYPE_BEAST ) - return SPELL_FAILED_BAD_TARGETS; - // use SMSG_PET_TAME_FAILURE? - if( !(cinfo->flag1 & 1) || !(cinfo->family) ) + if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ()) return SPELL_FAILED_BAD_TARGETS; if(m_caster->GetPetGUID()) @@ -3634,13 +3630,7 @@ uint8 Spell::CanCast(bool strict) return SPELL_FAILED_TARGET_NOT_LOOTED; } - uint32 skill; - if(creature->GetCreatureInfo()->flag1 & 256) - skill = SKILL_HERBALISM; // special case - else if(creature->GetCreatureInfo()->flag1 & 512) - skill = SKILL_MINING; // special case - else - skill = SKILL_SKINNING; // normal case + uint32 skill = creature->GetCreatureInfo()->GetRequiredLootSkill(); int32 skillValue = ((Player*)m_caster)->GetSkillValue(skill); int32 TargetLevel = m_targets.getUnitTarget()->getLevel(); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e711143..5077d87 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -3884,56 +3884,36 @@ void Spell::EffectTameCreature(uint32 /*i*/) if(creatureTarget->isPet()) return; - if(m_caster->getClass() == CLASS_HUNTER) - { - // cast finish successfully - //SendChannelUpdate(0); - finish(); + if(m_caster->getClass() != CLASS_HUNTER) + return; - Pet* pet = new Pet(HUNTER_PET); + // cast finish successfully + //SendChannelUpdate(0); + finish(); - if(!pet->CreateBaseAtCreature(creatureTarget)) - { - delete pet; - return; - } + Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget,m_spellInfo->Id); - creatureTarget->setDeathState(JUST_DIED); - creatureTarget->RemoveCorpse(); - creatureTarget->SetHealth(0); // just for nice GM-mode view + // kill original creature + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view - pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, m_caster->GetGUID()); - pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID()); - pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_caster->getFaction()); - pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); - if(!pet->InitStatsForLevel(creatureTarget->getLevel())) - { - sLog.outError("ERROR: InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); - delete pet; - return; - } + // add to world + MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet); - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); - pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); - // this enables pet details window (Shift+P) - pet->AIM_Initialize(); - pet->InitPetCreateSpells(); - pet->SetHealth(pet->GetMaxHealth()); + // caster have pet now + m_caster->SetPet(pet); - MapManager::Instance().GetMap(pet->GetMapId(), pet)->Add((Creature*)pet); - - // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); - - if(m_caster->GetTypeId() == TYPEID_PLAYER) - { - m_caster->SetPet(pet); - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - ((Player*)m_caster)->PetSpellInitialize(); - } + if(m_caster->GetTypeId() == TYPEID_PLAYER) + { + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + ((Player*)m_caster)->PetSpellInitialize(); } } @@ -5537,13 +5517,7 @@ void Spell::EffectSkinning(uint32 /*i*/) Creature* creature = (Creature*) unitTarget; int32 targetLevel = creature->getLevel(); - uint32 skill; - if(creature->GetCreatureInfo()->flag1 & 256) - skill = SKILL_HERBALISM; // special case - else if(creature->GetCreatureInfo()->flag1 & 512) - skill = SKILL_MINING; // special case - else - skill = SKILL_SKINNING; // normal case + uint32 skill = creature->GetCreatureInfo()->GetRequiredLootSkill(); ((Player*)m_caster)->SendLoot(creature->GetGUID(),LOOT_SKINNING); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index aaf107d..4a247da 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10817,3 +10817,34 @@ void Unit::RemovePetAura(PetAura const* petSpell) if(Pet* pet = GetPet()) pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry())); } + +Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id) +{ + Pet* pet = new Pet(HUNTER_PET); + + if(!pet->CreateBaseAtCreature(creatureTarget)) + { + delete pet; + return NULL; + } + + pet->SetUInt64Value(UNIT_FIELD_SUMMONEDBY, this->GetGUID()); + pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, this->GetGUID()); + pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,this->getFaction()); + pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); + + if(!pet->InitStatsForLevel(creatureTarget->getLevel())) + { + sLog.outError("ERROR: Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry()); + delete pet; + return NULL; + } + + pet->GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); + // this enables pet details window (Shift+P) + pet->AIM_Initialize(); + pet->InitPetCreateSpells(); + pet->SetHealth(pet->GetMaxHealth()); + + return pet; +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 99d6b61..ee5b94b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -985,6 +985,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject CharmInfo* GetCharmInfo() { return m_charmInfo; } CharmInfo* InitCharmInfo(Unit* charm); + Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); + bool AddAura(Aura *aur); void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); -- 2.11.4.GIT