[svn] * Little fix in RandomMovementGenerator

* Updated to 6731 and 680

--HG--
branch : trunk
rename : 6721-676 => 6731-680
This commit is contained in:
Neo2003 committed 2008-10-06 04:48:59 -05:00
1 parent 010ed993e1
commit 1fc5c0d6d7
49 files changed
+7104 -6884

No files matched your search

View File
File renamed without changes.
+2
View File
@@ -2338,6 +2338,7 @@ INSERT INTO `mangos_string` VALUES
(328,'Characters at account %s (Id: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (328,'Characters at account %s (Id: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(329,' %s (GUID %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (329,' %s (GUID %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(330,'No players found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (330,'No players found!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(331,'Extended item cost %u not exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (400,'|cffff0000[System Message]:|rScripts reloaded',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(401,'You change security level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (401,'You change security level of %s to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (402,'%s changed your security level to %i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
@@ -10485,6 +10486,7 @@ UNLOCK TABLES;
DROP TABLE IF EXISTS `quest_template`; DROP TABLE IF EXISTS `quest_template`;
CREATE TABLE `quest_template` ( CREATE TABLE `quest_template` (
`entry` mediumint(8) unsigned NOT NULL default '0', `entry` mediumint(8) unsigned NOT NULL default '0',
`Method` tinyint(3) unsigned NOT NULL default '2',
`ZoneOrSort` smallint(6) NOT NULL default '0', `ZoneOrSort` smallint(6) NOT NULL default '0',
`SkillOrClass` smallint(6) NOT NULL default '0', `SkillOrClass` smallint(6) NOT NULL default '0',
`MinLevel` tinyint(3) unsigned NOT NULL default '0', `MinLevel` tinyint(3) unsigned NOT NULL default '0',
+4
View File
@@ -0,0 +1,4 @@
ALTER TABLE `quest_template` ADD COLUMN `Method` tinyint(3) unsigned NOT NULL default '2' AFTER `entry`;
DELETE FROM mangos_string WHERE entry IN (331);
INSERT INTO mangos_string VALUES
(331,'Extended item cost %u not exist',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
File diff suppressed because it is too large. Load diff
+4 -4
View File
@@ -35,8 +35,8 @@ void ScriptedAI::MoveInLineOfSight(Unit *who)
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -54,8 +54,8 @@ void ScriptedAI::AttackStart(Unit* who)
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -582,8 +582,8 @@ void Scripted_NoMovementAI::MoveInLineOfSight(Unit *who)
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -601,8 +601,8 @@ void Scripted_NoMovementAI::AttackStart(Unit* who)
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -55,8 +55,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
case EVENT_T_SPAWNED: case EVENT_T_SPAWNED:
ProcessEvent(*i); ProcessEvent(*i);
break; break;
default:
break;
} }
} }
@@ -612,12 +610,18 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
caster = target; caster = target;
} }
//Interrupt any previous spell //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
if (caster->IsNonMeleeSpellCasted(false) && param3 & CAST_INTURRUPT_PREVIOUS) bool canCast = !(caster->IsNonMeleeSpellCasted(false) && (param3 & CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS));
caster->InterruptNonMeleeSpells(false);
//Cast only if not casting or if spell is triggered // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
if (param3 & CAST_TRIGGERED || !caster->IsNonMeleeSpellCasted(false)) if(param3 & CAST_AURA_NOT_PRESENT)
{
for(uint8 i = 0; i < 3; ++i)
if(target->HasAura(param1, i))
return;
}
if (canCast)
{ {
const SpellEntry* tSpell = GetSpellStore()->LookupEntry(param1); const SpellEntry* tSpell = GetSpellStore()->LookupEntry(param1);
@@ -638,7 +642,14 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle); m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), AttackDistance, AttackAngle);
} }
}else caster->CastSpell(target, param1, (param3 & CAST_TRIGGERED)); }else
{
//Interrupt any previous spell
if (caster->IsNonMeleeSpellCasted(false) && param3 & CAST_INTURRUPT_PREVIOUS)
caster->InterruptNonMeleeSpells(false);
caster->CastSpell(target, param1, (param3 & CAST_TRIGGERED));
}
}else if (EAI_ErrorLevel > 0) }else if (EAI_ErrorLevel > 0)
error_db_log("SD2: EventAI event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), param1); error_db_log("SD2: EventAI event %d creature %d attempt to cast spell that doesn't exist %d", EventId, m_creature->GetEntry(), param1);
@@ -996,11 +1007,11 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
error_db_log("SD2: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type); error_db_log("SD2: Creature %u using Event %u (Type = %u) has InitialMax < InitialMin. Event disabled.", m_creature->GetEntry(), (*i).Event.event_id, (*i).Event.event_type);
} }
break; break;
default: //default:
//TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void Aggro() //TODO: enable below code line / verify this is correct to enable events previously disabled (ex. aggro yell), instead of enable this in void Aggro()
//(*i).Enabled = true; //(*i).Enabled = true;
//(*i).Time = 0; //(*i).Time = 0;
break; //break;
} }
} }
} }
@@ -1029,8 +1040,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
case EVENT_T_EVADE: case EVENT_T_EVADE:
ProcessEvent(*i); ProcessEvent(*i);
break; break;
default:
break;
} }
} }
} }
@@ -1050,8 +1059,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
case EVENT_T_DEATH: case EVENT_T_DEATH:
ProcessEvent(*i, killer); ProcessEvent(*i, killer);
break; break;
default:
break;
} }
} }
} }
@@ -1069,8 +1076,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
case EVENT_T_KILL: case EVENT_T_KILL:
ProcessEvent(*i, victim); ProcessEvent(*i, victim);
break; break;
default:
break;
} }
} }
@@ -1089,8 +1094,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
case EVENT_T_SUMMONED_UNIT: case EVENT_T_SUMMONED_UNIT:
ProcessEvent(*i, pUnit); ProcessEvent(*i, pUnit);
break; break;
default:
break;
} }
} }
} }
@@ -1145,8 +1148,8 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -1193,8 +1196,8 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -1215,8 +1218,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
ProcessEvent(*i, pUnit); ProcessEvent(*i, pUnit);
} }
break; break;
default:
break;
} }
} }
} }
@@ -113,6 +113,7 @@ enum CastFlags
CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range
CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range
CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself CAST_FORCE_TARGET_SELF = 0x10, //Forces the target to cast this spell on itself
CAST_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell
}; };
enum EventFlags enum EventFlags
@@ -104,8 +104,6 @@ struct MANGOS_DLL_DECL mob_stolen_soulAI : public ScriptedAI
DoCast(m_creature->getVictim(), SPELL_MOONFIRE); DoCast(m_creature->getVictim(), SPELL_MOONFIRE);
Class_Timer = 10000; Class_Timer = 10000;
break; break;
default:
break;
} }
}else Class_Timer -= diff; }else Class_Timer -= diff;
@@ -204,8 +202,8 @@ struct MANGOS_DLL_DECL boss_exarch_maladaarAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -106,8 +106,8 @@ struct MANGOS_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -115,8 +115,8 @@ struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -125,8 +125,8 @@ struct MANGOS_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -74,8 +74,8 @@ struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -95,8 +95,8 @@ struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -61,8 +61,8 @@ struct MANGOS_DLL_DECL npc_ragged_johnAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -117,8 +117,8 @@ struct MANGOS_DLL_DECL boss_omor_the_unscarredAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -138,8 +138,8 @@ struct MANGOS_DLL_DECL boss_omor_the_unscarredAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -108,8 +108,8 @@ struct MANGOS_DLL_DECL boss_watchkeeper_gargolmarAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
else if (!HasTaunted && m_creature->IsWithinDistInMap(who, 60.0f)) else if (!HasTaunted && m_creature->IsWithinDistInMap(who, 60.0f))
@@ -200,8 +200,8 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
if( !InCombat ) if( !InCombat )
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -237,8 +237,8 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
if( !InCombat ) if( !InCombat )
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -582,13 +582,13 @@ struct MANGOS_DLL_DECL boss_malchezaarAI : public ScriptedAI
if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE) && !m_creature->IsNonMeleeSpellCasted(false)) if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE) && !m_creature->IsNonMeleeSpellCasted(false))
{ {
//Check for base attack //Check for base attack
if( m_creature->isAttackReady()) if( m_creature->isAttackReady() && m_creature->getVictim() )
{ {
m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer(); m_creature->resetAttackTimer();
} }
//Check for offhand attack //Check for offhand attack
if( m_creature->isAttackReady(OFF_ATTACK)) if( m_creature->isAttackReady(OFF_ATTACK) && m_creature->getVictim() )
{ {
m_creature->AttackerStateUpdate(m_creature->getVictim(), OFF_ATTACK); m_creature->AttackerStateUpdate(m_creature->getVictim(), OFF_ATTACK);
m_creature->resetAttackTimer(OFF_ATTACK); m_creature->resetAttackTimer(OFF_ATTACK);
@@ -163,9 +163,6 @@ class MANGOS_DLL_SPEC instance_molten_core : public ScriptedInstance
case ID_FLAMEWAKERPRIEST: case ID_FLAMEWAKERPRIEST:
FlamewakerPriest = creature->GetGUID(); FlamewakerPriest = creature->GetGUID();
break; break;
default:
return;
} }
} }
@@ -264,8 +264,6 @@ struct MANGOS_DLL_DECL npc_manaforge_control_consoleAI : public ScriptedAI
} }
++Phase; ++Phase;
break; break;
default:
break;
} }
} else Event_Timer -= diff; } else Event_Timer -= diff;
@@ -138,8 +138,8 @@ struct MANGOS_DLL_DECL npc_millhouse_manastormAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -153,8 +153,8 @@ struct MANGOS_DLL_DECL npc_millhouse_manastormAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -444,8 +444,6 @@ struct MANGOS_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
case 7: case 7:
pInstance->SetData(TYPE_WARDEN_5,IN_PROGRESS); pInstance->SetData(TYPE_WARDEN_5,IN_PROGRESS);
break; break;
default:
break;
} }
CanSpawn = true; CanSpawn = true;
} }
@@ -505,8 +503,6 @@ struct MANGOS_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
DoYell(YELL_WELCOME,LANG_UNIVERSAL,NULL); DoYell(YELL_WELCOME,LANG_UNIVERSAL,NULL);
DoPlaySoundToSet(m_creature,SOUND_WELCOME); DoPlaySoundToSet(m_creature,SOUND_WELCOME);
break; break;
default:
break;
} }
CanSpawn = false; CanSpawn = false;
++Phase; ++Phase;
@@ -553,8 +549,6 @@ struct MANGOS_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
DoPrepareForPhase(); DoPrepareForPhase();
EventProgress_Timer = 15000; EventProgress_Timer = 15000;
break; break;
default:
break;
} }
} }
} else EventProgress_Timer -= diff; } else EventProgress_Timer -= diff;
@@ -130,8 +130,8 @@ struct MANGOS_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -148,8 +148,8 @@ struct MANGOS_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
if( !InCombat ) if( !InCombat )
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -236,8 +236,6 @@ struct MANGOS_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
case 3: case 3:
Intro = true; Intro = true;
break; break;
default:
break;
} }
}else Intro_Timer -=diff; }else Intro_Timer -=diff;
} }
@@ -215,8 +215,8 @@ struct MANGOS_DLL_DECL advisorbase_ai : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -234,8 +234,8 @@ struct MANGOS_DLL_DECL advisorbase_ai : public ScriptedAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -863,14 +863,10 @@ struct MANGOS_DLL_DECL boss_kaelthasAI : public ScriptedAI
DoYell(SAY_SUMMON_PHOENIX1, LANG_UNIVERSAL, NULL); DoYell(SAY_SUMMON_PHOENIX1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SUMMON_PHOENIX1); DoPlaySoundToSet(m_creature, SOUND_SUMMON_PHOENIX1);
break; break;
case 1: case 1:
DoYell(SAY_SUMMON_PHOENIX2, LANG_UNIVERSAL, NULL); DoYell(SAY_SUMMON_PHOENIX2, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SUMMON_PHOENIX2); DoPlaySoundToSet(m_creature, SOUND_SUMMON_PHOENIX2);
break; break;
default:
break;
} }
Phoenix_Timer = 60000; Phoenix_Timer = 60000;
@@ -1252,8 +1248,8 @@ struct MANGOS_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_a
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
@@ -665,8 +665,8 @@ struct MANGOS_DLL_DECL boss_veklorAI : public boss_twinemperorsAI
if (!InCombat) if (!InCombat)
{ {
Aggro(who);
InCombat = true; InCombat = true;
Aggro(who);
} }
} }
} }
-56
View File
@@ -34,62 +34,6 @@
bool ChatHandler::load_command_table = true; bool ChatHandler::load_command_table = true;
LanguageDesc lang_description[LANGUAGES_COUNT] =
{
{ LANG_ADDON, 0, 0 },
{ LANG_UNIVERSAL, 0, 0 },
{ LANG_ORCISH, 669, SKILL_LANG_ORCISH },
{ LANG_DARNASSIAN, 671, SKILL_LANG_DARNASSIAN },
{ LANG_TAURAHE, 670, SKILL_LANG_TAURAHE },
{ LANG_DWARVISH, 672, SKILL_LANG_DWARVEN },
{ LANG_COMMON, 668, SKILL_LANG_COMMON },
{ LANG_DEMONIC, 815, SKILL_LANG_DEMON_TONGUE },
{ LANG_TITAN, 816, SKILL_LANG_TITAN },
{ LANG_THALASSIAN, 813, SKILL_LANG_THALASSIAN },
{ LANG_DRACONIC, 814, SKILL_LANG_DRACONIC },
{ LANG_KALIMAG, 817, SKILL_LANG_OLD_TONGUE },
{ LANG_GNOMISH, 7340, SKILL_LANG_GNOMISH },
{ LANG_TROLL, 7341, SKILL_LANG_TROLL },
{ LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK },
{ LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI },
{ LANG_ZOMBIE, 0, 0 },
{ LANG_GNOMISH_BINARY, 0, 0 },
{ LANG_GOBLIN_BINARY, 0, 0 }
};
LanguageDesc const* GetLanguageDescByID(uint32 lang)
{
for(int i = 0; i < LANGUAGES_COUNT; ++i)
{
if(uint32(lang_description[i].lang_id) == lang)
return &lang_description[i];
}
return NULL;
}
LanguageDesc const* GetLanguageDescBySpell(uint32 spell_id)
{
for(int i = 0; i < LANGUAGES_COUNT; ++i)
{
if(lang_description[i].spell_id == spell_id)
return &lang_description[i];
}
return NULL;
}
LanguageDesc const* GetLanguageDescBySkill(uint32 skill_id)
{
for(int i = 0; i < LANGUAGES_COUNT; ++i)
{
if(lang_description[i].skill_id == skill_id)
return &lang_description[i];
}
return NULL;
}
ChatCommand * ChatHandler::getCommandTable() ChatCommand * ChatHandler::getCommandTable()
{ {
static ChatCommand serverCommandTable[] = static ChatCommand serverCommandTable[] =
-13
View File
@@ -28,19 +28,6 @@ class Player;
class Unit; class Unit;
struct GameTele; struct GameTele;
struct LanguageDesc
{
Language lang_id;
uint32 spell_id;
uint32 skill_id;
};
extern LanguageDesc lang_description[LANGUAGES_COUNT];
LanguageDesc const* GetLanguageDescByID(uint32 lang);
LanguageDesc const* GetLanguageDescBySpell(uint32 spell_id);
LanguageDesc const* GetLanguageDescBySkill(uint32 skill_id);
class ChatCommand class ChatCommand
{ {
public: public:
+127 -34
View File
@@ -62,15 +62,36 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
return NULL; return NULL;
} }
bool VendorItemData::RemoveItem( uint32 item_id )
{
for(VendorItemList::iterator i = m_items.begin(); i != m_items.end(); ++i )
{
if((*i)->item==item_id)
{
m_items.erase(i);
return true;
}
}
return false;
}
VendorItem const* VendorItemData::FindItem(uint32 item_id) const
{
for(VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i )
if((*i)->item==item_id)
return *i;
return NULL;
}
Creature::Creature() : Creature::Creature() :
Unit(), i_AI(NULL), Unit(), i_AI(NULL),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
m_itemsLoaded(false), m_lootMoney(0), m_lootRecipient(0), m_lootMoney(0), m_lootRecipient(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
m_gossipOptionLoaded(false),m_emoteState(0), m_isPet(false), m_isTotem(false), m_gossipOptionLoaded(false),m_emoteState(0), m_isPet(false), m_isTotem(false),
m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0), m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),
m_AlreadyCallAssistence(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_AlreadyCallAssistence(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL) m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0)
{ {
m_valuesCount = UNIT_END; m_valuesCount = UNIT_END;
@@ -87,7 +108,7 @@ Creature::~Creature()
{ {
CleanupsBeforeDelete(); CleanupsBeforeDelete();
m_vendor_items.clear(); m_vendorItemCounts.clear();
delete i_AI; delete i_AI;
i_AI = NULL; i_AI = NULL;
@@ -503,6 +524,7 @@ bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, cons
m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_NORMAL); m_corpseDelay = sWorld.getConfig(CONFIG_CORPSE_DECAY_NORMAL);
break; break;
} }
LoadCreaturesAddon();
} }
return bResult; return bResult;
@@ -673,16 +695,16 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
cantalking=false; cantalking=false;
break; break;
case GOSSIP_OPTION_VENDOR: case GOSSIP_OPTION_VENDOR:
// load vendor items if not yet {
LoadGoods(); VendorItemData const* vItems = GetVendorItems();
if(!vItems || vItems->Empty())
if(!GetItemCount())
{ {
sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.",
GetGUIDLow(),GetEntry()); GetGUIDLow(),GetEntry());
cantalking=false; cantalking=false;
} }
break; break;
}
case GOSSIP_OPTION_TRAINER: case GOSSIP_OPTION_TRAINER:
if(!isCanTrainingOf(pPlayer,false)) if(!isCanTrainingOf(pPlayer,false))
cantalking=false; cantalking=false;
@@ -934,6 +956,9 @@ uint32 Creature::GetGossipTextId(uint32 action, uint32 zoneid)
uint32 Creature::GetNpcTextId() uint32 Creature::GetNpcTextId()
{ {
if (!m_DBTableGuid)
return DEFAULT_GOSSIP_MESSAGE;
if(uint32 pos = objmgr.GetNpcGossip(m_DBTableGuid)) if(uint32 pos = objmgr.GetNpcGossip(m_DBTableGuid))
return pos; return pos;
@@ -1046,6 +1071,8 @@ void Creature::SaveToDB()
void Creature::SaveToDB(uint32 mapid, uint8 spawnMask) void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
{ {
// update in loaded data // update in loaded data
if (!m_DBTableGuid)
m_DBTableGuid = GetGUIDLow();
CreatureData& data = objmgr.NewOrExistCreatureData(m_DBTableGuid); CreatureData& data = objmgr.NewOrExistCreatureData(m_DBTableGuid);
uint32 displayId = GetNativeDisplayId(); uint32 displayId = GetNativeDisplayId();
@@ -1237,7 +1264,6 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
Object::_Create(guidlow, Entry, HIGHGUID_UNIT); Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
m_DBTableGuid = guidlow;
if(!UpdateEntry(Entry, team, data)) if(!UpdateEntry(Entry, team, data))
return false; return false;
@@ -1263,7 +1289,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
return false; return false;
} }
uint32 stored_guid = guid; m_DBTableGuid = guid;
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT); if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
uint16 team = 0; uint16 team = 0;
@@ -1278,9 +1304,6 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
return false; return false;
} }
m_DBTableGuid = stored_guid;
LoadCreaturesAddon();
m_respawnradius = data->spawndist; m_respawnradius = data->spawndist;
m_respawnDelay = data->spawntimesecs; m_respawnDelay = data->spawntimesecs;
@@ -1346,24 +1369,6 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)
} }
} }
void Creature::LoadGoods()
{
// already loaded;
if(m_itemsLoaded)
return;
m_vendor_items.clear();
VendorItemList const* vList = objmgr.GetNpcVendorItemList(GetEntry());
if(!vList)
return;
for (VendorItemList::const_iterator _item_iter = vList->begin(); _item_iter != vList->end(); ++_item_iter)
AddItem( (*_item_iter)->item, (*_item_iter)->maxcount, (*_item_iter)->incrtime, (*_item_iter)->ExtendedCost);
m_itemsLoaded = true;
}
bool Creature::hasQuest(uint32 quest_id) const bool Creature::hasQuest(uint32 quest_id) const
{ {
QuestRelations const& qr = objmgr.mCreatureQuestRelations; QuestRelations const& qr = objmgr.mCreatureQuestRelations;
@@ -1388,6 +1393,12 @@ bool Creature::hasInvolvedQuest(uint32 quest_id) const
void Creature::DeleteFromDB() void Creature::DeleteFromDB()
{ {
if (!m_DBTableGuid)
{
sLog.outDebug("Trying to delete not saved creature!");
return;
}
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
objmgr.DeleteCreatureData(m_DBTableGuid); objmgr.DeleteCreatureData(m_DBTableGuid);
@@ -1494,7 +1505,8 @@ void Creature::Respawn()
if(getDeathState()==DEAD) if(getDeathState()==DEAD)
{ {
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0); if (m_DBTableGuid)
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
m_respawnTime = time(NULL); // respawn at next tick m_respawnTime = time(NULL); // respawn at next tick
} }
} }
@@ -1716,7 +1728,7 @@ void Creature::CallAssistence()
void Creature::SaveRespawnTime() void Creature::SaveRespawnTime()
{ {
if(isPet()) if(isPet() || !m_DBTableGuid)
return; return;
if(m_respawnTime > time(NULL)) // dead (no corpse) if(m_respawnTime > time(NULL)) // dead (no corpse)
@@ -1752,8 +1764,11 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const
CreatureDataAddon const* Creature::GetCreatureAddon() const CreatureDataAddon const* Creature::GetCreatureAddon() const
{ {
if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid)) if (m_DBTableGuid)
return addon; {
if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid))
return addon;
}
// dependent from heroic mode entry // dependent from heroic mode entry
return ObjectMgr::GetCreatureTemplateAddon(GetCreatureInfo()->Entry); return ObjectMgr::GetCreatureTemplateAddon(GetCreatureInfo()->Entry);
@@ -1956,6 +1971,84 @@ char const* Creature::GetScriptName() const
return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptName; return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptName;
} }
VendorItemData const* Creature::GetVendorItems() const
{
return objmgr.GetNpcVendorItemList(GetEntry());
}
uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem)
{
if(!vItem->maxcount)
return vItem->maxcount;
VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
for(; itr != m_vendorItemCounts.end(); ++itr)
if(itr->itemId==vItem->item)
break;
if(itr == m_vendorItemCounts.end())
return vItem->maxcount;
VendorItemCount* vCount = &*itr;
time_t ptime = time(NULL);
if( vCount->lastIncrementTime + vItem->incrtime <= ptime )
{
ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item);
uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
if((vCount->count + diff * pProto->BuyCount) >= vItem->maxcount )
{
m_vendorItemCounts.erase(itr);
return vItem->maxcount;
}
vCount->count += diff * pProto->BuyCount;
vCount->lastIncrementTime = ptime;
}
return vCount->count;
}
uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count)
{
if(!vItem->maxcount)
return 0;
VendorItemCounts::iterator itr = m_vendorItemCounts.begin();
for(; itr != m_vendorItemCounts.end(); ++itr)
if(itr->itemId==vItem->item)
break;
if(itr == m_vendorItemCounts.end())
{
uint32 new_count = vItem->maxcount > used_count ? vItem->maxcount-used_count : 0;
m_vendorItemCounts.push_back(VendorItemCount(vItem->item,new_count));
return new_count;
}
VendorItemCount* vCount = &*itr;
time_t ptime = time(NULL);
if( vCount->lastIncrementTime + vItem->incrtime <= ptime )
{
ItemPrototype const* pProto = objmgr.GetItemPrototype(vItem->item);
uint32 diff = uint32((ptime - vCount->lastIncrementTime)/vItem->incrtime);
if((vCount->count + diff * pProto->BuyCount) < vItem->maxcount )
vCount->count += diff * pProto->BuyCount;
else
vCount->count = vItem->maxcount;
}
vCount->count = vCount->count > used_count ? vCount->count-used_count : 0;
vCount->lastIncrementTime = ptime;
return vCount->count;
}
TrainerSpellData const* Creature::GetTrainerSpells() const TrainerSpellData const* Creature::GetTrainerSpells() const
{ {
return objmgr.GetNpcTrainerSpells(GetEntry()); return objmgr.GetNpcTrainerSpells(GetEntry());
+55 -52
View File
@@ -112,19 +112,6 @@ struct GossipOption
std::string Option; std::string Option;
}; };
struct CreatureItem
{
CreatureItem(uint32 _item, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
: id(_item), count(_maxcount), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost), lastincr((uint32)time(NULL)) {}
uint32 id;
uint32 count;
uint32 maxcount;
uint32 incrtime;
uint32 lastincr;
uint32 ExtendedCost;
};
enum CreatureFlagsExtra enum CreatureFlagsExtra
{ {
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
@@ -291,6 +278,56 @@ enum InhabitTypeValues
#pragma pack(pop) #pragma pack(pop)
#endif #endif
// Vendors
struct VendorItem
{
VendorItem(uint32 _item, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
: item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {}
uint32 item;
uint32 maxcount; // 0 for infinity item amount
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
};
typedef std::vector<VendorItem*> VendorItemList;
struct VendorItemData
{
VendorItemList m_items;
VendorItem* GetItem(uint32 slot) const
{
if(slot>=m_items.size()) return NULL;
return m_items[slot];
}
bool Empty() const { return m_items.empty(); }
uint8 GetItemCount() const { return m_items.size(); }
void AddItem( uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost)
{
m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost));
}
bool RemoveItem( uint32 item_id );
VendorItem const* FindItem(uint32 item_id) const;
void Clear()
{
for (VendorItemList::iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
delete (*itr);
}
};
struct VendorItemCount
{
explicit VendorItemCount(uint32 _item, uint32 _count)
: itemId(_item), count(_count), lastIncrementTime(time(NULL)) {}
uint32 itemId;
uint32 count;
time_t lastIncrementTime;
};
typedef std::list<VendorItemCount> VendorItemCounts;
struct TrainerSpell struct TrainerSpell
{ {
uint32 spell; uint32 spell;
@@ -418,41 +455,9 @@ class MANGOS_DLL_SPEC Creature : public Unit
uint32 GetCurrentEquipmentId() { return m_equipmentId; } uint32 GetCurrentEquipmentId() { return m_equipmentId; }
float GetSpellDamageMod(int32 Rank); float GetSpellDamageMod(int32 Rank);
/*********************************************************/ VendorItemData const* GetVendorItems() const;
/*** VENDOR SYSTEM ***/ uint32 GetVendorItemCurrentCount(VendorItem const* vItem);
/*********************************************************/ uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count);
void LoadGoods(); // must be called before access to vendor items, lazy loading at first call
void ReloadGoods() { m_itemsLoaded = false; LoadGoods(); }
CreatureItem* GetItem(uint32 slot)
{
if(slot>=m_vendor_items.size()) return NULL;
return &m_vendor_items[slot];
}
uint8 GetItemCount() const { return m_vendor_items.size(); }
void AddItem( uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost)
{
m_vendor_items.push_back(CreatureItem(item, maxcount, ptime, ExtendedCost));
}
bool RemoveItem( uint32 item_id )
{
for(CreatureItems::iterator i = m_vendor_items.begin(); i != m_vendor_items.end(); ++i )
{
if(i->id==item_id)
{
m_vendor_items.erase(i);
return true;
}
}
return false;
}
CreatureItem* FindItem(uint32 item_id)
{
for(CreatureItems::iterator i = m_vendor_items.begin(); i != m_vendor_items.end(); ++i )
if(i->id==item_id)
return &*i;
return NULL;
}
TrainerSpellData const* GetTrainerSpells() const; TrainerSpellData const* GetTrainerSpells() const;
@@ -562,9 +567,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL); bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
// vendor items // vendor items
typedef std::vector<CreatureItem> CreatureItems; VendorItemCounts m_vendorItemCounts;
CreatureItems m_vendor_items;
bool m_itemsLoaded; // vendor items loading state
void _RealtimeSetCreatureInfo(); void _RealtimeSetCreatureInfo();
@@ -592,7 +595,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
uint32 m_regenTimer; uint32 m_regenTimer;
MovementGeneratorType m_defaultMovementType; MovementGeneratorType m_defaultMovementType;
Cell m_currentCell; // store current cell where creature listed Cell m_currentCell; // store current cell where creature listed
uint32 m_DBTableGuid; uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
uint32 m_equipmentId; uint32 m_equipmentId;
bool m_AlreadyCallAssistence; bool m_AlreadyCallAssistence;
+1247 -1253
View File
File diff suppressed because it is too large. Load diff
+592 -592
View File
File diff suppressed because it is too large. Load diff
+6 -6
View File
@@ -391,7 +391,7 @@ void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID )
data << uint8(questStatus); data << uint8(questStatus);
pSession->SendPacket( &data ); pSession->SendPacket( &data );
//sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u",GUID_LOPART(npcGUID),questStatus); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u",GUID_LOPART(npcGUID),questStatus);
} }
void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept ) void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept )
@@ -477,7 +477,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
} }
pSession->SendPacket( &data ); pSession->SendPacket( &data );
//sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId()); sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_DETAILS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId());
} }
void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest ) void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
@@ -515,7 +515,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 ); // guess size WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 ); // guess size
data << uint32(pQuest->GetQuestId()); data << uint32(pQuest->GetQuestId());
data << uint32(pQuest->GetMinLevel()); // not MinLevel. Accepted values: 0, 1 or 2 Possible theory for future dev: 0==cannot in quest log, 1==can in quest log session only(removed on log out), 2==can in quest log always (save to db) data << uint32(pQuest->GetQuestMethod()); // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
data << uint32(pQuest->GetQuestLevel()); // may be 0 data << uint32(pQuest->GetQuestLevel()); // may be 0
data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log data << uint32(pQuest->GetZoneOrSort()); // zone or sort to display in quest log
@@ -597,7 +597,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
data << ObjectiveText[iI]; data << ObjectiveText[iI];
pSession->SendPacket( &data ); pSession->SendPacket( &data );
//sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() ); sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() );
} }
void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext ) void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext )
@@ -679,7 +679,7 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
data << uint32(pQuest->GetRewSpellCast()); // casted spell data << uint32(pQuest->GetRewSpellCast()); // casted spell
data << uint32(0); // Honor points reward, not implemented data << uint32(0); // Honor points reward, not implemented
pSession->SendPacket( &data ); pSession->SendPacket( &data );
//sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() ); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
} }
void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel ) void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel )
@@ -758,5 +758,5 @@ void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID
data << uint32(0x04) << uint32(0x08) << uint32(0x10); data << uint32(0x04) << uint32(0x08) << uint32(0x10);
pSession->SendPacket( &data ); pSession->SendPacket( &data );
//sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() ); sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() );
} }
+1211 -1221
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -303,6 +303,7 @@ enum MangosStrings
LANG_LOOKUP_PLAYER_ACCOUNT = 328, LANG_LOOKUP_PLAYER_ACCOUNT = 328,
LANG_LOOKUP_PLAYER_CHARACTER = 329, LANG_LOOKUP_PLAYER_CHARACTER = 329,
LANG_NO_PLAYERS_FOUND = 330, LANG_NO_PLAYERS_FOUND = 330,
LANG_EXTENDED_COST_NOT_EXIST = 331,
// Room for more level 2 // Room for more level 2
+11 -48
View File
@@ -1237,14 +1237,6 @@ bool ChatHandler::HandleAddVendorItemCommand(const char* args)
if (!*args) if (!*args)
return false; return false;
Creature* vendor = getSelectedCreature();
if (!vendor || !vendor->isVendor())
{
SendSysMessage(LANG_COMMAND_VENDORSELECTION);
SetSentErrorMessage(true);
return false;
}
char* pitem = extractKeyFromLink((char*)args,"Hitem"); char* pitem = extractKeyFromLink((char*)args,"Hitem");
if (!pitem) if (!pitem)
{ {
@@ -1252,6 +1244,7 @@ bool ChatHandler::HandleAddVendorItemCommand(const char* args)
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
uint32 itemId = atol(pitem); uint32 itemId = atol(pitem);
char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0 char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
@@ -1267,41 +1260,20 @@ bool ChatHandler::HandleAddVendorItemCommand(const char* args)
char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0 char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0; uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId); Creature* vendor = getSelectedCreature();
if(!pProto)
uint32 vendor_entry = vendor ? vendor->GetEntry() : 0;
if(!objmgr.IsVendorItemValid(vendor_entry,itemId,maxcount,incrtime,extendedcost,m_session->GetPlayer()))
{ {
PSendSysMessage(LANG_ITEM_NOT_FOUND, itemId);
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
if(extendedcost && !sItemExtendedCostStore.LookupEntry(extendedcost)) objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
{
PSendSysMessage(LANG_BAD_VALUE, extendedcost);
SetSentErrorMessage(true);
return false;
}
// load vendor items if not yet ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
vendor->LoadGoods();
if(vendor->FindItem(itemId))
{
PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,itemId);
SetSentErrorMessage(true);
return false;
}
if (vendor->GetItemCount() >= MAX_VENDOR_ITEMS)
{
SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS);
SetSentErrorMessage(true);
return false;
}
// add to DB and to current ingame vendor
WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",vendor->GetEntry(), itemId, maxcount,incrtime,extendedcost);
vendor->AddItem(itemId,maxcount,incrtime,extendedcost);
PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost); PSendSysMessage(LANG_ITEM_ADDED_TO_LIST,itemId,pProto->Name1,maxcount,incrtime,extendedcost);
return true; return true;
} }
@@ -1329,25 +1301,16 @@ bool ChatHandler::HandleDelVendorItemCommand(const char* args)
} }
uint32 itemId = atol(pitem); uint32 itemId = atol(pitem);
ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
if(!pProto)
{
PSendSysMessage(LANG_ITEM_NOT_FOUND, itemId);
SetSentErrorMessage(true);
return false;
}
// load vendor items if not yet if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
vendor->LoadGoods();
if (!vendor->RemoveItem(itemId))
{ {
PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId); PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",vendor->GetEntry(), itemId); ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1); PSendSysMessage(LANG_ITEM_DELETED_FROM_LIST,itemId,pProto->Name1);
return true; return true;
} }
+185 -64
View File
@@ -70,6 +70,40 @@ bool normalizePlayerName(std::string& name)
return true; return true;
} }
LanguageDesc lang_description[LANGUAGES_COUNT] =
{
{ LANG_ADDON, 0, 0 },
{ LANG_UNIVERSAL, 0, 0 },
{ LANG_ORCISH, 669, SKILL_LANG_ORCISH },
{ LANG_DARNASSIAN, 671, SKILL_LANG_DARNASSIAN },
{ LANG_TAURAHE, 670, SKILL_LANG_TAURAHE },
{ LANG_DWARVISH, 672, SKILL_LANG_DWARVEN },
{ LANG_COMMON, 668, SKILL_LANG_COMMON },
{ LANG_DEMONIC, 815, SKILL_LANG_DEMON_TONGUE },
{ LANG_TITAN, 816, SKILL_LANG_TITAN },
{ LANG_THALASSIAN, 813, SKILL_LANG_THALASSIAN },
{ LANG_DRACONIC, 814, SKILL_LANG_DRACONIC },
{ LANG_KALIMAG, 817, SKILL_LANG_OLD_TONGUE },
{ LANG_GNOMISH, 7340, SKILL_LANG_GNOMISH },
{ LANG_TROLL, 7341, SKILL_LANG_TROLL },
{ LANG_GUTTERSPEAK, 17737, SKILL_LANG_GUTTERSPEAK },
{ LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI },
{ LANG_ZOMBIE, 0, 0 },
{ LANG_GNOMISH_BINARY, 0, 0 },
{ LANG_GOBLIN_BINARY, 0, 0 }
};
LanguageDesc const* GetLanguageDescByID(uint32 lang)
{
for(int i = 0; i < LANGUAGES_COUNT; ++i)
{
if(uint32(lang_description[i].lang_id) == lang)
return &lang_description[i];
}
return NULL;
}
ObjectMgr::ObjectMgr() ObjectMgr::ObjectMgr()
{ {
m_hiCharGuid = 1; m_hiCharGuid = 1;
@@ -134,8 +168,7 @@ ObjectMgr::~ObjectMgr()
delete itr->second; delete itr->second;
for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
for (VendorItemList::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2) itr->second.Clear();
delete (*itr2);
for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr) for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
itr->second.Clear(); itr->second.Clear();
@@ -2697,35 +2730,35 @@ void ObjectMgr::LoadQuests()
mExclusiveQuestGroups.clear(); mExclusiveQuestGroups.clear();
// 0 1 2 3 4 5 6 7 // 0 1 2 3 4 5 6 7 8
QueryResult *result = WorldDatabase.Query("SELECT entry, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue," QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"
// 8 9 10 11 12 13 14 15 // 9 10 11 12 13 14 15 16
"RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime," "RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime,"
// 16 17 18 19 20 21 22 23 24 25 // 17 18 19 20 21 22 23 24 25 26
"QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell," "QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell,"
// 26 27 28 29 30 31 32 33 34 35 // 27 28 29 30 31 32 33 34 35 36
"Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4," "Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4,"
// 36 37 38 39 40 41 42 43 // 37 38 39 40 41 42 43 44
"ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4," "ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4,"
// 44 45 46 47 48 49 50 51 52 53 54 55 // 45 46 47 48 49 50 51 52 53 54 54 55
"ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4," "ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4,"
// 56 57 58 59 60 61 62 63 // 57 58 59 60 61 62 63 64
"ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4," "ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4,"
// 64 65 66 67 // 65 66 67 68
"ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4," "ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4,"
// 68 69 70 71 72 73 // 69 70 71 72 73 74
"RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6," "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6,"
// 74 75 76 77 78 79 // 75 76 77 78 79 80
"RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6," "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6,"
// 80 81 82 83 84 85 86 87 // 81 82 83 84 85 86 87 88
"RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4," "RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4,"
// 88 89 90 91 92 93 94 95 96 97 // 89 90 91 92 93 94 95 96 97 98
"RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5," "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5,"
// 98 99 100 101 102 103 104 105 106 107 // 99 100 101 102 103 104 105 106 107 108
"RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt," "RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt,"
// 108 109 110 111 112 113 114 115 116 117 // 109 110 111 112 113 114 115 116 117 118
"DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4," "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4,"
// 118 119 // 119 120
"StartScript, CompleteScript" "StartScript, CompleteScript"
" FROM quest_template"); " FROM quest_template");
if(result == NULL) if(result == NULL)
@@ -2761,6 +2794,11 @@ void ObjectMgr::LoadQuests()
// additional quest integrity checks (GO, creature_template and item_template must be loaded already) // additional quest integrity checks (GO, creature_template and item_template must be loaded already)
if( qinfo->GetQuestMethod() >= 3 )
{
sLog.outErrorDb("Quest %u has `Method` = %u, expected values are 0, 1 or 2.",qinfo->GetQuestId(),qinfo->GetQuestMethod());
}
if (qinfo->QuestFlags & ~QUEST_MANGOS_FLAGS_DB_ALLOWED) if (qinfo->QuestFlags & ~QUEST_MANGOS_FLAGS_DB_ALLOWED)
{ {
sLog.outErrorDb("Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u", sLog.outErrorDb("Quest %u has `SpecialFlags` = %u > max allowed value. Correct `SpecialFlags` to value <= %u",
@@ -6148,14 +6186,14 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
if(entry==0) if(entry==0)
{ {
sLog.outString("Table `%s` contain reserved entry 0, ignored.",table); sLog.outErrorDb("Table `%s` contain reserved entry 0, ignored.",table);
continue; continue;
} }
else if(entry < min_value || entry > max_value) else if(entry < min_value || entry > max_value)
{ {
int32 start = min_value > 0 ? min_value : max_value; int32 start = min_value > 0 ? min_value : max_value;
int32 end = min_value > 0 ? max_value : min_value; int32 end = min_value > 0 ? max_value : min_value;
sLog.outString("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.",table,entry,start,end); sLog.outErrorDb("Table `%s` contain entry %i out of allowed range (%d - %d), ignored.",table,entry,start,end);
continue; continue;
} }
@@ -6163,7 +6201,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
if(data.Content.size() > 0) if(data.Content.size() > 0)
{ {
sLog.outString("Table `%s` contain data for already loaded entry %i (from another table?), ignored.",table,entry); sLog.outErrorDb("Table `%s` contain data for already loaded entry %i (from another table?), ignored.",table,entry);
continue; continue;
} }
@@ -6656,22 +6694,30 @@ void ObjectMgr::LoadTrainerSpell()
barGoLink bar( result->GetRowCount() ); barGoLink bar( result->GetRowCount() );
uint32 count = 0,entry,spell; uint32 count = 0;
do do
{ {
bar.step(); bar.step();
Field* fields = result->Fetch(); Field* fields = result->Fetch();
entry = fields[0].GetUInt32(); uint32 entry = fields[0].GetUInt32();
spell = fields[1].GetUInt32(); uint32 spell = fields[1].GetUInt32();
if(!GetCreatureTemplate(entry)) CreatureInfo const* cInfo = GetCreatureTemplate(entry);
if(!cInfo)
{ {
sLog.outErrorDb("Table `npc_trainer` have entry for not existed creature template (Entry: %u), ignore", entry); sLog.outErrorDb("Table `npc_trainer` have entry for not existed creature template (Entry: %u), ignore", entry);
continue; continue;
} }
if(!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
{
sLog.outErrorDb("Table `npc_trainer` have data for not creature template (Entry: %u) without trainer flag, ignore", entry);
continue;
}
SpellEntry const *spellinfo = sSpellStore.LookupEntry(spell); SpellEntry const *spellinfo = sSpellStore.LookupEntry(spell);
if(!spellinfo) if(!spellinfo)
{ {
@@ -6715,10 +6761,7 @@ void ObjectMgr::LoadVendors()
{ {
// For reload case // For reload case
for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
{ itr->second.Clear();
for (VendorItemList::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
delete (*itr2);
}
m_mCacheVendorItemMap.clear(); m_mCacheVendorItemMap.clear();
QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor"); QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
@@ -6736,48 +6779,23 @@ void ObjectMgr::LoadVendors()
barGoLink bar( result->GetRowCount() ); barGoLink bar( result->GetRowCount() );
uint32 count = 0; uint32 count = 0;
uint32 entry, item_id, ExtendedCost;
do do
{ {
bar.step(); bar.step();
Field* fields = result->Fetch(); Field* fields = result->Fetch();
entry = fields[0].GetUInt32(); uint32 entry = fields[0].GetUInt32();
if(!GetCreatureTemplate(entry)) uint32 item_id = fields[1].GetUInt32();
{ uint32 maxcount = fields[2].GetUInt32();
sLog.outErrorDb("Table `npc_vendor` have data for not existed creature template (Entry: %u), ignore", entry); uint32 incrtime = fields[3].GetUInt32();
uint32 ExtendedCost = fields[4].GetUInt32();
if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost))
continue; continue;
}
item_id = fields[1].GetUInt32(); VendorItemData& vList = m_mCacheVendorItemMap[entry];
if(!GetItemPrototype(item_id))
{
sLog.outErrorDb("Table `npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",entry,item_id);
continue;
}
ExtendedCost = fields[4].GetUInt32(); vList.AddItem(item_id,maxcount,incrtime,ExtendedCost);
if(ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
{
sLog.outErrorDb("Table `npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,entry);
continue;
}
VendorItemList& vList = m_mCacheVendorItemMap[entry];
if(vList.size() >= MAX_VENDOR_ITEMS)
{
sLog.outErrorDb( "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore", vList.size(), MAX_VENDOR_ITEMS, entry);
continue;
}
VendorItem* pVendorItem = new VendorItem();
pVendorItem->item = item_id;
pVendorItem->maxcount = fields[2].GetUInt32();
pVendorItem->incrtime = fields[3].GetUInt32();
pVendorItem->ExtendedCost = ExtendedCost;
vList.push_back(pVendorItem);
++count; ++count;
} while (result->NextRow()); } while (result->NextRow());
@@ -6838,6 +6856,109 @@ void ObjectMgr::LoadNpcTextId()
sLog.outString( ">> Loaded %d NpcTextId ", count ); sLog.outString( ">> Loaded %d NpcTextId ", count );
} }
void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost )
{
VendorItemData& vList = m_mCacheVendorItemMap[entry];
vList.AddItem(item,maxcount,incrtime,extendedcost);
WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",entry, item, maxcount,incrtime,extendedcost);
}
bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item )
{
CacheVendorItemMap::iterator iter = m_mCacheVendorItemMap.find(entry);
if(iter == m_mCacheVendorItemMap.end())
return false;
if(!iter->second.FindItem(item))
return false;
iter->second.RemoveItem(item);
WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",entry, item);
return true;
}
bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl ) const
{
CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry);
if(!cInfo)
{
if(pl)
ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
else
sLog.outErrorDb("Table `npc_vendor` have data for not existed creature template (Entry: %u), ignore", vendor_entry);
return false;
}
if(!(cInfo->npcflag & UNIT_NPC_FLAG_VENDOR))
{
if(pl)
ChatHandler(pl).SendSysMessage(LANG_COMMAND_VENDORSELECTION);
else
sLog.outErrorDb("Table `npc_vendor` have data for not creature template (Entry: %u) without vendor flag, ignore", vendor_entry);
return false;
}
if(!GetItemPrototype(item_id))
{
if(pl)
ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id);
else
sLog.outErrorDb("Table `npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",vendor_entry,item_id);
return false;
}
if(ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost))
{
if(pl)
ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST,ExtendedCost);
else
sLog.outErrorDb("Table `npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,vendor_entry);
return false;
}
if(maxcount > 0 && incrtime == 0)
{
if(pl)
ChatHandler(pl).PSendSysMessage("MaxCount!=0 (%u) but IncrTime==0", maxcount);
else
sLog.outErrorDb( "Table `npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry);
return false;
}
else if(maxcount==0 && incrtime > 0)
{
if(pl)
ChatHandler(pl).PSendSysMessage("MaxCount==0 but IncrTime<>=0");
else
sLog.outErrorDb( "Table `npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry);
return false;
}
VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
if(!vItems)
return true; // later checks for non-empty lists
if(vItems->FindItem(item_id))
{
if(pl)
ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,item_id);
else
sLog.outErrorDb( "Table `npc_vendor` has duplicate items %u for vendor (Entry: %u), ignore", item_id, vendor_entry);
return false;
}
if(vItems->GetItemCount() >= MAX_VENDOR_ITEMS)
{
if(pl)
ChatHandler(pl).SendSysMessage(LANG_COMMAND_ADDVENDORITEMITEMS);
else
sLog.outErrorDb( "Table `npc_vendor` has too many items (%u >= %i) for vendor (Entry: %u), ignore", vItems->GetItemCount(), MAX_VENDOR_ITEMS, vendor_entry);
return false;
}
return true;
}
// Functions for scripting access // Functions for scripting access
const char* GetAreaTriggerScriptNameById(uint32 id) const char* GetAreaTriggerScriptNameById(uint32 id)
{ {
@@ -6848,7 +6969,7 @@ bool LoadMangosStrings(DatabaseType& db, char const* table,int32 start_value, in
{ {
if(start_value >= 0 || start_value <= end_value) // start/end reversed for negative values if(start_value >= 0 || start_value <= end_value) // start/end reversed for negative values
{ {
sLog.outError("Table '%s' attempt loaded with invalid range (%d - %d), use (%d - %d) instead.",table,start_value,end_value,-1,std::numeric_limits<int32>::min()); sLog.outErrorDb("Table '%s' attempt loaded with invalid range (%d - %d), use (%d - %d) instead.",table,start_value,end_value,-1,std::numeric_limits<int32>::min());
start_value = -1; start_value = -1;
end_value = std::numeric_limits<int32>::min(); end_value = std::numeric_limits<int32>::min();
} }
+15 -12
View File
@@ -228,18 +228,8 @@ struct PlayerCondition
// NPC gossip text id // NPC gossip text id
typedef HM_NAMESPACE::hash_map<uint32, uint32> CacheNpcTextIdMap; typedef HM_NAMESPACE::hash_map<uint32, uint32> CacheNpcTextIdMap;
// Vendors
struct VendorItem
{
uint32 item;
uint32 maxcount;
uint32 incrtime;
uint32 ExtendedCost;
};
typedef std::vector<VendorItem*> VendorItemList;
typedef HM_NAMESPACE::hash_map<uint32, VendorItemList> CacheVendorItemMap;
typedef HM_NAMESPACE::hash_map<uint32, VendorItemData> CacheVendorItemMap;
typedef HM_NAMESPACE::hash_map<uint32, TrainerSpellData> CacheTrainerSpellMap; typedef HM_NAMESPACE::hash_map<uint32, TrainerSpellData> CacheTrainerSpellMap;
enum SkillRangeType enum SkillRangeType
@@ -258,6 +248,16 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial);
bool normalizePlayerName(std::string& name); bool normalizePlayerName(std::string& name);
struct MANGOS_DLL_SPEC LanguageDesc
{
Language lang_id;
uint32 spell_id;
uint32 skill_id;
};
extern LanguageDesc lang_description[LANGUAGES_COUNT];
MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
class PlayerDumpReader; class PlayerDumpReader;
class ObjectMgr class ObjectMgr
@@ -732,7 +732,7 @@ class ObjectMgr
return &iter->second; return &iter->second;
} }
VendorItemList const* GetNpcVendorItemList(uint32 entry) const VendorItemData const* GetNpcVendorItemList(uint32 entry) const
{ {
CacheVendorItemMap::const_iterator iter = m_mCacheVendorItemMap.find(entry); CacheVendorItemMap::const_iterator iter = m_mCacheVendorItemMap.find(entry);
if(iter == m_mCacheVendorItemMap.end()) if(iter == m_mCacheVendorItemMap.end())
@@ -740,6 +740,9 @@ class ObjectMgr
return &iter->second; return &iter->second;
} }
void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost);
bool RemoveVendorItem(uint32 entry,uint32 item);
bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL ) const;
protected: protected:
uint32 m_auctionid; uint32 m_auctionid;
uint32 m_mailid; uint32 m_mailid;
+1750 -1750
View File
File diff suppressed because it is too large. Load diff
+36 -19
View File
@@ -5794,7 +5794,7 @@ void Player::RewardReputation(Unit *pVictim, float rate)
if(!pVictim || pVictim->GetTypeId() == TYPEID_PLAYER) if(!pVictim || pVictim->GetTypeId() == TYPEID_PLAYER)
return; return;
ReputationOnKillEntry const* Rep = objmgr.GetReputationOnKilEntry(pVictim->GetEntry()); ReputationOnKillEntry const* Rep = objmgr.GetReputationOnKilEntry(((Creature*)pVictim)->GetCreatureInfo()->Entry);
if(!Rep) if(!Rep)
return; return;
@@ -16380,20 +16380,28 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false; return false;
} }
// load vendor items if not yet VendorItemData const* vItems = pCreature->GetVendorItems();
pCreature->LoadGoods(); if(!vItems || vItems->Empty())
{
SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
return false;
}
CreatureItem* crItem = pCreature->FindItem(item); VendorItem const* crItem = vItems->FindItem(item);
if(!crItem) if(!crItem)
{ {
SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
return false; return false;
} }
if( crItem->maxcount != 0 && crItem->count < count ) // check current item amount if it limited
if( crItem->maxcount != 0 )
{ {
SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0); if(pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count )
return false; {
SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0);
return false;
}
} }
if( uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) if( uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank)
@@ -16508,17 +16516,16 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
if(Item *it = StoreNewItem( dest, item, true )) if(Item *it = StoreNewItem( dest, item, true ))
{ {
if( crItem->maxcount != 0 ) uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count);
crItem->count -= pProto->BuyCount * count;
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << pCreature->GetGUID(); data << pCreature->GetGUID();
data << (uint32)crItem->id; // entry data << (uint32)crItem->item;
data << (uint32)crItem->count; data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << (uint32)count; data << (uint32)count;
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
SendNewItem(it, count, true, false, false); SendNewItem(it, pProto->BuyCount*count, true, false, false);
} }
} }
else if( IsEquipmentPos( bag, slot ) ) else if( IsEquipmentPos( bag, slot ) )
@@ -16548,17 +16555,16 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
if(Item *it = EquipNewItem( dest, item, pProto->BuyCount * count, true )) if(Item *it = EquipNewItem( dest, item, pProto->BuyCount * count, true ))
{ {
if( crItem->maxcount != 0 ) uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count);
crItem->count -= pProto->BuyCount * count;
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << pCreature->GetGUID(); data << pCreature->GetGUID();
data << (uint32)crItem->id; // entry data << (uint32)crItem->item;
data << (uint32)crItem->count; data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << (uint32)count; data << (uint32)count;
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
SendNewItem(it, count, true, false, false); SendNewItem(it, pProto->BuyCount*count, true, false, false);
AutoUnequipOffhandIfNeed(); AutoUnequipOffhandIfNeed();
} }
@@ -16569,7 +16575,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false; return false;
} }
return crItem->maxcount!=0?true:false; return crItem->maxcount!=0;
} }
uint32 Player::GetMaxPersonalArenaRatingRequirement() uint32 Player::GetMaxPersonalArenaRatingRequirement()
@@ -17174,7 +17180,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
// set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment // set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment
if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight()) if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight())
SetUnitMovementFlags(GetUnitMovementFlags() | MOVEMENTFLAG_FLYING2); AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
} }
void Player::SendInitialPacketsAfterAddToMap() void Player::SendInitialPacketsAfterAddToMap()
@@ -18167,3 +18173,14 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
return false; return false;
} }
bool Player::isAllowUseBattleGroundObject()
{
return ( //InBattleGround() && // in battleground - not need, check in other cases
!IsMounted() && // not mounted
!HasStealthAura() && // not stealthed
!HasInvisibilityAura() && // not invisible
!HasAura(SPELL_RECENTLY_DROPPED_FLAG, 0) && // can't pickup
isAlive() // live player
);
}
+1
View File
@@ -1898,6 +1898,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void ClearAfkReports() { m_bgAfkReporter.clear(); } void ClearAfkReports() { m_bgAfkReporter.clear(); }
bool GetBGAccessByLevel(uint32 bgTypeId) const; bool GetBGAccessByLevel(uint32 bgTypeId) const;
bool isAllowUseBattleGroundObject();
/*********************************************************/ /*********************************************************/
/*** REST SYSTEM ***/ /*** REST SYSTEM ***/
+76 -73
View File
@@ -1,73 +1,76 @@
/* /*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "PointMovementGenerator.h" #include "PointMovementGenerator.h"
#include "Errors.h" #include "Errors.h"
#include "Creature.h" #include "Creature.h"
#include "CreatureAI.h" #include "CreatureAI.h"
#include "MapManager.h" #include "MapManager.h"
#include "DestinationHolderImp.h" #include "DestinationHolderImp.h"
//----- Point Movement Generator //----- Point Movement Generator
template<class T> template<class T>
void PointMovementGenerator<T>::Initialize(T &unit) void PointMovementGenerator<T>::Initialize(T &unit)
{ {
unit.StopMoving(); unit.StopMoving();
Traveller<T> traveller(unit); Traveller<T> traveller(unit);
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z); i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z);
}
if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly())
template<class T> unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff) }
{
if(!&unit) template<class T>
return false; bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED)) if(!&unit)
return true; return false;
Traveller<T> traveller(unit); if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
return true;
i_destinationHolder.UpdateTraveller(traveller, diff, false);
Traveller<T> traveller(unit);
if(i_destinationHolder.HasArrived())
{ i_destinationHolder.UpdateTraveller(traveller, diff, false);
unit.StopMoving();
MovementInform(unit); if(i_destinationHolder.HasArrived())
return false; {
} unit.StopMoving();
MovementInform(unit);
return true; return false;
} }
template<class T> return true;
void PointMovementGenerator<T>::MovementInform(T &unit) }
{
} template<class T>
void PointMovementGenerator<T>::MovementInform(T &unit)
template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit) {
{ }
unit.AI()->MovementInform(POINT_MOTION_TYPE, id);
} template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit)
{
template void PointMovementGenerator<Player>::Initialize(Player&); unit.AI()->MovementInform(POINT_MOTION_TYPE, id);
template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &diff); }
template void PointMovementGenerator<Player>::MovementInform(Player&);
template void PointMovementGenerator<Player>::Initialize(Player&);
template void PointMovementGenerator<Creature>::Initialize(Creature&); template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &diff);
template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &diff); template void PointMovementGenerator<Player>::MovementInform(Player&);
template void PointMovementGenerator<Creature>::Initialize(Creature&);
template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &diff);
+200 -199
View File
@@ -1,199 +1,200 @@
/* /*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "QuestDef.h" #include "QuestDef.h"
#include "Player.h" #include "Player.h"
#include "World.h" #include "World.h"
Quest::Quest(Field * questRecord) Quest::Quest(Field * questRecord)
{ {
QuestId = questRecord[0].GetUInt32(); QuestId = questRecord[0].GetUInt32();
ZoneOrSort = questRecord[1].GetInt32(); QuestMethod = questRecord[1].GetUInt32();
SkillOrClass = questRecord[2].GetInt32(); ZoneOrSort = questRecord[2].GetInt32();
MinLevel = questRecord[3].GetUInt32(); SkillOrClass = questRecord[3].GetInt32();
QuestLevel = questRecord[4].GetUInt32(); MinLevel = questRecord[4].GetUInt32();
Type = questRecord[5].GetUInt32(); QuestLevel = questRecord[5].GetUInt32();
RequiredRaces = questRecord[6].GetUInt32(); Type = questRecord[6].GetUInt32();
RequiredSkillValue = questRecord[7].GetUInt32(); RequiredRaces = questRecord[7].GetUInt32();
RepObjectiveFaction = questRecord[8].GetUInt32(); RequiredSkillValue = questRecord[8].GetUInt32();
RepObjectiveValue = questRecord[9].GetInt32(); RepObjectiveFaction = questRecord[9].GetUInt32();
RequiredMinRepFaction = questRecord[10].GetUInt32(); RepObjectiveValue = questRecord[10].GetInt32();
RequiredMinRepValue = questRecord[11].GetInt32(); RequiredMinRepFaction = questRecord[11].GetUInt32();
RequiredMaxRepFaction = questRecord[12].GetUInt32(); RequiredMinRepValue = questRecord[12].GetInt32();
RequiredMaxRepValue = questRecord[13].GetInt32(); RequiredMaxRepFaction = questRecord[13].GetUInt32();
SuggestedPlayers = questRecord[14].GetUInt32(); RequiredMaxRepValue = questRecord[14].GetInt32();
LimitTime = questRecord[15].GetUInt32(); SuggestedPlayers = questRecord[15].GetUInt32();
QuestFlags = questRecord[16].GetUInt16(); LimitTime = questRecord[16].GetUInt32();
uint32 SpecialFlags = questRecord[17].GetUInt16(); QuestFlags = questRecord[17].GetUInt16();
CharTitleId = questRecord[18].GetUInt32(); uint32 SpecialFlags = questRecord[18].GetUInt16();
PrevQuestId = questRecord[19].GetInt32(); CharTitleId = questRecord[19].GetUInt32();
NextQuestId = questRecord[20].GetInt32(); PrevQuestId = questRecord[20].GetInt32();
ExclusiveGroup = questRecord[21].GetInt32(); NextQuestId = questRecord[21].GetInt32();
NextQuestInChain = questRecord[22].GetUInt32(); ExclusiveGroup = questRecord[22].GetInt32();
SrcItemId = questRecord[23].GetUInt32(); NextQuestInChain = questRecord[23].GetUInt32();
SrcItemCount = questRecord[24].GetUInt32(); SrcItemId = questRecord[24].GetUInt32();
SrcSpell = questRecord[25].GetUInt32(); SrcItemCount = questRecord[25].GetUInt32();
Title = questRecord[26].GetCppString(); SrcSpell = questRecord[26].GetUInt32();
Details = questRecord[27].GetCppString(); Title = questRecord[27].GetCppString();
Objectives = questRecord[28].GetCppString(); Details = questRecord[28].GetCppString();
OfferRewardText = questRecord[29].GetCppString(); Objectives = questRecord[29].GetCppString();
RequestItemsText = questRecord[30].GetCppString(); OfferRewardText = questRecord[30].GetCppString();
EndText = questRecord[31].GetCppString(); RequestItemsText = questRecord[31].GetCppString();
EndText = questRecord[32].GetCppString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ObjectiveText[i] = questRecord[32+i].GetCppString(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ObjectiveText[i] = questRecord[33+i].GetCppString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqItemId[i] = questRecord[36+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqItemId[i] = questRecord[37+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqItemCount[i] = questRecord[40+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqItemCount[i] = questRecord[41+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
ReqSourceId[i] = questRecord[44+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
ReqSourceId[i] = questRecord[45+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
ReqSourceCount[i] = questRecord[48+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
ReqSourceCount[i] = questRecord[49+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
ReqSourceRef[i] = questRecord[52+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
ReqSourceRef[i] = questRecord[53+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqCreatureOrGOId[i] = questRecord[56+i].GetInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqCreatureOrGOCount[i] = questRecord[60+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqSpell[i] = questRecord[64+i].GetUInt32(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqSpell[i] = questRecord[65+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
RewChoiceItemId[i] = questRecord[68+i].GetUInt32(); for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
RewChoiceItemId[i] = questRecord[69+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
RewChoiceItemCount[i] = questRecord[74+i].GetUInt32(); for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
RewChoiceItemCount[i] = questRecord[75+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
RewItemId[i] = questRecord[80+i].GetUInt32(); for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
RewItemId[i] = questRecord[81+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
RewItemCount[i] = questRecord[84+i].GetUInt32(); for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
RewItemCount[i] = questRecord[85+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
RewRepFaction[i] = questRecord[88+i].GetUInt32(); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
RewRepFaction[i] = questRecord[89+i].GetUInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
RewRepValue[i] = questRecord[93+i].GetInt32(); for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
RewRepValue[i] = questRecord[94+i].GetInt32();
RewOrReqMoney = questRecord[98].GetInt32();
RewMoneyMaxLevel = questRecord[99].GetUInt32(); RewOrReqMoney = questRecord[99].GetInt32();
RewSpell = questRecord[100].GetUInt32(); RewMoneyMaxLevel = questRecord[100].GetUInt32();
RewSpellCast = questRecord[101].GetUInt32(); RewSpell = questRecord[101].GetUInt32();
RewMailTemplateId = questRecord[102].GetUInt32(); RewSpellCast = questRecord[102].GetUInt32();
RewMailDelaySecs = questRecord[103].GetUInt32(); RewMailTemplateId = questRecord[103].GetUInt32();
PointMapId = questRecord[104].GetUInt32(); RewMailDelaySecs = questRecord[104].GetUInt32();
PointX = questRecord[105].GetFloat(); PointMapId = questRecord[105].GetUInt32();
PointY = questRecord[106].GetFloat(); PointX = questRecord[106].GetFloat();
PointOpt = questRecord[107].GetUInt32(); PointY = questRecord[107].GetFloat();
PointOpt = questRecord[108].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
DetailsEmote[i] = questRecord[108+i].GetUInt32(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
DetailsEmote[i] = questRecord[109+i].GetUInt32();
IncompleteEmote = questRecord[112].GetUInt32();
CompleteEmote = questRecord[113].GetUInt32(); IncompleteEmote = questRecord[113].GetUInt32();
CompleteEmote = questRecord[114].GetUInt32();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
OfferRewardEmote[i] = questRecord[114+i].GetInt32(); for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
OfferRewardEmote[i] = questRecord[115+i].GetInt32();
QuestStartScript = questRecord[118].GetUInt32();
QuestCompleteScript = questRecord[119].GetUInt32(); QuestStartScript = questRecord[119].GetUInt32();
QuestCompleteScript = questRecord[120].GetUInt32();
QuestFlags |= SpecialFlags << 16;
QuestFlags |= SpecialFlags << 16;
m_reqitemscount = 0;
m_reqCreatureOrGOcount = 0; m_reqitemscount = 0;
m_rewitemscount = 0; m_reqCreatureOrGOcount = 0;
m_rewchoiceitemscount = 0; m_rewitemscount = 0;
m_rewchoiceitemscount = 0;
for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++)
{ for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++)
if ( ReqItemId[i] ) {
++m_reqitemscount; if ( ReqItemId[i] )
if ( ReqCreatureOrGOId[i] ) ++m_reqitemscount;
++m_reqCreatureOrGOcount; if ( ReqCreatureOrGOId[i] )
} ++m_reqCreatureOrGOcount;
}
for (int i=0; i < QUEST_REWARDS_COUNT; i++)
{ for (int i=0; i < QUEST_REWARDS_COUNT; i++)
if ( RewItemId[i] ) {
++m_rewitemscount; if ( RewItemId[i] )
} ++m_rewitemscount;
}
for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
{ for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
if (RewChoiceItemId[i]) {
++m_rewchoiceitemscount; if (RewChoiceItemId[i])
} ++m_rewchoiceitemscount;
} }
}
uint32 Quest::XPValue( Player *pPlayer ) const
{ uint32 Quest::XPValue( Player *pPlayer ) const
if( pPlayer ) {
{ if( pPlayer )
if( RewMoneyMaxLevel > 0 ) {
{ if( RewMoneyMaxLevel > 0 )
uint32 pLevel = pPlayer->getLevel(); {
uint32 qLevel = QuestLevel; uint32 pLevel = pPlayer->getLevel();
float fullxp = 0; uint32 qLevel = QuestLevel;
if (qLevel >= 65) float fullxp = 0;
fullxp = RewMoneyMaxLevel / 6.0f; if (qLevel >= 65)
else if (qLevel == 64) fullxp = RewMoneyMaxLevel / 6.0f;
fullxp = RewMoneyMaxLevel / 4.8f; else if (qLevel == 64)
else if (qLevel == 63) fullxp = RewMoneyMaxLevel / 4.8f;
fullxp = RewMoneyMaxLevel / 3.6f; else if (qLevel == 63)
else if (qLevel == 62) fullxp = RewMoneyMaxLevel / 3.6f;
fullxp = RewMoneyMaxLevel / 2.4f; else if (qLevel == 62)
else if (qLevel == 61) fullxp = RewMoneyMaxLevel / 2.4f;
fullxp = RewMoneyMaxLevel / 1.2f; else if (qLevel == 61)
else if (qLevel > 0 && qLevel <= 60) fullxp = RewMoneyMaxLevel / 1.2f;
fullxp = RewMoneyMaxLevel / 0.6f; else if (qLevel > 0 && qLevel <= 60)
fullxp = RewMoneyMaxLevel / 0.6f;
if( pLevel <= qLevel + 5 )
return (uint32)fullxp; if( pLevel <= qLevel + 5 )
else if( pLevel == qLevel + 6 ) return (uint32)fullxp;
return (uint32)(fullxp * 0.8f); else if( pLevel == qLevel + 6 )
else if( pLevel == qLevel + 7 ) return (uint32)(fullxp * 0.8f);
return (uint32)(fullxp * 0.6f); else if( pLevel == qLevel + 7 )
else if( pLevel == qLevel + 8 ) return (uint32)(fullxp * 0.6f);
return (uint32)(fullxp * 0.4f); else if( pLevel == qLevel + 8 )
else if( pLevel == qLevel + 9 ) return (uint32)(fullxp * 0.4f);
return (uint32)(fullxp * 0.2f); else if( pLevel == qLevel + 9 )
else return (uint32)(fullxp * 0.2f);
return (uint32)(fullxp * 0.1f); else
} return (uint32)(fullxp * 0.1f);
} }
return 0; }
} return 0;
}
int32 Quest::GetRewOrReqMoney() const
{ int32 Quest::GetRewOrReqMoney() const
if(RewOrReqMoney <=0) {
return RewOrReqMoney; if(RewOrReqMoney <=0)
return RewOrReqMoney;
return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY));
} return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY));
}
+332 -330
View File
@@ -1,330 +1,332 @@
/* /*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef MANGOSSERVER_QUEST_H #ifndef MANGOSSERVER_QUEST_H
#define MANGOSSERVER_QUEST_H #define MANGOSSERVER_QUEST_H
#include "Platform/Define.h" #include "Platform/Define.h"
#include "Database/DatabaseEnv.h" #include "Database/DatabaseEnv.h"
#include <string> #include <string>
#include <vector> #include <vector>
class Player; class Player;
class ObjectMgr; class ObjectMgr;
#define MAX_QUEST_LOG_SIZE 25 #define MAX_QUEST_LOG_SIZE 25
#define QUEST_OBJECTIVES_COUNT 4 #define QUEST_OBJECTIVES_COUNT 4
#define QUEST_SOURCE_ITEM_IDS_COUNT 4 #define QUEST_SOURCE_ITEM_IDS_COUNT 4
#define QUEST_REWARD_CHOICES_COUNT 6 #define QUEST_REWARD_CHOICES_COUNT 6
#define QUEST_REWARDS_COUNT 4 #define QUEST_REWARDS_COUNT 4
#define QUEST_DEPLINK_COUNT 10 #define QUEST_DEPLINK_COUNT 10
#define QUEST_REPUTATIONS_COUNT 5 #define QUEST_REPUTATIONS_COUNT 5
#define QUEST_EMOTE_COUNT 4 #define QUEST_EMOTE_COUNT 4
enum QuestFailedReasons enum QuestFailedReasons
{ {
INVALIDREASON_DONT_HAVE_REQ = 0, INVALIDREASON_DONT_HAVE_REQ = 0,
INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest. INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest.
INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race. INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race.
INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest. INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest.
INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time. INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time.
INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest
INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account. INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account.
INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest
INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage. INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage.
INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest. INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest.
INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today
INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time
}; };
enum QuestShareMessages enum QuestShareMessages
{ {
QUEST_PARTY_MSG_SHARING_QUEST = 0, QUEST_PARTY_MSG_SHARING_QUEST = 0,
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1, QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
QUEST_PARTY_MSG_ACCEPT_QUEST = 2, QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
QUEST_PARTY_MSG_REFUSE_QUEST = 3, QUEST_PARTY_MSG_REFUSE_QUEST = 3,
QUEST_PARTY_MSG_TOO_FAR = 4, QUEST_PARTY_MSG_TOO_FAR = 4,
QUEST_PARTY_MSG_BUSY = 5, QUEST_PARTY_MSG_BUSY = 5,
QUEST_PARTY_MSG_LOG_FULL = 6, QUEST_PARTY_MSG_LOG_FULL = 6,
QUEST_PARTY_MSG_HAVE_QUEST = 7, QUEST_PARTY_MSG_HAVE_QUEST = 7,
QUEST_PARTY_MSG_FINISH_QUEST = 8, QUEST_PARTY_MSG_FINISH_QUEST = 8,
}; };
enum __QuestTradeSkill enum __QuestTradeSkill
{ {
QUEST_TRSKILL_NONE = 0, QUEST_TRSKILL_NONE = 0,
QUEST_TRSKILL_ALCHEMY = 1, QUEST_TRSKILL_ALCHEMY = 1,
QUEST_TRSKILL_BLACKSMITHING = 2, QUEST_TRSKILL_BLACKSMITHING = 2,
QUEST_TRSKILL_COOKING = 3, QUEST_TRSKILL_COOKING = 3,
QUEST_TRSKILL_ENCHANTING = 4, QUEST_TRSKILL_ENCHANTING = 4,
QUEST_TRSKILL_ENGINEERING = 5, QUEST_TRSKILL_ENGINEERING = 5,
QUEST_TRSKILL_FIRSTAID = 6, QUEST_TRSKILL_FIRSTAID = 6,
QUEST_TRSKILL_HERBALISM = 7, QUEST_TRSKILL_HERBALISM = 7,
QUEST_TRSKILL_LEATHERWORKING = 8, QUEST_TRSKILL_LEATHERWORKING = 8,
QUEST_TRSKILL_POISONS = 9, QUEST_TRSKILL_POISONS = 9,
QUEST_TRSKILL_TAILORING = 10, QUEST_TRSKILL_TAILORING = 10,
QUEST_TRSKILL_MINING = 11, QUEST_TRSKILL_MINING = 11,
QUEST_TRSKILL_FISHING = 12, QUEST_TRSKILL_FISHING = 12,
QUEST_TRSKILL_SKINNING = 13, QUEST_TRSKILL_SKINNING = 13,
QUEST_TRSKILL_JEWELCRAFTING = 14, QUEST_TRSKILL_JEWELCRAFTING = 14,
}; };
enum QuestStatus enum QuestStatus
{ {
QUEST_STATUS_NONE = 0, QUEST_STATUS_NONE = 0,
QUEST_STATUS_COMPLETE = 1, QUEST_STATUS_COMPLETE = 1,
QUEST_STATUS_UNAVAILABLE = 2, QUEST_STATUS_UNAVAILABLE = 2,
QUEST_STATUS_INCOMPLETE = 3, QUEST_STATUS_INCOMPLETE = 3,
QUEST_STATUS_AVAILABLE = 4, QUEST_STATUS_AVAILABLE = 4,
MAX_QUEST_STATUS MAX_QUEST_STATUS
}; };
enum __QuestGiverStatus enum __QuestGiverStatus
{ {
DIALOG_STATUS_NONE = 0, DIALOG_STATUS_NONE = 0,
DIALOG_STATUS_UNAVAILABLE = 1, DIALOG_STATUS_UNAVAILABLE = 1,
DIALOG_STATUS_CHAT = 2, DIALOG_STATUS_CHAT = 2,
DIALOG_STATUS_INCOMPLETE = 3, DIALOG_STATUS_INCOMPLETE = 3,
DIALOG_STATUS_REWARD_REP = 4, DIALOG_STATUS_REWARD_REP = 4,
DIALOG_STATUS_AVAILABLE_REP = 5, DIALOG_STATUS_AVAILABLE_REP = 5,
DIALOG_STATUS_AVAILABLE = 6, DIALOG_STATUS_AVAILABLE = 6,
DIALOG_STATUS_REWARD2 = 7, // not yellow dot on minimap DIALOG_STATUS_REWARD2 = 7, // not yellow dot on minimap
DIALOG_STATUS_REWARD = 8 // yellow dot on minimap DIALOG_STATUS_REWARD = 8 // yellow dot on minimap
}; };
enum __QuestFlags enum __QuestFlags
{ {
// Flags used at server and sended to client // Flags used at server and sended to client
QUEST_FLAGS_STAY_ALIVE = 1, // Not used currently QUEST_FLAGS_STAY_ALIVE = 1, // Not used currently
QUEST_FLAGS_EVENT = 2, // Not used currently QUEST_FLAGS_PARTY_ACCEPT = 2, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
QUEST_FLAGS_EXPLORATION = 4, // Not used currently QUEST_FLAGS_EXPLORATION = 4, // Not used currently
QUEST_FLAGS_SHARABLE = 8, // Can be shared: Player::CanShareQuest() QUEST_FLAGS_SHARABLE = 8, // Can be shared: Player::CanShareQuest()
//QUEST_FLAGS_NONE2 = 16, // Not used currently //QUEST_FLAGS_NONE2 = 16, // Not used currently
QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content
QUEST_FLAGS_RAID = 64, // Not used currently QUEST_FLAGS_RAID = 64, // Not used currently
QUEST_FLAGS_TBC = 128, // Not used currently: Available if TBC expension enabled only QUEST_FLAGS_TBC = 128, // Not used currently: Available if TBC expension enabled only
QUEST_FLAGS_UNK2 = 256, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs QUEST_FLAGS_UNK2 = 256, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs
QUEST_FLAGS_HIDDEN_REWARDS = 512, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE)) QUEST_FLAGS_HIDDEN_REWARDS = 512, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
QUEST_FLAGS_AUTO_REWARDED = 1024, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side. QUEST_FLAGS_AUTO_REWARDED = 1024, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
QUEST_FLAGS_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests QUEST_FLAGS_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests
QUEST_FLAGS_DAILY = 4096, // Used to know quest is Daily one QUEST_FLAGS_DAILY = 4096, // Used to know quest is Daily one
// Mangos flags for set SpecialFlags in DB if required but used only at server // Mangos flags for set SpecialFlags in DB if required but used only at server
QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB
QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x020000, // Set by 2 in SpecialFlags from DB (if reequired area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL) QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x020000, // Set by 2 in SpecialFlags from DB (if reequired area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL)
QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT, QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT,
// Mangos flags for internal use only // Mangos flags for internal use only
QUEST_MANGOS_FLAGS_DELIVER = 0x040000, // Internal flag computed only QUEST_MANGOS_FLAGS_DELIVER = 0x040000, // Internal flag computed only
QUEST_MANGOS_FLAGS_SPEAKTO = 0x080000, // Internal flag computed only QUEST_MANGOS_FLAGS_SPEAKTO = 0x080000, // Internal flag computed only
QUEST_MANGOS_FLAGS_KILL_OR_CAST = 0x100000, // Internal flag computed only QUEST_MANGOS_FLAGS_KILL_OR_CAST = 0x100000, // Internal flag computed only
QUEST_MANGOS_FLAGS_TIMED = 0x200000, // Internal flag computed only QUEST_MANGOS_FLAGS_TIMED = 0x200000, // Internal flag computed only
}; };
struct QuestLocale struct QuestLocale
{ {
QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); } QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); }
std::vector<std::string> Title; std::vector<std::string> Title;
std::vector<std::string> Details; std::vector<std::string> Details;
std::vector<std::string> Objectives; std::vector<std::string> Objectives;
std::vector<std::string> OfferRewardText; std::vector<std::string> OfferRewardText;
std::vector<std::string> RequestItemsText; std::vector<std::string> RequestItemsText;
std::vector<std::string> EndText; std::vector<std::string> EndText;
std::vector< std::vector<std::string> > ObjectiveText; std::vector< std::vector<std::string> > ObjectiveText;
}; };
// This Quest class provides a convenient way to access a few pretotaled (cached) quest details, // This Quest class provides a convenient way to access a few pretotaled (cached) quest details,
// all base quest information, and any utility functions such as generating the amount of // all base quest information, and any utility functions such as generating the amount of
// xp to give // xp to give
class Quest class Quest
{ {
friend class ObjectMgr; friend class ObjectMgr;
public: public:
Quest(Field * questRecord); Quest(Field * questRecord);
uint32 XPValue( Player *pPlayer ) const; uint32 XPValue( Player *pPlayer ) const;
bool HasFlag( uint32 flag ) const { return ( QuestFlags & flag ) != 0; } bool HasFlag( uint32 flag ) const { return ( QuestFlags & flag ) != 0; }
void SetFlag( uint32 flag ) { QuestFlags |= flag; } void SetFlag( uint32 flag ) { QuestFlags |= flag; }
// table data accessors: // table data accessors:
uint32 GetQuestId() const { return QuestId; } uint32 GetQuestId() const { return QuestId; }
int32 GetZoneOrSort() const { return ZoneOrSort; } uint32 GetQuestMethod() const { return QuestMethod; }
int32 GetSkillOrClass() const { return SkillOrClass; } int32 GetZoneOrSort() const { return ZoneOrSort; }
uint32 GetMinLevel() const { return MinLevel; } int32 GetSkillOrClass() const { return SkillOrClass; }
uint32 GetQuestLevel() const { return QuestLevel; } uint32 GetMinLevel() const { return MinLevel; }
uint32 GetType() const { return Type; } uint32 GetQuestLevel() const { return QuestLevel; }
uint32 GetRequiredRaces() const { return RequiredRaces; } uint32 GetType() const { return Type; }
uint32 GetRequiredSkillValue() const { return RequiredSkillValue; } uint32 GetRequiredRaces() const { return RequiredRaces; }
uint32 GetRepObjectiveFaction() const { return RepObjectiveFaction; } uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
int32 GetRepObjectiveValue() const { return RepObjectiveValue; } uint32 GetRepObjectiveFaction() const { return RepObjectiveFaction; }
uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; } int32 GetRepObjectiveValue() const { return RepObjectiveValue; }
int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; } uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; }
uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; } int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; }
int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; } uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
uint32 GetSuggestedPlayers() const { return SuggestedPlayers; } int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
uint32 GetLimitTime() const { return LimitTime; } uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
int32 GetPrevQuestId() const { return PrevQuestId; } uint32 GetLimitTime() const { return LimitTime; }
int32 GetNextQuestId() const { return NextQuestId; } int32 GetPrevQuestId() const { return PrevQuestId; }
int32 GetExclusiveGroup() const { return ExclusiveGroup; } int32 GetNextQuestId() const { return NextQuestId; }
uint32 GetNextQuestInChain() const { return NextQuestInChain; } int32 GetExclusiveGroup() const { return ExclusiveGroup; }
uint32 GetCharTitleId() const { return CharTitleId; } uint32 GetNextQuestInChain() const { return NextQuestInChain; }
uint32 GetSrcItemId() const { return SrcItemId; } uint32 GetCharTitleId() const { return CharTitleId; }
uint32 GetSrcItemCount() const { return SrcItemCount; } uint32 GetSrcItemId() const { return SrcItemId; }
uint32 GetSrcSpell() const { return SrcSpell; } uint32 GetSrcItemCount() const { return SrcItemCount; }
std::string GetTitle() const { return Title; } uint32 GetSrcSpell() const { return SrcSpell; }
std::string GetDetails() const { return Details; } std::string GetTitle() const { return Title; }
std::string GetObjectives() const { return Objectives; } std::string GetDetails() const { return Details; }
std::string GetOfferRewardText() const { return OfferRewardText; } std::string GetObjectives() const { return Objectives; }
std::string GetRequestItemsText() const { return RequestItemsText; } std::string GetOfferRewardText() const { return OfferRewardText; }
std::string GetEndText() const { return EndText; } std::string GetRequestItemsText() const { return RequestItemsText; }
int32 GetRewOrReqMoney() const; std::string GetEndText() const { return EndText; }
uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; } int32 GetRewOrReqMoney() const;
// use in XP calculation at client uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; }
uint32 GetRewSpell() const { return RewSpell; } // use in XP calculation at client
uint32 GetRewSpellCast() const { return RewSpellCast; } uint32 GetRewSpell() const { return RewSpell; }
uint32 GetRewMailTemplateId() const { return RewMailTemplateId; } uint32 GetRewSpellCast() const { return RewSpellCast; }
uint32 GetRewMailDelaySecs() const { return RewMailDelaySecs; } uint32 GetRewMailTemplateId() const { return RewMailTemplateId; }
uint32 GetPointMapId() const { return PointMapId; } uint32 GetRewMailDelaySecs() const { return RewMailDelaySecs; }
float GetPointX() const { return PointX; } uint32 GetPointMapId() const { return PointMapId; }
float GetPointY() const { return PointY; } float GetPointX() const { return PointX; }
uint32 GetPointOpt() const { return PointOpt; } float GetPointY() const { return PointY; }
uint32 GetIncompleteEmote() const { return IncompleteEmote; } uint32 GetPointOpt() const { return PointOpt; }
uint32 GetCompleteEmote() const { return CompleteEmote; } uint32 GetIncompleteEmote() const { return IncompleteEmote; }
uint32 GetQuestStartScript() const { return QuestStartScript; } uint32 GetCompleteEmote() const { return CompleteEmote; }
uint32 GetQuestCompleteScript() const { return QuestCompleteScript; } uint32 GetQuestStartScript() const { return QuestStartScript; }
bool IsRepeatable() const { return QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE; } uint32 GetQuestCompleteScript() const { return QuestCompleteScript; }
bool IsAutoComplete() const { return Objectives.empty(); } bool IsRepeatable() const { return QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE; }
uint32 GetFlags() const { return QuestFlags; } bool IsAutoComplete() const { return QuestMethod ? false : true; }
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; } uint32 GetFlags() const { return QuestFlags; }
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }
// multiple values
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]; // multiple values
uint32 ReqItemId[QUEST_OBJECTIVES_COUNT]; std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT]; uint32 ReqItemId[QUEST_OBJECTIVES_COUNT];
uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT]; uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT];
uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT]; uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT];
uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT]; uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT];
int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT];
uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT]; int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
uint32 ReqSpell[QUEST_OBJECTIVES_COUNT]; uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT];
uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT]; uint32 ReqSpell[QUEST_OBJECTIVES_COUNT];
uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT]; uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT];
uint32 RewItemId[QUEST_REWARDS_COUNT]; uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT];
uint32 RewItemCount[QUEST_REWARDS_COUNT]; uint32 RewItemId[QUEST_REWARDS_COUNT];
uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT]; uint32 RewItemCount[QUEST_REWARDS_COUNT];
int32 RewRepValue[QUEST_REPUTATIONS_COUNT]; uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT];
uint32 DetailsEmote[QUEST_EMOTE_COUNT]; int32 RewRepValue[QUEST_REPUTATIONS_COUNT];
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT]; uint32 DetailsEmote[QUEST_EMOTE_COUNT];
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT];
uint32 GetReqItemsCount() const { return m_reqitemscount; }
uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; } uint32 GetReqItemsCount() const { return m_reqitemscount; }
uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; } uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; }
uint32 GetRewItemsCount() const { return m_rewitemscount; } uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; }
uint32 GetRewItemsCount() const { return m_rewitemscount; }
typedef std::vector<int32> PrevQuests;
PrevQuests prevQuests; typedef std::vector<int32> PrevQuests;
typedef std::vector<uint32> PrevChainQuests; PrevQuests prevQuests;
PrevChainQuests prevChainQuests; typedef std::vector<uint32> PrevChainQuests;
PrevChainQuests prevChainQuests;
// cached data
private: // cached data
uint32 m_reqitemscount; private:
uint32 m_reqCreatureOrGOcount; uint32 m_reqitemscount;
uint32 m_rewchoiceitemscount; uint32 m_reqCreatureOrGOcount;
uint32 m_rewitemscount; uint32 m_rewchoiceitemscount;
uint32 m_rewitemscount;
// table data
protected: // table data
uint32 QuestId; protected:
int32 ZoneOrSort; uint32 QuestId;
int32 SkillOrClass; uint32 QuestMethod;
uint32 MinLevel; int32 ZoneOrSort;
uint32 QuestLevel; int32 SkillOrClass;
uint32 Type; uint32 MinLevel;
uint32 RequiredRaces; uint32 QuestLevel;
uint32 RequiredSkillValue; uint32 Type;
uint32 RepObjectiveFaction; uint32 RequiredRaces;
int32 RepObjectiveValue; uint32 RequiredSkillValue;
uint32 RequiredMinRepFaction; uint32 RepObjectiveFaction;
int32 RequiredMinRepValue; int32 RepObjectiveValue;
uint32 RequiredMaxRepFaction; uint32 RequiredMinRepFaction;
int32 RequiredMaxRepValue; int32 RequiredMinRepValue;
uint32 SuggestedPlayers; uint32 RequiredMaxRepFaction;
uint32 LimitTime; int32 RequiredMaxRepValue;
uint32 QuestFlags; uint32 SuggestedPlayers;
uint32 CharTitleId; uint32 LimitTime;
int32 PrevQuestId; uint32 QuestFlags;
int32 NextQuestId; uint32 CharTitleId;
int32 ExclusiveGroup; int32 PrevQuestId;
uint32 NextQuestInChain; int32 NextQuestId;
uint32 SrcItemId; int32 ExclusiveGroup;
uint32 SrcItemCount; uint32 NextQuestInChain;
uint32 SrcSpell; uint32 SrcItemId;
std::string Title; uint32 SrcItemCount;
std::string Details; uint32 SrcSpell;
std::string Objectives; std::string Title;
std::string OfferRewardText; std::string Details;
std::string RequestItemsText; std::string Objectives;
std::string EndText; std::string OfferRewardText;
int32 RewOrReqMoney; std::string RequestItemsText;
uint32 RewMoneyMaxLevel; std::string EndText;
uint32 RewSpell; int32 RewOrReqMoney;
uint32 RewSpellCast; uint32 RewMoneyMaxLevel;
uint32 RewMailTemplateId; uint32 RewSpell;
uint32 RewMailDelaySecs; uint32 RewSpellCast;
uint32 PointMapId; uint32 RewMailTemplateId;
float PointX; uint32 RewMailDelaySecs;
float PointY; uint32 PointMapId;
uint32 PointOpt; float PointX;
uint32 IncompleteEmote; float PointY;
uint32 CompleteEmote; uint32 PointOpt;
uint32 QuestStartScript; uint32 IncompleteEmote;
uint32 QuestCompleteScript; uint32 CompleteEmote;
}; uint32 QuestStartScript;
uint32 QuestCompleteScript;
enum QuestUpdateState };
{
QUEST_UNCHANGED = 0, enum QuestUpdateState
QUEST_CHANGED = 1, {
QUEST_NEW = 2 QUEST_UNCHANGED = 0,
}; QUEST_CHANGED = 1,
QUEST_NEW = 2
struct QuestStatusData };
{
QuestStatusData() struct QuestStatusData
: m_status(QUEST_STATUS_NONE),m_rewarded(false), {
m_explored(false), m_timer(0), uState(QUEST_NEW) QuestStatusData()
{ : m_status(QUEST_STATUS_NONE),m_rewarded(false),
memset(m_itemcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32)); m_explored(false), m_timer(0), uState(QUEST_NEW)
memset(m_creatureOrGOcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32)); {
} memset(m_itemcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
memset(m_creatureOrGOcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
QuestStatus m_status; }
bool m_rewarded;
bool m_explored; QuestStatus m_status;
uint32 m_timer; bool m_rewarded;
QuestUpdateState uState; bool m_explored;
uint32 m_timer;
uint32 m_itemcount[ QUEST_OBJECTIVES_COUNT ]; QuestUpdateState uState;
uint32 m_creatureOrGOcount[ QUEST_OBJECTIVES_COUNT ];
}; uint32 m_itemcount[ QUEST_OBJECTIVES_COUNT ];
#endif uint32 m_creatureOrGOcount[ QUEST_OBJECTIVES_COUNT ];
};
#endif
+163 -159
View File
@@ -1,159 +1,163 @@
/* /*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "Creature.h" #include "Creature.h"
#include "MapManager.h" #include "MapManager.h"
#include "RandomMovementGenerator.h" #include "RandomMovementGenerator.h"
#include "DestinationHolderImp.h" #include "DestinationHolderImp.h"
#include "Map.h" #include "Map.h"
#include "Util.h" #include "Util.h"
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV" #define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
template<> template<>
void void
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature) RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{ {
float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist; float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist;
creature.GetRespawnCoord(X, Y, Z); creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance);
creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance);
z = creature.GetPositionZ();
z = creature.GetPositionZ(); uint32 mapid=creature.GetMapId();
uint32 mapid=creature.GetMapId(); Map const* map = MapManager::Instance().GetBaseMap(mapid);
Map const* map = MapManager::Instance().GetBaseMap(mapid);
// For 2D/3D system selection
// For 2D/3D system selection bool is_land_ok = creature.canWalk();
bool is_land_ok = creature.canWalk(); bool is_water_ok = creature.canSwim();
bool is_water_ok = creature.canSwim(); bool is_air_ok = creature.canFly();
bool is_air_ok = creature.canFly();
const float angle = rand_norm()*(M_PI*2);
const float angle = rand_norm()*(M_PI*2); const float range = rand_norm()*wander_distance;
const float range = rand_norm()*wander_distance; const float distanceX = range * cos(angle);
const float distanceX = range * cos(angle); const float distanceY = range * sin(angle);
const float distanceY = range * sin(angle);
nx = X + distanceX;
nx = X + distanceX; ny = Y + distanceY;
ny = Y + distanceY;
dist = distanceX*distanceX + distanceY*distanceY; // prevent invalid coordinates generation
MaNGOS::NormalizeMapCoord(nx);
if (is_air_ok) // 3D system above ground and above water (flying mode) MaNGOS::NormalizeMapCoord(ny);
{
const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change dist = distanceX*distanceX + distanceY*distanceY;
nz = Z + distanceZ;
float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height. if (is_air_ok) // 3D system above ground and above water (flying mode)
float wz = map->GetWaterLevel(nx, ny); {
if (tz >= nz || wz >= nz) const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change
return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick nz = Z + distanceZ;
} float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height.
//else if (is_water_ok) // 3D system under water and above ground (swimming mode) float wz = map->GetWaterLevel(nx, ny);
else // 2D only if (tz >= nz || wz >= nz)
{ return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE) }
// The fastest way to get an accurate result 90% of the time. //else if (is_water_ok) // 3D system under water and above ground (swimming mode)
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long. else // 2D only
nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check {
if (fabs(nz-Z)>dist) dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
{ // The fastest way to get an accurate result 90% of the time.
nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
if (fabs(nz-Z)>dist) nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check
{ if (fabs(nz-Z)>dist)
nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher {
if (fabs(nz-Z)>dist) nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above
return; // let's forget this bad coords where a z cannot be find and retry at next tick if (fabs(nz-Z)>dist)
} {
} nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher
} if (fabs(nz-Z)>dist)
return; // let's forget this bad coords where a z cannot be find and retry at next tick
Traveller<Creature> traveller(creature); }
creature.SetOrientation(creature.GetAngle(nx,ny)); }
i_destinationHolder.SetDestination(traveller, nx, ny, nz); }
creature.addUnitState(UNIT_STAT_ROAMING);
if (is_air_ok) Traveller<Creature> traveller(creature);
{ creature.SetOrientation(creature.GetAngle(nx,ny));
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); i_destinationHolder.SetDestination(traveller, nx, ny, nz);
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2); creature.addUnitState(UNIT_STAT_ROAMING);
} if (is_air_ok)
//else if (is_water_ok) // Swimming mode to be done with more than this check {
else i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
{ creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime())); }
creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE); //else if (is_water_ok) // Swimming mode to be done with more than this check
} else
} {
i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime()));
template<> creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
void }
RandomMovementGenerator<Creature>::Initialize(Creature &creature) }
{
if(!creature.isAlive()) template<>
return; void
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
if (creature.canFly()) {
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2); if(!creature.isAlive())
else return;
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE );
_setRandomLocation(creature); if (creature.canFly())
} creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
else
template<> creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE );
void _setRandomLocation(creature);
RandomMovementGenerator<Creature>::Reset(Creature &creature) }
{
Initialize(creature); template<>
} void
RandomMovementGenerator<Creature>::Reset(Creature &creature)
template<> {
bool Initialize(creature);
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff) }
{
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED)) template<>
{ bool
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
creature.clearUnitState(UNIT_STAT_ROAMING); {
return true; if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
} {
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
i_nextMoveTime.Update(diff); creature.clearUnitState(UNIT_STAT_ROAMING);
return true;
if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly()) }
creature.clearUnitState(UNIT_STAT_ROAMING);
i_nextMoveTime.Update(diff);
if(!i_destinationHolder.HasArrived() && creature.IsStopped())
creature.addUnitState(UNIT_STAT_ROAMING); if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
creature.clearUnitState(UNIT_STAT_ROAMING);
CreatureTraveller traveller(creature);
if(!i_destinationHolder.HasArrived() && creature.IsStopped())
if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) ) creature.addUnitState(UNIT_STAT_ROAMING);
{
if(i_nextMoveTime.Passed()) CreatureTraveller traveller(creature);
{
if (creature.canFly()) if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2); {
else if(i_nextMoveTime.Passed())
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE); {
_setRandomLocation(creature); if (creature.canFly())
} creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f) else
{ creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE);
creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE); _setRandomLocation(creature);
_setRandomLocation(creature); }
} else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f)
} {
return true; creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);
} _setRandomLocation(creature);
}
}
return true;
}
+5
View File
@@ -3681,6 +3681,11 @@ uint8 Spell::CanCast(bool strict)
(!m_targets.getItemTarget() || !m_targets.getItemTarget()->GetProto()->LockID || m_targets.getItemTarget()->GetOwner() != m_caster ) ) (!m_targets.getItemTarget() || !m_targets.getItemTarget()->GetProto()->LockID || m_targets.getItemTarget()->GetOwner() != m_caster ) )
return SPELL_FAILED_BAD_TARGETS; return SPELL_FAILED_BAD_TARGETS;
// In BattleGround players can use only flags and banners
if( ((Player*)m_caster)->InBattleGround() &&
!((Player*)m_caster)->isAllowUseBattleGroundObject() )
return SPELL_FAILED_TRY_AGAIN;
// get the lock entry // get the lock entry
LockEntry const *lockInfo = NULL; LockEntry const *lockInfo = NULL;
if (GameObject* go=m_targets.getGOTarget()) if (GameObject* go=m_targets.getGOTarget())
+103 -14
View File
@@ -52,6 +52,8 @@
#include "Language.h" #include "Language.h"
#include "SocialMgr.h" #include "SocialMgr.h"
#include "Util.h" #include "Util.h"
#include "TemporarySummon.h"
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
{ {
@@ -1006,10 +1008,78 @@ void Spell::EffectDummy(uint32 i)
m_caster->CastSpell(m_caster,42337,true,NULL); m_caster->CastSpell(m_caster,42337,true,NULL);
return; return;
} }
case 37573: //Temporal Phase Modulator
{
if(!unitTarget)
return;
TemporarySummon* tempSummon = dynamic_cast<TemporarySummon*>(unitTarget);
if(!tempSummon)
return;
uint32 health = tempSummon->GetHealth();
const uint32 entry_list[6] = {21821, 21820, 21817};
float x = tempSummon->GetPositionX();
float y = tempSummon->GetPositionY();
float z = tempSummon->GetPositionZ();
float o = tempSummon->GetOrientation();
tempSummon->UnSummon();
Creature* pCreature = m_caster->SummonCreature(entry_list[urand(0, 2)], x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000);
if (!pCreature)
return;
pCreature->SetHealth(health);
if(pCreature->AI())
pCreature->AI()->AttackStart(m_caster);
return;
}
case 34665: //Administer Antidote
{
if(!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER )
return;
if(!unitTarget)
return;
TemporarySummon* tempSummon = dynamic_cast<TemporarySummon*>(unitTarget);
if(!tempSummon)
return;
uint32 health = tempSummon->GetHealth();
float x = tempSummon->GetPositionX();
float y = tempSummon->GetPositionY();
float z = tempSummon->GetPositionZ();
float o = tempSummon->GetOrientation();
tempSummon->UnSummon();
Creature* pCreature = m_caster->SummonCreature(16992, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000);
if (!pCreature)
return;
pCreature->SetHealth(health);
((Player*)m_caster)->KilledMonster(16992,pCreature->GetGUID());
if (pCreature->AI())
pCreature->AI()->AttackStart(m_caster);
return;
}
case 44997: // Converting Sentry
{
//Converted Sentry Credit
m_caster->CastSpell(m_caster, 45009, true);
return;
}
case 45030: // Impale Emissary case 45030: // Impale Emissary
{ {
// Emissary of Hate Credit // Emissary of Hate Credit
m_caster->CastSpell(m_caster,45088,true); m_caster->CastSpell(m_caster, 45088, true);
return; return;
} }
case 50243: // Teach Language case 50243: // Teach Language
@@ -1102,6 +1172,16 @@ void Spell::EffectDummy(uint32 i)
} }
return; return;
} }
case 32826:
{
if ( unitTarget && unitTarget->GetTypeId() == TYPEID_UNIT )
{
//Polymorph Cast Visual Rank 1
const uint32 spell_list[6] = {32813, 32816, 32817, 32818, 32819, 32820};
unitTarget->CastSpell( unitTarget, spell_list[urand(0, 5)], true);
}
return;
}
} }
break; break;
case SPELLFAMILY_WARRIOR: case SPELLFAMILY_WARRIOR:
@@ -2760,27 +2840,26 @@ void Spell::EffectOpenLock(uint32 /*i*/)
if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune || if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune ||
goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK ) goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK )
{ {
if(BattleGround *bg = player->GetBattleGround())// in battleground //isAllowUseBattleGroundObject() already called in CanCast()
// in battleground check
if(BattleGround *bg = player->GetBattleGround())
{ {
if( !player->IsMounted() && // not mounted // check if it's correct bg
!player->HasStealthAura() && // not stealthed if(bg && bg->GetTypeID() == BATTLEGROUND_AB)
!player->HasInvisibilityAura() && // not invisible bg->EventPlayerClickedOnFlag(player, gameObjTarget);
player->isAlive() ) // live player return;
{
// check if it's correct bg
if(bg && bg->GetTypeID() == BATTLEGROUND_AB)
bg->EventPlayerClickedOnFlag(player, gameObjTarget);
return;
}
} }
} }
else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND) else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
{ {
//isAllowUseBattleGroundObject() already called in CanCast()
// in battleground check
if(BattleGround *bg = player->GetBattleGround()) if(BattleGround *bg = player->GetBattleGround())
{
if(bg->GetTypeID() == BATTLEGROUND_EY) if(bg->GetTypeID() == BATTLEGROUND_EY)
bg->EventPlayerClickedOnFlag(player, gameObjTarget); bg->EventPlayerClickedOnFlag(player, gameObjTarget);
return; return;
}
} }
lockId = gameObjTarget->GetLockId(); lockId = gameObjTarget->GetLockId();
guid = gameObjTarget->GetGUID(); guid = gameObjTarget->GetGUID();
@@ -4751,6 +4830,16 @@ void Spell::EffectScriptEffect(uint32 effIndex)
unitTarget->CastSpell(unitTarget, spellId, true); unitTarget->CastSpell(unitTarget, spellId, true);
break; break;
} }
//5,000 Gold
case 46642:
{
if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
((Player*)unitTarget)->ModifyMoney(50000000);
break;
}
} }
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN )
+211 -202
View File
@@ -1,202 +1,211 @@
/* /*
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "ByteBuffer.h" #include "ByteBuffer.h"
#include "TargetedMovementGenerator.h" #include "TargetedMovementGenerator.h"
#include "Errors.h" #include "Errors.h"
#include "Creature.h" #include "Creature.h"
#include "MapManager.h" #include "MapManager.h"
#include "DestinationHolderImp.h" #include "DestinationHolderImp.h"
#include "World.h" #include "World.h"
#define SMALL_ALPHA 0.05f #define SMALL_ALPHA 0.05f
#include <cmath> #include <cmath>
/* /*
struct StackCleaner struct StackCleaner
{ {
Creature &i_creature; Creature &i_creature;
StackCleaner(Creature &creature) : i_creature(creature) {} StackCleaner(Creature &creature) : i_creature(creature) {}
void Done(void) { i_creature.StopMoving(); } void Done(void) { i_creature.StopMoving(); }
~StackCleaner() ~StackCleaner()
{ {
i_creature->Clear(); i_creature->Clear();
} }
}; };
*/ */
template<class T> template<class T>
void void
TargetedMovementGenerator<T>::_setTargetLocation(T &owner) TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
{ {
if( !i_target.isValid() || !&owner ) if( !i_target.isValid() || !&owner )
return; return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) ) if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) )
return; return;
// prevent redundant micro-movement for pets, other followers. // prevent redundant micro-movement for pets, other followers.
if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset)) if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
return; return;
float x, y, z; float x, y, z;
if(!i_offset) if(!i_offset)
{ {
// to nearest contact position // to nearest contact position
i_target->GetContactPoint( &owner, x, y, z ); i_target->GetContactPoint( &owner, x, y, z );
} }
else else
{ {
// to at i_offset distance from target and i_angle from target facing // to at i_offset distance from target and i_angle from target facing
i_target->GetClosePoint(x,y,z,owner.GetObjectSize(),i_offset,i_angle); i_target->GetClosePoint(x,y,z,owner.GetObjectSize(),i_offset,i_angle);
} }
/* /*
We MUST not check the distance difference and avoid setting the new location for smaller distances. We MUST not check the distance difference and avoid setting the new location for smaller distances.
By that we risk having far too many GetContactPoint() calls freezing the whole system. By that we risk having far too many GetContactPoint() calls freezing the whole system.
In TargetedMovementGenerator<T>::Update() we check the distance to the target and at In TargetedMovementGenerator<T>::Update() we check the distance to the target and at
some range we calculate a new position. The calculation takes some processor cycles due to vmaps. some range we calculate a new position. The calculation takes some processor cycles due to vmaps.
If the distance to the target it too large to ignore, If the distance to the target it too large to ignore,
but the distance to the new contact point is short enough to be ignored, but the distance to the new contact point is short enough to be ignored,
we will calculate a new contact point each update loop, but will never move to it. we will calculate a new contact point each update loop, but will never move to it.
The system will freeze. The system will freeze.
ralf ralf
//We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize //We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize
float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE; float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE;
if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize ) if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
return; return;
*/ */
Traveller<T> traveller(owner); Traveller<T> traveller(owner);
i_destinationHolder.SetDestination(traveller, x, y, z); i_destinationHolder.SetDestination(traveller, x, y, z);
owner.addUnitState(UNIT_STAT_CHASE); owner.addUnitState(UNIT_STAT_CHASE);
} if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
template<class T> }
void
TargetedMovementGenerator<T>::Initialize(T &owner) template<class T>
{ void
if(!&owner) TargetedMovementGenerator<T>::Initialize(T &owner)
return; {
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); if(!&owner)
_setTargetLocation(owner); return;
} owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
template<class T> if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
void owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
TargetedMovementGenerator<T>::Finalize(T &owner)
{ _setTargetLocation(owner);
owner.clearUnitState(UNIT_STAT_CHASE); }
}
template<class T>
template<class T> void
void TargetedMovementGenerator<T>::Finalize(T &owner)
TargetedMovementGenerator<T>::Reset(T &owner) {
{ owner.clearUnitState(UNIT_STAT_CHASE);
Initialize(owner); }
}
template<class T>
template<class T> void
bool TargetedMovementGenerator<T>::Reset(T &owner)
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff) {
{ Initialize(owner);
if(!i_target.isValid()) }
return false;
template<class T>
if( !&owner || !owner.isAlive()) bool
return true; TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) ) if(!i_target.isValid())
return true; return false;
// prevent movement while casting spells with cast time or channel time if( !&owner || !owner.isAlive())
if ( owner.IsNonMeleeSpellCasted(false, false, true)) return true;
{
if (!owner.IsStopped()) if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
owner.StopMoving(); return true;
return true;
} // prevent movement while casting spells with cast time or channel time
if ( owner.IsNonMeleeSpellCasted(false, false, true))
// prevent crash after creature killed pet {
if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget()) if (!owner.IsStopped())
return true; owner.StopMoving();
return true;
Traveller<T> traveller(owner); }
if( !i_destinationHolder.HasDestination() ) // prevent crash after creature killed pet
_setTargetLocation(owner); if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
if( owner.IsStopped() && !i_destinationHolder.HasArrived() ) return true;
{
owner.addUnitState(UNIT_STAT_CHASE); Traveller<T> traveller(owner);
i_destinationHolder.StartTravel(traveller);
return true; if( !i_destinationHolder.HasDestination() )
} _setTargetLocation(owner);
if( owner.IsStopped() && !i_destinationHolder.HasArrived() )
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false)) {
{ owner.addUnitState(UNIT_STAT_CHASE);
// put targeted movement generators on a higher priority if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
if (owner.GetObjectSize()) owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
i_destinationHolder.ResetUpdate(50);
i_destinationHolder.StartTravel(traveller);
float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE); return true;
}
//More distance let have better performance, less distance let have more sensitive reaction at target move.
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
// try to counter precision differences {
if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist) // put targeted movement generators on a higher priority
{ if (owner.GetObjectSize())
owner.SetInFront(i_target.getTarget()); // Set new Angle For Map:: i_destinationHolder.ResetUpdate(50);
_setTargetLocation(owner); //Calculate New Dest and Send data To Player
} float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
// Update the Angle of the target only for Map::, no need to send packet for player
else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) ) //More distance let have better performance, less distance let have more sensitive reaction at target move.
owner.SetInFront(i_target.getTarget());
// try to counter precision differences
if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel ) if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist)
{ {
i_recalculateTravel = false; owner.SetInFront(i_target.getTarget()); // Set new Angle For Map::
//Angle update will take place into owner.StopMoving() _setTargetLocation(owner); //Calculate New Dest and Send data To Player
owner.SetInFront(i_target.getTarget()); }
// Update the Angle of the target only for Map::, no need to send packet for player
owner.StopMoving(); else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) )
if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW)) owner.SetInFront(i_target.getTarget());
owner.Attack(i_target.getTarget(),true);
} if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel )
} {
return true; i_recalculateTravel = false;
} //Angle update will take place into owner.StopMoving()
owner.SetInFront(i_target.getTarget());
template<class T>
Unit* owner.StopMoving();
TargetedMovementGenerator<T>::GetTarget() const if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
{ owner.Attack(i_target.getTarget(),true);
return i_target.getTarget(); }
} }
return true;
template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &); }
template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
template void TargetedMovementGenerator<Player>::Initialize(Player &); template<class T>
template void TargetedMovementGenerator<Creature>::Initialize(Creature &); Unit*
template void TargetedMovementGenerator<Player>::Finalize(Player &); TargetedMovementGenerator<T>::GetTarget() const
template void TargetedMovementGenerator<Creature>::Finalize(Creature &); {
template void TargetedMovementGenerator<Player>::Reset(Player &); return i_target.getTarget();
template void TargetedMovementGenerator<Creature>::Reset(Creature &); }
template bool TargetedMovementGenerator<Player>::Update(Player &, const uint32 &);
template bool TargetedMovementGenerator<Creature>::Update(Creature &, const uint32 &); template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
template Unit* TargetedMovementGenerator<Player>::GetTarget() const; template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
template Unit* TargetedMovementGenerator<Creature>::GetTarget() const; template void TargetedMovementGenerator<Player>::Initialize(Player &);
template void TargetedMovementGenerator<Creature>::Initialize(Creature &);
template void TargetedMovementGenerator<Player>::Finalize(Player &);
template void TargetedMovementGenerator<Creature>::Finalize(Creature &);
template void TargetedMovementGenerator<Player>::Reset(Player &);
template void TargetedMovementGenerator<Creature>::Reset(Creature &);
template bool TargetedMovementGenerator<Player>::Update(Player &, const uint32 &);
template bool TargetedMovementGenerator<Creature>::Update(Creature &, const uint32 &);
template Unit* TargetedMovementGenerator<Player>::GetTarget() const;
template Unit* TargetedMovementGenerator<Creature>::GetTarget() const;
+2 -2
View File
@@ -112,7 +112,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &di
// Now we re-set destination to same node and start travel // Now we re-set destination to same node and start travel
creature.addUnitState(UNIT_STAT_ROAMING); creature.addUnitState(UNIT_STAT_ROAMING);
if (creature.canFly()) if (creature.canFly())
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2); creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
const WaypointNode &node = i_path->at(i_currentNode); const WaypointNode &node = i_path->at(i_currentNode);
i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
@@ -176,7 +176,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &di
{ {
creature.addUnitState(UNIT_STAT_ROAMING); creature.addUnitState(UNIT_STAT_ROAMING);
if (creature.canFly()) if (creature.canFly())
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2); creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
const WaypointNode &node = i_path->at(i_currentNode); const WaypointNode &node = i_path->at(i_currentNode);
i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
+4 -4
View File
@@ -52,8 +52,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,2,6721,676 FILEVERSION 0,3,6731,680
PRODUCTVERSION 0,2,6721,676 PRODUCTVERSION 0,3,6731,680
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
BLOCK "080004b0" BLOCK "080004b0"
BEGIN BEGIN
VALUE "FileDescription", "TrinityCore" VALUE "FileDescription", "TrinityCore"
VALUE "FileVersion", "0, 2, 6721, 676" VALUE "FileVersion", "0, 3, 6731, 680"
VALUE "InternalName", "TrinityCore" VALUE "InternalName", "TrinityCore"
VALUE "LegalCopyright", "Copyright (C) 2008" VALUE "LegalCopyright", "Copyright (C) 2008"
VALUE "OriginalFilename", "TrinityCore.exe" VALUE "OriginalFilename", "TrinityCore.exe"
VALUE "ProductName", "TrinityCore" VALUE "ProductName", "TrinityCore"
VALUE "ProductVersion", "0, 2, 6721, 676" VALUE "ProductVersion", "0, 3, 6731, 680"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
+4 -4
View File
@@ -52,8 +52,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,2,6721,676 FILEVERSION 0,3,6731,680
PRODUCTVERSION 0,2,6721,676 PRODUCTVERSION 0,3,6731,680
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
BLOCK "080004b0" BLOCK "080004b0"
BEGIN BEGIN
VALUE "FileDescription", "TrinityRealm" VALUE "FileDescription", "TrinityRealm"
VALUE "FileVersion", "0, 2, 6721, 676" VALUE "FileVersion", "0, 3, 6731, 680"
VALUE "InternalName", "TrinityRealm" VALUE "InternalName", "TrinityRealm"
VALUE "LegalCopyright", "Copyright (C) 2008" VALUE "LegalCopyright", "Copyright (C) 2008"
VALUE "OriginalFilename", "TrinityRealm.exe" VALUE "OriginalFilename", "TrinityRealm.exe"
VALUE "ProductName", "TrinityRealm" VALUE "ProductName", "TrinityRealm"
VALUE "ProductVersion", "0, 2, 6721, 676" VALUE "ProductVersion", "0, 3, 6731, 680"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
+10 -10
View File
@@ -49,7 +49,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="/MP /wd 4748" AdditionalOptions="/MP /wd 4748 /wd 4244"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers" AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
PreprocessorDefinitions="ACE_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" PreprocessorDefinitions="ACE_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
@@ -138,7 +138,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="/MP /wd 4748" AdditionalOptions="/MP /wd 4748 /wd 4244"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers" AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
PreprocessorDefinitions="ACE_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" PreprocessorDefinitions="ACE_BUILD_DLL;_DEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
@@ -228,7 +228,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="/MP /wd 4748" AdditionalOptions="/MP /wd 4748 /wd 4244"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers" AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
PreprocessorDefinitions="ACE_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" PreprocessorDefinitions="ACE_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
@@ -316,7 +316,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalOptions="/MP /wd 4748" AdditionalOptions="/MP /wd 4748 /wd 4244"
Optimization="2" Optimization="2"
AdditionalIncludeDirectories="..\..\dep\ACE_wrappers" AdditionalIncludeDirectories="..\..\dep\ACE_wrappers"
PreprocessorDefinitions="ACE_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" PreprocessorDefinitions="ACE_BUILD_DLL;NDEBUG;WIN32;_WINDOWS;_CRT_NONSTDC_NO_WARNINGS;_AMD64_;_WIN64;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
@@ -2853,11 +2853,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\dep\ACE_wrappers\ace\OS_Errno.h" RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_errno.h"
> >
</File> </File>
<File <File
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_errno.h" RelativePath="..\..\dep\ACE_wrappers\ace\OS_Errno.h"
> >
</File> </File>
<File <File
@@ -3237,11 +3237,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\dep\ACE_wrappers\ace\OS_String.h" RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_string.h"
> >
</File> </File>
<File <File
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_string.h" RelativePath="..\..\dep\ACE_wrappers\ace\OS_String.h"
> >
</File> </File>
<File <File
@@ -3285,11 +3285,11 @@
> >
</File> </File>
<File <File
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\sys\os_time.h" RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_time.h"
> >
</File> </File>
<File <File
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_time.h" RelativePath="..\..\dep\ACE_wrappers\ace\os_include\sys\os_time.h"
> >
</File> </File>
<File <File