[svn] * Updated to 6743 and 685

Moved language id used by Arena to a higher place to solve conflicts
Added the empty script folders

--HG--
branch : trunk
rename : 6731-680 => 6743-685
This commit is contained in:
Neo2003 committed 2008-10-09 08:42:22 -05:00
1 parent e3079a1ba6
commit f736567a37
58 files changed
+24398 -24065

No files matched your search

View File
File renamed without changes.
Binary file not shown.
+1239 -1239
View File
File diff suppressed because it is too large. Load diff
+40 -18
View File
@@ -210,7 +210,8 @@ INSERT INTO `command` VALUES
('event stop',2,'Syntax: .event stop #event_id\r\nStop event #event_id. Set start time for event to time in past that make current moment is event stop time (change not saved in DB).'),
('explorecheat',3,'Syntax: .explorecheat #flag\r\n\r\nReveal or hide all maps for the selected player. If no player is selected, hide or reveal maps to you.\r\n\r\nUse a #flag of value 1 to reveal, use a #flag value of 0 to hide all maps.'),
('flusharenapoints',3,'Syntax: .flusharenapoints\r\n\r\nUse it to distribute arena points based on arena team ratings, and start a new week.'),
('gm',1,'Syntax: .gm on/off\r\n\r\nEnable or Disable GM MODE'),
('gm',1,'Syntax: .gm [on/off]\r\n\r\nEnable or Disable in game GM MODE or show current state of on/off not provided.'),
('gm chat',1,'Syntax: .gm chat [on/off]\r\n\r\nEnable or disable chat GM MODE (show gm badge in messages) or show current state of on/off not provided.'),
('gm fly',3,'Syntax: .gm fly on/off\r\nEnable/disable gm fly mode.'),
('gm list',0,'Syntax: .gm list\r\n\r\nDisplay a list of available Game Masters.'),
('gm visible',1,'Syntax: .gm visible on/off\r\n\r\nOutput current visibility state or make GM visible(on) and invisible(off) for other players.'),
@@ -352,7 +353,7 @@ INSERT INTO `command` VALUES
('save',0,'Syntax: .save\r\n\r\nSaves your character.'),
('saveall',1,'Syntax: .saveall\r\n\r\nSave all characters in game.'),
('security',3,'Syntax: .security $name #level\r\n\r\nSet the security level of player $name to a level of #level.\r\n\r\n#level may range from 0 to 5.'),
('sendmail',1,'Syntax: .sendmail #playername #subject #text\r\n\r\nSend a mail to a player. Note: subject may not contain spaces.'),
('sendmail',1,'Syntax: .sendmail #playername "#subject" "#text" itemid1[:count1] itemid2[:count2] ... itemidN[:countN]\r\n\r\nSend a mail to a player. Subject and mail text must be in "". If for itemid not provided related count values then expected 1, if count > max items in stack then items will be send in required amount stacks. All stacks amount in mail limited to 12.'),
('server info',0,'Syntax: .server info\r\n\r\nDisplay server version and the number of connected players.'),
('server idleshutdown',3,'Syntax: .server idleshutdown #delay|cancel\r\n\r\nShut the server down after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'),
('server idlerestart',3,'Syntax: .server idlerestart #delay|cancel\r\n\r\nRestart the server after #delay seconds if no active connections are present (no players) or cancel the restart/shutdown if cancel value is used.'),
@@ -2137,6 +2138,8 @@ INSERT INTO `mangos_string` VALUES
(49,'You must be at least level %u to enter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(50,'You must be at least level %u and have item %s to enter.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(51,'Hello! Ready for some training?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(52,'Invaid item count (%u) for item %u',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(53,'Mail can\'t have more %u item stacks',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(100,'Global notify: ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\nX: %f Y: %f Z: %f Orientation: %f\ngrid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(102,'%s is already being teleported.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
@@ -2339,6 +2342,10 @@ INSERT INTO `mangos_string` VALUES
(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),
(332,'GM mode is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(333,'GM mode is OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(334,'GM Chat Badge is ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(335,'GM Chat Badge is OFF',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),
@@ -2578,22 +2585,37 @@ INSERT INTO `mangos_string` VALUES
(710,'Away from Keyboard',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(711,'Your group is too large for this battleground. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(712,'Your group is too large for this arena. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(713,'Your group has members not in your arena team. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(714,'Your group does not have enough players to join this match.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(715,'The Gold Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(716,'The Green Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(717, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(718, 'Your group has an offline member. Please remove him before joining.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(719, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(720, 'Your group has players from different battleground brakets. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(721, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(722, 'Someone in your party is Deserter. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(723, 'Someone in your party is already in three battleground queues. You cannot join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(724, 'You cannot teleport to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(725, 'You cannot summon players to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(726, 'You must be in GM mode to teleport to a player in a battleground.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(727, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(728, 'Arena testing turned %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
(713,'You must be level %u to join an arena team!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(714,'%s is not high enough level to join your team',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(715,'You don\'t meet Battleground level requirements',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(716,'Your arena team is full, %s cannot join it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(730,'Your group has members not in your arena team. Please regroup to join.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(731,'Your group does not have enough players to join this match.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(732,'The Gold Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(733,'The Green Team wins!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(734, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(735, 'Your group has an offline member. Please remove him before joining.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(736, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(737, 'Your group has players from different battleground brakets. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(738, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(739, 'Someone in your party is Deserter. You can\'t join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(740, 'Someone in your party is already in three battleground queues. You cannot join as group.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(741, 'You cannot teleport to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(742, 'You cannot summon players to a battleground or arena map.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(743, 'You must be in GM mode to teleport to a player in a battleground.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(744, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(745, 'Arena testing turned %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(800,'Invalid name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(801,'You do not have enough gold',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(802,'You do not have enough free slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(803,'Your partner does not have enough free bag slots',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(804,'You do not have permission to perform that function',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(805,'Unknown language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(806,'You don\'t know that language',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(807,'Please provide character name',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(808,'Player %s not found or offline',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(809,'Account for character %s not found',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */;
UNLOCK TABLES;
+18 -17
View File
@@ -15,24 +15,25 @@ INSERT INTO `command` (`name`, `security`, `help`) VALUES
('debug arena',3,'Syntax: .debug arena\r\n\r\n Toggles arena 1v1 or normal mode.');
DELETE FROM mangos_string WHERE entry BETWEEN 711 AND 728;
DELETE FROM mangos_string WHERE entry IN (711,712);
DELETE FROM mangos_string WHERE entry BETWEEN 730 AND 745;
INSERT INTO mangos_string (entry, content_default) VALUES
(711,'Your group is too large for this battleground. Please regroup to join.'),
(712,'Your group is too large for this arena. Please regroup to join.'),
(713,'Your group has members not in your arena team. Please regroup to join.'),
(714,'Your group does not have enough players to join this match.'),
(715,'The Gold Team wins!'),
(716,'The Green Team wins!'),
(717, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.'),
(718, 'Your group has an offline member. Please remove him before joining.'),
(719, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.'),
(720, 'Your group has players from different battleground brakets. You can\'t join as group.'),
(721, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.'),
(722, 'Someone in your party is Deserter. You can\'t join as group.'),
(723, 'Someone in your party is already in three battleground queues. You cannot join as group.'),
(724, 'You cannot teleport to a battleground or arena map.'),
(725, 'You cannot summon players to a battleground or arena map.'),
(726, 'You must be in GM mode to teleport to a player in a battleground.'),
(727, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.'),
(728, 'Arena testing turned %s');
(730,'Your group has members not in your arena team. Please regroup to join.'),
(731,'Your group does not have enough players to join this match.'),
(732,'The Gold Team wins!'),
(733,'The Green Team wins!'),
(734, 'There aren\'t enough players in this battleground. It will end soon unless some more players join to balance the fight.'),
(735, 'Your group has an offline member. Please remove him before joining.'),
(736, 'Your group has players from the opposing faction. You can\'t join the battleground as a group.'),
(737, 'Your group has players from different battleground brakets. You can\'t join as group.'),
(738, 'Someone in your party is already in this battleground queue. (S)he must leave it before joining as group.'),
(739, 'Someone in your party is Deserter. You can\'t join as group.'),
(740, 'Someone in your party is already in three battleground queues. You cannot join as group.'),
(741, 'You cannot teleport to a battleground or arena map.'),
(742, 'You cannot summon players to a battleground or arena map.'),
(743, 'You must be in GM mode to teleport to a player in a battleground.'),
(744, 'You cannot teleport to a battleground from another battleground. Please leave the current battleground first.'),
(745, 'Arena testing turned %s');
-4
View File
@@ -1,4 +0,0 @@
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
+88 -94
View File
@@ -1,94 +1,88 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SCRIPTMGR_H
#define SCRIPTMGR_H
#include "Common.h"
#include "Platform/CompilerDefs.h"
#include "Database/DBCStructure.h"
class Player;
class Creature;
class CreatureAI;
class InstanceData;
class Quest;
class Item;
class GameObject;
class SpellCastTargets;
class Map;
class Unit;
class WorldObject;
#define MAX_SCRIPTS 1000 //72 bytes each (approx 71kb)
//MAX visible range (size of grid)
#define VISIBLE_RANGE (166.0f)
#define DEFAULT_TEXT "<Trinity Script Text Entry Missing!>"
//
struct Script
{
Script() :
pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), GetAI(NULL), GetInstanceData(NULL)
{}
std::string Name;
// -- Quest/gossip Methods to be scripted --
bool (*pGossipHello )(Player*, Creature*);
bool (*pQuestAccept )(Player*, Creature*, Quest const* );
bool (*pGossipSelect )(Player*, Creature*, uint32 , uint32 );
bool (*pGossipSelectWithCode)(Player*, Creature*, uint32 , uint32 , const char* );
bool (*pQuestSelect )(Player*, Creature*, Quest const* );
bool (*pQuestComplete )(Player*, Creature*, Quest const* );
uint32 (*pNPCDialogStatus )(Player*, Creature* );
uint32 (*pGODialogStatus )(Player *player, GameObject * _GO );
bool (*pChooseReward )(Player*, Creature*, Quest const*, uint32 );
bool (*pItemHello )(Player*, Item*, Quest const* );
bool (*pGOHello )(Player*, GameObject* );
bool (*pAreaTrigger )(Player*, AreaTriggerEntry* );
bool (*pItemQuestAccept )(Player*, Item *, Quest const* );
bool (*pGOQuestAccept )(Player*, GameObject*, Quest const* );
bool (*pGOChooseReward )(Player*, GameObject*_GO, Quest const*, uint32 );
bool (*pReceiveEmote )(Player*, Creature*, uint32 );
bool (*pItemUse )(Player*, Item*, SpellCastTargets const& );
CreatureAI* (*GetAI)(Creature*);
InstanceData* (*GetInstanceData)(Map*);
// -----------------------------------------
};
extern int nrscripts;
extern Script *m_scripts[MAX_SCRIPTS];
// Localized Text function
const char* GetEventAILocalizedText(uint32 entry);
const char* GetScriptLocalizedText(uint32 entry);
//EventAI text function
const char* GetEventAIText(uint32 entry); // TODO: Locales
// Script Text function
void ProcessScriptText(uint32 id, WorldObject* pSource, Unit* target = NULL); // TODO: Locales
#if COMPILER == COMPILER_GNU
#define FUNC_PTR(name,callconvention,returntype,parameters) typedef returntype(*name)parameters __attribute__ ((callconvention));
#else
#define FUNC_PTR(name, callconvention, returntype, parameters) typedef returntype(callconvention *name)parameters;
#endif
#ifdef WIN32
#define MANGOS_DLL_EXPORT extern "C" __declspec(dllexport)
#elif defined( __GNUC__ )
#define MANGOS_DLL_EXPORT extern "C"
#else
#define MANGOS_DLL_EXPORT extern "C" export
#endif
#endif
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software licensed under GPL version 2
* Please see the included DOCS/LICENSE.TXT for more information */
#ifndef SCRIPTMGR_H
#define SCRIPTMGR_H
#include "Common.h"
#include "Platform/CompilerDefs.h"
#include "Database/DBCStructure.h"
class Player;
class Creature;
class CreatureAI;
class InstanceData;
class Quest;
class Item;
class GameObject;
class SpellCastTargets;
class Map;
class Unit;
class WorldObject;
#define MAX_SCRIPTS 1000 //72 bytes each (approx 71kb)
#define VISIBLE_RANGE (166.0f) //MAX visible range (size of grid)
#define DEFAULT_TEXT "<Trinity Script Text Entry Missing!>"
struct Script
{
Script() :
pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL),pReceiveEmote(NULL),pItemUse(NULL), GetAI(NULL), GetInstanceData(NULL)
{}
std::string Name;
// Quest/gossip Methods to be scripted
bool (*pGossipHello )(Player*, Creature*);
bool (*pQuestAccept )(Player*, Creature*, Quest const* );
bool (*pGossipSelect )(Player*, Creature*, uint32 , uint32 );
bool (*pGossipSelectWithCode)(Player*, Creature*, uint32 , uint32 , const char* );
bool (*pQuestSelect )(Player*, Creature*, Quest const* );
bool (*pQuestComplete )(Player*, Creature*, Quest const* );
uint32 (*pNPCDialogStatus )(Player*, Creature* );
uint32 (*pGODialogStatus )(Player *player, GameObject * _GO );
bool (*pChooseReward )(Player*, Creature*, Quest const*, uint32 );
bool (*pItemHello )(Player*, Item*, Quest const* );
bool (*pGOHello )(Player*, GameObject* );
bool (*pAreaTrigger )(Player*, AreaTriggerEntry* );
bool (*pItemQuestAccept )(Player*, Item *, Quest const* );
bool (*pGOQuestAccept )(Player*, GameObject*, Quest const* );
bool (*pGOChooseReward )(Player*, GameObject*_GO, Quest const*, uint32 );
bool (*pReceiveEmote )(Player*, Creature*, uint32 );
bool (*pItemUse )(Player*, Item*, SpellCastTargets const& );
CreatureAI* (*GetAI)(Creature*);
InstanceData* (*GetInstanceData)(Map*);
};
extern int nrscripts;
extern Script *m_scripts[MAX_SCRIPTS];
// Localized Text function
const char* GetEventAILocalizedText(uint32 entry);
//EventAI text function
const char* GetEventAIText(uint32 entry); // TODO: Locales
//Generic scripting text function
void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target = NULL);
#if COMPILER == COMPILER_GNU
#define FUNC_PTR(name,callconvention,returntype,parameters) typedef returntype(*name)parameters __attribute__ ((callconvention));
#else
#define FUNC_PTR(name, callconvention, returntype, parameters) typedef returntype(callconvention *name)parameters;
#endif
#ifdef WIN32
#define MANGOS_DLL_EXPORT extern "C" __declspec(dllexport)
#elif defined( __GNUC__ )
#define MANGOS_DLL_EXPORT extern "C"
#else
#define MANGOS_DLL_EXPORT extern "C" export
#endif
#endif
@@ -399,7 +399,7 @@ struct MANGOS_DLL_DECL boss_malchezaarAI : public ScriptedAI
EnfeebleResetTimer=0;
}else EnfeebleResetTimer -= diff;
if(m_creature->hasUnitState(UNIT_STAT_STUNDED)) //While shifting to phase 2 malchezaar stuns himself
if(m_creature->hasUnitState(UNIT_STAT_STUNNED)) //While shifting to phase 2 malchezaar stuns himself
return;
if(m_creature->GetUInt64Value(UNIT_FIELD_TARGET)!=m_creature->getVictim()->GetGUID())
@@ -1002,7 +1002,7 @@ struct MANGOS_DLL_DECL boss_garaxxasAI : public boss_priestess_guestAI
Freezing_Trap_Timer = 30000;
}else Freezing_Trap_Timer -= diff;
if(!m_creature->getVictim()->hasUnitState(UNIT_STAT_STUNDED | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED | UNIT_STAT_DISTRACTED))
if(!m_creature->getVictim()->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED | UNIT_STAT_DISTRACTED))
DoMeleeAttackIfReady();
}else
{
@@ -16,7 +16,7 @@
/* ScriptData
SDName: Boss_Selin_Fireheart
SD%Complete: 99
SD%Complete: 90
SDComment: Heroic and Normal Support. Needs further testing.
SDCategory: Magister's Terrace
EndScriptData */
@@ -73,7 +73,7 @@ struct MANGOS_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
for(uint8 i = 0; i < size; ++i)
{
uint64 guid = pInstance->GetData64(DATA_FEL_CRYSTAL);
outstring_log("Selin: Adding Fel Crystal %u to list", guid);
debug_log("SD2: Selin: Adding Fel Crystal %u to list", guid);
Crystals.push_back(guid);
}
}
@@ -116,9 +116,9 @@ struct MANGOS_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
}
GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
if(Door)
Door->SetGoState(0); // Close the door. Open it only in JustDied.
if( Door )
Door->SetGoState(0); // Open the big encounter door. Close it in Aggro and open it only in JustDied(and here)
// Small door opened after event are expected to be closed by default
// Set Inst data for encounter
pInstance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
}else error_log(ERROR_INST_DATA);
@@ -160,10 +160,11 @@ struct MANGOS_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
}
}
}
if(CrystalChosen)
if( CrystalChosen )
{
DoYell(SAY_ENERGY, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_ENERGY);
CrystalChosen->CastSpell(CrystalChosen, SPELL_FEL_CRYSTAL_COSMETIC, true);
float x, y, z; // coords that we move to, close to the crystal.
@@ -185,7 +186,7 @@ struct MANGOS_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
{
//Creature* pCrystal = ((Creature*)Unit::GetUnit(*m_creature, FelCrystals[i]));
Creature* pCrystal = ((Creature*)Unit::GetUnit(*m_creature, *itr));
if(pCrystal && pCrystal->isAlive())
if( pCrystal && pCrystal->isAlive())
pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
}
}
@@ -194,6 +195,13 @@ struct MANGOS_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
{
DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_AGGRO);
if( pInstance )
{
GameObject* EncounterDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
if( EncounterDoor )
EncounterDoor->SetGoState(1); //Close the encounter door, open it in JustDied/Reset
}
}
void KilledUnit(Unit* victim)
@@ -245,9 +253,14 @@ struct MANGOS_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
}
pInstance->SetData(DATA_SELIN_EVENT, DONE); // Encounter complete!
GameObject* EncounterDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR));
if(EncounterDoor)
EncounterDoor->SetGoState(1); // Open the door
if( EncounterDoor )
EncounterDoor->SetGoState(0); // Open the encounter door
GameObject* ContinueDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_DOOR));
if( ContinueDoor )
ContinueDoor->SetGoState(0); // Open the door leading further in
ShatterRemainingCrystals();
}
@@ -302,23 +315,27 @@ struct MANGOS_DLL_DECL boss_selin_fireheartAI : public ScriptedAI
}else
{
if(IsDraining)
if(EmpowerTimer < diff)
if( IsDraining )
{
IsDraining = false;
DrainingCrystal = false;
DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_EMPOWERED);
Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
if(CrystalChosen && CrystalChosen->isAlive())
// Use Deal Damage to kill it, not setDeathState.
CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
if( EmpowerTimer < diff )
{
IsDraining = false;
DrainingCrystal = false;
CrystalGUID = 0;
DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_EMPOWERED);
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
}else EmpowerTimer -= diff;
Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
if( CrystalChosen && CrystalChosen->isAlive() )
// Use Deal Damage to kill it, not setDeathState.
CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
CrystalGUID = 0;
m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
}else EmpowerTimer -= diff;
}
}
DoMeleeAttackIfReady(); // No need to check if we are draining crystal here, as the spell has a stun.
@@ -16,7 +16,7 @@
/* ScriptData
SDName: Instance_Magisters_Terrace
SD%Complete: 100
SD%Complete: 60
SDComment: Designed only for Selin Fireheart
SDCategory: Magister's Terrace
EndScriptData */
@@ -118,15 +118,24 @@ struct MANGOS_DLL_DECL instance_magisters_terrace : public ScriptedInstance
{
switch(entry)
{
case 24723:
SelinGUID = creature->GetGUID();
break;
case 24560:
DelrissaGUID = creature->GetGUID();
break;
case 24722:
FelCrystals.push_back(creature->GetGUID());
break;
case 24723: SelinGUID = creature->GetGUID(); break;
case 24560: DelrissaGUID = creature->GetGUID(); break;
case 24722: FelCrystals.push_back(creature->GetGUID()); break;
}
}
void OnObjectCreate(GameObject* go)
{
switch(go->GetEntry())
{
case 187896: VexallusDoorGUID = go->GetGUID(); break;
//SunwellRaid Gate 02
case 187979: SelinDoorGUID = go->GetGUID(); break;
//Assembly Chamber Door
case 188065: SelinEncounterDoorGUID = go->GetGUID(); break;
case 187770: DelrissaDoorGUID = go->GetGUID(); break;
case 188165: KaelStatue[0] = go->GetGUID(); break;
case 188166: KaelStatue[1] = go->GetGUID(); break;
}
}
@@ -164,19 +173,6 @@ struct MANGOS_DLL_DECL instance_magisters_terrace : public ScriptedInstance
}
return 0;
}
void OnObjectCreate(GameObject* go)
{
switch(go->GetEntry())
{
case 187896: VexallusDoorGUID = go->GetGUID(); break;
case 187979: SelinDoorGUID = go->GetGUID(); break;
case 188118: SelinEncounterDoorGUID = go->GetGUID(); break;
case 187770: DelrissaDoorGUID = go->GetGUID(); break;
case 188165: KaelStatue[0] = go->GetGUID(); break;
case 188166: KaelStatue[1] = go->GetGUID(); break;
}
}
};
InstanceData* GetInstanceData_instance_magisters_terrace(Map* map)
@@ -87,7 +87,7 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI
AfterTeleportTimer = 0;
Abuse_Bug_Timer = 10000 + rand()%7000;
BugsTimer = 2000;
m_creature->clearUnitState(UNIT_STAT_STUNDED);
m_creature->clearUnitState(UNIT_STAT_STUNNED);
DontYellWhenDead = false;
EnrageTimer = 15*60000;
}
@@ -290,7 +290,7 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI
DoStopAttack();
DoResetThreat();
DoCast(m_creature, SPELL_TWIN_TELEPORT_VISUAL);
m_creature->addUnitState(UNIT_STAT_STUNDED);
m_creature->addUnitState(UNIT_STAT_STUNNED);
AfterTeleport = true;
AfterTeleportTimer = 2000;
tspellcasted = false;
@@ -302,9 +302,9 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI
{
if (!tspellcasted)
{
m_creature->clearUnitState(UNIT_STAT_STUNDED);
m_creature->clearUnitState(UNIT_STAT_STUNNED);
DoCast(m_creature, SPELL_TWIN_TELEPORT);
m_creature->addUnitState(UNIT_STAT_STUNDED);
m_creature->addUnitState(UNIT_STAT_STUNNED);
}
tspellcasted = true;
@@ -312,7 +312,7 @@ struct MANGOS_DLL_DECL boss_twinemperorsAI : public ScriptedAI
if (AfterTeleportTimer < diff)
{
AfterTeleport = false;
m_creature->clearUnitState(UNIT_STAT_STUNDED);
m_creature->clearUnitState(UNIT_STAT_STUNNED);
Unit *nearu = PickNearestPlayer();
//DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
AttackStart(nearu);
@@ -73,31 +73,41 @@ PRIMARY KEY (`id`)
DROP TABLE IF EXISTS `script_texts`;
CREATE TABLE `script_texts` (
`id` int(11) unsigned NOT NULL auto_increment COMMENT 'Identifier',
`sound` int(11) unsigned NOT NULL default '0',
`type` int(11) unsigned NOT NULL default '0',
`language` int(11) unsigned NOT NULL default '0',
`text` varchar(255) NOT NULL default '',
`comment` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
`entry` mediumint(8) NOT NULL,
`content_default` text NOT NULL,
`content_loc1` text,
`content_loc2` text,
`content_loc3` text,
`content_loc4` text,
`content_loc5` text,
`content_loc6` text,
`content_loc7` text,
`content_loc8` text,
`sound` mediumint(8) unsigned NOT NULL default '0',
`type` tinyint unsigned NOT NULL default '0',
`language` tinyint unsigned NOT NULL default '0',
`comment` text,
PRIMARY KEY (`entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Script Texts';
DROP TABLE IF EXISTS `script_localized_texts`;
CREATE TABLE `script_localized_texts` (
`id` int(11) unsigned NOT NULL auto_increment COMMENT 'Identifier',
`locale_1` varchar(255) NOT NULL default '',
`locale_2` varchar(255) NOT NULL default '',
`locale_3` varchar(255) NOT NULL default '',
`locale_4` varchar(255) NOT NULL default '',
`locale_5` varchar(255) NOT NULL default '',
`locale_6` varchar(255) NOT NULL default '',
`locale_7` varchar(255) NOT NULL default '',
`locale_8` varchar(255) NOT NULL default '',
`comment` varchar(255) NOT NULL default '' COMMENT 'Text Comment',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Localized Script Text';
DROP TABLE IF EXISTS `custom_texts`;
CREATE TABLE `custom_texts` (
`entry` mediumint(8) NOT NULL,
`content_default` text NOT NULL,
`content_loc1` text,
`content_loc2` text,
`content_loc3` text,
`content_loc4` text,
`content_loc5` text,
`content_loc6` text,
`content_loc7` text,
`content_loc8` text,
`sound` mediumint(8) unsigned NOT NULL default '0',
`type` tinyint unsigned NOT NULL default '0',
`language` tinyint unsigned NOT NULL default '0',
`comment` text,
PRIMARY KEY (`entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Custom Texts';
DROP TABLE IF EXISTS `script_db_version`;
CREATE TABLE `script_db_version` (
+1 -1
View File
@@ -47,7 +47,7 @@ AggressorAI::MoveInLineOfSight(Unit *u)
if( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
return;
if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNDED) && u->isTargetableForAttack() &&
if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
u->isInAccessablePlaceFor(&i_creature) )
{
+463 -462
View File
@@ -1,462 +1,463 @@
/*
* 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 "WorldSession.h"
#include "WorldPacket.h"
#include "Log.h"
#include "Database/DatabaseEnv.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "ArenaTeam.h"
#include "World.h"
#include "SocialMgr.h"
void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
{
sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid;
recv_data >> guid;
sLog.outDebug("Inspect Arena stats " I64FMTD, guid);
if(Player *plr = objmgr.GetPlayer(guid))
{
for (uint8 i = 0; i < MAX_ARENA_SLOT; i++)
{
if(uint32 a_id = plr->GetArenaTeamId(i))
{
if(ArenaTeam *at = objmgr.GetArenaTeamById(a_id))
at->InspectStats(this, plr->GetGUID());
}
}
}
}
void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" );
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId;
recv_data >> ArenaTeamId;
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam) // arena team not found
return;
arenateam->Query(this);
arenateam->Stats(this);
}
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" );
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam)
return;
arenateam->Roster(this);
}
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
uint32 ArenaTeamId; // arena team id
std::string Invitedname;
Player * player = NULL;
recv_data >> ArenaTeamId >> Invitedname;
if(!Invitedname.empty())
{
if(!normalizePlayerName(Invitedname))
return;
player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
}
if(!player)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
}
if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
{
//SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S);
// can't find related opcode
SendNotification("%s is not high enough level to join your team", player->GetName());
return;
}
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM);
return;
}
// OK result but not send invite
if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
return;
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
return;
}
if(player->GetArenaTeamId(arenateam->GetSlot()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
return;
}
if(player->GetArenaTeamIdInvited())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
return;
}
if(arenateam->GetMembersSize() >= arenateam->GetType() * 2)
{
// should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL
// SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL);
SendNotification("Your arena team is full, %s cannot join it.", player->GetName());
return;
}
sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str());
player->SetArenaTeamIdInvited(arenateam->GetId());
WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10));
data << GetPlayer()->GetName();
data << arenateam->GetName();
player->GetSession()->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE");
}
void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/)
{
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_ACCEPT"); // empty opcode
ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
if(!at)
{
// arena team not exist
return;
}
if(_player->GetArenaTeamId(at->GetSlot()))
{
// already in arena team that size
return;
}
// not let enemies sign petition
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain()))
return;
if(!at->AddMember(_player->GetGUID()))
return;
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_JOIN_SS, 2, _player->GetName(), at->GetName(), "");
at->BroadcastPacket(&data);
}
void WorldSession::HandleArenaTeamInviteDeclineOpcode(WorldPacket & /*recv_data*/)
{
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_DECLINE"); // empty opcode
_player->SetArenaTeamIdInvited(0); // no more invited
}
void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// send command result
return;
}
if(_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1)
{
// check for correctness
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
return;
}
// arena team has only one member (=captain)
if(_player->GetGUID() == at->GetCaptain())
{
at->Disband(this);
delete at;
return;
}
at->DelMember(_player->GetGUID());
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), "");
at->BroadcastPacket(&data);
//SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
}
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// arena team not found
return;
}
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
at->Disband(this);
delete at;
}
void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
uint32 ArenaTeamId;
std::string name;
recv_data >> ArenaTeamId;
recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// arena team not found
return;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
// player guid not found
return;
}
if(at->GetCaptain() == guid)
{
// unsure
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
if(at->GetCaptain() == guid)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
return;
}
at->DelMember(guid);
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_REMOVE_SSS, 3, name, at->GetName(), _player->GetName());
at->BroadcastPacket(&data);
}
void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
uint32 ArenaTeamId;
std::string name;
recv_data >> ArenaTeamId;
recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// arena team not found
return;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
// player guid not found
return;
}
if(at->GetCaptain() == guid)
{
// target player already captain
return;
}
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
at->SetCaptain(guid);
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 3, _player->GetName(), name, at->GetName());
at->BroadcastPacket(&data);
}
void WorldSession::SendArenaTeamCommandResult(uint32 unk1, std::string str1, std::string str2, uint32 unk3)
{
WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+str1.length()+1+str2.length()+1+4);
data << unk1;
data << str1;
data << str2;
data << unk3;
SendPacket(&data);
}
void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, std::string str1, std::string str2, std::string str3)
{
data->Initialize(SMSG_ARENA_TEAM_EVENT, 1+1+1);
*data << eventid;
*data << str_count;
switch(str_count)
{
case 1:
*data << str1;
break;
case 2:
*data << str1;
*data << str2;
break;
case 3:
*data << str1;
*data << str2;
*data << str3;
break;
default:
sLog.outError("Unhandled str_count %u in SendArenaTeamEvent()", str_count);
return;
}
}
void WorldSession::SendNotInArenaTeamPacket(uint8 type)
{
WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team
uint32 unk = 0;
data << uint32(unk); // unk(0)
if(!unk)
data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types...
SendPacket(&data);
}
/*
+ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
+ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
+ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
+ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
+ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
+ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team"
+ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team"
+ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name"
+ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\""
+ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team"
+ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that"
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size"
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
+ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
+ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
+ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
+ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
+ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
+ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
+ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
+ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
*/
/*
* 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 "WorldSession.h"
#include "WorldPacket.h"
#include "Log.h"
#include "Database/DatabaseEnv.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "ArenaTeam.h"
#include "World.h"
#include "SocialMgr.h"
#include "Language.h"
void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
{
sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 8);
uint64 guid;
recv_data >> guid;
sLog.outDebug("Inspect Arena stats " I64FMTD, guid);
if(Player *plr = objmgr.GetPlayer(guid))
{
for (uint8 i = 0; i < MAX_ARENA_SLOT; i++)
{
if(uint32 a_id = plr->GetArenaTeamId(i))
{
if(ArenaTeam *at = objmgr.GetArenaTeamById(a_id))
at->InspectStats(this, plr->GetGUID());
}
}
}
}
void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" );
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId;
recv_data >> ArenaTeamId;
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam) // arena team not found
return;
arenateam->Query(this);
arenateam->Stats(this);
}
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
{
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" );
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam)
return;
arenateam->Roster(this);
}
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
uint32 ArenaTeamId; // arena team id
std::string Invitedname;
Player * player = NULL;
recv_data >> ArenaTeamId >> Invitedname;
if(!Invitedname.empty())
{
if(!normalizePlayerName(Invitedname))
return;
player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
}
if(!player)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
return;
}
if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
{
//SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S);
// can't find related opcode
SendNotification(LANG_HIS_ARENA_LEVEL_REQ_ERROR, player->GetName());
return;
}
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
if(!arenateam)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM);
return;
}
// OK result but not send invite
if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
return;
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
return;
}
if(player->GetArenaTeamId(arenateam->GetSlot()))
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
return;
}
if(player->GetArenaTeamIdInvited())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
return;
}
if(arenateam->GetMembersSize() >= arenateam->GetType() * 2)
{
// should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL
// SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL);
SendNotification(LANG_YOUR_ARENA_TEAM_FULL, player->GetName());
return;
}
sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str());
player->SetArenaTeamIdInvited(arenateam->GetId());
WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10));
data << GetPlayer()->GetName();
data << arenateam->GetName();
player->GetSession()->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE");
}
void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/)
{
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_ACCEPT"); // empty opcode
ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
if(!at)
{
// arena team not exist
return;
}
if(_player->GetArenaTeamId(at->GetSlot()))
{
// already in arena team that size
return;
}
// not let enemies sign petition
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain()))
return;
if(!at->AddMember(_player->GetGUID()))
return;
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_JOIN_SS, 2, _player->GetName(), at->GetName(), "");
at->BroadcastPacket(&data);
}
void WorldSession::HandleArenaTeamInviteDeclineOpcode(WorldPacket & /*recv_data*/)
{
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_DECLINE"); // empty opcode
_player->SetArenaTeamIdInvited(0); // no more invited
}
void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// send command result
return;
}
if(_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1)
{
// check for correctness
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
return;
}
// arena team has only one member (=captain)
if(_player->GetGUID() == at->GetCaptain())
{
at->Disband(this);
delete at;
return;
}
at->DelMember(_player->GetGUID());
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), "");
at->BroadcastPacket(&data);
//SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
}
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4);
uint32 ArenaTeamId; // arena team id
recv_data >> ArenaTeamId;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// arena team not found
return;
}
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
at->Disband(this);
delete at;
}
void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
uint32 ArenaTeamId;
std::string name;
recv_data >> ArenaTeamId;
recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// arena team not found
return;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
// player guid not found
return;
}
if(at->GetCaptain() == guid)
{
// unsure
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
if(at->GetCaptain() == guid)
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
return;
}
at->DelMember(guid);
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_REMOVE_SSS, 3, name, at->GetName(), _player->GetName());
at->BroadcastPacket(&data);
}
void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data)
{
sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN");
//recv_data.hexlike();
CHECK_PACKET_SIZE(recv_data, 4+1);
uint32 ArenaTeamId;
std::string name;
recv_data >> ArenaTeamId;
recv_data >> name;
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
if(!at)
{
// arena team not found
return;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
// player guid not found
return;
}
if(at->GetCaptain() == guid)
{
// target player already captain
return;
}
if(at->GetCaptain() != _player->GetGUID())
{
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
return;
}
at->SetCaptain(guid);
// event
WorldPacket data;
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 3, _player->GetName(), name, at->GetName());
at->BroadcastPacket(&data);
}
void WorldSession::SendArenaTeamCommandResult(uint32 unk1, std::string str1, std::string str2, uint32 unk3)
{
WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+str1.length()+1+str2.length()+1+4);
data << unk1;
data << str1;
data << str2;
data << unk3;
SendPacket(&data);
}
void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, std::string str1, std::string str2, std::string str3)
{
data->Initialize(SMSG_ARENA_TEAM_EVENT, 1+1+1);
*data << eventid;
*data << str_count;
switch(str_count)
{
case 1:
*data << str1;
break;
case 2:
*data << str1;
*data << str2;
break;
case 3:
*data << str1;
*data << str2;
*data << str3;
break;
default:
sLog.outError("Unhandled str_count %u in SendArenaTeamEvent()", str_count);
return;
}
}
void WorldSession::SendNotInArenaTeamPacket(uint8 type)
{
WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team
uint32 unk = 0;
data << uint32(unk); // unk(0)
if(!unk)
data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types...
SendPacket(&data);
}
/*
+ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
+ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
+ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
+ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
+ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
+ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team"
+ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team"
+ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name"
+ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\""
+ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team"
+ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that"
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size"
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
+ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
+ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
+ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
+ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
+ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
+ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
+ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
+ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
+ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
*/
File diff suppressed because it is too large. Load diff
+1066 -1065
View File
File diff suppressed because it is too large. Load diff
+23 -16
View File
@@ -353,6 +353,7 @@ ChatCommand * ChatHandler::getCommandTable()
static ChatCommand gmCommandTable[] =
{
{ "chat", SEC_MODERATOR, &ChatHandler::HandleGMChatCommand, "", NULL },
{ "list", SEC_PLAYER, &ChatHandler::HandleGMListCommand, "", NULL },
{ "visible", SEC_MODERATOR, &ChatHandler::HandleVisibleCommand, "", NULL },
{ "fly", SEC_ADMINISTRATOR, &ChatHandler::HandleFlyModeCommand, "", NULL },
@@ -507,18 +508,29 @@ const char *ChatHandler::GetMangosString(int32 entry)
return m_session->GetMangosString(entry);
}
bool ChatHandler::hasStringAbbr(const char* s1, const char* s2)
bool ChatHandler::hasStringAbbr(const char* name, const char* part)
{
for(;;)
// non "" command
if( *name )
{
if( !*s2 )
return true;
else if( !*s1 )
// "" part from non-"" command
if( !*part )
return false;
else if( tolower( *s1 ) != tolower( *s2 ) )
return false;
++s1; ++s2;
for(;;)
{
if( !*part )
return true;
else if( !*name )
return false;
else if( tolower( *name ) != tolower( *part ) )
return false;
++name; ++part;
}
}
// allow with any for ""
return true;
}
void ChatHandler::SendSysMessage(const char *str)
@@ -594,13 +606,9 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand *table, const char* text, st
while (*text == ' ') ++text;
if(!cmd.length())
return false;
for(uint32 i = 0; table[i].Name != NULL; i++)
{
// allow pass "" command name in table
if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, cmd.c_str()))
if( !hasStringAbbr(table[i].Name, cmd.c_str()) )
continue;
// select subcommand from child commands list
@@ -688,8 +696,7 @@ bool ChatHandler::ShowHelpForSubCommands(ChatCommand *table, char const* cmd, ch
if(m_session->GetSecurity() < table[i].SecurityLevel)
continue;
if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, subcmd))
continue;
if( !hasStringAbbr(table[i].Name, subcmd) )
(list += "\n ") += table[i].Name;
}
@@ -717,7 +724,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand *table, const char* cmd)
if(m_session->GetSecurity() < table[i].SecurityLevel)
continue;
if(strlen(table[i].Name) && !hasStringAbbr(table[i].Name, cmd))
if( !hasStringAbbr(table[i].Name, cmd) )
continue;
// have subcommand
+2 -1
View File
@@ -69,7 +69,7 @@ class ChatHandler
int ParseCommands(const char* text);
protected:
bool hasStringAbbr(const char* s1, const char* s2);
bool hasStringAbbr(const char* name, const char* part);
void SendGlobalSysMessage(const char *str);
bool ExecuteCommandInTable(ChatCommand *table, const char* text, std::string fullcommand);
@@ -94,6 +94,7 @@ class ChatHandler
bool HandleAnnounceCommand(const char* args);
bool HandleNotifyCommand(const char* args);
bool HandleGMmodeCommand(const char* args);
bool HandleGMChatCommand(const char* args);
bool HandleVisibleCommand(const char* args);
bool HandleGPSCommand(const char* args);
bool HandleTaxiCheatCommand(const char* args);
+583 -583
View File
File diff suppressed because it is too large. Load diff
+155 -155
View File
@@ -1,155 +1,155 @@
/*
* 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 "Opcodes.h"
#include "ConfusedMovementGenerator.h"
#include "DestinationHolderImp.h"
template<class T>
void
ConfusedMovementGenerator<T>::Initialize(T &unit)
{
const float wander_distance=11;
float x,y,z;
x = unit.GetPositionX();
y = unit.GetPositionY();
z = unit.GetPositionZ();
uint32 mapid=unit.GetMapId();
Map const* map = MapManager::Instance().GetBaseMap(mapid);
i_nextMove = 1;
bool is_water_ok, is_land_ok;
_InitSpecific(unit, is_water_ok, is_land_ok);
for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx)
{
const float wanderX=wander_distance*rand_norm() - wander_distance/2;
const float wanderY=wander_distance*rand_norm() - wander_distance/2;
i_waypoints[idx][0] = x + wanderX;
i_waypoints[idx][1] = y + wanderY;
// prevent invalid coordinates generation
MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
// if generated wrong path just ignore
if( is_water && !is_water_ok || !is_water && !is_land_ok )
{
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
}
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
i_waypoints[idx][2] = z;
}
unit.StopMoving();
unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
unit.addUnitState(UNIT_STAT_CONFUSED);
}
template<>
void
ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
{
is_water_ok = creature.canSwim();
is_land_ok = creature.canWalk();
}
template<>
void
ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
{
is_water_ok = true;
is_land_ok = true;
}
template<class T>
void
ConfusedMovementGenerator<T>::Reset(T &unit)
{
i_nextMove = 1;
i_nextMoveTime.Reset(0);
i_destinationHolder.ResetUpdate();
unit.StopMoving();
}
template<class T>
bool
ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
if(!&unit)
return true;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
return true;
if( i_nextMoveTime.Passed() )
{
// currently moving, update location
Traveller<T> traveller(unit);
if( i_destinationHolder.UpdateTraveller(traveller, diff, false))
{
if( i_destinationHolder.HasArrived())
{
// arrived, stop and wait a bit
unit.StopMoving();
i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher
}
}
}
else
{
// waiting for next move
i_nextMoveTime.Update(diff);
if( i_nextMoveTime.Passed() )
{
// start moving
assert( i_nextMove <= MAX_CONF_WAYPOINTS );
const float x = i_waypoints[i_nextMove][0];
const float y = i_waypoints[i_nextMove][1];
const float z = i_waypoints[i_nextMove][2];
Traveller<T> traveller(unit);
i_destinationHolder.SetDestination(traveller, x, y, z);
}
}
return true;
}
template<class T>
void
ConfusedMovementGenerator<T>::Finalize(T &unit)
{
unit.clearUnitState(UNIT_STAT_CONFUSED);
}
template void ConfusedMovementGenerator<Player>::Initialize(Player &player);
template void ConfusedMovementGenerator<Creature>::Initialize(Creature &creature);
template void ConfusedMovementGenerator<Player>::Finalize(Player &player);
template void ConfusedMovementGenerator<Creature>::Finalize(Creature &creature);
template void ConfusedMovementGenerator<Player>::Reset(Player &player);
template void ConfusedMovementGenerator<Creature>::Reset(Creature &creature);
template bool ConfusedMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
template bool ConfusedMovementGenerator<Creature>::Update(Creature &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 "Creature.h"
#include "MapManager.h"
#include "Opcodes.h"
#include "ConfusedMovementGenerator.h"
#include "DestinationHolderImp.h"
template<class T>
void
ConfusedMovementGenerator<T>::Initialize(T &unit)
{
const float wander_distance=11;
float x,y,z;
x = unit.GetPositionX();
y = unit.GetPositionY();
z = unit.GetPositionZ();
uint32 mapid=unit.GetMapId();
Map const* map = MapManager::Instance().GetBaseMap(mapid);
i_nextMove = 1;
bool is_water_ok, is_land_ok;
_InitSpecific(unit, is_water_ok, is_land_ok);
for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx)
{
const float wanderX=wander_distance*rand_norm() - wander_distance/2;
const float wanderY=wander_distance*rand_norm() - wander_distance/2;
i_waypoints[idx][0] = x + wanderX;
i_waypoints[idx][1] = y + wanderY;
// prevent invalid coordinates generation
MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
// if generated wrong path just ignore
if( is_water && !is_water_ok || !is_water && !is_land_ok )
{
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
}
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
i_waypoints[idx][2] = z;
}
unit.StopMoving();
unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
unit.addUnitState(UNIT_STAT_CONFUSED);
}
template<>
void
ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
{
is_water_ok = creature.canSwim();
is_land_ok = creature.canWalk();
}
template<>
void
ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
{
is_water_ok = true;
is_land_ok = true;
}
template<class T>
void
ConfusedMovementGenerator<T>::Reset(T &unit)
{
i_nextMove = 1;
i_nextMoveTime.Reset(0);
i_destinationHolder.ResetUpdate();
unit.StopMoving();
}
template<class T>
bool
ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
if(!&unit)
return true;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
return true;
if( i_nextMoveTime.Passed() )
{
// currently moving, update location
Traveller<T> traveller(unit);
if( i_destinationHolder.UpdateTraveller(traveller, diff, false))
{
if( i_destinationHolder.HasArrived())
{
// arrived, stop and wait a bit
unit.StopMoving();
i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher
}
}
}
else
{
// waiting for next move
i_nextMoveTime.Update(diff);
if( i_nextMoveTime.Passed() )
{
// start moving
assert( i_nextMove <= MAX_CONF_WAYPOINTS );
const float x = i_waypoints[i_nextMove][0];
const float y = i_waypoints[i_nextMove][1];
const float z = i_waypoints[i_nextMove][2];
Traveller<T> traveller(unit);
i_destinationHolder.SetDestination(traveller, x, y, z);
}
}
return true;
}
template<class T>
void
ConfusedMovementGenerator<T>::Finalize(T &unit)
{
unit.clearUnitState(UNIT_STAT_CONFUSED);
}
template void ConfusedMovementGenerator<Player>::Initialize(Player &player);
template void ConfusedMovementGenerator<Creature>::Initialize(Creature &creature);
template void ConfusedMovementGenerator<Player>::Finalize(Player &player);
template void ConfusedMovementGenerator<Creature>::Finalize(Creature &creature);
template void ConfusedMovementGenerator<Player>::Reset(Player &player);
template void ConfusedMovementGenerator<Creature>::Reset(Creature &creature);
template bool ConfusedMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
template bool ConfusedMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff);
+29 -18
View File
@@ -75,6 +75,14 @@ bool VendorItemData::RemoveItem( uint32 item_id )
return false;
}
size_t VendorItemData::FindItemSlot(uint32 item_id) const
{
for(size_t i = 0; i < m_items.size(); ++i )
if(m_items[i]->item==item_id)
return i;
return m_items.size();
}
VendorItem const* VendorItemData::FindItem(uint32 item_id) const
{
for(VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i )
@@ -1910,26 +1918,29 @@ time_t Creature::GetRespawnTimeEx() const
void Creature::GetRespawnCoord( float &x, float &y, float &z, float* ori, float* dist ) const
{
if(CreatureData const* data = objmgr.GetCreatureData(GetDBTableGUIDLow()))
if (m_DBTableGuid)
{
x = data->posX;
y = data->posY;
z = data->posZ;
if(ori)
*ori = data->orientation;
if(dist)
*dist = data->spawndist;
}
else
{
x = GetPositionX();
y = GetPositionY();
z = GetPositionZ();
if(ori)
*ori = GetOrientation();
if(dist)
*dist = 0;
if (CreatureData const* data = objmgr.GetCreatureData(GetDBTableGUIDLow()))
{
x = data->posX;
y = data->posY;
z = data->posZ;
if(ori)
*ori = data->orientation;
if(dist)
*dist = data->spawndist;
return;
}
}
x = GetPositionX();
y = GetPositionY();
z = GetPositionZ();
if(ori)
*ori = GetOrientation();
if(dist)
*dist = 0;
}
void Creature::AllLootRemovedFromCorpse()
+1
View File
@@ -308,6 +308,7 @@ struct VendorItemData
}
bool RemoveItem( uint32 item_id );
VendorItem const* FindItem(uint32 item_id) const;
size_t FindItemSlot(uint32 item_id) const;
void Clear()
{
+379 -379
View File
@@ -1,379 +1,379 @@
/*
* 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 "FleeingMovementGenerator.h"
#include "DestinationHolderImp.h"
#include "ObjectAccessor.h"
#define MIN_QUIET_DISTANCE 28.0f
#define MAX_QUIET_DISTANCE 43.0f
template<class T>
void
FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
{
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) )
return;
if(!_setMoveData(owner))
return;
float x, y, z;
if(!_getPoint(owner, x, y, z))
return;
owner.addUnitState(UNIT_STAT_FLEEING);
Traveller<T> traveller(owner);
i_destinationHolder.SetDestination(traveller, x, y, z);
}
template<class T>
bool
FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
{
if(!&owner)
return false;
x = owner.GetPositionX();
y = owner.GetPositionY();
z = owner.GetPositionZ();
float temp_x, temp_y, angle;
const Map * _map = MapManager::Instance().GetBaseMap(owner.GetMapId());
//primitive path-finding
for(uint8 i = 0; i < 18; i++)
{
if(i_only_forward && i > 2)
break;
float distance = 5.0f;
switch(i)
{
case 0:
angle = i_cur_angle;
break;
case 1:
angle = i_cur_angle;
distance /= 2;
break;
case 2:
angle = i_cur_angle;
distance /= 4;
break;
case 3:
angle = i_cur_angle + M_PI/4.0f;
break;
case 4:
angle = i_cur_angle - M_PI/4.0f;
break;
case 5:
angle = i_cur_angle + M_PI/4.0f;
distance /= 2;
break;
case 6:
angle = i_cur_angle - M_PI/4.0f;
distance /= 2;
break;
case 7:
angle = i_cur_angle + M_PI/2.0f;
break;
case 8:
angle = i_cur_angle - M_PI/2.0f;
break;
case 9:
angle = i_cur_angle + M_PI/2.0f;
distance /= 2;
break;
case 10:
angle = i_cur_angle - M_PI/2.0f;
distance /= 2;
break;
case 11:
angle = i_cur_angle + M_PI/4.0f;
distance /= 4;
break;
case 12:
angle = i_cur_angle - M_PI/4.0f;
distance /= 4;
break;
case 13:
angle = i_cur_angle + M_PI/2.0f;
distance /= 4;
break;
case 14:
angle = i_cur_angle - M_PI/2.0f;
distance /= 4;
break;
case 15:
angle = i_cur_angle + M_PI*3/4.0f;
distance /= 2;
break;
case 16:
angle = i_cur_angle - M_PI*3/4.0f;
distance /= 2;
break;
case 17:
angle = i_cur_angle + M_PI;
distance /= 2;
break;
}
temp_x = x + distance * cos(angle);
temp_y = y + distance * sin(angle);
MaNGOS::NormalizeMapCoord(temp_x);
MaNGOS::NormalizeMapCoord(temp_y);
if( owner.IsWithinLOS(temp_x,temp_y,z))
{
bool is_water_now = _map->IsInWater(x,y,z);
if(is_water_now && _map->IsInWater(temp_x,temp_y,z))
{
x = temp_x;
y = temp_y;
return true;
}
float new_z = _map->GetHeight(temp_x,temp_y,z,true);
if(new_z <= INVALID_HEIGHT)
continue;
bool is_water_next = _map->IsInWater(temp_x,temp_y,new_z);
if((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
continue;
if( !(new_z - z) || distance / fabs(new_z - z) > 1.0f)
{
float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+M_PI/2),temp_y + 1.0f*sin(angle+M_PI/2),z,true);
float new_z_right = _map->GetHeight(temp_x + 1.0f*cos(angle-M_PI/2),temp_y + 1.0f*sin(angle-M_PI/2),z,true);
if(fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f)
{
x = temp_x;
y = temp_y;
z = new_z;
return true;
}
}
}
}
i_to_distance_from_caster = 0.0f;
i_nextCheckTime.Reset( urand(500,1000) );
return false;
}
template<class T>
bool
FleeingMovementGenerator<T>::_setMoveData(T &owner)
{
float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z);
if(i_to_distance_from_caster > 0.0f)
{
if((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster) ||
// if we reach lower distance
(i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz > i_last_distance_from_caster) ||
// if we can't be close
(i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster) ||
// if we reach bigger distance
(cur_dist_xyz > MAX_QUIET_DISTANCE) || // if we are too far
(i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE) )
// if we leave 'quiet zone'
{
// we are very far or too close, stopping
i_to_distance_from_caster = 0.0f;
i_nextCheckTime.Reset( urand(500,1000) );
return false;
}
else
{
// now we are running, continue
i_last_distance_from_caster = cur_dist_xyz;
return true;
}
}
float cur_dist;
float angle_to_caster;
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
if(fright)
{
cur_dist = fright->GetDistance(&owner);
if(cur_dist < cur_dist_xyz)
{
i_caster_x = fright->GetPositionX();
i_caster_y = fright->GetPositionY();
i_caster_z = fright->GetPositionZ();
angle_to_caster = fright->GetAngle(&owner);
}
else
{
cur_dist = cur_dist_xyz;
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
}
}
else
{
cur_dist = cur_dist_xyz;
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
}
// if we too close may use 'path-finding' else just stop
i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3;
//get angle and 'distance from caster' to run
float angle;
if(i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time
{
angle = rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * M_PI/3 + rand_norm()*M_PI*2/3;
i_to_distance_from_caster = MIN_QUIET_DISTANCE;
i_only_forward = true;
}
else if(cur_dist < MIN_QUIET_DISTANCE)
{
angle = M_PI/6 + rand_norm()*M_PI*2/3;
i_to_distance_from_caster = cur_dist*2/3 + rand_norm()*(MIN_QUIET_DISTANCE - cur_dist*2/3);
}
else if(cur_dist > MAX_QUIET_DISTANCE)
{
angle = rand_norm()*M_PI/3 + M_PI*2/3;
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
}
else
{
angle = rand_norm()*M_PI;
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
}
int8 sign = rand_norm() > 0.5f ? 1 : -1;
i_cur_angle = sign*angle + angle_to_caster;
// current distance
i_last_distance_from_caster = cur_dist;
return true;
}
template<class T>
void
FleeingMovementGenerator<T>::Initialize(T &owner)
{
if(!&owner)
return;
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
if(!fright)
return;
_Init(owner);
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
i_caster_x = fright->GetPositionX();
i_caster_y = fright->GetPositionY();
i_caster_z = fright->GetPositionZ();
i_only_forward = true;
i_cur_angle = 0.0f;
i_last_distance_from_caster = 0.0f;
i_to_distance_from_caster = 0.0f;
_setTargetLocation(owner);
}
template<>
void
FleeingMovementGenerator<Creature>::_Init(Creature &owner)
{
if(!&owner)
return;
owner.SetUInt64Value(UNIT_FIELD_TARGET, 0);
is_water_ok = owner.canSwim();
is_land_ok = owner.canWalk();
}
template<>
void
FleeingMovementGenerator<Player>::_Init(Player &)
{
is_water_ok = true;
is_land_ok = true;
}
template<class T>
void
FleeingMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_FLEEING);
}
template<class T>
void
FleeingMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
template<class T>
bool
FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{
if( !&owner || !owner.isAlive() )
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) )
return true;
Traveller<T> traveller(owner);
i_nextCheckTime.Update(time_diff);
if( (owner.IsStopped() && !i_destinationHolder.HasArrived()) || !i_destinationHolder.HasDestination() )
{
_setTargetLocation(owner);
return true;
}
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
{
i_destinationHolder.ResetUpdate(50);
if(i_nextCheckTime.Passed() && i_destinationHolder.HasArrived())
{
_setTargetLocation(owner);
return true;
}
}
return true;
}
template void FleeingMovementGenerator<Player>::Initialize(Player &);
template void FleeingMovementGenerator<Creature>::Initialize(Creature &);
template bool FleeingMovementGenerator<Player>::_setMoveData(Player &);
template bool FleeingMovementGenerator<Creature>::_setMoveData(Creature &);
template bool FleeingMovementGenerator<Player>::_getPoint(Player &, float &, float &, float &);
template bool FleeingMovementGenerator<Creature>::_getPoint(Creature &, float &, float &, float &);
template void FleeingMovementGenerator<Player>::_setTargetLocation(Player &);
template void FleeingMovementGenerator<Creature>::_setTargetLocation(Creature &);
template void FleeingMovementGenerator<Player>::Finalize(Player &);
template void FleeingMovementGenerator<Creature>::Finalize(Creature &);
template void FleeingMovementGenerator<Player>::Reset(Player &);
template void FleeingMovementGenerator<Creature>::Reset(Creature &);
template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32 &);
template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32 &);
/*
* 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 "FleeingMovementGenerator.h"
#include "DestinationHolderImp.h"
#include "ObjectAccessor.h"
#define MIN_QUIET_DISTANCE 28.0f
#define MAX_QUIET_DISTANCE 43.0f
template<class T>
void
FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
{
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
return;
if(!_setMoveData(owner))
return;
float x, y, z;
if(!_getPoint(owner, x, y, z))
return;
owner.addUnitState(UNIT_STAT_FLEEING);
Traveller<T> traveller(owner);
i_destinationHolder.SetDestination(traveller, x, y, z);
}
template<class T>
bool
FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
{
if(!&owner)
return false;
x = owner.GetPositionX();
y = owner.GetPositionY();
z = owner.GetPositionZ();
float temp_x, temp_y, angle;
const Map * _map = MapManager::Instance().GetBaseMap(owner.GetMapId());
//primitive path-finding
for(uint8 i = 0; i < 18; i++)
{
if(i_only_forward && i > 2)
break;
float distance = 5.0f;
switch(i)
{
case 0:
angle = i_cur_angle;
break;
case 1:
angle = i_cur_angle;
distance /= 2;
break;
case 2:
angle = i_cur_angle;
distance /= 4;
break;
case 3:
angle = i_cur_angle + M_PI/4.0f;
break;
case 4:
angle = i_cur_angle - M_PI/4.0f;
break;
case 5:
angle = i_cur_angle + M_PI/4.0f;
distance /= 2;
break;
case 6:
angle = i_cur_angle - M_PI/4.0f;
distance /= 2;
break;
case 7:
angle = i_cur_angle + M_PI/2.0f;
break;
case 8:
angle = i_cur_angle - M_PI/2.0f;
break;
case 9:
angle = i_cur_angle + M_PI/2.0f;
distance /= 2;
break;
case 10:
angle = i_cur_angle - M_PI/2.0f;
distance /= 2;
break;
case 11:
angle = i_cur_angle + M_PI/4.0f;
distance /= 4;
break;
case 12:
angle = i_cur_angle - M_PI/4.0f;
distance /= 4;
break;
case 13:
angle = i_cur_angle + M_PI/2.0f;
distance /= 4;
break;
case 14:
angle = i_cur_angle - M_PI/2.0f;
distance /= 4;
break;
case 15:
angle = i_cur_angle + M_PI*3/4.0f;
distance /= 2;
break;
case 16:
angle = i_cur_angle - M_PI*3/4.0f;
distance /= 2;
break;
case 17:
angle = i_cur_angle + M_PI;
distance /= 2;
break;
}
temp_x = x + distance * cos(angle);
temp_y = y + distance * sin(angle);
MaNGOS::NormalizeMapCoord(temp_x);
MaNGOS::NormalizeMapCoord(temp_y);
if( owner.IsWithinLOS(temp_x,temp_y,z))
{
bool is_water_now = _map->IsInWater(x,y,z);
if(is_water_now && _map->IsInWater(temp_x,temp_y,z))
{
x = temp_x;
y = temp_y;
return true;
}
float new_z = _map->GetHeight(temp_x,temp_y,z,true);
if(new_z <= INVALID_HEIGHT)
continue;
bool is_water_next = _map->IsInWater(temp_x,temp_y,new_z);
if((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
continue;
if( !(new_z - z) || distance / fabs(new_z - z) > 1.0f)
{
float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+M_PI/2),temp_y + 1.0f*sin(angle+M_PI/2),z,true);
float new_z_right = _map->GetHeight(temp_x + 1.0f*cos(angle-M_PI/2),temp_y + 1.0f*sin(angle-M_PI/2),z,true);
if(fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f)
{
x = temp_x;
y = temp_y;
z = new_z;
return true;
}
}
}
}
i_to_distance_from_caster = 0.0f;
i_nextCheckTime.Reset( urand(500,1000) );
return false;
}
template<class T>
bool
FleeingMovementGenerator<T>::_setMoveData(T &owner)
{
float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z);
if(i_to_distance_from_caster > 0.0f)
{
if((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster) ||
// if we reach lower distance
(i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz > i_last_distance_from_caster) ||
// if we can't be close
(i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster) ||
// if we reach bigger distance
(cur_dist_xyz > MAX_QUIET_DISTANCE) || // if we are too far
(i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE) )
// if we leave 'quiet zone'
{
// we are very far or too close, stopping
i_to_distance_from_caster = 0.0f;
i_nextCheckTime.Reset( urand(500,1000) );
return false;
}
else
{
// now we are running, continue
i_last_distance_from_caster = cur_dist_xyz;
return true;
}
}
float cur_dist;
float angle_to_caster;
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
if(fright)
{
cur_dist = fright->GetDistance(&owner);
if(cur_dist < cur_dist_xyz)
{
i_caster_x = fright->GetPositionX();
i_caster_y = fright->GetPositionY();
i_caster_z = fright->GetPositionZ();
angle_to_caster = fright->GetAngle(&owner);
}
else
{
cur_dist = cur_dist_xyz;
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
}
}
else
{
cur_dist = cur_dist_xyz;
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
}
// if we too close may use 'path-finding' else just stop
i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3;
//get angle and 'distance from caster' to run
float angle;
if(i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time
{
angle = rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * M_PI/3 + rand_norm()*M_PI*2/3;
i_to_distance_from_caster = MIN_QUIET_DISTANCE;
i_only_forward = true;
}
else if(cur_dist < MIN_QUIET_DISTANCE)
{
angle = M_PI/6 + rand_norm()*M_PI*2/3;
i_to_distance_from_caster = cur_dist*2/3 + rand_norm()*(MIN_QUIET_DISTANCE - cur_dist*2/3);
}
else if(cur_dist > MAX_QUIET_DISTANCE)
{
angle = rand_norm()*M_PI/3 + M_PI*2/3;
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
}
else
{
angle = rand_norm()*M_PI;
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
}
int8 sign = rand_norm() > 0.5f ? 1 : -1;
i_cur_angle = sign*angle + angle_to_caster;
// current distance
i_last_distance_from_caster = cur_dist;
return true;
}
template<class T>
void
FleeingMovementGenerator<T>::Initialize(T &owner)
{
if(!&owner)
return;
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
if(!fright)
return;
_Init(owner);
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
i_caster_x = fright->GetPositionX();
i_caster_y = fright->GetPositionY();
i_caster_z = fright->GetPositionZ();
i_only_forward = true;
i_cur_angle = 0.0f;
i_last_distance_from_caster = 0.0f;
i_to_distance_from_caster = 0.0f;
_setTargetLocation(owner);
}
template<>
void
FleeingMovementGenerator<Creature>::_Init(Creature &owner)
{
if(!&owner)
return;
owner.SetUInt64Value(UNIT_FIELD_TARGET, 0);
is_water_ok = owner.canSwim();
is_land_ok = owner.canWalk();
}
template<>
void
FleeingMovementGenerator<Player>::_Init(Player &)
{
is_water_ok = true;
is_land_ok = true;
}
template<class T>
void
FleeingMovementGenerator<T>::Finalize(T &owner)
{
owner.clearUnitState(UNIT_STAT_FLEEING);
}
template<class T>
void
FleeingMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
template<class T>
bool
FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
{
if( !&owner || !owner.isAlive() )
return false;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
return true;
Traveller<T> traveller(owner);
i_nextCheckTime.Update(time_diff);
if( (owner.IsStopped() && !i_destinationHolder.HasArrived()) || !i_destinationHolder.HasDestination() )
{
_setTargetLocation(owner);
return true;
}
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
{
i_destinationHolder.ResetUpdate(50);
if(i_nextCheckTime.Passed() && i_destinationHolder.HasArrived())
{
_setTargetLocation(owner);
return true;
}
}
return true;
}
template void FleeingMovementGenerator<Player>::Initialize(Player &);
template void FleeingMovementGenerator<Creature>::Initialize(Creature &);
template bool FleeingMovementGenerator<Player>::_setMoveData(Player &);
template bool FleeingMovementGenerator<Creature>::_setMoveData(Creature &);
template bool FleeingMovementGenerator<Player>::_getPoint(Player &, float &, float &, float &);
template bool FleeingMovementGenerator<Creature>::_getPoint(Creature &, float &, float &, float &);
template void FleeingMovementGenerator<Player>::_setTargetLocation(Player &);
template void FleeingMovementGenerator<Creature>::_setTargetLocation(Creature &);
template void FleeingMovementGenerator<Player>::Finalize(Player &);
template void FleeingMovementGenerator<Creature>::Finalize(Creature &);
template void FleeingMovementGenerator<Player>::Reset(Player &);
template void FleeingMovementGenerator<Creature>::Reset(Creature &);
template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32 &);
template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32 &);
+1 -1
View File
@@ -852,7 +852,7 @@ namespace MaNGOS
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
(u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNDED) || u->hasUnitState(UNIT_STAT_STUNDED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
(u->isFeared() || u->isCharmed() || u->isFrozen() || u->hasUnitState(UNIT_STAT_STUNNED) || u->hasUnitState(UNIT_STAT_CONFUSED)))
{
return true;
}
+1454 -1454
View File
File diff suppressed because it is too large. Load diff
+86 -86
View File
@@ -1,86 +1,86 @@
/*
* 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 "HomeMovementGenerator.h"
#include "Creature.h"
#include "Traveller.h"
#include "MapManager.h"
#include "ObjectAccessor.h"
#include "DestinationHolderImp.h"
#include "ObjectMgr.h"
#include "WorldPacket.h"
void
HomeMovementGenerator<Creature>::Initialize(Creature & owner)
{
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
_setTargetLocation(owner);
}
void
HomeMovementGenerator<Creature>::Reset(Creature &)
{
}
void
HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner)
{
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) )
return;
float x, y, z;
owner.GetRespawnCoord(x, y, z);
CreatureTraveller traveller(owner);
uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z);
modifyTravelTime(travel_time);
owner.clearUnitState(UNIT_STAT_ALL_STATE);
}
bool
HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff)
{
CreatureTraveller traveller( owner);
i_destinationHolder.UpdateTraveller(traveller, time_diff, false);
if (time_diff > i_travel_timer)
{
owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
// restore orientation of not moving creature at returning to home
if(owner.GetDefaultMovementType()==IDLE_MOTION_TYPE)
{
if(CreatureData const* data = objmgr.GetCreatureData(owner.GetDBTableGUIDLow()))
{
owner.SetOrientation(data->orientation);
WorldPacket packet;
owner.BuildHeartBeatMsg(&packet);
owner.SendMessageToSet(&packet, false);
}
}
return false;
}
i_travel_timer -= time_diff;
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 "HomeMovementGenerator.h"
#include "Creature.h"
#include "Traveller.h"
#include "MapManager.h"
#include "ObjectAccessor.h"
#include "DestinationHolderImp.h"
#include "ObjectMgr.h"
#include "WorldPacket.h"
void
HomeMovementGenerator<Creature>::Initialize(Creature & owner)
{
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
_setTargetLocation(owner);
}
void
HomeMovementGenerator<Creature>::Reset(Creature &)
{
}
void
HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner)
{
if( !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
return;
float x, y, z;
owner.GetRespawnCoord(x, y, z);
CreatureTraveller traveller(owner);
uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z);
modifyTravelTime(travel_time);
owner.clearUnitState(UNIT_STAT_ALL_STATE);
}
bool
HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff)
{
CreatureTraveller traveller( owner);
i_destinationHolder.UpdateTraveller(traveller, time_diff, false);
if (time_diff > i_travel_timer)
{
owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
// restore orientation of not moving creature at returning to home
if(owner.GetDefaultMovementType()==IDLE_MOTION_TYPE)
{
if(CreatureData const* data = objmgr.GetCreatureData(owner.GetDBTableGUIDLow()))
{
owner.SetOrientation(data->orientation);
WorldPacket packet;
owner.BuildHeartBeatMsg(&packet);
owner.SendMessageToSet(&packet, false);
}
}
return false;
}
i_travel_timer -= time_diff;
return true;
}
+50 -75
View File
@@ -75,7 +75,9 @@ enum MangosStrings
LANG_LEVEL_MINREQUIRED = 49,
LANG_LEVEL_MINREQUIRED_AND_ITEM = 50,
LANG_NPC_TAINER_HELLO = 51,
// Room for more level 0
LANG_COMMAND_INVALID_ITEM_COUNT = 52,
LANG_COMMAND_MAIL_ITEMS_LIMIT = 53,
// Room for more level 0 54-99 not used
// level 1 chat
LANG_GLOBAL_NOTIFY = 100,
@@ -159,7 +161,7 @@ enum MangosStrings
LANG_MAIL_SENT = 169,
LANG_SOUND_NOT_EXIST = 170,
// Room for more level 1
// Room for more level 1 171-199 not used
// level 2 chat
LANG_NO_SELECTION = 200,
@@ -304,8 +306,11 @@ enum MangosStrings
LANG_LOOKUP_PLAYER_CHARACTER = 329,
LANG_NO_PLAYERS_FOUND = 330,
LANG_EXTENDED_COST_NOT_EXIST = 331,
// Room for more level 2
LANG_GM_ON = 332,
LANG_GM_OFF = 333,
LANG_GM_CHAT_ON = 334,
LANG_GM_CHAT_OFF = 335,
// Room for more level 2 336-399 not used
// level 3 chat
LANG_SCRIPTS_RELOADED = 400,
@@ -610,79 +615,49 @@ enum MangosStrings
LANG_BG_GROUP_TOO_LARGE = 711,
LANG_ARENA_GROUP_TOO_LARGE = 712,
LANG_ARENA_YOUR_TEAM_ONLY = 713,
LANG_ARENA_NOT_ENOUGH_PLAYERS = 714,
LANG_ARENA_GOLD_WINS = 715,
LANG_ARENA_GREEN_WINS = 716,
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 717,
LANG_BG_GROUP_OFFLINE_MEMBER = 718,
LANG_BG_GROUP_MIXED_FACTION = 719,
LANG_BG_GROUP_MIXED_LEVELS = 720,
LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 721,
LANG_BG_GROUP_MEMBER_DESERTER = 722,
LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 723,
LANG_YOUR_ARENA_LEVEL_REQ_ERROR = 713,
LANG_HIS_ARENA_LEVEL_REQ_ERROR = 714,
LANG_YOUR_BG_LEVEL_REQ_ERROR = 715,
LANG_YOUR_ARENA_TEAM_FULL = 716,
// Room for BG/ARENA 717-799 not used
LANG_CANNOT_TELE_TO_BG = 724,
LANG_CANNOT_SUMMON_TO_BG = 725,
LANG_CANNOT_GO_TO_BG_GM = 726,
LANG_CANNOT_GO_TO_BG_FROM_BG = 727,
LANG_ARENA_YOUR_TEAM_ONLY = 730,
LANG_ARENA_NOT_ENOUGH_PLAYERS = 731,
LANG_ARENA_GOLD_WINS = 732,
LANG_ARENA_GREEN_WINS = 733,
LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 734,
LANG_BG_GROUP_OFFLINE_MEMBER = 735,
LANG_BG_GROUP_MIXED_FACTION = 736,
LANG_BG_GROUP_MIXED_LEVELS = 737,
LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 738,
LANG_BG_GROUP_MEMBER_DESERTER = 739,
LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 740,
LANG_ARENA_TESTING = 728
LANG_CANNOT_TELE_TO_BG = 741,
LANG_CANNOT_SUMMON_TO_BG = 742,
LANG_CANNOT_GO_TO_BG_GM = 743,
LANG_CANNOT_GO_TO_BG_FROM_BG = 744,
LANG_ARENA_TESTING = 745,
// in game strings
LANG_PET_INVALID_NAME = 800,
LANG_NOT_ENOUGH_GOLD = 801,
LANG_NOT_FREE_TRADE_SLOTS = 802,
LANG_NOT_PARTNER_FREE_TRADE_SLOTS = 803,
LANG_YOU_NOT_HAVE_PERMISSION = 804,
LANG_UNKNOWN_LANGUAGE = 805,
LANG_NOT_LEARNED_LANGUAGE = 806,
LANG_NEED_CHARACTER_NAME = 807,
LANG_PLAYER_NOT_EXIST_OR_OFFLINE = 808,
LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND = 809,
// Room for in-game strings 810-999 not used
// FREE IDS 1000-9999
// Use for not-in-svn patches 10000-10999
// Use for custom patches 11000-11999
// NOT RESERVED IDS 12000-
};
#endif
/* NOT USED VALUES
// alliance ranks
#define LANG_ALI_PRIVATE "Private "
#define LANG_ALI_CORPORAL "Corporal "
#define LANG_ALI_SERGEANT "Sergeant "
#define LANG_ALI_MASTER_SERGEANT "Master Sergeant "
#define LANG_ALI_SERGEANT_MAJOR "Sergeant Major "
#define LANG_ALI_KNIGHT "Knight "
#define LANG_ALI_KNIGHT_LIEUTENANT "Knight-Lieutenant "
#define LANG_ALI_KNIGHT_CAPTAIN "Knight-Captain "
#define LANG_ALI_KNIGHT_CHAMPION "Knight-Champion "
#define LANG_ALI_LIEUTENANT_COMMANDER "Lieutenant Commander "
#define LANG_ALI_COMMANDER "Commander "
#define LANG_ALI_MARSHAL "Marshal "
#define LANG_ALI_FIELD_MARSHAL "Field Marshal "
#define LANG_ALI_GRAND_MARSHAL "Grand Marshal "
#define LANG_ALI_GAME_MASTER "Game Master "
// horde ranks
#define LANG_HRD_SCOUT "Scout "
#define LANG_HRD_GRUNT "Grunt "
#define LANG_HRD_SERGEANT "Sergeant "
#define LANG_HRD_SENIOR_SERGEANT "Senior Sergeant "
#define LANG_HRD_FIRST_SERGEANT "First Sergeant "
#define LANG_HRD_STONE_GUARD "Stone Guard "
#define LANG_HRD_BLOOD_GUARD "Blood Guard "
#define LANG_HRD_LEGIONNARE "Legionnaire "
#define LANG_HRD_CENTURION "Centurion "
#define LANG_HRD_CHAMPION "Champion "
#define LANG_HRD_LIEUTENANT_GENERAL "Lieutenant General "
#define LANG_HRD_GENERAL "General "
#define LANG_HRD_WARLORD "Warlord "
#define LANG_HRD_HIGH_WARLORD "High Warlord "
#define LANG_HRD_GAME_MASTER "Game Master "
#define LANG_NO_RANK "No rank "
#define LANG_RANK "%s (Rank %u)"
#define LANG_HONOR_TODAY "Today: [Honorable kills: |c0000ff00%u|r] [Dishonorable kills: |c00ff0000%u|r]"
#define LANG_HONOR_YESTERDAY "Yesterday: [Kills: |c0000ff00%u|r] [Honor: %u]"
#define LANG_HONOR_THIS_WEEK "This week: [Kills: |c0000ff00%u|r] [Honor: %u]"
#define LANG_HONOR_LAST_WEEK "Last week: [Kills: |c0000ff00%u|r] [Honor: %u] [Standing: %u]"
#define LANG_HONOR_LIFE "Lifetime: [Honorable kills: |c0000ff00%u|r] [Dishonorable kills: |c00ff0000%u|r] [Highest rank %u: %s]"
// level 2
#define LANG_ADD_OBJ "AddObject at Chat.cpp" //log
#define LANG_DEMORPHED "Demorphed %s" //log
// level 3
#define LANG_SPAWNING_SPIRIT_HEAL "Spawning spirit healers\n"
#define LANG_NO_SPIRIT_HEAL_DB "No spirit healers in database, exiting."
#define LANG_ADD_OBJ_LV3 "AddObject at Level3.cpp line 1176"
*/
+151 -12
View File
@@ -147,9 +147,11 @@ bool ChatHandler::HandleGMmodeCommand(const char* args)
{
if(!*args)
{
SendSysMessage(LANG_USE_BOL);
SetSentErrorMessage(true);
return false;
if(m_session->GetPlayer()->isGameMaster())
m_session->SendNotification(LANG_GM_ON);
else
m_session->SendNotification(LANG_GM_OFF);
return true;
}
std::string argstr = (char*)args;
@@ -157,7 +159,7 @@ bool ChatHandler::HandleGMmodeCommand(const char* args)
if (argstr == "on")
{
m_session->GetPlayer()->SetGameMaster(true);
m_session->SendNotification("GM mode is ON");
m_session->SendNotification(LANG_GM_ON);
#ifdef _DEBUG_VMAPS
VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
vMapManager->processCommand("stoplog");
@@ -168,7 +170,7 @@ bool ChatHandler::HandleGMmodeCommand(const char* args)
if (argstr == "off")
{
m_session->GetPlayer()->SetGameMaster(false);
m_session->SendNotification("GM mode is OFF");
m_session->SendNotification(LANG_GM_OFF);
#ifdef _DEBUG_VMAPS
VMAP::IVMapManager *vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
vMapManager->processCommand("startlog");
@@ -181,6 +183,40 @@ bool ChatHandler::HandleGMmodeCommand(const char* args)
return false;
}
// Enables or disables hiding of the staff badge
bool ChatHandler::HandleGMChatCommand(const char* args)
{
if(!*args)
{
if(m_session->GetPlayer()->isGMChat())
m_session->SendNotification(LANG_GM_CHAT_ON);
else
m_session->SendNotification(LANG_GM_CHAT_OFF);
return true;
}
std::string argstr = (char*)args;
if (argstr == "on")
{
m_session->GetPlayer()->SetGMChat(true);
m_session->SendNotification(LANG_GM_CHAT_ON);
return true;
}
if (argstr == "off")
{
m_session->GetPlayer()->SetGMChat(false);
m_session->SendNotification(LANG_GM_CHAT_OFF);
return true;
}
SendSysMessage(LANG_USE_BOL);
SetSentErrorMessage(true);
return false;
}
//Enable\Dissable Invisible mode
bool ChatHandler::HandleVisibleCommand(const char* args)
{
@@ -195,13 +231,13 @@ bool ChatHandler::HandleVisibleCommand(const char* args)
if (argstr == "on")
{
m_session->GetPlayer()->SetGMVisible(true);
m_session->SendNotification(GetMangosString(LANG_INVISIBLE_VISIBLE));
m_session->SendNotification(LANG_INVISIBLE_VISIBLE);
return true;
}
if (argstr == "off")
{
m_session->SendNotification(GetMangosString(LANG_INVISIBLE_INVISIBLE));
m_session->SendNotification(LANG_INVISIBLE_INVISIBLE);
m_session->GetPlayer()->SetGMVisible(false);
return true;
}
@@ -1823,19 +1859,107 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
if(!*args)
return false;
// format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12]
char* pName = strtok((char*)args, " ");
char* msgSubject = strtok(NULL, " ");
char* msgText = strtok(NULL, "");
if(!pName)
return false;
char* tail1 = strtok(NULL, "");
if(!tail1)
return false;
char* msgSubject;
if(*tail1=='"')
msgSubject = strtok(tail1+1, "\"");
else
{
char* space = strtok(tail1, "\"");
if(!space)
return false;
msgSubject = strtok(NULL, "\"");
}
if (!msgSubject)
return false;
char* tail2 = strtok(NULL, "");
if(!tail2)
return false;
char* msgText;
if(*tail2=='"')
msgText = strtok(tail2+1, "\"");
else
{
char* space = strtok(tail2, "\"");
if(!space)
return false;
msgText = strtok(NULL, "\"");
}
if (!msgText)
return false;
// pName, msgSubject, msgText isn't NUL after prev. check
std::string name = pName;
std::string subject = msgSubject;
std::string text = msgText;
// extract items
typedef std::pair<uint32,uint32> ItemPair;
typedef std::list< ItemPair > ItemPairs;
ItemPairs items;
// get all tail string
char* tail = strtok(NULL, "");
// get from tail next item str
while(char* itemStr = strtok(tail, " "))
{
// and get new tail
tail = strtok(NULL, "");
// parse item str
char* itemIdStr = strtok(itemStr, ":");
char* itemCountStr = strtok(NULL, " ");
uint32 item_id = atoi(itemIdStr);
if(!item_id)
return false;
ItemPrototype const* item_proto = objmgr.GetItemPrototype(item_id);
if(!item_proto)
{
PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
SetSentErrorMessage(true);
return false;
}
uint32 item_count = itemCountStr ? atoi(itemCountStr) : 1;
if(item_count < 1 || item_proto->MaxCount && item_count > item_proto->MaxCount)
{
PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, item_count,item_id);
SetSentErrorMessage(true);
return false;
}
while(item_count > item_proto->Stackable)
{
items.push_back(ItemPair(item_id,item_proto->Stackable));
item_count -= item_proto->Stackable;
}
items.push_back(ItemPair(item_id,item_count));
if(items.size() > MAX_MAIL_ITEMS)
{
PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS);
SetSentErrorMessage(true);
return false;
}
}
if(!normalizePlayerName(name))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -1844,9 +1968,12 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
}
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if(!receiver_guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
uint32 mailId = objmgr.GenerateMailID();
uint32 sender_guidlo = m_session->GetPlayer()->GetGUIDLow();
@@ -1860,7 +1987,19 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
Player *receiver = objmgr.GetPlayer(receiver_guid);
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE);
// fill mail
MailItemsInfo mi; // item list preparing
for(ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
{
if(Item* item = Item::CreateItem(itr->first,itr->second,m_session->GetPlayer()))
{
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item);
}
}
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_NONE);
PSendSysMessage(LANG_MAIL_SENT, name.c_str());
return true;
+1759 -1765
View File
File diff suppressed because it is too large. Load diff
+342 -342
View File
@@ -1,342 +1,342 @@
/*
* 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 "MotionMaster.h"
#include "CreatureAISelector.h"
#include "Creature.h"
#include "Traveller.h"
#include "ConfusedMovementGenerator.h"
#include "FleeingMovementGenerator.h"
#include "HomeMovementGenerator.h"
#include "IdleMovementGenerator.h"
#include "PointMovementGenerator.h"
#include "TargetedMovementGenerator.h"
#include "WaypointMovementGenerator.h"
#include <cassert>
inline bool isStatic(MovementGenerator *mv)
{
return (mv == &si_idleMovement);
}
void
MotionMaster::Initialize()
{
// clear ALL movement generators (including default)
while(!empty())
{
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic( curr ) )
delete curr;
}
// set new default movement generator
if(i_owner->GetTypeId() == TYPEID_UNIT)
{
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
push( movement == NULL ? &si_idleMovement : movement );
top()->Initialize(*i_owner);
}
else
push(&si_idleMovement);
}
MotionMaster::~MotionMaster()
{
// clear ALL movement generators (including default)
while(!empty())
{
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic( curr ) )
delete curr;
}
}
void
MotionMaster::UpdateMotion(const uint32 &diff)
{
if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED) )
return;
assert( !empty() );
if (!top()->Update(*i_owner, diff))
MovementExpired();
}
void
MotionMaster::Clear(bool reset)
{
while( !empty() && size() > 1 )
{
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic( curr ) )
delete curr;
}
if (reset)
{
assert( !empty() );
top()->Reset(*i_owner);
}
}
void
MotionMaster::MovementExpired(bool reset)
{
if( empty() || size() == 1 )
return;
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic(curr) )
delete curr;
assert( !empty() );
while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
{
// Should check if target is still valid? If not valid it will crash.
curr = top();
curr->Finalize(*i_owner);
pop();
delete curr;
}
if( empty() )
Initialize();
if (reset) top()->Reset(*i_owner);
}
void MotionMaster::MoveIdle()
{
if( empty() || !isStatic( top() ) )
push( &si_idleMovement );
}
void
MotionMaster::MoveTargetedHome()
{
if(i_owner->hasUnitState(UNIT_STAT_FLEEING))
return;
Clear(false);
if(i_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)i_owner)->GetCharmerOrOwnerGUID())
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow());
Mutate(new HomeMovementGenerator<Creature>());
}
else if(i_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)i_owner)->GetCharmerOrOwnerGUID())
{
sLog.outError("Pet or controlled creature (Entry: %u GUID: %u) attempt targeted home",
i_owner->GetEntry(), i_owner->GetGUIDLow() );
}
else
{
sLog.outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow() );
}
}
void
MotionMaster::MoveConfused()
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) move confused", i_owner->GetGUIDLow() );
Mutate(new ConfusedMovementGenerator<Player>());
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) move confused",
i_owner->GetEntry(), i_owner->GetGUIDLow() );
Mutate(new ConfusedMovementGenerator<Creature>());
}
}
void
MotionMaster::MoveChase(Unit* target, float dist, float angle)
{
// ignore movement request if target not exist
if(!target)
return;
i_owner->clearUnitState(UNIT_STAT_FOLLOW);
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) chase to %s (GUID: %u)",
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) chase to %s (GUID: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
}
}
void
MotionMaster::MoveFollow(Unit* target, float dist, float angle)
{
Clear();
// ignore movement request if target not exist
if(!target)
return;
i_owner->addUnitState(UNIT_STAT_FOLLOW);
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
}
}
void
MotionMaster::MovePoint(uint32 id, float x, float y, float z)
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), id, x, y, z );
Mutate(new PointMovementGenerator<Player>(id,x,y,z));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), id, x, y, z );
Mutate(new PointMovementGenerator<Creature>(id,x,y,z));
}
}
void
MotionMaster::MoveFleeing(Unit* enemy)
{
if(!enemy)
return;
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) flee from %s (GUID: %u)", i_owner->GetGUIDLow(),
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(),
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()));
}
}
void
MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) taxi to (Path %u node %u)", i_owner->GetGUIDLow(), path, pathnode);
FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(path,pathnode);
Mutate(mgen);
}
else
{
sLog.outError("Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), path, pathnode );
}
}
void
MotionMaster::MoveDistract(uint32 timer)
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) distracted (timer: %u)", i_owner->GetGUIDLow(), timer);
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) (timer: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), timer);
}
DistractMovementGenerator* mgen = new DistractMovementGenerator(timer);
Mutate(mgen);
}
void MotionMaster::Mutate(MovementGenerator *m)
{
if (!empty())
{
switch(top()->GetMovementGeneratorType())
{
// HomeMovement is not that important, delete it if meanwhile a new comes
case HOME_MOTION_TYPE:
// DistractMovement interrupted by any other movement
case DISTRACT_MOTION_TYPE:
MovementExpired(false);
}
}
m->Initialize(*i_owner);
push(m);
}
void MotionMaster::propagateSpeedChange()
{
Impl::container_type::iterator it = Impl::c.begin();
for ( ;it != end(); ++it)
{
(*it)->unitSpeedChanged();
}
}
MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
{
if(empty())
return IDLE_MOTION_TYPE;
return top()->GetMovementGeneratorType();
}
bool MotionMaster::GetDestination(float &x, float &y, float &z)
{
if(empty())
return false;
return top()->GetDestination(x,y,z);
}
/*
* 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 "MotionMaster.h"
#include "CreatureAISelector.h"
#include "Creature.h"
#include "Traveller.h"
#include "ConfusedMovementGenerator.h"
#include "FleeingMovementGenerator.h"
#include "HomeMovementGenerator.h"
#include "IdleMovementGenerator.h"
#include "PointMovementGenerator.h"
#include "TargetedMovementGenerator.h"
#include "WaypointMovementGenerator.h"
#include <cassert>
inline bool isStatic(MovementGenerator *mv)
{
return (mv == &si_idleMovement);
}
void
MotionMaster::Initialize()
{
// clear ALL movement generators (including default)
while(!empty())
{
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic( curr ) )
delete curr;
}
// set new default movement generator
if(i_owner->GetTypeId() == TYPEID_UNIT)
{
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
push( movement == NULL ? &si_idleMovement : movement );
top()->Initialize(*i_owner);
}
else
push(&si_idleMovement);
}
MotionMaster::~MotionMaster()
{
// clear ALL movement generators (including default)
while(!empty())
{
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic( curr ) )
delete curr;
}
}
void
MotionMaster::UpdateMotion(const uint32 &diff)
{
if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
return;
assert( !empty() );
if (!top()->Update(*i_owner, diff))
MovementExpired();
}
void
MotionMaster::Clear(bool reset)
{
while( !empty() && size() > 1 )
{
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic( curr ) )
delete curr;
}
if (reset)
{
assert( !empty() );
top()->Reset(*i_owner);
}
}
void
MotionMaster::MovementExpired(bool reset)
{
if( empty() || size() == 1 )
return;
MovementGenerator *curr = top();
curr->Finalize(*i_owner);
pop();
if( !isStatic(curr) )
delete curr;
assert( !empty() );
while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
{
// Should check if target is still valid? If not valid it will crash.
curr = top();
curr->Finalize(*i_owner);
pop();
delete curr;
}
if( empty() )
Initialize();
if (reset) top()->Reset(*i_owner);
}
void MotionMaster::MoveIdle()
{
if( empty() || !isStatic( top() ) )
push( &si_idleMovement );
}
void
MotionMaster::MoveTargetedHome()
{
if(i_owner->hasUnitState(UNIT_STAT_FLEEING))
return;
Clear(false);
if(i_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)i_owner)->GetCharmerOrOwnerGUID())
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow());
Mutate(new HomeMovementGenerator<Creature>());
}
else if(i_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)i_owner)->GetCharmerOrOwnerGUID())
{
sLog.outError("Pet or controlled creature (Entry: %u GUID: %u) attempt targeted home",
i_owner->GetEntry(), i_owner->GetGUIDLow() );
}
else
{
sLog.outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow() );
}
}
void
MotionMaster::MoveConfused()
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) move confused", i_owner->GetGUIDLow() );
Mutate(new ConfusedMovementGenerator<Player>());
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) move confused",
i_owner->GetEntry(), i_owner->GetGUIDLow() );
Mutate(new ConfusedMovementGenerator<Creature>());
}
}
void
MotionMaster::MoveChase(Unit* target, float dist, float angle)
{
// ignore movement request if target not exist
if(!target)
return;
i_owner->clearUnitState(UNIT_STAT_FOLLOW);
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) chase to %s (GUID: %u)",
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) chase to %s (GUID: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
}
}
void
MotionMaster::MoveFollow(Unit* target, float dist, float angle)
{
Clear();
// ignore movement request if target not exist
if(!target)
return;
i_owner->addUnitState(UNIT_STAT_FOLLOW);
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
}
}
void
MotionMaster::MovePoint(uint32 id, float x, float y, float z)
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), id, x, y, z );
Mutate(new PointMovementGenerator<Player>(id,x,y,z));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), id, x, y, z );
Mutate(new PointMovementGenerator<Creature>(id,x,y,z));
}
}
void
MotionMaster::MoveFleeing(Unit* enemy)
{
if(!enemy)
return;
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) flee from %s (GUID: %u)", i_owner->GetGUIDLow(),
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()));
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(),
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()));
}
}
void
MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) taxi to (Path %u node %u)", i_owner->GetGUIDLow(), path, pathnode);
FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(path,pathnode);
Mutate(mgen);
}
else
{
sLog.outError("Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), path, pathnode );
}
}
void
MotionMaster::MoveDistract(uint32 timer)
{
if(i_owner->GetTypeId()==TYPEID_PLAYER)
{
DEBUG_LOG("Player (GUID: %u) distracted (timer: %u)", i_owner->GetGUIDLow(), timer);
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) (timer: %u)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), timer);
}
DistractMovementGenerator* mgen = new DistractMovementGenerator(timer);
Mutate(mgen);
}
void MotionMaster::Mutate(MovementGenerator *m)
{
if (!empty())
{
switch(top()->GetMovementGeneratorType())
{
// HomeMovement is not that important, delete it if meanwhile a new comes
case HOME_MOTION_TYPE:
// DistractMovement interrupted by any other movement
case DISTRACT_MOTION_TYPE:
MovementExpired(false);
}
}
m->Initialize(*i_owner);
push(m);
}
void MotionMaster::propagateSpeedChange()
{
Impl::container_type::iterator it = Impl::c.begin();
for ( ;it != end(); ++it)
{
(*it)->unitSpeedChanged();
}
}
MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
{
if(empty())
return IDLE_MOTION_TYPE;
return top()->GetMovementGeneratorType();
}
bool MotionMaster::GetDestination(float &x, float &y, float &z)
{
if(empty())
return false;
return top()->GetDestination(x,y,z);
}
+1447 -1447
View File
File diff suppressed because it is too large. Load diff
+21 -7
View File
@@ -6679,6 +6679,8 @@ void ObjectMgr::LoadTrainerSpell()
itr->second.Clear();
m_mCacheTrainerSpellMap.clear();
std::set<uint32> skip_trainers;
QueryResult *result = WorldDatabase.PQuery("SELECT entry, spell,spellcost,reqskill,reqskillvalue,reqlevel FROM npc_trainer");
if( !result )
@@ -6714,7 +6716,11 @@ void ObjectMgr::LoadTrainerSpell()
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);
if(skip_trainers.count(entry) == 0)
{
sLog.outErrorDb("Table `npc_trainer` have data for not creature template (Entry: %u) without trainer flag, ignore", entry);
skip_trainers.insert(entry);
}
continue;
}
@@ -6764,6 +6770,8 @@ void ObjectMgr::LoadVendors()
itr->second.Clear();
m_mCacheVendorItemMap.clear();
std::set<uint32> skip_vendors;
QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor");
if( !result )
{
@@ -6790,7 +6798,7 @@ void ObjectMgr::LoadVendors()
uint32 incrtime = fields[3].GetUInt32();
uint32 ExtendedCost = fields[4].GetUInt32();
if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost))
if(!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost,NULL,&skip_vendors))
continue;
VendorItemData& vList = m_mCacheVendorItemMap[entry];
@@ -6878,7 +6886,7 @@ bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item )
return true;
}
bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl ) const
bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* pl, std::set<uint32>* skip_vendors ) const
{
CreatureInfo const* cInfo = GetCreatureTemplate(vendor_entry);
if(!cInfo)
@@ -6892,10 +6900,16 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m
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);
if(!skip_vendors || skip_vendors->count(vendor_entry)==0)
{
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);
if(skip_vendors)
skip_vendors->insert(vendor_entry);
}
return false;
}
+1 -1
View File
@@ -742,7 +742,7 @@ class ObjectMgr
}
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;
bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL ) const;
protected:
uint32 m_auctionid;
uint32 m_mailid;
+649 -648
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+58 -16
View File
@@ -265,8 +265,8 @@ Player::Player (WorldSession *session): Unit()
if(GetSession()->GetSecurity() >= SEC_GAMEMASTER)
SetAcceptTicket(true);
// players always and GM if set in config accept whispers by default
if(GetSession()->GetSecurity() == SEC_PLAYER || sWorld.getConfig(CONFIG_GM_WISPERING_TO))
// players always accept
if(GetSession()->GetSecurity() == SEC_PLAYER)
SetAcceptWhispers(true);
m_curSelection = 0;
@@ -1415,7 +1415,7 @@ uint8 Player::chatTag() const
// 0x4 - gm
// 0x2 - dnd
// 0x1 - afk
if(isGameMaster())
if(isGMChat())
return 4;
else if(isDND())
return 3;
@@ -1555,10 +1555,13 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
}
}
SetSemaphoreTeleport(false);
if(!GetSession()->PlayerLogout())
{
// don't reset teleport semaphore while logging out, otherwise m_teleport_dest won't be used in Player::SaveToDB
SetSemaphoreTeleport(false);
UpdateZone(GetZoneId());
}
// new zone
if(old_zone != GetZoneId())
@@ -9322,6 +9325,11 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
ItemPrototype const *pProto = pItem->GetProto();
if( pProto )
{
// May be here should be more stronger checks; STUNNED checked
// ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked.
if (not_loading && hasUnitState(UNIT_STAT_STUNNED))
return EQUIP_ERR_YOU_ARE_STUNNED;
if(pItem->IsBindedNotWith(GetGUID()))
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
@@ -9346,6 +9354,9 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
if(isInCombat()&& pProto->Class == ITEM_CLASS_WEAPON && m_weaponChangeTimer != 0)
return EQUIP_ERR_CANT_DO_RIGHT_NOW; // maybe exist better err
if(IsNonMeleeSpellCasted(false))
return EQUIP_ERR_CANT_DO_RIGHT_NOW;
uint8 eslot = FindEquipSlot( pProto, slot, swap );
if( eslot == NULL_SLOT )
return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
@@ -13798,16 +13809,45 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
{
switch(sWorld.getConfig(CONFIG_GM_LOGIN_STATE))
{
case 0: // disable
break;
case 1: // enable
SetGameMaster(true);
break;
default:
case 0: break; // disable
case 1: SetGameMaster(true); break; // enable
case 2: // save state
if(gmstate)
if(gmstate & PLAYER_EXTRA_GM_ON)
SetGameMaster(true);
break;
}
switch(sWorld.getConfig(CONFIG_GM_ACCEPT_TICKETS))
{
default:
case 0: break; // disable
case 1: SetAcceptTicket(true); break; // enable
case 2: // save state
if(gmstate & PLAYER_EXTRA_GM_ACCEPT_TICKETS)
SetAcceptTicket(true);
break;
}
switch(sWorld.getConfig(CONFIG_GM_CHAT))
{
default:
case 0: break; // disable
case 1: SetGMChat(true); break; // enable
case 2: // save state
if(gmstate & PLAYER_EXTRA_GM_CHAT)
SetGMChat(true);
break;
}
switch(sWorld.getConfig(CONFIG_GM_WISPERING_TO))
{
default:
case 0: break; // disable
case 1: SetAcceptWhispers(true); break; // enable
case 2: // save state
if(gmstate & PLAYER_EXTRA_ACCEPT_WHISPERS)
SetAcceptWhispers(true);
break;
}
}
@@ -14877,7 +14917,7 @@ void Player::SaveToDB()
ss << "0";
ss << ", ";
ss << (isGameMaster()? 1 : 0);
ss << m_ExtraFlags;
ss << ", ";
ss << uint32(m_stableSlots); // to prevent save uint8 as char
@@ -16387,13 +16427,15 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false;
}
VendorItem const* crItem = vItems->FindItem(item);
if(!crItem)
size_t vendor_slot = vItems->FindItemSlot(item);
if(vendor_slot >= vItems->GetItemCount())
{
SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
return false;
}
VendorItem const* crItem = vItems->m_items[vendor_slot];
// check current item amount if it limited
if( crItem->maxcount != 0 )
{
@@ -16520,7 +16562,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << pCreature->GetGUID();
data << (uint32)crItem->item;
data << (uint32)(vendor_slot+1); // numbered from 1 at client
data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << (uint32)count;
GetSession()->SendPacket(&data);
@@ -16559,7 +16601,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << pCreature->GetGUID();
data << (uint32)crItem->item;
data << (uint32)(vendor_slot+1); // numbered from 1 at client
data << (uint32)(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << (uint32)count;
GetSession()->SendPacket(&data);
+3
View File
@@ -496,6 +496,7 @@ enum PlayerExtraFlags
PLAYER_EXTRA_ACCEPT_WHISPERS = 0x0004,
PLAYER_EXTRA_TAXICHEAT = 0x0008,
PLAYER_EXTRA_GM_INVISIBLE = 0x0010,
PLAYER_EXTRA_GM_CHAT = 0x0020, // Show GM badge in chat messages
// other states
PLAYER_EXTRA_PVP_DEATH = 0x0100 // store PvP death status until corpse creating.
@@ -954,6 +955,8 @@ class MANGOS_DLL_SPEC Player : public Unit
void SetAcceptWhispers(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_ACCEPT_WHISPERS; else m_ExtraFlags &= ~PLAYER_EXTRA_ACCEPT_WHISPERS; }
bool isGameMaster() const { return m_ExtraFlags & PLAYER_EXTRA_GM_ON; }
void SetGameMaster(bool on);
bool isGMChat() const { return GetSession()->GetSecurity() >= SEC_MODERATOR && (m_ExtraFlags & PLAYER_EXTRA_GM_CHAT); }
void SetGMChat(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_GM_CHAT; else m_ExtraFlags &= ~PLAYER_EXTRA_GM_CHAT; }
bool isTaxiCheater() const { return m_ExtraFlags & PLAYER_EXTRA_TAXICHEAT; }
void SetTaxiCheater(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; }
bool isGMVisible() const { return !(m_ExtraFlags & PLAYER_EXTRA_GM_INVISIBLE); }
+1 -1
View File
@@ -41,7 +41,7 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
if(!&unit)
return false;
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED))
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
return true;
Traveller<T> traveller(unit);
+1 -1
View File
@@ -126,7 +126,7 @@ template<>
bool
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
{
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
{
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
creature.clearUnitState(UNIT_STAT_ROAMING);
+311 -309
View File
@@ -1,309 +1,311 @@
/*
* 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 "SocialMgr.h"
#include "Policies/SingletonImp.h"
#include "Database/DatabaseEnv.h"
#include "Opcodes.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "World.h"
#include "Util.h"
INSTANTIATE_SINGLETON_1( SocialMgr );
PlayerSocial::PlayerSocial()
{
m_playerGUID = 0;
}
PlayerSocial::~PlayerSocial()
{
m_playerSocialMap.clear();
}
bool PlayerSocial::AddToSocialList(uint32 friend_guid, bool ignore)
{
// prevent list (client-side) overflow
if(m_playerSocialMap.size() >= (255-1))
return false;
uint32 flag = SOCIAL_FLAG_FRIEND;
if(ignore)
flag = SOCIAL_FLAG_IGNORED;
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr != m_playerSocialMap.end())
{
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags | %u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
m_playerSocialMap[friend_guid].Flags |= flag;
}
else
{
CharacterDatabase.PExecute("INSERT INTO character_social (guid, friend, flags) VALUES ('%u', '%u', '%u')", GetPlayerGUID(), friend_guid, flag);
FriendInfo fi;
fi.Flags |= flag;
m_playerSocialMap[friend_guid] = fi;
}
return true;
}
void PlayerSocial::RemoveFromSocialList(uint32 friend_guid, bool ignore)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr == m_playerSocialMap.end()) // not exist
return;
uint32 flag = SOCIAL_FLAG_FRIEND;
if(ignore)
flag = SOCIAL_FLAG_IGNORED;
itr->second.Flags &= ~flag;
if(itr->second.Flags == 0)
{
CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' AND friend = '%u'", GetPlayerGUID(), friend_guid);
m_playerSocialMap.erase(itr);
}
else
{
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags & ~%u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
}
}
void PlayerSocial::SetFriendNote(uint32 friend_guid, std::string note)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr == m_playerSocialMap.end()) // not exist
return;
utf8truncate(note,48); // DB and client size limitation
CharacterDatabase.escape_string(note);
CharacterDatabase.PExecute("UPDATE character_social SET note = '%s' WHERE guid = '%u' AND friend = '%u'", note.c_str(), GetPlayerGUID(), friend_guid);
m_playerSocialMap[friend_guid].Note = note;
}
void PlayerSocial::SendSocialList()
{
Player *plr = objmgr.GetPlayer(GetPlayerGUID());
if(!plr)
return;
uint32 size = m_playerSocialMap.size();
WorldPacket data(SMSG_CONTACT_LIST, (4+4+size*25)); // just can guess size
data << uint32(7); // unk flag (0x1, 0x2, 0x4), 0x7 if it include ignore list
data << uint32(size); // friends count
for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
{
sSocialMgr.GetFriendInfo(plr, itr->first, itr->second);
data << uint64(itr->first); // player guid
data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?)
data << itr->second.Note; // string note
if(itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend()
{
data << uint8(itr->second.Status); // online/offline/etc?
if(itr->second.Status) // if online
{
data << uint32(itr->second.Area); // player area
data << uint32(itr->second.Level); // player level
data << uint32(itr->second.Class); // player class
}
}
}
plr->GetSession()->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_CONTACT_LIST");
}
bool PlayerSocial::HasFriend(uint32 friend_guid)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr != m_playerSocialMap.end())
return itr->second.Flags & SOCIAL_FLAG_FRIEND;
return false;
}
bool PlayerSocial::HasIgnore(uint32 ignore_guid)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(ignore_guid);
if(itr != m_playerSocialMap.end())
return itr->second.Flags & SOCIAL_FLAG_IGNORED;
return false;
}
SocialMgr::SocialMgr()
{
}
SocialMgr::~SocialMgr()
{
}
void SocialMgr::RemovePlayerSocial(uint32 guid)
{
SocialMap::iterator itr = m_socialMap.find(guid);
if(itr != m_socialMap.end())
m_socialMap.erase(itr);
}
void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)
{
if(!player)
return;
Player *pFriend = ObjectAccessor::FindPlayer(friendGUID);
uint32 team = player->GetTeam();
uint32 security = player->GetSession()->GetSecurity();
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER;
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
if( pFriend && pFriend->GetName() &&
( security > SEC_PLAYER ||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
( pFriend->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && pFriend->IsVisibleGloballyFor(player) )))
{
friendInfo.Status = FRIEND_STATUS_ONLINE;
if(pFriend->isAFK())
friendInfo.Status = FRIEND_STATUS_AFK;
if(pFriend->isDND())
friendInfo.Status = FRIEND_STATUS_DND;
friendInfo.Area = pFriend->GetZoneId();
friendInfo.Level = pFriend->getLevel();
friendInfo.Class = pFriend->getClass();
}
else
{
friendInfo.Status = FRIEND_STATUS_OFFLINE;
friendInfo.Area = 0;
friendInfo.Level = 0;
friendInfo.Class = 0;
}
}
void SocialMgr::MakeFriendStatusPacket(FriendsResult result, uint32 guid, WorldPacket *data)
{
data->Initialize(SMSG_FRIEND_STATUS, 5);
*data << uint8(result);
*data << uint64(guid);
}
void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast)
{
FriendInfo fi;
WorldPacket data;
MakeFriendStatusPacket(result, friend_guid, &data);
switch(result)
{
case FRIEND_ONLINE:
GetFriendInfo(player, friend_guid, fi);
data << uint8(fi.Status);
data << uint32(fi.Area);
data << uint32(fi.Level);
data << uint32(fi.Class);
break;
case FRIEND_ADDED_ONLINE:
GetFriendInfo(player, friend_guid, fi);
data << name;
data << uint8(fi.Status);
data << uint32(fi.Area);
data << uint32(fi.Level);
data << uint32(fi.Class);
break;
case FRIEND_ADDED_OFFLINE:
data << name;
break;
}
if(broadcast)
BroadcastToFriendListers(player, &data);
else
player->GetSession()->SendPacket(&data);
}
void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet)
{
if(!player)
return;
uint32 team = player->GetTeam();
uint32 security = player->GetSession()->GetSecurity();
uint32 guid = player->GetGUIDLow();
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST);
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
for(SocialMap::iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
{
PlayerSocialMap::iterator itr2 = itr->second.m_playerSocialMap.find(guid);
if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
{
Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
if( pFriend && pFriend->IsInWorld() &&
( pFriend->GetSession()->GetSecurity() > SEC_PLAYER ||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
(security == SEC_PLAYER || gmInWhoList && player->IsVisibleGloballyFor(pFriend) )))
{
pFriend->GetSession()->SendPacket(packet);
}
}
}
}
PlayerSocial *SocialMgr::LoadFromDB(QueryResult *result, uint32 guid)
{
PlayerSocial *social = &m_socialMap[guid];
social->SetPlayerGUID(guid);
if(!result)
return social;
uint32 friend_guid = 0;
uint32 flags = 0;
std::string note = "";
do
{
Field *fields = result->Fetch();
friend_guid = fields[0].GetUInt32();
flags = fields[1].GetUInt32();
note = fields[2].GetCppString();
social->m_playerSocialMap[friend_guid] = FriendInfo(flags, note);
// prevent list (client-side) overflow
if(social->m_playerSocialMap.size() >= 255)
break;
}
while( result->NextRow() );
delete result;
return social;
}
/*
* 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 "SocialMgr.h"
#include "Policies/SingletonImp.h"
#include "Database/DatabaseEnv.h"
#include "Opcodes.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "World.h"
#include "Util.h"
INSTANTIATE_SINGLETON_1( SocialMgr );
PlayerSocial::PlayerSocial()
{
m_playerGUID = 0;
}
PlayerSocial::~PlayerSocial()
{
m_playerSocialMap.clear();
}
bool PlayerSocial::AddToSocialList(uint32 friend_guid, bool ignore)
{
// client limit
if(m_playerSocialMap.size() >= 50)
return false;
uint32 flag = SOCIAL_FLAG_FRIEND;
if(ignore)
flag = SOCIAL_FLAG_IGNORED;
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr != m_playerSocialMap.end())
{
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags | %u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
m_playerSocialMap[friend_guid].Flags |= flag;
}
else
{
CharacterDatabase.PExecute("INSERT INTO character_social (guid, friend, flags) VALUES ('%u', '%u', '%u')", GetPlayerGUID(), friend_guid, flag);
FriendInfo fi;
fi.Flags |= flag;
m_playerSocialMap[friend_guid] = fi;
}
return true;
}
void PlayerSocial::RemoveFromSocialList(uint32 friend_guid, bool ignore)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr == m_playerSocialMap.end()) // not exist
return;
uint32 flag = SOCIAL_FLAG_FRIEND;
if(ignore)
flag = SOCIAL_FLAG_IGNORED;
itr->second.Flags &= ~flag;
if(itr->second.Flags == 0)
{
CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' AND friend = '%u'", GetPlayerGUID(), friend_guid);
m_playerSocialMap.erase(itr);
}
else
{
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags & ~%u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
}
}
void PlayerSocial::SetFriendNote(uint32 friend_guid, std::string note)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr == m_playerSocialMap.end()) // not exist
return;
utf8truncate(note,48); // DB and client size limitation
CharacterDatabase.escape_string(note);
CharacterDatabase.PExecute("UPDATE character_social SET note = '%s' WHERE guid = '%u' AND friend = '%u'", note.c_str(), GetPlayerGUID(), friend_guid);
m_playerSocialMap[friend_guid].Note = note;
}
void PlayerSocial::SendSocialList()
{
Player *plr = objmgr.GetPlayer(GetPlayerGUID());
if(!plr)
return;
uint32 size = m_playerSocialMap.size();
WorldPacket data(SMSG_CONTACT_LIST, (4+4+size*25)); // just can guess size
data << uint32(7); // unk flag (0x1, 0x2, 0x4), 0x7 if it include ignore list
data << uint32(size); // friends count
for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
{
sSocialMgr.GetFriendInfo(plr, itr->first, itr->second);
data << uint64(itr->first); // player guid
data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?)
data << itr->second.Note; // string note
if(itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend()
{
data << uint8(itr->second.Status); // online/offline/etc?
if(itr->second.Status) // if online
{
data << uint32(itr->second.Area); // player area
data << uint32(itr->second.Level); // player level
data << uint32(itr->second.Class); // player class
}
}
}
plr->GetSession()->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_CONTACT_LIST");
}
bool PlayerSocial::HasFriend(uint32 friend_guid)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
if(itr != m_playerSocialMap.end())
return itr->second.Flags & SOCIAL_FLAG_FRIEND;
return false;
}
bool PlayerSocial::HasIgnore(uint32 ignore_guid)
{
PlayerSocialMap::iterator itr = m_playerSocialMap.find(ignore_guid);
if(itr != m_playerSocialMap.end())
return itr->second.Flags & SOCIAL_FLAG_IGNORED;
return false;
}
SocialMgr::SocialMgr()
{
}
SocialMgr::~SocialMgr()
{
}
void SocialMgr::RemovePlayerSocial(uint32 guid)
{
SocialMap::iterator itr = m_socialMap.find(guid);
if(itr != m_socialMap.end())
m_socialMap.erase(itr);
}
void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)
{
if(!player)
return;
Player *pFriend = ObjectAccessor::FindPlayer(friendGUID);
uint32 team = player->GetTeam();
uint32 security = player->GetSession()->GetSecurity();
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER;
PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);
if(itr != player->GetSocial()->m_playerSocialMap.end())
friendInfo.Note = itr->second.Note;
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
if( pFriend && pFriend->GetName() &&
( security > SEC_PLAYER ||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
( pFriend->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && pFriend->IsVisibleGloballyFor(player) )))
{
friendInfo.Status = FRIEND_STATUS_ONLINE;
if(pFriend->isAFK())
friendInfo.Status = FRIEND_STATUS_AFK;
if(pFriend->isDND())
friendInfo.Status = FRIEND_STATUS_DND;
friendInfo.Area = pFriend->GetZoneId();
friendInfo.Level = pFriend->getLevel();
friendInfo.Class = pFriend->getClass();
}
else
{
friendInfo.Status = FRIEND_STATUS_OFFLINE;
friendInfo.Area = 0;
friendInfo.Level = 0;
friendInfo.Class = 0;
}
}
void SocialMgr::MakeFriendStatusPacket(FriendsResult result, uint32 guid, WorldPacket *data)
{
data->Initialize(SMSG_FRIEND_STATUS, 5);
*data << uint8(result);
*data << uint64(guid);
}
void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast)
{
FriendInfo fi;
WorldPacket data;
MakeFriendStatusPacket(result, friend_guid, &data);
GetFriendInfo(player, friend_guid, fi);
switch(result)
{
case FRIEND_ADDED_OFFLINE:
case FRIEND_ADDED_ONLINE:
data << fi.Note;
break;
}
switch(result)
{
case FRIEND_ADDED_ONLINE:
case FRIEND_ONLINE:
data << uint8(fi.Status);
data << uint32(fi.Area);
data << uint32(fi.Level);
data << uint32(fi.Class);
break;
}
if(broadcast)
BroadcastToFriendListers(player, &data);
else
player->GetSession()->SendPacket(&data);
}
void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet)
{
if(!player)
return;
uint32 team = player->GetTeam();
uint32 security = player->GetSession()->GetSecurity();
uint32 guid = player->GetGUIDLow();
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST);
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
for(SocialMap::iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
{
PlayerSocialMap::iterator itr2 = itr->second.m_playerSocialMap.find(guid);
if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
{
Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
if( pFriend && pFriend->IsInWorld() &&
( pFriend->GetSession()->GetSecurity() > SEC_PLAYER ||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
(security == SEC_PLAYER || gmInWhoList && player->IsVisibleGloballyFor(pFriend) )))
{
pFriend->GetSession()->SendPacket(packet);
}
}
}
}
PlayerSocial *SocialMgr::LoadFromDB(QueryResult *result, uint32 guid)
{
PlayerSocial *social = &m_socialMap[guid];
social->SetPlayerGUID(guid);
if(!result)
return social;
uint32 friend_guid = 0;
uint32 flags = 0;
std::string note = "";
do
{
Field *fields = result->Fetch();
friend_guid = fields[0].GetUInt32();
flags = fields[1].GetUInt32();
note = fields[2].GetCppString();
social->m_playerSocialMap[friend_guid] = FriendInfo(flags, note);
// client limit
if(social->m_playerSocialMap.size() >= 50)
break;
}
while( result->NextRow() );
delete result;
return social;
}
+2 -2
View File
@@ -986,7 +986,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
if( !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
{
if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNDED))
if(!unit->IsStandState() && !unit->hasUnitState(UNIT_STAT_STUNNED))
unit->SetStandState(PLAYER_STATE_NONE);
if(!unit->isInCombat() && unit->GetTypeId() != TYPEID_PLAYER && ((Creature*)unit)->AI())
@@ -2407,7 +2407,7 @@ void Spell::update(uint32 difftime)
cancel();
// check for incapacitating player states
if( m_caster->hasUnitState(UNIT_STAT_STUNDED | UNIT_STAT_CONFUSED))
if( m_caster->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_CONFUSED))
cancel();
// check if player has turned if flag is set
+6360 -6360
View File
File diff suppressed because it is too large. Load diff
+2 -2
View File
@@ -1465,7 +1465,7 @@ void Spell::EffectDummy(uint32 i)
if(!spell_proto)
return;
if( !unitTarget->hasUnitState(UNIT_STAT_STUNDED) && m_caster->GetTypeId()==TYPEID_PLAYER)
if( !unitTarget->hasUnitState(UNIT_STAT_STUNNED) && m_caster->GetTypeId()==TYPEID_PLAYER)
{
// decreased damage (/2) for non-stunned target.
SpellModifier *mod = new SpellModifier;
@@ -3401,7 +3401,7 @@ void Spell::EffectDistract(uint32 /*i*/)
return;
// target must be OK to do this
if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING ) )
if( unitTarget->hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING ) )
return;
float angle = unitTarget->GetAngle(m_targets.m_destX, m_targets.m_destY);
+2 -2
View File
@@ -47,7 +47,7 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
if( !i_target.isValid() || !&owner )
return;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED) )
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
return;
// prevent redundant micro-movement for pets, other followers.
@@ -127,7 +127,7 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
if( !&owner || !owner.isAlive())
return true;
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
return true;
// prevent movement while casting spells with cast time or channel time
+634 -633
View File
File diff suppressed because it is too large. Load diff
+8 -8
View File
@@ -470,7 +470,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if(pVictim != this)
RemoveSpellsCausingAura(SPELL_AURA_MOD_INVISIBILITY);
if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNDED))
if(pVictim->GetTypeId() == TYPEID_PLAYER && !pVictim->IsStandState() && !pVictim->hasUnitState(UNIT_STAT_STUNNED))
pVictim->SetStandState(PLAYER_STATE_NONE);
}
@@ -2149,7 +2149,7 @@ void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDama
void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )
{
if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNDED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
if(hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) )
return;
if (!pVictim->isAlive())
@@ -2961,7 +2961,7 @@ uint32 Unit::GetDefenseSkillValue(Unit const* target) const
float Unit::GetUnitDodgeChance() const
{
if(hasUnitState(UNIT_STAT_STUNDED))
if(hasUnitState(UNIT_STAT_STUNNED))
return 0.0f;
if( GetTypeId() == TYPEID_PLAYER )
return GetFloatValue(PLAYER_DODGE_PERCENTAGE);
@@ -2980,7 +2980,7 @@ float Unit::GetUnitDodgeChance() const
float Unit::GetUnitParryChance() const
{
if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNDED))
if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNNED))
return 0.0f;
float chance = 0.0f;
@@ -3012,7 +3012,7 @@ float Unit::GetUnitParryChance() const
float Unit::GetUnitBlockChance() const
{
if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNDED))
if ( IsNonMeleeSpellCasted(false) || hasUnitState(UNIT_STAT_STUNNED))
return 0.0f;
if(GetTypeId() == TYPEID_PLAYER)
@@ -7985,7 +7985,7 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo, bool useCharges)
//FIX ME this hack: don't get feared if stunned
if (spellInfo->Mechanic == MECHANIC_FEAR )
{
if ( hasUnitState(UNIT_STAT_STUNDED) )
if ( hasUnitState(UNIT_STAT_STUNNED) )
return true;
}
@@ -8662,7 +8662,7 @@ bool Unit::isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList)
return true;
//If a mob or player is stunned he will not be able to detect stealth
if (u->hasUnitState(UNIT_STAT_STUNDED) && (u != this))
if (u->hasUnitState(UNIT_STAT_STUNNED) && (u != this))
return false;
// Creature can detect target only in aggro radius
@@ -9136,7 +9136,7 @@ bool Unit::SelectHostilTarget()
if(target)
{
if(!hasUnitState(UNIT_STAT_STUNDED))
if(!hasUnitState(UNIT_STAT_STUNNED))
SetInFront(target);
((Creature*)this)->AI()->AttackStart(target);
return true;
+2 -2
View File
@@ -346,7 +346,7 @@ enum UnitState
UNIT_STAT_DIED = 0x0001,
UNIT_STAT_MELEE_ATTACKING = 0x0002, // player is melee attacking someone
//UNIT_STAT_MELEE_ATTACK_BY = 0x0004, // player is melee attack by someone
UNIT_STAT_STUNDED = 0x0008,
UNIT_STAT_STUNNED = 0x0008,
UNIT_STAT_ROAMING = 0x0010,
UNIT_STAT_CHASE = 0x0020,
UNIT_STAT_SEARCHING = 0x0040,
@@ -756,7 +756,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool CanFreeMove() const
{
return !hasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_FLEEING | UNIT_STAT_IN_FLIGHT |
UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0;
UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED ) && GetOwnerGUID()==0;
}
uint32 getLevel() const { return GetUInt32Value(UNIT_FIELD_LEVEL); }
+1 -1
View File
@@ -85,7 +85,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &di
// Waypoint movement can be switched on/off
// This is quite handy for escort quests and other stuff
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNDED | UNIT_STAT_DISTRACTED))
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
return true;
// prevent a crash at empty waypoint path.
+8 -5
View File
@@ -642,11 +642,14 @@ void World::LoadConfigSettings(bool reload)
m_configs[CONFIG_MIN_PETITION_SIGNS] = 9;
}
m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetBoolDefault("GM.WhisperingTo",false);
m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList",false);
m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false);
m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState",2);
m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false);
m_configs[CONFIG_GM_LOGIN_STATE] = sConfig.GetIntDefault("GM.LoginState",2);
m_configs[CONFIG_GM_ACCEPT_TICKETS] = sConfig.GetIntDefault("GM.AcceptTickets",2);
m_configs[CONFIG_GM_CHAT] = sConfig.GetIntDefault("GM.Chat",2);
m_configs[CONFIG_GM_WISPERING_TO] = sConfig.GetIntDefault("GM.WhisperingTo",2);
m_configs[CONFIG_GM_IN_GM_LIST] = sConfig.GetBoolDefault("GM.InGMList",false);
m_configs[CONFIG_GM_IN_WHO_LIST] = sConfig.GetBoolDefault("GM.InWhoList",false);
m_configs[CONFIG_GM_LOG_TRADE] = sConfig.GetBoolDefault("GM.LogTrade", false);
m_configs[CONFIG_GROUP_VISIBILITY] = sConfig.GetIntDefault("Visibility.GroupMode",0);
+542 -540
View File
File diff suppressed because it is too large. Load diff
+511 -493
View File
File diff suppressed because it is too large. Load diff
+643 -642
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+117 -117
View File
@@ -1,117 +1,117 @@
#ifndef _WHEATYEXCEPTIONREPORT_
#define _WHEATYEXCEPTIONREPORT_
#include <dbghelp.h>
#if _MSC_VER < 1400
# define countof(array) (sizeof(array) / sizeof(array[0]))
#else
# include <stdlib.h>
# define countof _countof
#endif // _MSC_VER < 1400
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31
};
const char* const rgBaseType[] =
{
" <user defined> ", // btNoType = 0,
" void ", // btVoid = 1,
" char* ", // btChar = 2,
" wchar_t* ", // btWChar = 3,
" signed char ",
" unsigned char ",
" int ", // btInt = 6,
" unsigned int ", // btUInt = 7,
" float ", // btFloat = 8,
" <BCD> ", // btBCD = 9,
" bool ", // btBool = 10,
" short ",
" unsigned short ",
" long ", // btLong = 13,
" unsigned long ", // btULong = 14,
" __int8 ",
" __int16 ",
" __int32 ",
" __int64 ",
" __int128 ",
" unsigned __int8 ",
" unsigned __int16 ",
" unsigned __int32 ",
" unsigned __int64 ",
" unsigned __int128 ",
" <currency> ", // btCurrency = 25,
" <date> ", // btDate = 26,
" VARIANT ", // btVariant = 27,
" <complex> ", // btComplex = 28,
" <bit> ", // btBit = 29,
" BSTR ", // btBSTR = 30,
" HRESULT " // btHresult = 31
};
class WheatyExceptionReport
{
public:
WheatyExceptionReport( );
~WheatyExceptionReport( );
// entry point where control comes on an unhandled exception
static LONG WINAPI WheatyUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo );
private:
// where report info is extracted and generated
static void GenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo );
static void PrintSystemInfo();
static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
// Helper functions
static LPTSTR GetExceptionString( DWORD dwCode );
static BOOL GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len,
DWORD& section, DWORD_PTR& offset );
static void WriteStackDetails( PCONTEXT pContext, bool bWriteVariables );
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO,ULONG, PVOID);
static bool FormatSymbolValue( PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer );
static char * DumpTypeIndex( char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool & , char*);
static char * FormatOutputValue( char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress );
static BasicType GetBasicType( DWORD typeIndex, DWORD64 modBase );
static int __cdecl _tprintf(const TCHAR * format, ...);
// Variables used by the class
static TCHAR m_szLogFileName[MAX_PATH];
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
static HANDLE m_hReportFile;
static HANDLE m_hProcess;
};
extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
#endif //WheatyExceptionReport
#ifndef _WHEATYEXCEPTIONREPORT_
#define _WHEATYEXCEPTIONREPORT_
#include <dbghelp.h>
#if _MSC_VER < 1400
# define countof(array) (sizeof(array) / sizeof(array[0]))
#else
# include <stdlib.h>
# define countof _countof
#endif // _MSC_VER < 1400
enum BasicType // Stolen from CVCONST.H in the DIA 2.0 SDK
{
btNoType = 0,
btVoid = 1,
btChar = 2,
btWChar = 3,
btInt = 6,
btUInt = 7,
btFloat = 8,
btBCD = 9,
btBool = 10,
btLong = 13,
btULong = 14,
btCurrency = 25,
btDate = 26,
btVariant = 27,
btComplex = 28,
btBit = 29,
btBSTR = 30,
btHresult = 31
};
const char* const rgBaseType[] =
{
" <user defined> ", // btNoType = 0,
" void ", // btVoid = 1,
" char* ", // btChar = 2,
" wchar_t* ", // btWChar = 3,
" signed char ",
" unsigned char ",
" int ", // btInt = 6,
" unsigned int ", // btUInt = 7,
" float ", // btFloat = 8,
" <BCD> ", // btBCD = 9,
" bool ", // btBool = 10,
" short ",
" unsigned short ",
" long ", // btLong = 13,
" unsigned long ", // btULong = 14,
" __int8 ",
" __int16 ",
" __int32 ",
" __int64 ",
" __int128 ",
" unsigned __int8 ",
" unsigned __int16 ",
" unsigned __int32 ",
" unsigned __int64 ",
" unsigned __int128 ",
" <currency> ", // btCurrency = 25,
" <date> ", // btDate = 26,
" VARIANT ", // btVariant = 27,
" <complex> ", // btComplex = 28,
" <bit> ", // btBit = 29,
" BSTR ", // btBSTR = 30,
" HRESULT " // btHresult = 31
};
class WheatyExceptionReport
{
public:
WheatyExceptionReport( );
~WheatyExceptionReport( );
// entry point where control comes on an unhandled exception
static LONG WINAPI WheatyUnhandledExceptionFilter(
PEXCEPTION_POINTERS pExceptionInfo );
static void printTracesForAllThreads();
private:
// where report info is extracted and generated
static void GenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo );
static void PrintSystemInfo();
static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
// Helper functions
static LPTSTR GetExceptionString( DWORD dwCode );
static BOOL GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len,
DWORD& section, DWORD_PTR& offset );
static void WriteStackDetails( PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO,ULONG, PVOID);
static bool FormatSymbolValue( PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer );
static char * DumpTypeIndex( char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool & , char*);
static char * FormatOutputValue( char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress );
static BasicType GetBasicType( DWORD typeIndex, DWORD64 modBase );
static int __cdecl _tprintf(const TCHAR * format, ...);
// Variables used by the class
static TCHAR m_szLogFileName[MAX_PATH];
static LPTOP_LEVEL_EXCEPTION_FILTER m_previousFilter;
static HANDLE m_hReportFile;
static HANDLE m_hProcess;
};
extern WheatyExceptionReport g_WheatyExceptionReport; // global instance of class
#endif //WheatyExceptionReport
+4 -4
View File
@@ -52,8 +52,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,3,6731,680
PRODUCTVERSION 0,3,6731,680
FILEVERSION 0,4,6743,685
PRODUCTVERSION 0,4,6743,685
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
BLOCK "080004b0"
BEGIN
VALUE "FileDescription", "TrinityCore"
VALUE "FileVersion", "0, 3, 6731, 680"
VALUE "FileVersion", "0, 4, 6743, 685"
VALUE "InternalName", "TrinityCore"
VALUE "LegalCopyright", "Copyright (C) 2008"
VALUE "OriginalFilename", "TrinityCore.exe"
VALUE "ProductName", "TrinityCore"
VALUE "ProductVersion", "0, 3, 6731, 680"
VALUE "ProductVersion", "0, 4, 6743, 685"
END
END
BLOCK "VarFileInfo"
+4 -4
View File
@@ -52,8 +52,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,3,6731,680
PRODUCTVERSION 0,3,6731,680
FILEVERSION 0,4,6743,685
PRODUCTVERSION 0,4,6743,685
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
BLOCK "080004b0"
BEGIN
VALUE "FileDescription", "TrinityRealm"
VALUE "FileVersion", "0, 3, 6731, 680"
VALUE "FileVersion", "0, 4, 6743, 685"
VALUE "InternalName", "TrinityRealm"
VALUE "LegalCopyright", "Copyright (C) 2008"
VALUE "OriginalFilename", "TrinityRealm.exe"
VALUE "ProductName", "TrinityRealm"
VALUE "ProductVersion", "0, 3, 6731, 680"
VALUE "ProductVersion", "0, 4, 6743, 685"
END
END
BLOCK "VarFileInfo"