[svn] * Little fix in RandomMovementGenerator
* Updated to 6731 and 680 --HG-- branch : trunk rename : 6721-676 => 6731-680
This commit is contained in:
@@ -2338,6 +2338,7 @@ INSERT INTO `mangos_string` VALUES
|
||||
(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),
|
||||
(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),
|
||||
(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),
|
||||
@@ -10485,6 +10486,7 @@ UNLOCK TABLES;
|
||||
DROP TABLE IF EXISTS `quest_template`;
|
||||
CREATE TABLE `quest_template` (
|
||||
`entry` mediumint(8) unsigned NOT NULL default '0',
|
||||
`Method` tinyint(3) unsigned NOT NULL default '2',
|
||||
`ZoneOrSort` smallint(6) NOT NULL default '0',
|
||||
`SkillOrClass` smallint(6) NOT NULL default '0',
|
||||
`MinLevel` tinyint(3) unsigned NOT NULL default '0',
|
||||
|
||||
@@ -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
@@ -35,8 +35,8 @@ void ScriptedAI::MoveInLineOfSight(Unit *who)
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,8 +54,8 @@ void ScriptedAI::AttackStart(Unit* who)
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -582,8 +582,8 @@ void Scripted_NoMovementAI::MoveInLineOfSight(Unit *who)
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -601,8 +601,8 @@ void Scripted_NoMovementAI::AttackStart(Unit* who)
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
case EVENT_T_SPAWNED:
|
||||
ProcessEvent(*i);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,12 +610,18 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
caster = target;
|
||||
}
|
||||
|
||||
//Interrupt any previous spell
|
||||
if (caster->IsNonMeleeSpellCasted(false) && param3 & CAST_INTURRUPT_PREVIOUS)
|
||||
caster->InterruptNonMeleeSpells(false);
|
||||
//Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
|
||||
bool canCast = !(caster->IsNonMeleeSpellCasted(false) && (param3 & CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS));
|
||||
|
||||
//Cast only if not casting or if spell is triggered
|
||||
if (param3 & CAST_TRIGGERED || !caster->IsNonMeleeSpellCasted(false))
|
||||
// If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
|
||||
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);
|
||||
|
||||
@@ -638,7 +642,14 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
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)
|
||||
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);
|
||||
}
|
||||
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()
|
||||
//(*i).Enabled = true;
|
||||
//(*i).Time = 0;
|
||||
break;
|
||||
//break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1029,8 +1040,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
case EVENT_T_EVADE:
|
||||
ProcessEvent(*i);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1050,8 +1059,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
case EVENT_T_DEATH:
|
||||
ProcessEvent(*i, killer);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1069,8 +1076,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
case EVENT_T_KILL:
|
||||
ProcessEvent(*i, victim);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1089,8 +1094,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
case EVENT_T_SUMMONED_UNIT:
|
||||
ProcessEvent(*i, pUnit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1145,8 +1148,8 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1193,8 +1196,8 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1215,8 +1218,6 @@ struct MANGOS_DLL_DECL Mob_EventAI : public ScriptedAI
|
||||
ProcessEvent(*i, pUnit);
|
||||
}
|
||||
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_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_AURA_NOT_PRESENT = 0x20, //Only casts the spell if the target does not have an aura from the spell
|
||||
};
|
||||
|
||||
enum EventFlags
|
||||
|
||||
+1
-3
@@ -104,8 +104,6 @@ struct MANGOS_DLL_DECL mob_stolen_soulAI : public ScriptedAI
|
||||
DoCast(m_creature->getVictim(), SPELL_MOONFIRE);
|
||||
Class_Timer = 10000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else Class_Timer -= diff;
|
||||
|
||||
@@ -204,8 +202,8 @@ struct MANGOS_DLL_DECL boss_exarch_maladaarAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -106,8 +106,8 @@ struct MANGOS_DLL_DECL boss_nexusprince_shaffarAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -115,8 +115,8 @@ struct MANGOS_DLL_DECL boss_talon_king_ikissAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -125,8 +125,8 @@ struct MANGOS_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,8 @@ struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,8 +95,8 @@ struct MANGOS_DLL_DECL boss_murmurAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ struct MANGOS_DLL_DECL npc_ragged_johnAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -117,8 +117,8 @@ struct MANGOS_DLL_DECL boss_omor_the_unscarredAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,8 +138,8 @@ struct MANGOS_DLL_DECL boss_omor_the_unscarredAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -108,8 +108,8 @@ struct MANGOS_DLL_DECL boss_watchkeeper_gargolmarAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
else if (!HasTaunted && m_creature->IsWithinDistInMap(who, 60.0f))
|
||||
|
||||
+2
-2
@@ -200,8 +200,8 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
|
||||
|
||||
if( !InCombat )
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,8 +237,8 @@ struct MANGOS_DLL_DECL boss_grand_warlock_nethekurseAI : public ScriptedAI
|
||||
|
||||
if( !InCombat )
|
||||
{
|
||||
Aggro(who);
|
||||
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))
|
||||
{
|
||||
//Check for base attack
|
||||
if( m_creature->isAttackReady())
|
||||
if( m_creature->isAttackReady() && m_creature->getVictim() )
|
||||
{
|
||||
m_creature->AttackerStateUpdate(m_creature->getVictim());
|
||||
m_creature->resetAttackTimer();
|
||||
}
|
||||
//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->resetAttackTimer(OFF_ATTACK);
|
||||
|
||||
@@ -163,9 +163,6 @@ class MANGOS_DLL_SPEC instance_molten_core : public ScriptedInstance
|
||||
case ID_FLAMEWAKERPRIEST:
|
||||
FlamewakerPriest = creature->GetGUID();
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -264,8 +264,6 @@ struct MANGOS_DLL_DECL npc_manaforge_control_consoleAI : public ScriptedAI
|
||||
}
|
||||
++Phase;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else Event_Timer -= diff;
|
||||
|
||||
|
||||
@@ -138,8 +138,8 @@ struct MANGOS_DLL_DECL npc_millhouse_manastormAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,8 +153,8 @@ struct MANGOS_DLL_DECL npc_millhouse_manastormAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -444,8 +444,6 @@ struct MANGOS_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
|
||||
case 7:
|
||||
pInstance->SetData(TYPE_WARDEN_5,IN_PROGRESS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CanSpawn = true;
|
||||
}
|
||||
@@ -505,8 +503,6 @@ struct MANGOS_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
|
||||
DoYell(YELL_WELCOME,LANG_UNIVERSAL,NULL);
|
||||
DoPlaySoundToSet(m_creature,SOUND_WELCOME);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CanSpawn = false;
|
||||
++Phase;
|
||||
@@ -553,8 +549,6 @@ struct MANGOS_DLL_DECL npc_warden_mellicharAI : public ScriptedAI
|
||||
DoPrepareForPhase();
|
||||
EventProgress_Timer = 15000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else EventProgress_Timer -= diff;
|
||||
|
||||
@@ -130,8 +130,8 @@ struct MANGOS_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,8 +148,8 @@ struct MANGOS_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
|
||||
|
||||
if( !InCombat )
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,8 +236,6 @@ struct MANGOS_DLL_DECL boss_harbinger_skyrissAI : public ScriptedAI
|
||||
case 3:
|
||||
Intro = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else Intro_Timer -=diff;
|
||||
}
|
||||
|
||||
@@ -215,8 +215,8 @@ struct MANGOS_DLL_DECL advisorbase_ai : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,8 +234,8 @@ struct MANGOS_DLL_DECL advisorbase_ai : public ScriptedAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -863,14 +863,10 @@ struct MANGOS_DLL_DECL boss_kaelthasAI : public ScriptedAI
|
||||
DoYell(SAY_SUMMON_PHOENIX1, LANG_UNIVERSAL, NULL);
|
||||
DoPlaySoundToSet(m_creature, SOUND_SUMMON_PHOENIX1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
DoYell(SAY_SUMMON_PHOENIX2, LANG_UNIVERSAL, NULL);
|
||||
DoPlaySoundToSet(m_creature, SOUND_SUMMON_PHOENIX2);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Phoenix_Timer = 60000;
|
||||
@@ -1252,8 +1248,8 @@ struct MANGOS_DLL_DECL boss_grand_astromancer_capernianAI : public advisorbase_a
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,8 +665,8 @@ struct MANGOS_DLL_DECL boss_veklorAI : public boss_twinemperorsAI
|
||||
|
||||
if (!InCombat)
|
||||
{
|
||||
Aggro(who);
|
||||
InCombat = true;
|
||||
Aggro(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,62 +34,6 @@
|
||||
|
||||
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()
|
||||
{
|
||||
static ChatCommand serverCommandTable[] =
|
||||
|
||||
@@ -28,19 +28,6 @@ class Player;
|
||||
class Unit;
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
||||
+127
-34
@@ -62,15 +62,36 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
|
||||
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() :
|
||||
Unit(), i_AI(NULL),
|
||||
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_gossipOptionLoaded(false),m_emoteState(0), m_isPet(false), m_isTotem(false),
|
||||
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_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL)
|
||||
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0)
|
||||
{
|
||||
m_valuesCount = UNIT_END;
|
||||
|
||||
@@ -87,7 +108,7 @@ Creature::~Creature()
|
||||
{
|
||||
CleanupsBeforeDelete();
|
||||
|
||||
m_vendor_items.clear();
|
||||
m_vendorItemCounts.clear();
|
||||
|
||||
delete i_AI;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
LoadCreaturesAddon();
|
||||
}
|
||||
|
||||
return bResult;
|
||||
@@ -673,16 +695,16 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
|
||||
cantalking=false;
|
||||
break;
|
||||
case GOSSIP_OPTION_VENDOR:
|
||||
// load vendor items if not yet
|
||||
LoadGoods();
|
||||
|
||||
if(!GetItemCount())
|
||||
{
|
||||
VendorItemData const* vItems = GetVendorItems();
|
||||
if(!vItems || vItems->Empty())
|
||||
{
|
||||
sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.",
|
||||
GetGUIDLow(),GetEntry());
|
||||
cantalking=false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GOSSIP_OPTION_TRAINER:
|
||||
if(!isCanTrainingOf(pPlayer,false))
|
||||
cantalking=false;
|
||||
@@ -934,6 +956,9 @@ uint32 Creature::GetGossipTextId(uint32 action, uint32 zoneid)
|
||||
|
||||
uint32 Creature::GetNpcTextId()
|
||||
{
|
||||
if (!m_DBTableGuid)
|
||||
return DEFAULT_GOSSIP_MESSAGE;
|
||||
|
||||
if(uint32 pos = objmgr.GetNpcGossip(m_DBTableGuid))
|
||||
return pos;
|
||||
|
||||
@@ -1046,6 +1071,8 @@ void Creature::SaveToDB()
|
||||
void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
|
||||
{
|
||||
// update in loaded data
|
||||
if (!m_DBTableGuid)
|
||||
m_DBTableGuid = GetGUIDLow();
|
||||
CreatureData& data = objmgr.NewOrExistCreatureData(m_DBTableGuid);
|
||||
|
||||
uint32 displayId = GetNativeDisplayId();
|
||||
@@ -1237,7 +1264,6 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const
|
||||
|
||||
Object::_Create(guidlow, Entry, HIGHGUID_UNIT);
|
||||
|
||||
m_DBTableGuid = guidlow;
|
||||
if(!UpdateEntry(Entry, team, data))
|
||||
return false;
|
||||
|
||||
@@ -1263,7 +1289,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 stored_guid = guid;
|
||||
m_DBTableGuid = guid;
|
||||
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
|
||||
|
||||
uint16 team = 0;
|
||||
@@ -1278,9 +1304,6 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_DBTableGuid = stored_guid;
|
||||
LoadCreaturesAddon();
|
||||
|
||||
m_respawnradius = data->spawndist;
|
||||
|
||||
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
|
||||
{
|
||||
QuestRelations const& qr = objmgr.mCreatureQuestRelations;
|
||||
@@ -1388,6 +1393,12 @@ bool Creature::hasInvolvedQuest(uint32 quest_id) const
|
||||
|
||||
void Creature::DeleteFromDB()
|
||||
{
|
||||
if (!m_DBTableGuid)
|
||||
{
|
||||
sLog.outDebug("Trying to delete not saved creature!");
|
||||
return;
|
||||
}
|
||||
|
||||
objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
|
||||
objmgr.DeleteCreatureData(m_DBTableGuid);
|
||||
|
||||
@@ -1494,7 +1505,8 @@ void Creature::Respawn()
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1716,7 +1728,7 @@ void Creature::CallAssistence()
|
||||
|
||||
void Creature::SaveRespawnTime()
|
||||
{
|
||||
if(isPet())
|
||||
if(isPet() || !m_DBTableGuid)
|
||||
return;
|
||||
|
||||
if(m_respawnTime > time(NULL)) // dead (no corpse)
|
||||
@@ -1752,8 +1764,11 @@ bool Creature::IsOutOfThreatArea(Unit* pVictim) const
|
||||
|
||||
CreatureDataAddon const* Creature::GetCreatureAddon() const
|
||||
{
|
||||
if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid))
|
||||
return addon;
|
||||
if (m_DBTableGuid)
|
||||
{
|
||||
if(CreatureDataAddon const* addon = ObjectMgr::GetCreatureAddon(m_DBTableGuid))
|
||||
return addon;
|
||||
}
|
||||
|
||||
// dependent from heroic mode entry
|
||||
return ObjectMgr::GetCreatureTemplateAddon(GetCreatureInfo()->Entry);
|
||||
@@ -1956,6 +1971,84 @@ char const* Creature::GetScriptName() const
|
||||
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
|
||||
{
|
||||
return objmgr.GetNpcTrainerSpells(GetEntry());
|
||||
|
||||
+55
-52
@@ -112,19 +112,6 @@ struct GossipOption
|
||||
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
|
||||
{
|
||||
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)
|
||||
#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
|
||||
{
|
||||
uint32 spell;
|
||||
@@ -418,41 +455,9 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||
uint32 GetCurrentEquipmentId() { return m_equipmentId; }
|
||||
float GetSpellDamageMod(int32 Rank);
|
||||
|
||||
/*********************************************************/
|
||||
/*** VENDOR SYSTEM ***/
|
||||
/*********************************************************/
|
||||
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;
|
||||
}
|
||||
VendorItemData const* GetVendorItems() const;
|
||||
uint32 GetVendorItemCurrentCount(VendorItem const* vItem);
|
||||
uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count);
|
||||
|
||||
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);
|
||||
|
||||
// vendor items
|
||||
typedef std::vector<CreatureItem> CreatureItems;
|
||||
CreatureItems m_vendor_items;
|
||||
bool m_itemsLoaded; // vendor items loading state
|
||||
VendorItemCounts m_vendorItemCounts;
|
||||
|
||||
void _RealtimeSetCreatureInfo();
|
||||
|
||||
@@ -592,7 +595,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
||||
uint32 m_regenTimer;
|
||||
MovementGeneratorType m_defaultMovementType;
|
||||
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;
|
||||
|
||||
bool m_AlreadyCallAssistence;
|
||||
|
||||
+1247
-1253
File diff suppressed because it is too large
Load Diff
+592
-592
File diff suppressed because it is too large
Load Diff
@@ -391,7 +391,7 @@ void PlayerMenu::SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID )
|
||||
data << uint8(questStatus);
|
||||
|
||||
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 )
|
||||
@@ -477,7 +477,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID
|
||||
}
|
||||
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 )
|
||||
@@ -515,7 +515,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
|
||||
WorldPacket data( SMSG_QUEST_QUERY_RESPONSE, 100 ); // guess size
|
||||
|
||||
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->GetZoneOrSort()); // zone or sort to display in quest log
|
||||
|
||||
@@ -597,7 +597,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
|
||||
data << ObjectiveText[iI];
|
||||
|
||||
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 )
|
||||
@@ -679,7 +679,7 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,
|
||||
data << uint32(pQuest->GetRewSpellCast()); // casted spell
|
||||
data << uint32(0); // Honor points reward, not implemented
|
||||
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 )
|
||||
@@ -758,5 +758,5 @@ void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID
|
||||
data << uint32(0x04) << uint32(0x08) << uint32(0x10);
|
||||
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -303,6 +303,7 @@ enum MangosStrings
|
||||
LANG_LOOKUP_PLAYER_ACCOUNT = 328,
|
||||
LANG_LOOKUP_PLAYER_CHARACTER = 329,
|
||||
LANG_NO_PLAYERS_FOUND = 330,
|
||||
LANG_EXTENDED_COST_NOT_EXIST = 331,
|
||||
|
||||
// Room for more level 2
|
||||
|
||||
|
||||
+11
-48
@@ -1237,14 +1237,6 @@ bool ChatHandler::HandleAddVendorItemCommand(const char* args)
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
Creature* vendor = getSelectedCreature();
|
||||
if (!vendor || !vendor->isVendor())
|
||||
{
|
||||
SendSysMessage(LANG_COMMAND_VENDORSELECTION);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
char* pitem = extractKeyFromLink((char*)args,"Hitem");
|
||||
if (!pitem)
|
||||
{
|
||||
@@ -1252,6 +1244,7 @@ bool ChatHandler::HandleAddVendorItemCommand(const char* args)
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 itemId = atol(pitem);
|
||||
|
||||
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
|
||||
uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
|
||||
|
||||
ItemPrototype const *pProto = objmgr.GetItemPrototype(itemId);
|
||||
if(!pProto)
|
||||
Creature* vendor = getSelectedCreature();
|
||||
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(extendedcost && !sItemExtendedCostStore.LookupEntry(extendedcost))
|
||||
{
|
||||
PSendSysMessage(LANG_BAD_VALUE, extendedcost);
|
||||
SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
objmgr.AddVendorItem(vendor_entry,itemId,maxcount,incrtime,extendedcost);
|
||||
|
||||
// load vendor items if not yet
|
||||
vendor->LoadGoods();
|
||||
ItemPrototype const* pProto = objmgr.GetItemPrototype(itemId);
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
@@ -1329,25 +1301,16 @@ bool ChatHandler::HandleDelVendorItemCommand(const char* args)
|
||||
}
|
||||
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
|
||||
vendor->LoadGoods();
|
||||
|
||||
if (!vendor->RemoveItem(itemId))
|
||||
if(!objmgr.RemoveVendorItem(vendor->GetEntry(),itemId))
|
||||
{
|
||||
PSendSysMessage(LANG_ITEM_NOT_IN_LIST,itemId);
|
||||
SetSentErrorMessage(true);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
+185
-64
@@ -70,6 +70,40 @@ bool normalizePlayerName(std::string& name)
|
||||
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()
|
||||
{
|
||||
m_hiCharGuid = 1;
|
||||
@@ -134,8 +168,7 @@ ObjectMgr::~ObjectMgr()
|
||||
delete itr->second;
|
||||
|
||||
for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
|
||||
for (VendorItemList::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
|
||||
delete (*itr2);
|
||||
itr->second.Clear();
|
||||
|
||||
for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr)
|
||||
itr->second.Clear();
|
||||
@@ -2697,35 +2730,35 @@ void ObjectMgr::LoadQuests()
|
||||
|
||||
mExclusiveQuestGroups.clear();
|
||||
|
||||
// 0 1 2 3 4 5 6 7
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"
|
||||
// 8 9 10 11 12 13 14 15
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"
|
||||
// 9 10 11 12 13 14 15 16
|
||||
"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,"
|
||||
// 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,"
|
||||
// 36 37 38 39 40 41 42 43
|
||||
// 37 38 39 40 41 42 43 44
|
||||
"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,"
|
||||
// 56 57 58 59 60 61 62 63
|
||||
// 57 58 59 60 61 62 63 64
|
||||
"ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4,"
|
||||
// 64 65 66 67
|
||||
// 65 66 67 68
|
||||
"ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4,"
|
||||
// 68 69 70 71 72 73
|
||||
// 69 70 71 72 73 74
|
||||
"RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6,"
|
||||
// 74 75 76 77 78 79
|
||||
// 75 76 77 78 79 80
|
||||
"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,"
|
||||
// 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,"
|
||||
// 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,"
|
||||
// 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,"
|
||||
// 118 119
|
||||
// 119 120
|
||||
"StartScript, CompleteScript"
|
||||
" FROM quest_template");
|
||||
if(result == NULL)
|
||||
@@ -2761,6 +2794,11 @@ void ObjectMgr::LoadQuests()
|
||||
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
sLog.outString("Table `%s` contain reserved entry 0, ignored.",table);
|
||||
sLog.outErrorDb("Table `%s` contain reserved entry 0, ignored.",table);
|
||||
continue;
|
||||
}
|
||||
else if(entry < min_value || entry > max_value)
|
||||
{
|
||||
int32 start = min_value > 0 ? min_value : max_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;
|
||||
}
|
||||
|
||||
@@ -6163,7 +6201,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -6656,22 +6694,30 @@ void ObjectMgr::LoadTrainerSpell()
|
||||
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
|
||||
uint32 count = 0,entry,spell;
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
entry = fields[0].GetUInt32();
|
||||
spell = fields[1].GetUInt32();
|
||||
uint32 entry = fields[0].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);
|
||||
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);
|
||||
if(!spellinfo)
|
||||
{
|
||||
@@ -6715,10 +6761,7 @@ void ObjectMgr::LoadVendors()
|
||||
{
|
||||
// For reload case
|
||||
for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr)
|
||||
{
|
||||
for (VendorItemList::iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
|
||||
delete (*itr2);
|
||||
}
|
||||
itr->second.Clear();
|
||||
m_mCacheVendorItemMap.clear();
|
||||
|
||||
QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
|
||||
@@ -6736,48 +6779,23 @@ void ObjectMgr::LoadVendors()
|
||||
barGoLink bar( result->GetRowCount() );
|
||||
|
||||
uint32 count = 0;
|
||||
uint32 entry, item_id, ExtendedCost;
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
entry = fields[0].GetUInt32();
|
||||
if(!GetCreatureTemplate(entry))
|
||||
{
|
||||
sLog.outErrorDb("Table `npc_vendor` have data for not existed creature template (Entry: %u), ignore", entry);
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
uint32 item_id = fields[1].GetUInt32();
|
||||
uint32 maxcount = fields[2].GetUInt32();
|
||||
uint32 incrtime = fields[3].GetUInt32();
|
||||
uint32 ExtendedCost = fields[4].GetUInt32();
|
||||
|
||||
if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost))
|
||||
continue;
|
||||
}
|
||||
|
||||
item_id = fields[1].GetUInt32();
|
||||
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;
|
||||
}
|
||||
VendorItemData& vList = m_mCacheVendorItemMap[entry];
|
||||
|
||||
ExtendedCost = fields[4].GetUInt32();
|
||||
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);
|
||||
vList.AddItem(item_id,maxcount,incrtime,ExtendedCost);
|
||||
++count;
|
||||
|
||||
} while (result->NextRow());
|
||||
@@ -6838,6 +6856,109 @@ void ObjectMgr::LoadNpcTextId()
|
||||
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
|
||||
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
|
||||
{
|
||||
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;
|
||||
end_value = std::numeric_limits<int32>::min();
|
||||
}
|
||||
|
||||
+15
-12
@@ -228,18 +228,8 @@ struct PlayerCondition
|
||||
// NPC gossip text id
|
||||
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;
|
||||
|
||||
enum SkillRangeType
|
||||
@@ -258,6 +248,16 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial);
|
||||
|
||||
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 ObjectMgr
|
||||
@@ -732,7 +732,7 @@ class ObjectMgr
|
||||
return &iter->second;
|
||||
}
|
||||
|
||||
VendorItemList const* GetNpcVendorItemList(uint32 entry) const
|
||||
VendorItemData const* GetNpcVendorItemList(uint32 entry) const
|
||||
{
|
||||
CacheVendorItemMap::const_iterator iter = m_mCacheVendorItemMap.find(entry);
|
||||
if(iter == m_mCacheVendorItemMap.end())
|
||||
@@ -740,6 +740,9 @@ class ObjectMgr
|
||||
|
||||
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:
|
||||
uint32 m_auctionid;
|
||||
uint32 m_mailid;
|
||||
|
||||
+1750
-1750
File diff suppressed because it is too large
Load Diff
+36
-19
@@ -5794,7 +5794,7 @@ void Player::RewardReputation(Unit *pVictim, float rate)
|
||||
if(!pVictim || pVictim->GetTypeId() == TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
ReputationOnKillEntry const* Rep = objmgr.GetReputationOnKilEntry(pVictim->GetEntry());
|
||||
ReputationOnKillEntry const* Rep = objmgr.GetReputationOnKilEntry(((Creature*)pVictim)->GetCreatureInfo()->Entry);
|
||||
|
||||
if(!Rep)
|
||||
return;
|
||||
@@ -16380,20 +16380,28 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
|
||||
return false;
|
||||
}
|
||||
|
||||
// load vendor items if not yet
|
||||
pCreature->LoadGoods();
|
||||
VendorItemData const* vItems = pCreature->GetVendorItems();
|
||||
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)
|
||||
{
|
||||
SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
|
||||
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);
|
||||
return false;
|
||||
if(pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count )
|
||||
{
|
||||
SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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( crItem->maxcount != 0 )
|
||||
crItem->count -= pProto->BuyCount * count;
|
||||
uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count);
|
||||
|
||||
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
|
||||
data << pCreature->GetGUID();
|
||||
data << (uint32)crItem->id; // entry
|
||||
data << (uint32)crItem->count;
|
||||
data << (uint32)crItem->item;
|
||||
data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
|
||||
data << (uint32)count;
|
||||
GetSession()->SendPacket(&data);
|
||||
|
||||
SendNewItem(it, count, true, false, false);
|
||||
SendNewItem(it, pProto->BuyCount*count, true, false, false);
|
||||
}
|
||||
}
|
||||
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( crItem->maxcount != 0 )
|
||||
crItem->count -= pProto->BuyCount * count;
|
||||
uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count);
|
||||
|
||||
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
|
||||
data << pCreature->GetGUID();
|
||||
data << (uint32)crItem->id; // entry
|
||||
data << (uint32)crItem->count;
|
||||
data << (uint32)crItem->item;
|
||||
data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
|
||||
data << (uint32)count;
|
||||
GetSession()->SendPacket(&data);
|
||||
|
||||
SendNewItem(it, count, true, false, false);
|
||||
SendNewItem(it, pProto->BuyCount*count, true, false, false);
|
||||
|
||||
AutoUnequipOffhandIfNeed();
|
||||
}
|
||||
@@ -16569,7 +16575,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
|
||||
return false;
|
||||
}
|
||||
|
||||
return crItem->maxcount!=0?true:false;
|
||||
return crItem->maxcount!=0;
|
||||
}
|
||||
|
||||
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
|
||||
if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight())
|
||||
SetUnitMovementFlags(GetUnitMovementFlags() | MOVEMENTFLAG_FLYING2);
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
|
||||
void Player::SendInitialPacketsAfterAddToMap()
|
||||
@@ -18167,3 +18173,14 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1898,6 +1898,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||
void ClearAfkReports() { m_bgAfkReporter.clear(); }
|
||||
|
||||
bool GetBGAccessByLevel(uint32 bgTypeId) const;
|
||||
bool isAllowUseBattleGroundObject();
|
||||
|
||||
/*********************************************************/
|
||||
/*** REST SYSTEM ***/
|
||||
|
||||
@@ -1,73 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "PointMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
|
||||
//----- Point Movement Generator
|
||||
template<class T>
|
||||
void PointMovementGenerator<T>::Initialize(T &unit)
|
||||
{
|
||||
unit.StopMoving();
|
||||
Traveller<T> traveller(unit);
|
||||
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
|
||||
{
|
||||
if(!&unit)
|
||||
return false;
|
||||
|
||||
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(unit);
|
||||
|
||||
i_destinationHolder.UpdateTraveller(traveller, diff, false);
|
||||
|
||||
if(i_destinationHolder.HasArrived())
|
||||
{
|
||||
unit.StopMoving();
|
||||
MovementInform(unit);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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<Player>::Initialize(Player&);
|
||||
template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &diff);
|
||||
template void PointMovementGenerator<Player>::MovementInform(Player&);
|
||||
|
||||
template void PointMovementGenerator<Creature>::Initialize(Creature&);
|
||||
template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &diff);
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "PointMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
|
||||
//----- Point Movement Generator
|
||||
template<class T>
|
||||
void PointMovementGenerator<T>::Initialize(T &unit)
|
||||
{
|
||||
unit.StopMoving();
|
||||
Traveller<T> traveller(unit);
|
||||
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z);
|
||||
|
||||
if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly())
|
||||
unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
|
||||
{
|
||||
if(!&unit)
|
||||
return false;
|
||||
|
||||
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(unit);
|
||||
|
||||
i_destinationHolder.UpdateTraveller(traveller, diff, false);
|
||||
|
||||
if(i_destinationHolder.HasArrived())
|
||||
{
|
||||
unit.StopMoving();
|
||||
MovementInform(unit);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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<Player>::Initialize(Player&);
|
||||
template bool PointMovementGenerator<Player>::Update(Player &, 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
@@ -1,199 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "QuestDef.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
|
||||
Quest::Quest(Field * questRecord)
|
||||
{
|
||||
QuestId = questRecord[0].GetUInt32();
|
||||
ZoneOrSort = questRecord[1].GetInt32();
|
||||
SkillOrClass = questRecord[2].GetInt32();
|
||||
MinLevel = questRecord[3].GetUInt32();
|
||||
QuestLevel = questRecord[4].GetUInt32();
|
||||
Type = questRecord[5].GetUInt32();
|
||||
RequiredRaces = questRecord[6].GetUInt32();
|
||||
RequiredSkillValue = questRecord[7].GetUInt32();
|
||||
RepObjectiveFaction = questRecord[8].GetUInt32();
|
||||
RepObjectiveValue = questRecord[9].GetInt32();
|
||||
RequiredMinRepFaction = questRecord[10].GetUInt32();
|
||||
RequiredMinRepValue = questRecord[11].GetInt32();
|
||||
RequiredMaxRepFaction = questRecord[12].GetUInt32();
|
||||
RequiredMaxRepValue = questRecord[13].GetInt32();
|
||||
SuggestedPlayers = questRecord[14].GetUInt32();
|
||||
LimitTime = questRecord[15].GetUInt32();
|
||||
QuestFlags = questRecord[16].GetUInt16();
|
||||
uint32 SpecialFlags = questRecord[17].GetUInt16();
|
||||
CharTitleId = questRecord[18].GetUInt32();
|
||||
PrevQuestId = questRecord[19].GetInt32();
|
||||
NextQuestId = questRecord[20].GetInt32();
|
||||
ExclusiveGroup = questRecord[21].GetInt32();
|
||||
NextQuestInChain = questRecord[22].GetUInt32();
|
||||
SrcItemId = questRecord[23].GetUInt32();
|
||||
SrcItemCount = questRecord[24].GetUInt32();
|
||||
SrcSpell = questRecord[25].GetUInt32();
|
||||
Title = questRecord[26].GetCppString();
|
||||
Details = questRecord[27].GetCppString();
|
||||
Objectives = questRecord[28].GetCppString();
|
||||
OfferRewardText = questRecord[29].GetCppString();
|
||||
RequestItemsText = questRecord[30].GetCppString();
|
||||
EndText = questRecord[31].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)
|
||||
ReqItemId[i] = questRecord[36+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqItemCount[i] = questRecord[40+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)
|
||||
ReqSourceCount[i] = questRecord[48+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_OBJECTIVES_COUNT; ++i)
|
||||
ReqCreatureOrGOId[i] = questRecord[56+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)
|
||||
ReqSpell[i] = questRecord[64+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)
|
||||
RewChoiceItemCount[i] = questRecord[74+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)
|
||||
RewItemCount[i] = questRecord[84+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)
|
||||
RewRepValue[i] = questRecord[93+i].GetInt32();
|
||||
|
||||
RewOrReqMoney = questRecord[98].GetInt32();
|
||||
RewMoneyMaxLevel = questRecord[99].GetUInt32();
|
||||
RewSpell = questRecord[100].GetUInt32();
|
||||
RewSpellCast = questRecord[101].GetUInt32();
|
||||
RewMailTemplateId = questRecord[102].GetUInt32();
|
||||
RewMailDelaySecs = questRecord[103].GetUInt32();
|
||||
PointMapId = questRecord[104].GetUInt32();
|
||||
PointX = questRecord[105].GetFloat();
|
||||
PointY = questRecord[106].GetFloat();
|
||||
PointOpt = questRecord[107].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
DetailsEmote[i] = questRecord[108+i].GetUInt32();
|
||||
|
||||
IncompleteEmote = questRecord[112].GetUInt32();
|
||||
CompleteEmote = questRecord[113].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
OfferRewardEmote[i] = questRecord[114+i].GetInt32();
|
||||
|
||||
QuestStartScript = questRecord[118].GetUInt32();
|
||||
QuestCompleteScript = questRecord[119].GetUInt32();
|
||||
|
||||
QuestFlags |= SpecialFlags << 16;
|
||||
|
||||
m_reqitemscount = 0;
|
||||
m_reqCreatureOrGOcount = 0;
|
||||
m_rewitemscount = 0;
|
||||
m_rewchoiceitemscount = 0;
|
||||
|
||||
for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++)
|
||||
{
|
||||
if ( ReqItemId[i] )
|
||||
++m_reqitemscount;
|
||||
if ( ReqCreatureOrGOId[i] )
|
||||
++m_reqCreatureOrGOcount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARDS_COUNT; i++)
|
||||
{
|
||||
if ( RewItemId[i] )
|
||||
++m_rewitemscount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
|
||||
{
|
||||
if (RewChoiceItemId[i])
|
||||
++m_rewchoiceitemscount;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Quest::XPValue( Player *pPlayer ) const
|
||||
{
|
||||
if( pPlayer )
|
||||
{
|
||||
if( RewMoneyMaxLevel > 0 )
|
||||
{
|
||||
uint32 pLevel = pPlayer->getLevel();
|
||||
uint32 qLevel = QuestLevel;
|
||||
float fullxp = 0;
|
||||
if (qLevel >= 65)
|
||||
fullxp = RewMoneyMaxLevel / 6.0f;
|
||||
else if (qLevel == 64)
|
||||
fullxp = RewMoneyMaxLevel / 4.8f;
|
||||
else if (qLevel == 63)
|
||||
fullxp = RewMoneyMaxLevel / 3.6f;
|
||||
else if (qLevel == 62)
|
||||
fullxp = RewMoneyMaxLevel / 2.4f;
|
||||
else if (qLevel == 61)
|
||||
fullxp = RewMoneyMaxLevel / 1.2f;
|
||||
else if (qLevel > 0 && qLevel <= 60)
|
||||
fullxp = RewMoneyMaxLevel / 0.6f;
|
||||
|
||||
if( pLevel <= qLevel + 5 )
|
||||
return (uint32)fullxp;
|
||||
else if( pLevel == qLevel + 6 )
|
||||
return (uint32)(fullxp * 0.8f);
|
||||
else if( pLevel == qLevel + 7 )
|
||||
return (uint32)(fullxp * 0.6f);
|
||||
else if( pLevel == qLevel + 8 )
|
||||
return (uint32)(fullxp * 0.4f);
|
||||
else if( pLevel == qLevel + 9 )
|
||||
return (uint32)(fullxp * 0.2f);
|
||||
else
|
||||
return (uint32)(fullxp * 0.1f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Quest::GetRewOrReqMoney() const
|
||||
{
|
||||
if(RewOrReqMoney <=0)
|
||||
return RewOrReqMoney;
|
||||
|
||||
return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY));
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "QuestDef.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
|
||||
Quest::Quest(Field * questRecord)
|
||||
{
|
||||
QuestId = questRecord[0].GetUInt32();
|
||||
QuestMethod = questRecord[1].GetUInt32();
|
||||
ZoneOrSort = questRecord[2].GetInt32();
|
||||
SkillOrClass = questRecord[3].GetInt32();
|
||||
MinLevel = questRecord[4].GetUInt32();
|
||||
QuestLevel = questRecord[5].GetUInt32();
|
||||
Type = questRecord[6].GetUInt32();
|
||||
RequiredRaces = questRecord[7].GetUInt32();
|
||||
RequiredSkillValue = questRecord[8].GetUInt32();
|
||||
RepObjectiveFaction = questRecord[9].GetUInt32();
|
||||
RepObjectiveValue = questRecord[10].GetInt32();
|
||||
RequiredMinRepFaction = questRecord[11].GetUInt32();
|
||||
RequiredMinRepValue = questRecord[12].GetInt32();
|
||||
RequiredMaxRepFaction = questRecord[13].GetUInt32();
|
||||
RequiredMaxRepValue = questRecord[14].GetInt32();
|
||||
SuggestedPlayers = questRecord[15].GetUInt32();
|
||||
LimitTime = questRecord[16].GetUInt32();
|
||||
QuestFlags = questRecord[17].GetUInt16();
|
||||
uint32 SpecialFlags = questRecord[18].GetUInt16();
|
||||
CharTitleId = questRecord[19].GetUInt32();
|
||||
PrevQuestId = questRecord[20].GetInt32();
|
||||
NextQuestId = questRecord[21].GetInt32();
|
||||
ExclusiveGroup = questRecord[22].GetInt32();
|
||||
NextQuestInChain = questRecord[23].GetUInt32();
|
||||
SrcItemId = questRecord[24].GetUInt32();
|
||||
SrcItemCount = questRecord[25].GetUInt32();
|
||||
SrcSpell = questRecord[26].GetUInt32();
|
||||
Title = questRecord[27].GetCppString();
|
||||
Details = questRecord[28].GetCppString();
|
||||
Objectives = questRecord[29].GetCppString();
|
||||
OfferRewardText = questRecord[30].GetCppString();
|
||||
RequestItemsText = questRecord[31].GetCppString();
|
||||
EndText = questRecord[32].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[37+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[45+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[53+i].GetUInt32();
|
||||
|
||||
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[61+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[69+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[81+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[89+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
|
||||
RewRepValue[i] = questRecord[94+i].GetInt32();
|
||||
|
||||
RewOrReqMoney = questRecord[99].GetInt32();
|
||||
RewMoneyMaxLevel = questRecord[100].GetUInt32();
|
||||
RewSpell = questRecord[101].GetUInt32();
|
||||
RewSpellCast = questRecord[102].GetUInt32();
|
||||
RewMailTemplateId = questRecord[103].GetUInt32();
|
||||
RewMailDelaySecs = questRecord[104].GetUInt32();
|
||||
PointMapId = questRecord[105].GetUInt32();
|
||||
PointX = questRecord[106].GetFloat();
|
||||
PointY = questRecord[107].GetFloat();
|
||||
PointOpt = questRecord[108].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
DetailsEmote[i] = questRecord[109+i].GetUInt32();
|
||||
|
||||
IncompleteEmote = questRecord[113].GetUInt32();
|
||||
CompleteEmote = questRecord[114].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
OfferRewardEmote[i] = questRecord[115+i].GetInt32();
|
||||
|
||||
QuestStartScript = questRecord[119].GetUInt32();
|
||||
QuestCompleteScript = questRecord[120].GetUInt32();
|
||||
|
||||
QuestFlags |= SpecialFlags << 16;
|
||||
|
||||
m_reqitemscount = 0;
|
||||
m_reqCreatureOrGOcount = 0;
|
||||
m_rewitemscount = 0;
|
||||
m_rewchoiceitemscount = 0;
|
||||
|
||||
for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++)
|
||||
{
|
||||
if ( ReqItemId[i] )
|
||||
++m_reqitemscount;
|
||||
if ( ReqCreatureOrGOId[i] )
|
||||
++m_reqCreatureOrGOcount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARDS_COUNT; i++)
|
||||
{
|
||||
if ( RewItemId[i] )
|
||||
++m_rewitemscount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
|
||||
{
|
||||
if (RewChoiceItemId[i])
|
||||
++m_rewchoiceitemscount;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Quest::XPValue( Player *pPlayer ) const
|
||||
{
|
||||
if( pPlayer )
|
||||
{
|
||||
if( RewMoneyMaxLevel > 0 )
|
||||
{
|
||||
uint32 pLevel = pPlayer->getLevel();
|
||||
uint32 qLevel = QuestLevel;
|
||||
float fullxp = 0;
|
||||
if (qLevel >= 65)
|
||||
fullxp = RewMoneyMaxLevel / 6.0f;
|
||||
else if (qLevel == 64)
|
||||
fullxp = RewMoneyMaxLevel / 4.8f;
|
||||
else if (qLevel == 63)
|
||||
fullxp = RewMoneyMaxLevel / 3.6f;
|
||||
else if (qLevel == 62)
|
||||
fullxp = RewMoneyMaxLevel / 2.4f;
|
||||
else if (qLevel == 61)
|
||||
fullxp = RewMoneyMaxLevel / 1.2f;
|
||||
else if (qLevel > 0 && qLevel <= 60)
|
||||
fullxp = RewMoneyMaxLevel / 0.6f;
|
||||
|
||||
if( pLevel <= qLevel + 5 )
|
||||
return (uint32)fullxp;
|
||||
else if( pLevel == qLevel + 6 )
|
||||
return (uint32)(fullxp * 0.8f);
|
||||
else if( pLevel == qLevel + 7 )
|
||||
return (uint32)(fullxp * 0.6f);
|
||||
else if( pLevel == qLevel + 8 )
|
||||
return (uint32)(fullxp * 0.4f);
|
||||
else if( pLevel == qLevel + 9 )
|
||||
return (uint32)(fullxp * 0.2f);
|
||||
else
|
||||
return (uint32)(fullxp * 0.1f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Quest::GetRewOrReqMoney() const
|
||||
{
|
||||
if(RewOrReqMoney <=0)
|
||||
return RewOrReqMoney;
|
||||
|
||||
return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY));
|
||||
}
|
||||
|
||||
+332
-330
@@ -1,330 +1,332 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_QUEST_H
|
||||
#define MANGOSSERVER_QUEST_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Player;
|
||||
|
||||
class ObjectMgr;
|
||||
|
||||
#define MAX_QUEST_LOG_SIZE 25
|
||||
|
||||
#define QUEST_OBJECTIVES_COUNT 4
|
||||
#define QUEST_SOURCE_ITEM_IDS_COUNT 4
|
||||
#define QUEST_REWARD_CHOICES_COUNT 6
|
||||
#define QUEST_REWARDS_COUNT 4
|
||||
#define QUEST_DEPLINK_COUNT 10
|
||||
#define QUEST_REPUTATIONS_COUNT 5
|
||||
#define QUEST_EMOTE_COUNT 4
|
||||
|
||||
enum QuestFailedReasons
|
||||
{
|
||||
INVALIDREASON_DONT_HAVE_REQ = 0,
|
||||
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_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_ALREADY_ON = 13, //You are already on that quest
|
||||
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_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_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
|
||||
};
|
||||
|
||||
enum QuestShareMessages
|
||||
{
|
||||
QUEST_PARTY_MSG_SHARING_QUEST = 0,
|
||||
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
|
||||
QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
|
||||
QUEST_PARTY_MSG_REFUSE_QUEST = 3,
|
||||
QUEST_PARTY_MSG_TOO_FAR = 4,
|
||||
QUEST_PARTY_MSG_BUSY = 5,
|
||||
QUEST_PARTY_MSG_LOG_FULL = 6,
|
||||
QUEST_PARTY_MSG_HAVE_QUEST = 7,
|
||||
QUEST_PARTY_MSG_FINISH_QUEST = 8,
|
||||
};
|
||||
|
||||
enum __QuestTradeSkill
|
||||
{
|
||||
QUEST_TRSKILL_NONE = 0,
|
||||
QUEST_TRSKILL_ALCHEMY = 1,
|
||||
QUEST_TRSKILL_BLACKSMITHING = 2,
|
||||
QUEST_TRSKILL_COOKING = 3,
|
||||
QUEST_TRSKILL_ENCHANTING = 4,
|
||||
QUEST_TRSKILL_ENGINEERING = 5,
|
||||
QUEST_TRSKILL_FIRSTAID = 6,
|
||||
QUEST_TRSKILL_HERBALISM = 7,
|
||||
QUEST_TRSKILL_LEATHERWORKING = 8,
|
||||
QUEST_TRSKILL_POISONS = 9,
|
||||
QUEST_TRSKILL_TAILORING = 10,
|
||||
QUEST_TRSKILL_MINING = 11,
|
||||
QUEST_TRSKILL_FISHING = 12,
|
||||
QUEST_TRSKILL_SKINNING = 13,
|
||||
QUEST_TRSKILL_JEWELCRAFTING = 14,
|
||||
};
|
||||
|
||||
enum QuestStatus
|
||||
{
|
||||
QUEST_STATUS_NONE = 0,
|
||||
QUEST_STATUS_COMPLETE = 1,
|
||||
QUEST_STATUS_UNAVAILABLE = 2,
|
||||
QUEST_STATUS_INCOMPLETE = 3,
|
||||
QUEST_STATUS_AVAILABLE = 4,
|
||||
MAX_QUEST_STATUS
|
||||
};
|
||||
|
||||
enum __QuestGiverStatus
|
||||
{
|
||||
DIALOG_STATUS_NONE = 0,
|
||||
DIALOG_STATUS_UNAVAILABLE = 1,
|
||||
DIALOG_STATUS_CHAT = 2,
|
||||
DIALOG_STATUS_INCOMPLETE = 3,
|
||||
DIALOG_STATUS_REWARD_REP = 4,
|
||||
DIALOG_STATUS_AVAILABLE_REP = 5,
|
||||
DIALOG_STATUS_AVAILABLE = 6,
|
||||
DIALOG_STATUS_REWARD2 = 7, // not yellow dot on minimap
|
||||
DIALOG_STATUS_REWARD = 8 // yellow dot on minimap
|
||||
};
|
||||
|
||||
enum __QuestFlags
|
||||
{
|
||||
// Flags used at server and sended to client
|
||||
QUEST_FLAGS_STAY_ALIVE = 1, // Not used currently
|
||||
QUEST_FLAGS_EVENT = 2, // Not used currently
|
||||
QUEST_FLAGS_EXPLORATION = 4, // Not used currently
|
||||
QUEST_FLAGS_SHARABLE = 8, // Can be shared: Player::CanShareQuest()
|
||||
//QUEST_FLAGS_NONE2 = 16, // Not used currently
|
||||
QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content
|
||||
QUEST_FLAGS_RAID = 64, // Not used currently
|
||||
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_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_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests
|
||||
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
|
||||
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_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT,
|
||||
|
||||
// Mangos flags for internal use only
|
||||
QUEST_MANGOS_FLAGS_DELIVER = 0x040000, // 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_TIMED = 0x200000, // Internal flag computed only
|
||||
};
|
||||
|
||||
struct QuestLocale
|
||||
{
|
||||
QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); }
|
||||
|
||||
std::vector<std::string> Title;
|
||||
std::vector<std::string> Details;
|
||||
std::vector<std::string> Objectives;
|
||||
std::vector<std::string> OfferRewardText;
|
||||
std::vector<std::string> RequestItemsText;
|
||||
std::vector<std::string> EndText;
|
||||
std::vector< std::vector<std::string> > ObjectiveText;
|
||||
};
|
||||
|
||||
// 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
|
||||
// xp to give
|
||||
class Quest
|
||||
{
|
||||
friend class ObjectMgr;
|
||||
public:
|
||||
Quest(Field * questRecord);
|
||||
uint32 XPValue( Player *pPlayer ) const;
|
||||
|
||||
bool HasFlag( uint32 flag ) const { return ( QuestFlags & flag ) != 0; }
|
||||
void SetFlag( uint32 flag ) { QuestFlags |= flag; }
|
||||
|
||||
// table data accessors:
|
||||
uint32 GetQuestId() const { return QuestId; }
|
||||
int32 GetZoneOrSort() const { return ZoneOrSort; }
|
||||
int32 GetSkillOrClass() const { return SkillOrClass; }
|
||||
uint32 GetMinLevel() const { return MinLevel; }
|
||||
uint32 GetQuestLevel() const { return QuestLevel; }
|
||||
uint32 GetType() const { return Type; }
|
||||
uint32 GetRequiredRaces() const { return RequiredRaces; }
|
||||
uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
|
||||
uint32 GetRepObjectiveFaction() const { return RepObjectiveFaction; }
|
||||
int32 GetRepObjectiveValue() const { return RepObjectiveValue; }
|
||||
uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; }
|
||||
int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; }
|
||||
uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
|
||||
int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
|
||||
uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
|
||||
uint32 GetLimitTime() const { return LimitTime; }
|
||||
int32 GetPrevQuestId() const { return PrevQuestId; }
|
||||
int32 GetNextQuestId() const { return NextQuestId; }
|
||||
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
|
||||
uint32 GetNextQuestInChain() const { return NextQuestInChain; }
|
||||
uint32 GetCharTitleId() const { return CharTitleId; }
|
||||
uint32 GetSrcItemId() const { return SrcItemId; }
|
||||
uint32 GetSrcItemCount() const { return SrcItemCount; }
|
||||
uint32 GetSrcSpell() const { return SrcSpell; }
|
||||
std::string GetTitle() const { return Title; }
|
||||
std::string GetDetails() const { return Details; }
|
||||
std::string GetObjectives() const { return Objectives; }
|
||||
std::string GetOfferRewardText() const { return OfferRewardText; }
|
||||
std::string GetRequestItemsText() const { return RequestItemsText; }
|
||||
std::string GetEndText() const { return EndText; }
|
||||
int32 GetRewOrReqMoney() const;
|
||||
uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; }
|
||||
// use in XP calculation at client
|
||||
uint32 GetRewSpell() const { return RewSpell; }
|
||||
uint32 GetRewSpellCast() const { return RewSpellCast; }
|
||||
uint32 GetRewMailTemplateId() const { return RewMailTemplateId; }
|
||||
uint32 GetRewMailDelaySecs() const { return RewMailDelaySecs; }
|
||||
uint32 GetPointMapId() const { return PointMapId; }
|
||||
float GetPointX() const { return PointX; }
|
||||
float GetPointY() const { return PointY; }
|
||||
uint32 GetPointOpt() const { return PointOpt; }
|
||||
uint32 GetIncompleteEmote() const { return IncompleteEmote; }
|
||||
uint32 GetCompleteEmote() const { return CompleteEmote; }
|
||||
uint32 GetQuestStartScript() const { return QuestStartScript; }
|
||||
uint32 GetQuestCompleteScript() const { return QuestCompleteScript; }
|
||||
bool IsRepeatable() const { return QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE; }
|
||||
bool IsAutoComplete() const { return Objectives.empty(); }
|
||||
uint32 GetFlags() const { return QuestFlags; }
|
||||
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }
|
||||
|
||||
// multiple values
|
||||
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemId[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
|
||||
uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSpell[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewItemId[QUEST_REWARDS_COUNT];
|
||||
uint32 RewItemCount[QUEST_REWARDS_COUNT];
|
||||
uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT];
|
||||
int32 RewRepValue[QUEST_REPUTATIONS_COUNT];
|
||||
uint32 DetailsEmote[QUEST_EMOTE_COUNT];
|
||||
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT];
|
||||
|
||||
uint32 GetReqItemsCount() const { return m_reqitemscount; }
|
||||
uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; }
|
||||
uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; }
|
||||
uint32 GetRewItemsCount() const { return m_rewitemscount; }
|
||||
|
||||
typedef std::vector<int32> PrevQuests;
|
||||
PrevQuests prevQuests;
|
||||
typedef std::vector<uint32> PrevChainQuests;
|
||||
PrevChainQuests prevChainQuests;
|
||||
|
||||
// cached data
|
||||
private:
|
||||
uint32 m_reqitemscount;
|
||||
uint32 m_reqCreatureOrGOcount;
|
||||
uint32 m_rewchoiceitemscount;
|
||||
uint32 m_rewitemscount;
|
||||
|
||||
// table data
|
||||
protected:
|
||||
uint32 QuestId;
|
||||
int32 ZoneOrSort;
|
||||
int32 SkillOrClass;
|
||||
uint32 MinLevel;
|
||||
uint32 QuestLevel;
|
||||
uint32 Type;
|
||||
uint32 RequiredRaces;
|
||||
uint32 RequiredSkillValue;
|
||||
uint32 RepObjectiveFaction;
|
||||
int32 RepObjectiveValue;
|
||||
uint32 RequiredMinRepFaction;
|
||||
int32 RequiredMinRepValue;
|
||||
uint32 RequiredMaxRepFaction;
|
||||
int32 RequiredMaxRepValue;
|
||||
uint32 SuggestedPlayers;
|
||||
uint32 LimitTime;
|
||||
uint32 QuestFlags;
|
||||
uint32 CharTitleId;
|
||||
int32 PrevQuestId;
|
||||
int32 NextQuestId;
|
||||
int32 ExclusiveGroup;
|
||||
uint32 NextQuestInChain;
|
||||
uint32 SrcItemId;
|
||||
uint32 SrcItemCount;
|
||||
uint32 SrcSpell;
|
||||
std::string Title;
|
||||
std::string Details;
|
||||
std::string Objectives;
|
||||
std::string OfferRewardText;
|
||||
std::string RequestItemsText;
|
||||
std::string EndText;
|
||||
int32 RewOrReqMoney;
|
||||
uint32 RewMoneyMaxLevel;
|
||||
uint32 RewSpell;
|
||||
uint32 RewSpellCast;
|
||||
uint32 RewMailTemplateId;
|
||||
uint32 RewMailDelaySecs;
|
||||
uint32 PointMapId;
|
||||
float PointX;
|
||||
float PointY;
|
||||
uint32 PointOpt;
|
||||
uint32 IncompleteEmote;
|
||||
uint32 CompleteEmote;
|
||||
uint32 QuestStartScript;
|
||||
uint32 QuestCompleteScript;
|
||||
};
|
||||
|
||||
enum QuestUpdateState
|
||||
{
|
||||
QUEST_UNCHANGED = 0,
|
||||
QUEST_CHANGED = 1,
|
||||
QUEST_NEW = 2
|
||||
};
|
||||
|
||||
struct QuestStatusData
|
||||
{
|
||||
QuestStatusData()
|
||||
: m_status(QUEST_STATUS_NONE),m_rewarded(false),
|
||||
m_explored(false), m_timer(0), uState(QUEST_NEW)
|
||||
{
|
||||
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;
|
||||
uint32 m_timer;
|
||||
QuestUpdateState uState;
|
||||
|
||||
uint32 m_itemcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
uint32 m_creatureOrGOcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_QUEST_H
|
||||
#define MANGOSSERVER_QUEST_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Player;
|
||||
|
||||
class ObjectMgr;
|
||||
|
||||
#define MAX_QUEST_LOG_SIZE 25
|
||||
|
||||
#define QUEST_OBJECTIVES_COUNT 4
|
||||
#define QUEST_SOURCE_ITEM_IDS_COUNT 4
|
||||
#define QUEST_REWARD_CHOICES_COUNT 6
|
||||
#define QUEST_REWARDS_COUNT 4
|
||||
#define QUEST_DEPLINK_COUNT 10
|
||||
#define QUEST_REPUTATIONS_COUNT 5
|
||||
#define QUEST_EMOTE_COUNT 4
|
||||
|
||||
enum QuestFailedReasons
|
||||
{
|
||||
INVALIDREASON_DONT_HAVE_REQ = 0,
|
||||
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_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_ALREADY_ON = 13, //You are already on that quest
|
||||
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_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_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
|
||||
};
|
||||
|
||||
enum QuestShareMessages
|
||||
{
|
||||
QUEST_PARTY_MSG_SHARING_QUEST = 0,
|
||||
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
|
||||
QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
|
||||
QUEST_PARTY_MSG_REFUSE_QUEST = 3,
|
||||
QUEST_PARTY_MSG_TOO_FAR = 4,
|
||||
QUEST_PARTY_MSG_BUSY = 5,
|
||||
QUEST_PARTY_MSG_LOG_FULL = 6,
|
||||
QUEST_PARTY_MSG_HAVE_QUEST = 7,
|
||||
QUEST_PARTY_MSG_FINISH_QUEST = 8,
|
||||
};
|
||||
|
||||
enum __QuestTradeSkill
|
||||
{
|
||||
QUEST_TRSKILL_NONE = 0,
|
||||
QUEST_TRSKILL_ALCHEMY = 1,
|
||||
QUEST_TRSKILL_BLACKSMITHING = 2,
|
||||
QUEST_TRSKILL_COOKING = 3,
|
||||
QUEST_TRSKILL_ENCHANTING = 4,
|
||||
QUEST_TRSKILL_ENGINEERING = 5,
|
||||
QUEST_TRSKILL_FIRSTAID = 6,
|
||||
QUEST_TRSKILL_HERBALISM = 7,
|
||||
QUEST_TRSKILL_LEATHERWORKING = 8,
|
||||
QUEST_TRSKILL_POISONS = 9,
|
||||
QUEST_TRSKILL_TAILORING = 10,
|
||||
QUEST_TRSKILL_MINING = 11,
|
||||
QUEST_TRSKILL_FISHING = 12,
|
||||
QUEST_TRSKILL_SKINNING = 13,
|
||||
QUEST_TRSKILL_JEWELCRAFTING = 14,
|
||||
};
|
||||
|
||||
enum QuestStatus
|
||||
{
|
||||
QUEST_STATUS_NONE = 0,
|
||||
QUEST_STATUS_COMPLETE = 1,
|
||||
QUEST_STATUS_UNAVAILABLE = 2,
|
||||
QUEST_STATUS_INCOMPLETE = 3,
|
||||
QUEST_STATUS_AVAILABLE = 4,
|
||||
MAX_QUEST_STATUS
|
||||
};
|
||||
|
||||
enum __QuestGiverStatus
|
||||
{
|
||||
DIALOG_STATUS_NONE = 0,
|
||||
DIALOG_STATUS_UNAVAILABLE = 1,
|
||||
DIALOG_STATUS_CHAT = 2,
|
||||
DIALOG_STATUS_INCOMPLETE = 3,
|
||||
DIALOG_STATUS_REWARD_REP = 4,
|
||||
DIALOG_STATUS_AVAILABLE_REP = 5,
|
||||
DIALOG_STATUS_AVAILABLE = 6,
|
||||
DIALOG_STATUS_REWARD2 = 7, // not yellow dot on minimap
|
||||
DIALOG_STATUS_REWARD = 8 // yellow dot on minimap
|
||||
};
|
||||
|
||||
enum __QuestFlags
|
||||
{
|
||||
// Flags used at server and sended to client
|
||||
QUEST_FLAGS_STAY_ALIVE = 1, // 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_SHARABLE = 8, // Can be shared: Player::CanShareQuest()
|
||||
//QUEST_FLAGS_NONE2 = 16, // Not used currently
|
||||
QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content
|
||||
QUEST_FLAGS_RAID = 64, // Not used currently
|
||||
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_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_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests
|
||||
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
|
||||
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_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT,
|
||||
|
||||
// Mangos flags for internal use only
|
||||
QUEST_MANGOS_FLAGS_DELIVER = 0x040000, // 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_TIMED = 0x200000, // Internal flag computed only
|
||||
};
|
||||
|
||||
struct QuestLocale
|
||||
{
|
||||
QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); }
|
||||
|
||||
std::vector<std::string> Title;
|
||||
std::vector<std::string> Details;
|
||||
std::vector<std::string> Objectives;
|
||||
std::vector<std::string> OfferRewardText;
|
||||
std::vector<std::string> RequestItemsText;
|
||||
std::vector<std::string> EndText;
|
||||
std::vector< std::vector<std::string> > ObjectiveText;
|
||||
};
|
||||
|
||||
// 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
|
||||
// xp to give
|
||||
class Quest
|
||||
{
|
||||
friend class ObjectMgr;
|
||||
public:
|
||||
Quest(Field * questRecord);
|
||||
uint32 XPValue( Player *pPlayer ) const;
|
||||
|
||||
bool HasFlag( uint32 flag ) const { return ( QuestFlags & flag ) != 0; }
|
||||
void SetFlag( uint32 flag ) { QuestFlags |= flag; }
|
||||
|
||||
// table data accessors:
|
||||
uint32 GetQuestId() const { return QuestId; }
|
||||
uint32 GetQuestMethod() const { return QuestMethod; }
|
||||
int32 GetZoneOrSort() const { return ZoneOrSort; }
|
||||
int32 GetSkillOrClass() const { return SkillOrClass; }
|
||||
uint32 GetMinLevel() const { return MinLevel; }
|
||||
uint32 GetQuestLevel() const { return QuestLevel; }
|
||||
uint32 GetType() const { return Type; }
|
||||
uint32 GetRequiredRaces() const { return RequiredRaces; }
|
||||
uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
|
||||
uint32 GetRepObjectiveFaction() const { return RepObjectiveFaction; }
|
||||
int32 GetRepObjectiveValue() const { return RepObjectiveValue; }
|
||||
uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; }
|
||||
int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; }
|
||||
uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
|
||||
int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
|
||||
uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
|
||||
uint32 GetLimitTime() const { return LimitTime; }
|
||||
int32 GetPrevQuestId() const { return PrevQuestId; }
|
||||
int32 GetNextQuestId() const { return NextQuestId; }
|
||||
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
|
||||
uint32 GetNextQuestInChain() const { return NextQuestInChain; }
|
||||
uint32 GetCharTitleId() const { return CharTitleId; }
|
||||
uint32 GetSrcItemId() const { return SrcItemId; }
|
||||
uint32 GetSrcItemCount() const { return SrcItemCount; }
|
||||
uint32 GetSrcSpell() const { return SrcSpell; }
|
||||
std::string GetTitle() const { return Title; }
|
||||
std::string GetDetails() const { return Details; }
|
||||
std::string GetObjectives() const { return Objectives; }
|
||||
std::string GetOfferRewardText() const { return OfferRewardText; }
|
||||
std::string GetRequestItemsText() const { return RequestItemsText; }
|
||||
std::string GetEndText() const { return EndText; }
|
||||
int32 GetRewOrReqMoney() const;
|
||||
uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; }
|
||||
// use in XP calculation at client
|
||||
uint32 GetRewSpell() const { return RewSpell; }
|
||||
uint32 GetRewSpellCast() const { return RewSpellCast; }
|
||||
uint32 GetRewMailTemplateId() const { return RewMailTemplateId; }
|
||||
uint32 GetRewMailDelaySecs() const { return RewMailDelaySecs; }
|
||||
uint32 GetPointMapId() const { return PointMapId; }
|
||||
float GetPointX() const { return PointX; }
|
||||
float GetPointY() const { return PointY; }
|
||||
uint32 GetPointOpt() const { return PointOpt; }
|
||||
uint32 GetIncompleteEmote() const { return IncompleteEmote; }
|
||||
uint32 GetCompleteEmote() const { return CompleteEmote; }
|
||||
uint32 GetQuestStartScript() const { return QuestStartScript; }
|
||||
uint32 GetQuestCompleteScript() const { return QuestCompleteScript; }
|
||||
bool IsRepeatable() const { return QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE; }
|
||||
bool IsAutoComplete() const { return QuestMethod ? false : true; }
|
||||
uint32 GetFlags() const { return QuestFlags; }
|
||||
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }
|
||||
|
||||
// multiple values
|
||||
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemId[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
|
||||
uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSpell[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewItemId[QUEST_REWARDS_COUNT];
|
||||
uint32 RewItemCount[QUEST_REWARDS_COUNT];
|
||||
uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT];
|
||||
int32 RewRepValue[QUEST_REPUTATIONS_COUNT];
|
||||
uint32 DetailsEmote[QUEST_EMOTE_COUNT];
|
||||
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT];
|
||||
|
||||
uint32 GetReqItemsCount() const { return m_reqitemscount; }
|
||||
uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; }
|
||||
uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; }
|
||||
uint32 GetRewItemsCount() const { return m_rewitemscount; }
|
||||
|
||||
typedef std::vector<int32> PrevQuests;
|
||||
PrevQuests prevQuests;
|
||||
typedef std::vector<uint32> PrevChainQuests;
|
||||
PrevChainQuests prevChainQuests;
|
||||
|
||||
// cached data
|
||||
private:
|
||||
uint32 m_reqitemscount;
|
||||
uint32 m_reqCreatureOrGOcount;
|
||||
uint32 m_rewchoiceitemscount;
|
||||
uint32 m_rewitemscount;
|
||||
|
||||
// table data
|
||||
protected:
|
||||
uint32 QuestId;
|
||||
uint32 QuestMethod;
|
||||
int32 ZoneOrSort;
|
||||
int32 SkillOrClass;
|
||||
uint32 MinLevel;
|
||||
uint32 QuestLevel;
|
||||
uint32 Type;
|
||||
uint32 RequiredRaces;
|
||||
uint32 RequiredSkillValue;
|
||||
uint32 RepObjectiveFaction;
|
||||
int32 RepObjectiveValue;
|
||||
uint32 RequiredMinRepFaction;
|
||||
int32 RequiredMinRepValue;
|
||||
uint32 RequiredMaxRepFaction;
|
||||
int32 RequiredMaxRepValue;
|
||||
uint32 SuggestedPlayers;
|
||||
uint32 LimitTime;
|
||||
uint32 QuestFlags;
|
||||
uint32 CharTitleId;
|
||||
int32 PrevQuestId;
|
||||
int32 NextQuestId;
|
||||
int32 ExclusiveGroup;
|
||||
uint32 NextQuestInChain;
|
||||
uint32 SrcItemId;
|
||||
uint32 SrcItemCount;
|
||||
uint32 SrcSpell;
|
||||
std::string Title;
|
||||
std::string Details;
|
||||
std::string Objectives;
|
||||
std::string OfferRewardText;
|
||||
std::string RequestItemsText;
|
||||
std::string EndText;
|
||||
int32 RewOrReqMoney;
|
||||
uint32 RewMoneyMaxLevel;
|
||||
uint32 RewSpell;
|
||||
uint32 RewSpellCast;
|
||||
uint32 RewMailTemplateId;
|
||||
uint32 RewMailDelaySecs;
|
||||
uint32 PointMapId;
|
||||
float PointX;
|
||||
float PointY;
|
||||
uint32 PointOpt;
|
||||
uint32 IncompleteEmote;
|
||||
uint32 CompleteEmote;
|
||||
uint32 QuestStartScript;
|
||||
uint32 QuestCompleteScript;
|
||||
};
|
||||
|
||||
enum QuestUpdateState
|
||||
{
|
||||
QUEST_UNCHANGED = 0,
|
||||
QUEST_CHANGED = 1,
|
||||
QUEST_NEW = 2
|
||||
};
|
||||
|
||||
struct QuestStatusData
|
||||
{
|
||||
QuestStatusData()
|
||||
: m_status(QUEST_STATUS_NONE),m_rewarded(false),
|
||||
m_explored(false), m_timer(0), uState(QUEST_NEW)
|
||||
{
|
||||
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;
|
||||
uint32 m_timer;
|
||||
QuestUpdateState uState;
|
||||
|
||||
uint32 m_itemcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
uint32 m_creatureOrGOcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,159 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "Map.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
|
||||
{
|
||||
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);
|
||||
|
||||
z = creature.GetPositionZ();
|
||||
uint32 mapid=creature.GetMapId();
|
||||
Map const* map = MapManager::Instance().GetBaseMap(mapid);
|
||||
|
||||
// For 2D/3D system selection
|
||||
bool is_land_ok = creature.canWalk();
|
||||
bool is_water_ok = creature.canSwim();
|
||||
bool is_air_ok = creature.canFly();
|
||||
|
||||
const float angle = rand_norm()*(M_PI*2);
|
||||
const float range = rand_norm()*wander_distance;
|
||||
const float distanceX = range * cos(angle);
|
||||
const float distanceY = range * sin(angle);
|
||||
|
||||
nx = X + distanceX;
|
||||
ny = Y + distanceY;
|
||||
dist = distanceX*distanceX + distanceY*distanceY;
|
||||
|
||||
if (is_air_ok) // 3D system above ground and above water (flying mode)
|
||||
{
|
||||
const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change
|
||||
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.
|
||||
float wz = map->GetWaterLevel(nx, ny);
|
||||
if (tz >= nz || wz >= nz)
|
||||
return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
|
||||
}
|
||||
//else if (is_water_ok) // 3D system under water and above ground (swimming mode)
|
||||
else // 2D only
|
||||
{
|
||||
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.
|
||||
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
|
||||
nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check
|
||||
if (fabs(nz-Z)>dist)
|
||||
{
|
||||
nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above
|
||||
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)
|
||||
{
|
||||
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
//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()));
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
|
||||
{
|
||||
if(!creature.isAlive())
|
||||
return;
|
||||
|
||||
if (creature.canFly())
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE );
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Reset(Creature &creature)
|
||||
{
|
||||
Initialize(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
|
||||
{
|
||||
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
|
||||
{
|
||||
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
return true;
|
||||
}
|
||||
|
||||
i_nextMoveTime.Update(diff);
|
||||
|
||||
if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
if(!i_destinationHolder.HasArrived() && creature.IsStopped())
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
CreatureTraveller traveller(creature);
|
||||
|
||||
if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
|
||||
{
|
||||
if(i_nextMoveTime.Passed())
|
||||
{
|
||||
if (creature.canFly())
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f)
|
||||
{
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "Map.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
|
||||
{
|
||||
float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist;
|
||||
|
||||
creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance);
|
||||
|
||||
z = creature.GetPositionZ();
|
||||
uint32 mapid=creature.GetMapId();
|
||||
Map const* map = MapManager::Instance().GetBaseMap(mapid);
|
||||
|
||||
// For 2D/3D system selection
|
||||
bool is_land_ok = creature.canWalk();
|
||||
bool is_water_ok = creature.canSwim();
|
||||
bool is_air_ok = creature.canFly();
|
||||
|
||||
const float angle = rand_norm()*(M_PI*2);
|
||||
const float range = rand_norm()*wander_distance;
|
||||
const float distanceX = range * cos(angle);
|
||||
const float distanceY = range * sin(angle);
|
||||
|
||||
nx = X + distanceX;
|
||||
ny = Y + distanceY;
|
||||
|
||||
// prevent invalid coordinates generation
|
||||
MaNGOS::NormalizeMapCoord(nx);
|
||||
MaNGOS::NormalizeMapCoord(ny);
|
||||
|
||||
dist = distanceX*distanceX + distanceY*distanceY;
|
||||
|
||||
if (is_air_ok) // 3D system above ground and above water (flying mode)
|
||||
{
|
||||
const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change
|
||||
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.
|
||||
float wz = map->GetWaterLevel(nx, ny);
|
||||
if (tz >= nz || wz >= nz)
|
||||
return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
|
||||
}
|
||||
//else if (is_water_ok) // 3D system under water and above ground (swimming mode)
|
||||
else // 2D only
|
||||
{
|
||||
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.
|
||||
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
|
||||
nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check
|
||||
if (fabs(nz-Z)>dist)
|
||||
{
|
||||
nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above
|
||||
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)
|
||||
{
|
||||
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
//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()));
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
|
||||
{
|
||||
if(!creature.isAlive())
|
||||
return;
|
||||
|
||||
if (creature.canFly())
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE );
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Reset(Creature &creature)
|
||||
{
|
||||
Initialize(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
|
||||
{
|
||||
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
|
||||
{
|
||||
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
return true;
|
||||
}
|
||||
|
||||
i_nextMoveTime.Update(diff);
|
||||
|
||||
if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
if(!i_destinationHolder.HasArrived() && creature.IsStopped())
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
CreatureTraveller traveller(creature);
|
||||
|
||||
if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
|
||||
{
|
||||
if(i_nextMoveTime.Passed())
|
||||
{
|
||||
if (creature.canFly())
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f)
|
||||
{
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3681,6 +3681,11 @@ uint8 Spell::CanCast(bool strict)
|
||||
(!m_targets.getItemTarget() || !m_targets.getItemTarget()->GetProto()->LockID || m_targets.getItemTarget()->GetOwner() != m_caster ) )
|
||||
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
|
||||
LockEntry const *lockInfo = NULL;
|
||||
if (GameObject* go=m_targets.getGOTarget())
|
||||
|
||||
+103
-14
@@ -52,6 +52,8 @@
|
||||
#include "Language.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Util.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
|
||||
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||
{
|
||||
@@ -1006,10 +1008,78 @@ void Spell::EffectDummy(uint32 i)
|
||||
m_caster->CastSpell(m_caster,42337,true,NULL);
|
||||
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
|
||||
{
|
||||
// Emissary of Hate Credit
|
||||
m_caster->CastSpell(m_caster,45088,true);
|
||||
m_caster->CastSpell(m_caster, 45088, true);
|
||||
return;
|
||||
}
|
||||
case 50243: // Teach Language
|
||||
@@ -1102,6 +1172,16 @@ void Spell::EffectDummy(uint32 i)
|
||||
}
|
||||
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;
|
||||
case SPELLFAMILY_WARRIOR:
|
||||
@@ -2760,27 +2840,26 @@ void Spell::EffectOpenLock(uint32 /*i*/)
|
||||
if( goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune ||
|
||||
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
|
||||
!player->HasStealthAura() && // not stealthed
|
||||
!player->HasInvisibilityAura() && // not invisible
|
||||
player->isAlive() ) // live player
|
||||
{
|
||||
// check if it's correct bg
|
||||
if(bg && bg->GetTypeID() == BATTLEGROUND_AB)
|
||||
bg->EventPlayerClickedOnFlag(player, gameObjTarget);
|
||||
|
||||
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)
|
||||
{
|
||||
//isAllowUseBattleGroundObject() already called in CanCast()
|
||||
// in battleground check
|
||||
if(BattleGround *bg = player->GetBattleGround())
|
||||
{
|
||||
if(bg->GetTypeID() == BATTLEGROUND_EY)
|
||||
bg->EventPlayerClickedOnFlag(player, gameObjTarget);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
lockId = gameObjTarget->GetLockId();
|
||||
guid = gameObjTarget->GetGUID();
|
||||
@@ -4751,6 +4830,16 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
||||
unitTarget->CastSpell(unitTarget, spellId, true);
|
||||
break;
|
||||
}
|
||||
//5,000 Gold
|
||||
case 46642:
|
||||
{
|
||||
if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
((Player*)unitTarget)->ModifyMoney(50000000);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN )
|
||||
|
||||
@@ -1,202 +1,211 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "World.h"
|
||||
|
||||
#define SMALL_ALPHA 0.05f
|
||||
|
||||
#include <cmath>
|
||||
/*
|
||||
struct StackCleaner
|
||||
{
|
||||
Creature &i_creature;
|
||||
StackCleaner(Creature &creature) : i_creature(creature) {}
|
||||
void Done(void) { i_creature.StopMoving(); }
|
||||
~StackCleaner()
|
||||
{
|
||||
i_creature->Clear();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
|
||||
{
|
||||
if( !i_target.isValid() || !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) )
|
||||
return;
|
||||
|
||||
// prevent redundant micro-movement for pets, other followers.
|
||||
if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
if(!i_offset)
|
||||
{
|
||||
// to nearest contact position
|
||||
i_target->GetContactPoint( &owner, x, y, z );
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
/*
|
||||
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.
|
||||
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.
|
||||
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,
|
||||
we will calculate a new contact point each update loop, but will never move to it.
|
||||
The system will freeze.
|
||||
ralf
|
||||
|
||||
//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;
|
||||
if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
|
||||
return;
|
||||
*/
|
||||
Traveller<T> traveller(owner);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Initialize(T &owner)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Finalize(T &owner)
|
||||
{
|
||||
owner.clearUnitState(UNIT_STAT_CHASE);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Reset(T &owner)
|
||||
{
|
||||
Initialize(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
||||
{
|
||||
if(!i_target.isValid())
|
||||
return false;
|
||||
|
||||
if( !&owner || !owner.isAlive())
|
||||
return true;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
|
||||
return true;
|
||||
|
||||
// prevent movement while casting spells with cast time or channel time
|
||||
if ( owner.IsNonMeleeSpellCasted(false, false, true))
|
||||
{
|
||||
if (!owner.IsStopped())
|
||||
owner.StopMoving();
|
||||
return true;
|
||||
}
|
||||
|
||||
// prevent crash after creature killed pet
|
||||
if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(owner);
|
||||
|
||||
if( !i_destinationHolder.HasDestination() )
|
||||
_setTargetLocation(owner);
|
||||
if( owner.IsStopped() && !i_destinationHolder.HasArrived() )
|
||||
{
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
i_destinationHolder.StartTravel(traveller);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
|
||||
{
|
||||
// put targeted movement generators on a higher priority
|
||||
if (owner.GetObjectSize())
|
||||
i_destinationHolder.ResetUpdate(50);
|
||||
|
||||
float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
|
||||
|
||||
//More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
|
||||
// try to counter precision differences
|
||||
if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist)
|
||||
{
|
||||
owner.SetInFront(i_target.getTarget()); // Set new Angle For Map::
|
||||
_setTargetLocation(owner); //Calculate New Dest and Send data To Player
|
||||
}
|
||||
// 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() ) )
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel )
|
||||
{
|
||||
i_recalculateTravel = false;
|
||||
//Angle update will take place into owner.StopMoving()
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
owner.StopMoving();
|
||||
if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
|
||||
owner.Attack(i_target.getTarget(),true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Unit*
|
||||
TargetedMovementGenerator<T>::GetTarget() const
|
||||
{
|
||||
return i_target.getTarget();
|
||||
}
|
||||
|
||||
template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
|
||||
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;
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "World.h"
|
||||
|
||||
#define SMALL_ALPHA 0.05f
|
||||
|
||||
#include <cmath>
|
||||
/*
|
||||
struct StackCleaner
|
||||
{
|
||||
Creature &i_creature;
|
||||
StackCleaner(Creature &creature) : i_creature(creature) {}
|
||||
void Done(void) { i_creature.StopMoving(); }
|
||||
~StackCleaner()
|
||||
{
|
||||
i_creature->Clear();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
|
||||
{
|
||||
if( !i_target.isValid() || !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) )
|
||||
return;
|
||||
|
||||
// prevent redundant micro-movement for pets, other followers.
|
||||
if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
if(!i_offset)
|
||||
{
|
||||
// to nearest contact position
|
||||
i_target->GetContactPoint( &owner, x, y, z );
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
/*
|
||||
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.
|
||||
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.
|
||||
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,
|
||||
we will calculate a new contact point each update loop, but will never move to it.
|
||||
The system will freeze.
|
||||
ralf
|
||||
|
||||
//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;
|
||||
if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
|
||||
return;
|
||||
*/
|
||||
Traveller<T> traveller(owner);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
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)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Finalize(T &owner)
|
||||
{
|
||||
owner.clearUnitState(UNIT_STAT_CHASE);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Reset(T &owner)
|
||||
{
|
||||
Initialize(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
||||
{
|
||||
if(!i_target.isValid())
|
||||
return false;
|
||||
|
||||
if( !&owner || !owner.isAlive())
|
||||
return true;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
|
||||
return true;
|
||||
|
||||
// prevent movement while casting spells with cast time or channel time
|
||||
if ( owner.IsNonMeleeSpellCasted(false, false, true))
|
||||
{
|
||||
if (!owner.IsStopped())
|
||||
owner.StopMoving();
|
||||
return true;
|
||||
}
|
||||
|
||||
// prevent crash after creature killed pet
|
||||
if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(owner);
|
||||
|
||||
if( !i_destinationHolder.HasDestination() )
|
||||
_setTargetLocation(owner);
|
||||
if( owner.IsStopped() && !i_destinationHolder.HasArrived() )
|
||||
{
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
|
||||
i_destinationHolder.StartTravel(traveller);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
|
||||
{
|
||||
// put targeted movement generators on a higher priority
|
||||
if (owner.GetObjectSize())
|
||||
i_destinationHolder.ResetUpdate(50);
|
||||
|
||||
float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
|
||||
|
||||
//More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
|
||||
// try to counter precision differences
|
||||
if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist)
|
||||
{
|
||||
owner.SetInFront(i_target.getTarget()); // Set new Angle For Map::
|
||||
_setTargetLocation(owner); //Calculate New Dest and Send data To Player
|
||||
}
|
||||
// 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() ) )
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel )
|
||||
{
|
||||
i_recalculateTravel = false;
|
||||
//Angle update will take place into owner.StopMoving()
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
owner.StopMoving();
|
||||
if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
|
||||
owner.Attack(i_target.getTarget(),true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Unit*
|
||||
TargetedMovementGenerator<T>::GetTarget() const
|
||||
{
|
||||
return i_target.getTarget();
|
||||
}
|
||||
|
||||
template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
|
||||
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;
|
||||
|
||||
@@ -112,7 +112,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &di
|
||||
// Now we re-set destination to same node and start travel
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
if (creature.canFly())
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2);
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
const WaypointNode &node = i_path->at(i_currentNode);
|
||||
i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
|
||||
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
|
||||
@@ -176,7 +176,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &di
|
||||
{
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
if (creature.canFly())
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_FLYING2);
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
const WaypointNode &node = i_path->at(i_currentNode);
|
||||
i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z);
|
||||
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
|
||||
|
||||
@@ -52,8 +52,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,2,6721,676
|
||||
PRODUCTVERSION 0,2,6721,676
|
||||
FILEVERSION 0,3,6731,680
|
||||
PRODUCTVERSION 0,3,6731,680
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -69,12 +69,12 @@ BEGIN
|
||||
BLOCK "080004b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "TrinityCore"
|
||||
VALUE "FileVersion", "0, 2, 6721, 676"
|
||||
VALUE "FileVersion", "0, 3, 6731, 680"
|
||||
VALUE "InternalName", "TrinityCore"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2008"
|
||||
VALUE "OriginalFilename", "TrinityCore.exe"
|
||||
VALUE "ProductName", "TrinityCore"
|
||||
VALUE "ProductVersion", "0, 2, 6721, 676"
|
||||
VALUE "ProductVersion", "0, 3, 6731, 680"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -52,8 +52,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 0,2,6721,676
|
||||
PRODUCTVERSION 0,2,6721,676
|
||||
FILEVERSION 0,3,6731,680
|
||||
PRODUCTVERSION 0,3,6731,680
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -69,12 +69,12 @@ BEGIN
|
||||
BLOCK "080004b0"
|
||||
BEGIN
|
||||
VALUE "FileDescription", "TrinityRealm"
|
||||
VALUE "FileVersion", "0, 2, 6721, 676"
|
||||
VALUE "FileVersion", "0, 3, 6731, 680"
|
||||
VALUE "InternalName", "TrinityRealm"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2008"
|
||||
VALUE "OriginalFilename", "TrinityRealm.exe"
|
||||
VALUE "ProductName", "TrinityRealm"
|
||||
VALUE "ProductVersion", "0, 2, 6721, 676"
|
||||
VALUE "ProductVersion", "0, 3, 6731, 680"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
+10
-10
@@ -49,7 +49,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="0"
|
||||
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"
|
||||
@@ -138,7 +138,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="0"
|
||||
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"
|
||||
@@ -228,7 +228,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="2"
|
||||
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"
|
||||
@@ -316,7 +316,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/MP /wd 4748"
|
||||
AdditionalOptions="/MP /wd 4748 /wd 4244"
|
||||
Optimization="2"
|
||||
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"
|
||||
@@ -2853,11 +2853,11 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\OS_Errno.h"
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_errno.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_errno.h"
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\OS_Errno.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@@ -3237,11 +3237,11 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\OS_String.h"
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_string.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_string.h"
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\OS_String.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@@ -3285,11 +3285,11 @@
|
||||
>
|
||||
</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
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\os_time.h"
|
||||
RelativePath="..\..\dep\ACE_wrappers\ace\os_include\sys\os_time.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
|
||||
Reference in New Issue
Block a user