aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2008-12-31 10:03:07 -0600
committermegamage <none@none>2008-12-31 10:03:07 -0600
commitba58ddac9c302953fc15987bc84d5f858a011e56 (patch)
tree5bafa1aa17b64d7e325a347f4538eb8402b222a3
parentaa3b89d7764c093ba87ee2cf99775e3aedc37637 (diff)
parent3885ce94d9be86616bb01e660a70087fcbfc6ffd (diff)
*Update to HG 730.
--HG-- branch : trunk
-rw-r--r--configure.ac32
-rw-r--r--sql/updates/722_world_script_texts.sql9
-rw-r--r--sql/updates/724_world.sql3
-rw-r--r--sql/updates/725_characters.sql6
-rw-r--r--sql/updates/725_world.sql30
-rw-r--r--sql/updates/728_world_scripts.sql1
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp20
-rw-r--r--src/bindings/scripts/docs/Text-tables.txt1
-rw-r--r--src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp217
-rw-r--r--src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp28
-rw-r--r--src/game/CharacterHandler.cpp16
-rw-r--r--src/game/Chat.cpp19
-rw-r--r--src/game/Chat.h21
-rw-r--r--src/game/ChatHandler.cpp5
-rw-r--r--src/game/GMTicketHandler.cpp177
-rw-r--r--src/game/GMTicketMgr.cpp82
-rw-r--r--src/game/GMTicketMgr.h125
-rw-r--r--src/game/GridDefines.h4
-rw-r--r--src/game/Language.h32
-rw-r--r--src/game/Level1.cpp317
-rw-r--r--src/game/Level2.cpp6
-rw-r--r--src/game/Opcodes.cpp4
-rw-r--r--src/game/Player.cpp15
-rw-r--r--src/game/Player.h3
-rw-r--r--src/game/Spell.cpp20
-rw-r--r--src/game/Spell.h1
-rw-r--r--src/game/SpellAuras.cpp12
-rw-r--r--src/game/SpellEffects.cpp11
-rw-r--r--src/game/TicketHandler.cpp186
-rw-r--r--src/game/TicketMgr.cpp207
-rw-r--r--src/game/TicketMgr.h89
-rw-r--r--src/game/World.cpp12
-rw-r--r--src/game/World.h9
-rw-r--r--src/game/WorldSession.h16
-rw-r--r--src/trinitycore/WorldRunnable.cpp86
-rw-r--r--src/trinitycore/trinitycore.conf.dist28
-rw-r--r--win/VC71/game.vcproj21
-rw-r--r--win/VC80/game.vcproj24
-rw-r--r--win/VC90/game.vcproj24
39 files changed, 1408 insertions, 511 deletions
diff --git a/configure.ac b/configure.ac
index fd14e0ca3a4..0b9fa8971fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -216,6 +216,38 @@ AC_ARG_ENABLE(ra,
])
AC_MSG_RESULT($TRINITYD_ENABLE_RA)
+# Enable large cells?
+AC_MSG_CHECKING(whether we use large cells)
+TRINITYD_ENABLE_LC=no
+AC_ARG_ENABLE(lc,
+[ --enable-lc Enable large cells (more CPU usage)],
+[
+ if test "$enableval" = "yes" ; then
+ CFLAGS="-DLARGE_CELL $CFLAGS"
+ CXXFLAGS="-DLARGE_CELL $CXXFLAGS"
+ TRINITYD_ENABLE_LC=yes
+ elif test "$withval" != "no" ; then
+ AC_MSG_ERROR(Please choose yes or no)
+ fi
+])
+AC_MSG_RESULT($TRINITYD_ENABLE_LC)
+
+# Enable short world sleep?
+AC_MSG_CHECKING(whether we use short world sleep)
+TRINITYD_ENABLE_SS=no
+AC_ARG_ENABLE(ss,
+[ --enable-ss Enable short world sleep],
+[
+ if test "$enableval" = "yes" ; then
+ CFLAGS="-DSHORT_SLEEP $CFLAGS"
+ CXXFLAGS="-DSHORT_SLEEP $CXXFLAGS"
+ TRINITYD_ENABLE_SS=yes
+ elif test "$withval" != "no" ; then
+ AC_MSG_ERROR(Please choose yes or no)
+ fi
+])
+AC_MSG_RESULT($TRINITYD_ENABLE_SS)
+
## Check for required header files.
AC_HEADER_STDC
AC_HEADER_DIRENT
diff --git a/sql/updates/722_world_script_texts.sql b/sql/updates/722_world_script_texts.sql
new file mode 100644
index 00000000000..8be4cd9a86f
--- /dev/null
+++ b/sql/updates/722_world_script_texts.sql
@@ -0,0 +1,9 @@
+DELETE FROM `script_texts` WHERE `entry` BETWEEN -1000146 AND -1000140;
+INSERT INTO `script_texts` (`entry`,`content_default`,`sound`,`type`,`language`,`comment`) VALUES
+(-1000140,'Let\'s go.',0,0,1,'lilatha SAY_START'),
+(-1000141,'$N, let\'s use the antechamber to the right.',0,0,1,'lilatha SAY_PROGRESS1'),
+(-1000142,'I can see the light at the end of the tunnel!',0,0,1,'lilatha SAY_PROGRESS2'),
+(-1000143,'There\'s Farstrider Enclave now, $C. Not far to go... Look out! Troll ambush!!',0,0,1,'lilatha SAY_PROGRESS3'),
+(-1000144,'Thank you for saving my life and bringing me back to safety, $N',0,0,1,'lilatha SAY_END1'),
+(-1000145,'Captain Helios, I\'ve been rescued from the Amani Catacombs. Reporting for duty, sir!',0,0,1,'lilatha SAY_END2'),
+(-1000146,'Liatha, get someone to look at those injuries. Thank you for bringing her back safely.',0,0,1,'lilatha CAPTAIN_ANSWER'); \ No newline at end of file
diff --git a/sql/updates/724_world.sql b/sql/updates/724_world.sql
new file mode 100644
index 00000000000..36a2d007de3
--- /dev/null
+++ b/sql/updates/724_world.sql
@@ -0,0 +1,3 @@
+ALTER TABLE custom_texts ADD COLUMN emote tinyint(3) UNSIGNED DEFAULT '0' NOT NULL AFTER language;
+ALTER TABLE eventai_texts ADD COLUMN emote tinyint(3) UNSIGNED DEFAULT '0' NOT NULL AFTER language;
+ALTER TABLE script_texts ADD COLUMN emote tinyint(3) UNSIGNED DEFAULT '0' NOT NULL AFTER language; \ No newline at end of file
diff --git a/sql/updates/725_characters.sql b/sql/updates/725_characters.sql
new file mode 100644
index 00000000000..c875bf9399c
--- /dev/null
+++ b/sql/updates/725_characters.sql
@@ -0,0 +1,6 @@
+ALTER TABLE `character_ticket` RENAME TO `gm_tickets`;
+ALTER TABLE gm_tickets CHANGE `guid` `playerGuid` int(11) unsigned NOT NULL default '0';
+ALTER TABLE gm_tickets CHANGE `ticket_id` `guid` int(11) unsigned NOT NULL default '0';
+ALTER TABLE gm_tickets CHANGE `ticket_text` `message` text(0) NOT NULL;
+ALTER TABLE gm_tickets CHANGE `ticket_lastchange` `timestamp` int(10) NOT NULL default '0';
+ALTER TABLE gm_tickets ADD( `closed` bit(1) NOT NULL, `assignedto` int(10) NOT NULL default '0', `comment` text(0) NOT NULL default ''); \ No newline at end of file
diff --git a/sql/updates/725_world.sql b/sql/updates/725_world.sql
new file mode 100644
index 00000000000..1a3172fb6dc
--- /dev/null
+++ b/sql/updates/725_world.sql
@@ -0,0 +1,30 @@
+DELETE FROM `trinity_string` WHERE (`entry`='290');
+DELETE FROM `trinity_string` WHERE (`entry`='296');
+DELETE FROM `trinity_string` WHERE (`entry`='289');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2000, '|cff00ff00New ticket from|r|cffff00ff %s.|r |cff00ff00Ticket entry:|r|cffff00ff %d.|r', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2001, '|cff00ff00Character|r|cffff00ff %s |r|cff00ff00edited his/her ticket:|r|cffff00ff %d.|r', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2002, '|cff00ff00Character|r|cffff00ff %s |r|cff00ff00abandoned ticket entry:|r|cffff00ff %d.|r', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2003, '|cffff00ff %s|r |cff00ff00closed ticket|r |cffff00ff %d.|r', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2004, 'Ticket %d permanently deleted by %s.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2005, 'Ticket not found.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2007, 'Please close ticket before deleting it permanently.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2008, 'Ticket %d is already assigned to GM %s.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2009, '%u Tickets succesfully reloaded from the database.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2010, 'Showing list of open tickets.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2011, 'Showing list of open tickets whose creator is online.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2012, 'Invalid name specified. Name should be that of an online Gamemaster.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2013, 'This ticket is already assigned to yourself. To unassign use .ticket unassign %d and then reassign.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2014, 'Ticket %d is not assigned, you cannot unassign it.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2015, 'You cannot unassign tickets from staffmembers with a higher security level than yourself.', '', '', '', '', '', '', '', '');
+INSERT INTO trinity_string (`entry`, `content_default`, `content_loc1`, `content_loc2`, `content_loc3`, `content_loc4`, `content_loc5`, `content_loc6`, `content_loc7`, `content_loc8`) VALUES (2016, 'Cannot close ticket %d, it is assigned to another GM.', '', '', '', '', '', '', '', '');
+DELETE FROM `command` WHERE (`name` LIKE '%ticket%');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket list','1','Displays a list of open GM tickets.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket onlinelist','1','Displays a list of open GM tickets whose owner is online.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket viewname','1','Usage: .ticket viewname $creatorname. \r\nReturns details about specified ticket. Ticket must be open and not deleted.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket viewid','1','Usage: .ticket viewid $ticketid.\r\nReturns details about specified ticket. Ticket must be open and not deleted.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket close','2','Usage: .ticket close $ticketid.\r\nCloses the specified ticket. Does not delete permanently.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket delete','3','Usage: .ticket delete $ticketid.\r\nDeletes the specified ticket permanently. Ticket must be closed first.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket assign','3','Usage: .ticket assign $ticketid $gmname.\r\nAssigns the specified ticket to the specified Game Master.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket unassign','3','Usage: .ticket unassign $ticketid.\r\nUnassigns the specified ticket from the current assigned Game Master.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.ticket comment','2','Usage: .ticket comment $ticketid $comment.\r\nAllows the adding or modifying of a comment to the specified ticket.');
+INSERT INTO `command` (`name`,`security`,`help`) VALUES ('.reload tickets','4','Usage: .reload tickets.\r\nReloads GM Tickets from the database and re-caches them into memory.');
diff --git a/sql/updates/728_world_scripts.sql b/sql/updates/728_world_scripts.sql
new file mode 100644
index 00000000000..5b042ee40a1
--- /dev/null
+++ b/sql/updates/728_world_scripts.sql
@@ -0,0 +1 @@
+update creature_template set scriptname='npc_apprentice_mirveda' where entry=15402; \ No newline at end of file
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index 5d78d40030d..0dc71482df8 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -29,6 +29,7 @@ struct StringTextData
uint32 SoundId;
uint8 Type;
uint32 Language;
+ uint32 Emote;
};
// Enums used by StringTextData::Type
@@ -654,7 +655,7 @@ void LoadDatabase()
LoadTrinityStrings(TScriptDB,"eventai_texts",-1,1+(TEXT_SOURCE_RANGE));
// Gather Additional data from EventAI Texts
- result = TScriptDB.PQuery("SELECT entry, sound, type, language FROM eventai_texts");
+ result = TScriptDB.PQuery("SELECT entry, sound, type, language, emote FROM eventai_texts");
outstring_log("TSCR: Loading EventAI Texts additional data...");
if (result)
@@ -672,6 +673,7 @@ void LoadDatabase()
temp.SoundId = fields[1].GetInt32();
temp.Type = fields[2].GetInt32();
temp.Language = fields[3].GetInt32();
+ temp.Emote = fields[4].GetInt32();
if (i >= 0)
{
@@ -736,6 +738,7 @@ void LoadDatabase()
temp.SoundId = fields[1].GetInt32();
temp.Type = fields[2].GetInt32();
temp.Language = fields[3].GetInt32();
+ temp.Emote = fields[4].GetInt32();
if (i >= 0)
{
@@ -782,7 +785,7 @@ void LoadDatabase()
LoadTrinityStrings(TScriptDB,"custom_texts",TEXT_SOURCE_RANGE*2,1+(TEXT_SOURCE_RANGE*3));
// Gather Additional data from Custom Texts
- result = TScriptDB.PQuery("SELECT entry, sound, type, language FROM custom_texts");
+ result = TScriptDB.PQuery("SELECT entry, sound, type, language, emote FROM custom_texts");
outstring_log("TSCR: Loading Custom Texts additional data...");
if (result)
@@ -800,6 +803,7 @@ void LoadDatabase()
temp.SoundId = fields[1].GetInt32();
temp.Type = fields[2].GetInt32();
temp.Language = fields[3].GetInt32();
+ temp.Emote = fields[4].GetInt32();
if (i >= 0)
{
@@ -1838,7 +1842,7 @@ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
return;
}
- debug_log("TSCR: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u",textEntry,(*i).second.SoundId,(*i).second.Type,(*i).second.Language);
+ debug_log("TSCR: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u",textEntry,(*i).second.SoundId,(*i).second.Type,(*i).second.Language,(*i).second.Emote);
if((*i).second.SoundId)
{
@@ -1850,6 +1854,16 @@ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target)
error_log("TSCR: DoScriptText entry %i tried to process invalid sound id %u.",textEntry,(*i).second.SoundId);
}
+ if((*i).second.Emote)
+ {
+ if (pSource->GetTypeId() == TYPEID_UNIT || pSource->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Unit*)pSource)->HandleEmoteCommand((*i).second.Emote);
+ }
+ else
+ error_log("TSCR: DoScriptText entry %i tried to process emote for invalid TypeId (%u).",textEntry,pSource->GetTypeId());
+ }
+
switch((*i).second.Type)
{
case CHAT_TYPE_SAY:
diff --git a/src/bindings/scripts/docs/Text-tables.txt b/src/bindings/scripts/docs/Text-tables.txt
index c335ce41d58..6db1ce9d852 100644
--- a/src/bindings/scripts/docs/Text-tables.txt
+++ b/src/bindings/scripts/docs/Text-tables.txt
@@ -37,6 +37,7 @@ content_loc8 This is the actual text presented in the Localization #8 C
sound This value is the Sound ID that corresponds to the actual text used (Defined in SoundEntries.dbc).
type Variables used to define type of text (Say/Yell/Textemote/Whisper).
language This value is the Language that the text is native in (Defined in Languages.dbc).
+emote Value from enum Emote (defined in Emotes.dbc). Only source of text will play this emote (not target, if target are defined in DoScriptText)
comment This is a comment regarding the text entry (For ACID, accepted format is to use Creature ID of NPC using it).
Note: Fields `content_loc1` to `content_loc8` are NULL values by default and are handled by seperate localization projects.
diff --git a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
index 30292d37c72..bfd8a5d51ce 100644
--- a/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
+++ b/src/bindings/scripts/scripts/zone/eversong_woods/eversong_woods.cpp
@@ -17,13 +17,15 @@
/* ScriptData
SDName: Eversong_Woods
SD%Complete: 100
-SDComment: Quest support: 8346, 8483
+SDComment: Quest support: 8346, 8483, 8488, 8490
SDCategory: Eversong Woods
EndScriptData */
/* ContentData
mobs_mana_tapped
npc_prospector_anvilward
+npc_apprentice_mirveda
+npc_infused_crystal
EndContentData */
#include "precompiled.h"
@@ -547,6 +549,208 @@ bool GOHello_go_second_trial(Player *player, GameObject* _GO)
return true;
}
+/*######
+## npc_apprentice_mirveda
+######*/
+
+#define QUEST_UNEXPECTED_RESULT 8488
+#define MOB_GHARZUL 15958
+#define MOB_ANGERSHADE 15656
+
+struct TRINITY_DLL_DECL npc_apprentice_mirvedaAI : public ScriptedAI
+{
+ npc_apprentice_mirvedaAI(Creature* c) : ScriptedAI(c), Summons(m_creature) {Reset();}
+
+ uint32 KillCount;
+ uint64 PlayerGUID;
+ bool Summon;
+ SummonList Summons;
+
+ void Reset()
+ {
+ KillCount = 0;
+ PlayerGUID = 0;
+ Summons.DespawnAll();
+ Summon = false;
+ }
+
+ void Aggro(Unit* who){}
+
+ void JustSummoned(Creature *summoned)
+ {
+ summoned->AI()->AttackStart(m_creature);
+ Summons.Summon(summoned);
+ }
+
+ void SummonedCreatureDespawn(Creature* summoned)
+ {
+ Summons.Despawn(summoned);
+ ++KillCount;
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (PlayerGUID)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+ if (player)
+ ((Player*)player)->FailQuest(QUEST_UNEXPECTED_RESULT);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(KillCount >= 3)
+ {
+ if (PlayerGUID)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+ ((Player*)player)->GroupEventHappens(QUEST_UNEXPECTED_RESULT, m_creature);
+ }
+ }
+
+ if(Summon)
+ {
+ m_creature->SummonCreature(MOB_GHARZUL, 8745, -7134.32, 35.22, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000);
+ m_creature->SummonCreature(MOB_ANGERSHADE, 8745, -7134.32, 35.22, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000);
+ m_creature->SummonCreature(MOB_ANGERSHADE, 8745, -7134.32, 35.22, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000);
+ Summon = false;
+ }
+ }
+};
+
+bool QuestAccept_npc_apprentice_mirveda(Player* player, Creature* creature, Quest const* quest)
+{
+ if (quest->GetQuestId() == QUEST_UNEXPECTED_RESULT)
+ {
+ ((npc_apprentice_mirvedaAI*)creature->AI())->Summon = true;
+ ((npc_apprentice_mirvedaAI*)creature->AI())->PlayerGUID = player->GetGUID();
+ }
+ return true;
+}
+
+CreatureAI* GetAI_npc_apprentice_mirvedaAI(Creature *_Creature)
+{
+ return new npc_apprentice_mirvedaAI (_Creature);
+}
+
+/*######
+## npc_infused_crystal not working yet.
+######*/
+
+#define MOB_ENRAGED_WRAITH 17086
+#define EMOTE "releases the last of its energies into the nerarby runestone, succesfully reactivating it."
+#define QUEST_POWERING_OUR_DEFENSES 8490
+
+struct Location
+{
+ float x, y, z;
+};
+
+static Location SpawnLocations[]=
+{
+ {8270.68, -7188.53, 139.619},
+ {8284.27, -7187.78, 139.603},
+ {8297.43, -7193.53, 139.603},
+ {8303.5, -7201.96, 139.577},
+ {8273.22, -7241.82, 139.382},
+ {8254.89, -7222.12, 139.603},
+ {8278.51, -7242.13, 139.162},
+ {8267.97, -7239.17, 139.517}
+};
+
+struct TRINITY_DLL_DECL npc_infused_crystalAI : public Scripted_NoMovementAI
+{
+ npc_infused_crystalAI(Creature* c) : Scripted_NoMovementAI(c) {Reset();}
+
+ uint32 EndTimer;
+ uint32 WaveTimer;
+ bool Completed;
+ bool Progress;
+ uint64 PlayerGUID;
+
+ void Reset()
+ {
+ EndTimer = 0;
+ WaveTimer = 0;
+ PlayerGUID = 0;
+ Completed = false;
+ Progress = false;
+ }
+
+ void Aggro(Unit* who){}
+
+ void JustSummoned(Creature *summoned)
+ {
+ summoned->AI()->AttackStart(m_creature);
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ error_log("MoveLos");
+ if( who->GetTypeId() == TYPEID_PLAYER && !m_creature->canStartAttack(who) )
+ {
+ error_log("TypeId check");
+ if( ((Player*)who)->GetQuestStatus(QUEST_POWERING_OUR_DEFENSES) == QUEST_STATUS_INCOMPLETE )
+ {
+ error_log("Queststaus");
+ float Radius = 10.0;
+ if( m_creature->IsWithinDistInMap(who, Radius) )
+ {
+ PlayerGUID = who->GetGUID();
+ WaveTimer = 1000;
+ EndTimer = 60000;
+ Progress = true;
+ error_log("Event started");
+ }
+ }
+ }
+ }
+
+ void JustDied(Unit* killer)
+ {
+ if (PlayerGUID && !Completed)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+ if (player)
+ ((Player*)player)->FailQuest(QUEST_POWERING_OUR_DEFENSES);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(EndTimer < diff && Progress)
+ {
+ DoTextEmote(EMOTE, NULL);
+ Completed = true;
+ if (PlayerGUID)
+ {
+ Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
+ ((Player*)player)->GroupEventHappens(QUEST_POWERING_OUR_DEFENSES, m_creature);
+ }
+ m_creature->DealDamage(m_creature,m_creature->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_creature->RemoveCorpse();
+ error_log("EndTimer done");
+ }else EndTimer -= diff;
+
+ if(WaveTimer < diff && !Completed && Progress)
+ {
+ uint32 ran = rand()%8;
+ DoSpawnCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran].x, SpawnLocations[ran].y, SpawnLocations[ran].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000);
+ DoSpawnCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran].x, SpawnLocations[ran].y, SpawnLocations[ran].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000);
+ DoSpawnCreature(MOB_ENRAGED_WRAITH, SpawnLocations[ran].x, SpawnLocations[ran].y, SpawnLocations[ran].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 4000);
+ WaveTimer = 30000;
+ error_log("Wave summon");
+ }else WaveTimer -= diff;
+ }
+};
+
+
+CreatureAI* GetAI_npc_infused_crystalAI(Creature *_Creature)
+{
+ return new npc_infused_crystalAI (_Creature);
+}
+
void AddSC_eversong_woods()
{
Script *newscript;
@@ -579,4 +783,15 @@ void AddSC_eversong_woods()
newscript->Name="go_second_trial";
newscript->pGOHello = &GOHello_go_second_trial;
newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_apprentice_mirveda";
+ newscript->GetAI = &GetAI_npc_apprentice_mirvedaAI;
+ newscript->pQuestAccept = &QuestAccept_npc_apprentice_mirveda;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_infused_crystal";
+ newscript->GetAI = &GetAI_npc_infused_crystalAI;
+ newscript->RegisterSelf();
}
diff --git a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
index ca9c9c6bf44..b38e21687da 100644
--- a/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
+++ b/src/bindings/scripts/scripts/zone/ghostlands/ghostlands.cpp
@@ -131,13 +131,13 @@ bool GOHello_gilded_brazier(Player *player, GameObject* _GO)
## npc_ranger_lilatha
######*/
-#define SAY_START "Let's go."
-#define SAY_PROGRESS1 "$N, let's use the antechamber to the right."
-#define SAY_PROGRESS2 "I can see the light at the end of the tunnel!"
-#define SAY_PROGRESS3 "There's Farstrider Enclave now, $C. Not far to go... Look out! Troll ambush!!"
-#define SAY_END1 "Thank you for saving my life and bringing me back to safety, $N"
-#define SAY_END2 "Captain Helios, I've been rescued from the Amani Catacombs. Reporting for duty, sir!"
-#define CAPTAIN_ANSWER "Liatha, get someone to look at those injuries. Thank you for bringing her back safely."
+#define SAY_START -1000140
+#define SAY_PROGRESS1 -1000141
+#define SAY_PROGRESS2 -1000142
+#define SAY_PROGRESS3 -1000143
+#define SAY_END1 -1000144
+#define SAY_END2 -1000145
+#define SAY_CAPTAIN_ANSWER -1000146
#define QUEST_ESCAPE_FROM_THE_CATACOMBS 9212
#define GO_CAGE 181152
@@ -164,18 +164,18 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
GameObject* Cage = FindGameObject(GO_CAGE);
if(Cage)
Cage->SetGoState(0);
- DoSay(SAY_START, LANG_UNIVERSAL, player);
+ DoScriptText(SAY_START, m_creature, player);
break;
}
case 5:
- DoSay(SAY_PROGRESS1, LANG_UNIVERSAL, player); break;
+ DoScriptText(SAY_PROGRESS1, m_creature, player);
case 11:
- DoSay(SAY_PROGRESS2, LANG_UNIVERSAL, player);
+ DoScriptText(SAY_PROGRESS2, m_creature, player);
m_creature->SetOrientation(4.762841);
break;
case 18:
{
- DoSay(SAY_PROGRESS3, LANG_UNIVERSAL, player);
+ DoScriptText(SAY_PROGRESS3, m_creature, player);
Creature* Summ1 = m_creature->SummonCreature(16342, 7627.083984, -7532.538086, 152.128616, 1.082733, TEMPSUMMON_DEAD_DESPAWN, 0);
Creature* Summ2 = m_creature->SummonCreature(16343, 7620.432129, -7532.550293, 152.454865, 0.827478, TEMPSUMMON_DEAD_DESPAWN, 0);
Summ1->Attack(m_creature, true);
@@ -193,14 +193,14 @@ struct TRINITY_DLL_DECL npc_ranger_lilathaAI : public npc_escortAI
break;
case 32:
m_creature->SetOrientation(2.978281);
- DoSay(SAY_END1, LANG_UNIVERSAL, player);
+ DoScriptText(SAY_END1, m_creature, player);
break;
case 33:
m_creature->SetOrientation(5.858011);
- DoSay(SAY_END2, LANG_UNIVERSAL, player);
+ DoScriptText(SAY_END2, m_creature, player);
Unit* CaptainHelios = FindCreature(NPC_CAPTAIN_HELIOS, 50);
if(CaptainHelios)
- ((Creature*)CaptainHelios)->Say(CAPTAIN_ANSWER, LANG_UNIVERSAL, PlayerGUID);
+ DoScriptText(SAY_CAPTAIN_ANSWER, CaptainHelios, player);
break;
}
}
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index 121a9b0d98d..f7c1fe5090a 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -40,6 +40,8 @@
#include "Util.h"
#include "ArenaTeam.h"
#include "Language.h"
+#include "Chat.h"
+#include "SystemConfig.h"
class LoginQueryHolder : public SqlQueryHolder
{
@@ -571,6 +573,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
Player* pCurrChar = new Player(this);
pCurrChar->GetMotionMaster()->Initialize();
+ // for send server info and strings (config)
+ ChatHandler chH = ChatHandler(pCurrChar);
// "GetAccountId()==db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
if(!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder))
@@ -636,6 +640,12 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
SendPacket( &data );
DEBUG_LOG( "WORLD: Sent motd (SMSG_MOTD)" );
+
+ // send server info
+ if(sWorld.getConfig(CONFIG_ENABLE_SINFO_LOGIN) == 1)
+ chH.PSendSysMessage(_FULLVERSION);
+
+ DEBUG_LOG( "WORLD: Sent server info" );
}
//QueryResult *result = CharacterDatabase.PQuery("SELECT guildid,rank FROM guild_member WHERE guid = '%u'",pCurrChar->GetGUIDLow());
@@ -709,7 +719,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
data << uint32(rEntry->CinematicSequence);
SendPacket( &data );
}
- }
+
+ // send new char string if not empty
+ if (!sWorld.GetNewCharString().empty())
+ chH.PSendSysMessage(sWorld.GetNewCharString().c_str());
+ }
}
if (!pCurrChar->GetMap()->Add(pCurrChar))
diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp
index 9c6c38a6b8b..fedcd982a35 100644
--- a/src/game/Chat.cpp
+++ b/src/game/Chat.cpp
@@ -34,6 +34,7 @@
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
#include "AccountMgr.h"
+#include "TicketMgr.h"
bool ChatHandler::load_command_table = true;
@@ -302,6 +303,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL },
{ "locales_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesQuestCommand, "", NULL },
{ "waypoint_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadWpScriptsCommand, "", NULL },
+ { "tickets", SEC_ADMINISTRATOR, true, &ChatHandler::HandleGMTicketReloadCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
@@ -502,10 +504,25 @@ ChatCommand * ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
+ static ChatCommand ticketCommandTable[] =
+ {
+ { "list", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketListCommand, "", NULL },
+ { "onlinelist", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketListOnlineCommand, "", NULL },
+ { "viewname", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketGetByNameCommand, "", NULL },
+ { "viewid", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketGetByIdCommand, "", NULL },
+ { "close", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketCloseByIdCommand, "", NULL },
+ { "delete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleGMTicketDeleteByIdCommand, "", NULL },
+ { "assign", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketAssignToCommand, "", NULL },
+ { "unassign", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketUnAssignCommand, "", NULL },
+ { "comment", SEC_MODERATOR, false, &ChatHandler::HandleGMTicketCommentCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
static ChatCommand commandTable[] =
{
{ "account", SEC_PLAYER, true, NULL, "", accountCommandTable },
{ "gm", SEC_MODERATOR, true, NULL, "", gmCommandTable },
+ { "ticket", SEC_MODERATOR, true, NULL, "", ticketCommandTable },
{ "npc", SEC_MODERATOR, false, NULL, "", npcCommandTable },
{ "go", SEC_MODERATOR, false, NULL, "", goCommandTable },
{ "learn", SEC_MODERATOR, false, NULL, "", learnCommandTable },
@@ -579,8 +596,6 @@ ChatCommand * ChatHandler::getCommandTable()
{ "additemset", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAddItemSetCommand, "", NULL },
{ "bank", SEC_ADMINISTRATOR, false, &ChatHandler::HandleBankCommand, "", NULL },
{ "wchange", SEC_ADMINISTRATOR, false, &ChatHandler::HandleChangeWeather, "", NULL },
- { "ticket", SEC_GAMEMASTER, true, &ChatHandler::HandleTicketCommand, "", NULL },
- { "delticket", SEC_GAMEMASTER, true, &ChatHandler::HandleDelTicketCommand, "", NULL },
{ "maxskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMaxSkillCommand, "", NULL },
{ "setskill", SEC_ADMINISTRATOR, false, &ChatHandler::HandleSetSkillCommand, "", NULL },
{ "whispers", SEC_MODERATOR, false, &ChatHandler::HandleWhispersCommand, "", NULL },
diff --git a/src/game/Chat.h b/src/game/Chat.h
index 6ecbe9ac186..a3ce666541b 100644
--- a/src/game/Chat.h
+++ b/src/game/Chat.h
@@ -46,7 +46,7 @@ class ChatHandler
public:
explicit ChatHandler(WorldSession* session) : m_session(session) {}
explicit ChatHandler(Player* player) : m_session(player->GetSession()) {}
- ~ChatHandler() {}
+ ~ChatHandler() {}
static void FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker);
@@ -72,6 +72,7 @@ class ChatHandler
int ParseCommands(const char* text);
virtual char const* GetName() const;
+
protected:
explicit ChatHandler() : m_session(NULL) {} // for CLI subclass
@@ -406,8 +407,20 @@ class ChatHandler
bool HandleResetTalentsCommand(const char * args);
bool HandleResetAllCommand(const char * args);
- bool HandleTicketCommand(const char* args);
- bool HandleDelTicketCommand(const char* args);
+
+
+ // GM ticket command handlers
+ bool HandleGMTicketListCommand(const char* args);
+ bool HandleGMTicketListOnlineCommand(const char* args);
+ bool HandleGMTicketGetByIdCommand(const char* args);
+ bool HandleGMTicketGetByNameCommand(const char* args);
+ bool HandleGMTicketCloseByIdCommand(const char* args);
+ bool HandleGMTicketAssignToCommand(const char* args);
+ bool HandleGMTicketUnAssignCommand(const char* args);
+ bool HandleGMTicketCommentCommand(const char* args);
+ bool HandleGMTicketDeleteByIdCommand(const char* args);
+ bool HandleGMTicketReloadCommand(const char*);
+
bool HandleMaxSkillCommand(const char* args);
bool HandleSetSkillCommand(const char* args);
bool HandleListCreatureCommand(const char* args);
@@ -494,7 +507,7 @@ class ChatHandler
void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
private:
WorldSession * m_session; // != NULL for chat command call and NULL for CLI command
-
+
// common global flag
static bool load_command_table;
bool sentErrorMessage;
diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
index 0eefd3a81b4..3752d7db6cc 100644
--- a/src/game/ChatHandler.cpp
+++ b/src/game/ChatHandler.cpp
@@ -583,3 +583,8 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recv_data )
ChatHandler::FillMessageData(&data, this, CHAT_MSG_IGNORED, LANG_UNIVERSAL, NULL, GetPlayer()->GetGUID(), GetPlayer()->GetName(),NULL);
player->GetSession()->SendPacket(&data);
}
+
+void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
+{
+ sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+} \ No newline at end of file
diff --git a/src/game/GMTicketHandler.cpp b/src/game/GMTicketHandler.cpp
deleted file mode 100644
index 448730bd3ea..00000000000
--- a/src/game/GMTicketHandler.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS
- *
- * Copyright (C) 2008 Trinity
- *
- * 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 "Common.h"
-#include "Language.h"
-#include "WorldPacket.h"
-#include "Log.h"
-#include "GMTicketMgr.h"
-#include "ObjectAccessor.h"
-#include "Player.h"
-#include "Chat.h"
-
-void WorldSession::SendGMTicketGetTicket(uint32 status, char const* text)
-{
- int len = text ? strlen(text) : 0;
- WorldPacket data( SMSG_GMTICKET_GETTICKET, (4+len+1+4+2+4+4) );
- data << uint32(status); // standard 0x0A, 0x06 if text present
- if(status == 6)
- {
- data << text; // ticket text
- data << uint8(0x7); // ticket category
- data << float(0); // time from ticket creation?
- data << float(0); // const
- data << float(0); // const
- data << uint8(0); // const
- data << uint8(0); // const
- }
- SendPacket( &data );
-}
-
-void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/ )
-{
- WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
- data << (uint32)time(NULL);
- data << (uint32)0;
- SendPacket( &data );
-
- GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow());
- if(ticket)
- SendGMTicketGetTicket(0x06,ticket->GetText());
- else
- SendGMTicketGetTicket(0x0A,0);
-}
-
-void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data )
-{
- CHECK_PACKET_SIZE(recv_data,1);
-
- std::string ticketText;
- recv_data >> ticketText;
-
- if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
- ticket->SetText(ticketText.c_str());
- else
- sLog.outError("Ticket update: Player %s (GUID: %u) doesn't have active ticket", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
-}
-
-void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/ )
-{
- ticketmgr.Delete(GetPlayer()->GetGUIDLow());
-
- WorldPacket data( SMSG_GMTICKET_DELETETICKET, 4 );
- data << uint32(9);
- SendPacket( &data );
-
- SendGMTicketGetTicket(0x0A, 0);
-}
-
-void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
-{
- CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
-
- uint32 map;
- float x, y, z;
- std::string ticketText = "";
- uint32 unk1, unk2;
-
- recv_data >> map >> x >> y >> z; // last check 2.4.3
- recv_data >> ticketText;
-
- // recheck
- CHECK_PACKET_SIZE(recv_data,4*4+(ticketText.size()+1)+2*4);
-
- recv_data >> unk1 >> unk2;
- // note: the packet might contain more data, but the exact structure of that is unknown
-
- sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
-
- if(ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
- {
- WorldPacket data( SMSG_GMTICKET_CREATE, 4 );
- data << uint32(1);
- SendPacket( &data );
- return;
- }
-
- ticketmgr.Create(_player->GetGUIDLow(), ticketText.c_str());
-
- WorldPacket data( SMSG_QUERY_TIME_RESPONSE, 4+4 );
- data << (uint32)time(NULL);
- data << (uint32)0;
- SendPacket( &data );
-
- data.Initialize( SMSG_GMTICKET_CREATE, 4 );
- data << uint32(2);
- SendPacket( &data );
- DEBUG_LOG("update the ticket\n");
-
- //TODO: Guard player map
- HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers();
- for(HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr)
- {
- if(itr->second->GetSession()->GetSecurity() >= SEC_GAMEMASTER && itr->second->isAcceptTickets())
- ChatHandler(itr->second).PSendSysMessage(LANG_COMMAND_TICKETNEW,GetPlayer()->GetName());
- }
-}
-
-void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/ )
-{
- WorldPacket data( SMSG_GMTICKET_SYSTEMSTATUS,4 );
- data << uint32(1); // we can also disable ticket system by sending 0 value
-
- SendPacket( &data );
-}
-
-void WorldSession::HandleGMSurveySubmit( WorldPacket & recv_data)
-{
- // GM survey is shown after SMSG_GM_TICKET_STATUS_UPDATE with status = 3
- CHECK_PACKET_SIZE(recv_data,4+4);
- uint32 x;
- recv_data >> x; // answer range? (6 = 0-5?)
- sLog.outDebug("SURVEY: X = %u", x);
-
- uint8 result[10];
- memset(result, 0, sizeof(result));
- for( int i = 0; i < 10; ++i)
- {
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+4);
- uint32 questionID;
- recv_data >> questionID; // GMSurveyQuestions.dbc
- if (!questionID)
- break;
-
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1+1);
- uint8 value;
- std::string unk_text;
- recv_data >> value; // answer
- recv_data >> unk_text; // always empty?
-
- result[i] = value;
- sLog.outDebug("SURVEY: ID %u, value %u, text %s", questionID, value, unk_text.c_str());
- }
-
- CHECK_PACKET_SIZE(recv_data,recv_data.rpos()+1);
- std::string comment;
- recv_data >> comment; // addional comment
- sLog.outDebug("SURVEY: comment %s", comment.c_str());
-
- // TODO: chart this data in some way
-}
diff --git a/src/game/GMTicketMgr.cpp b/src/game/GMTicketMgr.cpp
deleted file mode 100644
index a085167a2bc..00000000000
--- a/src/game/GMTicketMgr.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS
- *
- * Copyright (C) 2008 Trinity
- *
- * 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 "Common.h"
-#include "Database/DatabaseEnv.h"
-#include "Database/SQLStorage.h"
-#include "GMTicketMgr.h"
-#include "ObjectMgr.h"
-#include "ProgressBar.h"
-#include "Policies/SingletonImp.h"
-#include "Player.h"
-#include "ObjectDefines.h"
-
-INSTANTIATE_SINGLETON_1(GMTicketMgr);
-
-void GMTicketMgr::LoadGMTickets()
-{
- m_GMTicketMap.clear(); // For reload case
-
- QueryResult *result = CharacterDatabase.Query(
- // 0 1 2
- "SELECT guid, ticket_text,UNIX_TIMESTAMP(ticket_lastchange) FROM character_ticket");
-
- if( !result )
- {
- barGoLink bar( 1 );
-
- bar.step();
-
- sLog.outString();
- sLog.outString(">> Loaded `character_ticket`, table is empty.");
- return;
- }
-
- barGoLink bar( result->GetRowCount() );
-
- uint32 count = 0;
-
- do
- {
- bar.step();
-
- Field* fields = result->Fetch();
-
- uint32 guid = fields[0].GetUInt32();
- m_GMTicketMap[guid] = GMTicket(guid, fields[1].GetCppString(), time_t(fields[2].GetUInt64()));
- ++count;
-
- } while (result->NextRow());
- delete result;
-
- sLog.outString();
- sLog.outString( ">> Loaded %d GM tickets", count );
-}
-
-void GMTicketMgr::DeleteAll()
-{
- for(GMTicketMap::iterator itr = m_GMTicketMap.begin(); itr != m_GMTicketMap.end(); ++itr)
- {
- if(Player* owner = objmgr.GetPlayer(MAKE_NEW_GUID(itr->first,0,HIGHGUID_PLAYER)))
- owner->GetSession()->SendGMTicketGetTicket(0x0A,0);
- }
- CharacterDatabase.PExecute("DELETE FROM character_ticket");
- m_GMTicketMap.clear();
-}
diff --git a/src/game/GMTicketMgr.h b/src/game/GMTicketMgr.h
deleted file mode 100644
index c55804914a3..00000000000
--- a/src/game/GMTicketMgr.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _GMTICKETMGR_H
-#define _GMTICKETMGR_H
-
-#include "Policies/Singleton.h"
-#include "Database/DatabaseEnv.h"
-#include "Util.h"
-#include <map>
-
-class GMTicket
-{
- public:
- explicit GMTicket()
- {
- }
-
- GMTicket(uint32 guid, const std::string& text, time_t update) : m_guid(guid), m_text(text), m_lastUpdate(update)
- {
-
- }
-
- const char* GetText() const
- {
- return m_text.c_str();
- }
-
- uint64 GetLastUpdate() const
- {
- return m_lastUpdate;
- }
-
- void SetText(const char* text)
- {
- m_text = text ? text : "";
- m_lastUpdate = time(NULL);
-
- std::string escapedString = m_text;
- CharacterDatabase.escape_string(escapedString);
- CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", escapedString.c_str(), m_guid);
- }
-
- void DeleteFromDB() const
- {
- CharacterDatabase.PExecute("DELETE FROM character_ticket WHERE guid = '%u' LIMIT 1", m_guid);
- }
-
- void SaveToDB() const
- {
- CharacterDatabase.BeginTransaction();
- DeleteFromDB();
-
- std::string escapedString = m_text;
- CharacterDatabase.escape_string(escapedString);
-
- CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, escapedString.c_str());
- CharacterDatabase.CommitTransaction();
- }
- private:
- uint32 m_guid;
- std::string m_text;
- time_t m_lastUpdate;
-};
-typedef std::map<uint32, GMTicket> GMTicketMap;
-
-class GMTicketMgr
-{
- public:
- GMTicketMgr() { }
- ~GMTicketMgr() { }
-
- void LoadGMTickets();
-
- GMTicket* GetGMTicket(uint32 guid)
- {
- GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
- if(itr == m_GMTicketMap.end())
- return NULL;
- return &(itr->second);
- }
-
- size_t GetTicketCount() const
- {
- return m_GMTicketMap.size();
- }
-
- void Delete(uint32 guid)
- {
- GMTicketMap::iterator itr = m_GMTicketMap.find(guid);
- if(itr == m_GMTicketMap.end())
- return;
- itr->second.DeleteFromDB();
- m_GMTicketMap.erase(itr);
- }
-
- void DeleteAll();
-
- void Create(uint32 guid, const char* text)
- {
- GMTicket t = GMTicket(guid, text, time(NULL));
- t.SaveToDB();
- m_GMTicketMap[guid] = t;
- }
- private:
- GMTicketMap m_GMTicketMap;
-};
-
-#define ticketmgr Trinity::Singleton<GMTicketMgr>::Instance()
-#endif
diff --git a/src/game/GridDefines.h b/src/game/GridDefines.h
index 661dc863d1a..a68ecb4da97 100644
--- a/src/game/GridDefines.h
+++ b/src/game/GridDefines.h
@@ -33,10 +33,6 @@ class GameObject;
class Pet;
class Player;
-//comment the next line if CPU usage is too high
-//uncomment it otherwise
-//#define LARGE_CELL
-
#ifdef LARGE_CELL
#define MAX_NUMBER_OF_CELLS 4
#define CENTER_GRID_CELL_ID 128
diff --git a/src/game/Language.h b/src/game/Language.h
index 06f9d0b1ed1..251ba55174f 100644
--- a/src/game/Language.h
+++ b/src/game/Language.h
@@ -271,15 +271,9 @@ enum TrinityStrings
LANG_COMMAND_WHISPERON = 285,
LANG_COMMAND_WHISPEROFF = 286,
LANG_COMMAND_CREATGUIDNOTFOUND = 287,
- LANG_COMMAND_TICKETCOUNT = 288,
- LANG_COMMAND_TICKETNEW = 289,
- LANG_COMMAND_TICKETVIEW = 290,
- LANG_COMMAND_TICKETON = 291,
- LANG_COMMAND_TICKETOFF = 292,
- LANG_COMMAND_TICKENOTEXIST = 293,
- LANG_COMMAND_ALLTICKETDELETED = 294,
- LANG_COMMAND_TICKETPLAYERDEL = 295,
- LANG_COMMAND_TICKETDEL = 296,
+ // TICKET STRINGS NEED REWRITE // 288-296 FREE
+
+ // END
LANG_COMMAND_SPAWNDIST = 297,
LANG_COMMAND_SPAWNTIME = 298,
LANG_COMMAND_MODIFY_HONOR = 299,
@@ -791,7 +785,25 @@ enum TrinityStrings
LANG_MUST_MALE_OR_FEMALE = 1119,
LANG_YOU_CHANGE_GENDER = 1120,
LANG_YOUR_GENDER_CHANGED = 1121,
- // Room for more level 3 1122-1199 not used
+
+ // Ticket Strings 2000-2020
+ LANG_COMMAND_TICKETNEW = 2000,
+ LANG_COMMAND_TICKETUPDATED = 2001,
+ LANG_COMMAND_TICKETPLAYERABANDON = 2002,
+ LANG_COMMAND_TICKETCLOSED = 2003,
+ LANG_COMMAND_TICKETDELETED = 2004,
+ LANG_COMMAND_TICKETNOTEXIST = 2005,
+ LANG_COMMAND_TICKETCLOSEFIRST = 2007,
+ LANG_COMMAND_TICKETALREADYASSIGNED = 2008,
+ LANG_COMMAND_TICKETRELOAD = 2009,
+ LANG_COMMAND_TICKETSHOWLIST = 2010,
+ LANG_COMMAND_TICKETSHOWONLINELIST = 2011,
+ LANG_COMMAND_TICKETASSIGNERROR_A = 2012,
+ LANG_COMMAND_TICKETASSIGNERROR_B = 2013,
+ LANG_COMMAND_TICKETNOTASSIGNED = 2014,
+ LANG_COMMAND_TICKETUNASSIGNSECURITY = 2015,
+ LANG_COMMAND_TICKETCANNOTCLOSE = 2016,
+
// Trinity strings 5000-9999
LANG_COMMAND_FREEZE = 5000,
diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp
index df96ac08974..be8d4cfb0bf 100644
--- a/src/game/Level1.cpp
+++ b/src/game/Level1.cpp
@@ -34,6 +34,8 @@
#include "CellImpl.h"
#include "InstanceSaveMgr.h"
#include "Util.h"
+#include "TicketMgr.h"
+
#ifdef _DEBUG_VMAPS
#include "VMapFactory.h"
#endif
@@ -268,6 +270,319 @@ bool ChatHandler::HandleGMChatCommand(const char* args)
return false;
}
+bool ChatHandler::HandleGMTicketListCommand(const char* args)
+{
+ SendSysMessage(LANG_COMMAND_TICKETSHOWLIST);
+ for(GmTicketList::iterator itr = ticketmgr.GM_TicketList.begin(); itr != ticketmgr.GM_TicketList.end(); ++itr)
+ {
+ if((*itr)->closed)
+ continue;
+
+ std::stringstream message;
+ message << "|cff00ff00Ticket|r: |cff00ccff" << (*itr)->guid;
+ message << ".|r |cff00ff00created by:|r |cff00ccff" << (*itr)->name;
+ message << ".|r |cff00ff00Last change:|r |cff00ccff " << secsToTimeString(time(NULL) - (*itr)->timestamp, true, false) << " ago.";
+ if((*itr)->assignedToGM != 0 && objmgr.GetPlayer((*itr)->assignedToGM))
+ {
+ std::string gmname = objmgr.GetPlayer((*itr)->assignedToGM)->GetName();
+ message << "|r |cff00ff00Assigned to:|r |cff00ccff " << gmname;
+ }
+ SendGlobalGMSysMessage(message.str().c_str());
+ }
+ return true;
+}
+
+
+bool ChatHandler::HandleGMTicketListOnlineCommand(const char* args)
+{
+ SendSysMessage(LANG_COMMAND_TICKETSHOWONLINELIST);
+ for(GmTicketList::iterator itr = ticketmgr.GM_TicketList.begin(); itr != ticketmgr.GM_TicketList.end(); ++itr)
+ {
+ if((*itr)->closed || !objmgr.GetPlayer((*itr)->playerGuid))
+ continue;
+
+ std::stringstream message;
+ message << "|cff00ff00Ticket|r: |cff00ccff" << (*itr)->guid;
+ message << ".|r |cff00ff00created by:|r |cff00ccff" << (*itr)->name;
+ message << ".|r |cff00ff00Last change:|r |cff00ccff " << secsToTimeString((time(NULL) - (*itr)->timestamp), true, false) << " ago.";
+ if((*itr)->assignedToGM != 0 && objmgr.GetPlayer((*itr)->assignedToGM))
+ {
+ std::string gmname = objmgr.GetPlayer((*itr)->assignedToGM)->GetName();
+ message << "|r |cff00ff00Assigned to:|r |cff00ccff " << gmname;
+ }
+ SendGlobalGMSysMessage(message.str().c_str());
+ }
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketGetByIdCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ uint64 tguid = atoi(args);
+ GM_Ticket *ticket = ticketmgr.GetGMTicket(tguid);
+ if(!ticket)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+
+ std::stringstream message;
+ message << "|cff00ff00Ticket|r: |cff00ccff" << ticket->guid;
+ message << ".|r |cff00ff00created by:|r |cff00ccff" << ticket->name;
+ message << ".|r |cff00ff00Last change:|r |cff00ccff " << secsToTimeString((time(NULL)-ticket->timestamp), true, false) << " ago.";
+ if(ticket->assignedToGM != 0 && objmgr.GetPlayer(ticket->assignedToGM))
+ {
+ std::string gmname = objmgr.GetPlayer(ticket->assignedToGM)->GetName();
+ message << "|r |cff00ff00Assigned to:|r |cff00ccff " << gmname;
+ }
+ message << "|r\n|cff00ff00Message:|r " << ticket->message;
+ if(ticket->comment != "")
+ {
+ message << "|r |cff00ff00Comment:|r |cff00ccff " << ticket->comment;
+ }
+ PSendSysMessage(message.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketGetByNameCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ GM_Ticket *ticket = ticketmgr.GetGMTicketByName(args);
+ if(!ticket)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+
+ std::stringstream message;
+ message << "|cff00ff00Ticket|r: |cff00ccff" << ticket->guid;
+ message << ".|r |cff00ff00created by:|r |cff00ccff" << ticket->name;
+ message << ".|r |cff00ff00Last change:|r |cff00ccff " << secsToTimeString((time(NULL)-ticket->timestamp), true, false) << " ago.";
+ if(ticket->assignedToGM != 0 && objmgr.GetPlayer(ticket->assignedToGM))
+ {
+ std::string gmname = objmgr.GetPlayer(ticket->assignedToGM)->GetName();
+ message << "|r |cff00ff00Assigned to:|r |cff00ccff " << gmname;
+ }
+ message << "|r\n|cff00ff00Message:|r " << ticket->message;
+ if(ticket->comment != "")
+ {
+ message << "|r |cff00ff00Comment:|r |cff00ccff " << ticket->comment;
+ }
+ PSendSysMessage(message.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketCloseByIdCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ uint64 tguid = atoi(args);
+ GM_Ticket *ticket = ticketmgr.GetGMTicket(tguid);
+ if(!ticket || ticket->closed)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ if(ticket && ticket->assignedToGM != m_session->GetPlayer()->GetGUID())
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->guid);
+
+ }
+ sWorld.SendGMText(LANG_COMMAND_TICKETCLOSED, ticket->name, ticket->guid);
+ ticketmgr.RemoveGMTicket(ticket->guid);
+ Player *plr = objmgr.GetPlayer(ticket->playerGuid);
+
+ if(!plr || !plr->IsInWorld())
+ return true;
+
+ // send abandon ticket
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(9);
+ plr->GetSession()->SendPacket( &data );
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketAssignToCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ char* tguid = strtok((char*)args, " ");
+ uint64 ticketGuid = atoi(tguid);
+ char* targetgm = strtok( NULL, " ");
+
+ if(!targetgm)
+ return false;
+
+ std::string targm = targetgm;
+
+ if(!normalizePlayerName(targm))
+ return false;
+
+ Player *cplr = m_session->GetPlayer();
+ std::string gmname;
+ GM_Ticket *ticket = ticketmgr.GetGMTicket(ticketGuid);
+
+ if(!ticket || ticket->closed)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ Player *plr = objmgr.GetPlayer(targm.c_str());
+ if(!plr || !plr->IsInWorld() || plr->GetSession()->GetSecurity() < SEC_MODERATOR)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
+ return true;
+ }
+ if(ticket->assignedToGM == plr->GetGUID())
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->guid);
+ return true;
+ }
+ if(ticket->assignedToGM != 0 && ticket->assignedToGM != cplr->GetGUID())
+ {
+ Player *aplr = objmgr.GetPlayer(ticket->assignedToGM);
+ if(aplr && aplr->IsInWorld())
+ {
+ gmname = aplr->GetName();
+ PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid, gmname.c_str());
+ return true;
+ }
+ }
+
+ ticket->assignedToGM = plr->GetGUID();
+ ticketmgr.UpdateGMTicket(ticket);
+ std::stringstream ss;
+ ss << "|cff00ff00Ticket:|r ";
+ ss << "|cffff00ff" << ticket->guid << ". " << cplr->GetName() << "|r";
+ ss << "|cff00ff00 assigned to:|r ";
+ ss << "|cffff00ff\"" << targetgm << "\".";
+ SendGlobalGMSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketUnAssignCommand(const char* args)
+{
+ if(!*args)
+ return false;
+
+ uint64 ticketGuid = atoi(args);
+ Player *cplr = m_session->GetPlayer();
+ GM_Ticket *ticket = ticketmgr.GetGMTicket(ticketGuid);
+
+ if(!ticket|| ticket->closed)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ if(ticket->assignedToGM = 0)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETNOTASSIGNED);
+ return true;
+ }
+
+ Player *plr = objmgr.GetPlayer(ticket->assignedToGM);
+
+ if(plr && plr->IsInWorld() && plr->GetSession()->GetSecurity() > cplr->GetSession()->GetSecurity())
+ {
+ SendSysMessage(LANG_COMMAND_TICKETUNASSIGNSECURITY);
+ return true;
+ }
+
+ std::stringstream ss;
+ ss << "|cff00ff00Ticket:|r ";
+ ss << "|cffff00ff" << ticket->guid << ". " << cplr->GetName() << "|r";
+ ss << "|cff00ff00 unassigned.|r";
+ SendGlobalGMSysMessage(ss.str().c_str());
+ ticket->assignedToGM = 0;
+ ticketmgr.UpdateGMTicket(ticket);
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketCommentCommand(const char* args)
+{
+ if(!args)
+ return false;
+
+ char* tguid = strtok((char*)args, " ");
+ uint64 ticketGuid = atoi(tguid);
+ char* comment = strtok( NULL, "\n");
+
+ if(!comment)
+ return false;
+
+ std::string gmname;
+ Player *cplr = m_session->GetPlayer();
+ GM_Ticket *ticket = ticketmgr.GetGMTicket(ticketGuid);
+
+ if(!ticket || ticket->closed)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
+ return true;
+ }
+ if(ticket->assignedToGM = 0 && ticket->assignedToGM != cplr->GetGUID())
+ {
+ gmname = objmgr.GetPlayer(ticket->assignedToGM)->GetName();
+ PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid, gmname.c_str());
+ return true;
+ }
+
+ ticket->comment = comment;
+ ticketmgr.UpdateGMTicket(ticket);
+ std::stringstream ss;
+ ss << "|cff00ff00Ticket:|r ";
+ ss << "|cffff00ff" << ticket->guid << ". " << cplr->GetName() << "|r";
+ ss << "|cff00ff00 added comment:|r ";
+ ss << "|cffff00ff\"" << ticket->comment << "\".";
+ SendGlobalGMSysMessage(ss.str().c_str());
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketDeleteByIdCommand(const char* args)
+{
+ if(!*args)
+ return false;
+ uint64 ticketGuid = atoi(args);
+ GM_Ticket *ticket = ticketmgr.GetGMTicket(ticketGuid);
+
+ if(!ticket)
+ {
+ PSendSysMessage(LANG_COMMAND_TICKETNOTEXIST, ticketGuid);
+ return true;
+ }
+ if(!ticket->closed)
+ {
+ SendSysMessage(LANG_COMMAND_TICKETCLOSEFIRST);
+ return true;
+ }
+
+ std::string gmname = m_session->GetPlayer()->GetName();
+ sWorld.SendGMText(LANG_COMMAND_TICKETDELETED, ticket->guid, gmname.c_str());
+ ticketmgr.DeleteGMTicketPermanently(ticket->guid);
+ Player *plr = objmgr.GetPlayer(ticket->playerGuid);
+ if(plr && plr->IsInWorld())
+ {
+ // Force abandon ticket
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(9);
+ plr->GetSession()->SendPacket( &data );
+ }
+
+ ticket = NULL;
+ return true;
+}
+
+bool ChatHandler::HandleGMTicketReloadCommand(const char*)
+{
+ ticketmgr.LoadGMTickets();
+ return true;
+}
+
//Enable\Dissable Invisible mode
bool ChatHandler::HandleVisibleCommand(const char* args)
{
@@ -283,7 +598,7 @@ bool ChatHandler::HandleVisibleCommand(const char* args)
{
m_session->GetPlayer()->SetGMVisible(true);
m_session->SendNotification(LANG_INVISIBLE_VISIBLE);
- return true;
+ return true;
}
if (argstr == "off")
diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp
index 319ae608f7c..afe22846cdd 100644
--- a/src/game/Level2.cpp
+++ b/src/game/Level2.cpp
@@ -36,7 +36,7 @@
#include "GameEvent.h"
#include "SpellMgr.h"
#include "AccountMgr.h"
-#include "GMTicketMgr.h"
+//#include "GMTicketMgr.h"
#include "WaypointManager.h"
#include "Util.h"
#include <cctype>
@@ -1967,7 +1967,7 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
return true;
}
-//show tickets
+/*//show tickets
void ChatHandler::ShowTicket(uint64 guid, char const* text, char const* time)
{
std::string name;
@@ -2148,7 +2148,7 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,px);
return true;
-}
+}*/
//set spawn dist of creature
bool ChatHandler::HandleNpcSpawnDistCommand(const char* args)
diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp
index 0fa8e9573d0..6d78a117e3d 100644
--- a/src/game/Opcodes.cpp
+++ b/src/game/Opcodes.cpp
@@ -547,7 +547,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode },
/*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, &WorldSession::Handle_ServerSide },
- /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateTextOpcode },
+ /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateOpcode },
/*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData },
@@ -1067,7 +1067,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, &WorldSession::Handle_NULL },
- /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, &WorldSession::Handle_NULL },
+ /*0x40F*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_LOGGEDIN, &WorldSession::HandleChannelDeclineInvite },
/*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x411*/ { "CMSG_GROUPACTION_THROTTLED", STATUS_NEVER, &WorldSession::Handle_NULL },
/*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, &WorldSession::Handle_ServerSide },
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 2956a525896..3a42e4ea80b 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -276,9 +276,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)
m_divider = 0;
m_ExtraFlags = 0;
- if(GetSession()->GetSecurity() >= SEC_GAMEMASTER)
- SetAcceptTicket(true);
-
+
// players always accept
if(GetSession()->GetSecurity() == SEC_PLAYER)
SetAcceptWhispers(true);
@@ -14639,17 +14637,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
break;
}
- switch(sWorld.getConfig(CONFIG_GM_ACCEPT_TICKETS))
- {
- default:
- case 0: break; // disable
- case 1: SetAcceptTicket(true); break; // enable
- case 2: // save state
- if(extraflags & PLAYER_EXTRA_GM_ACCEPT_TICKETS)
- SetAcceptTicket(true);
- break;
- }
-
switch(sWorld.getConfig(CONFIG_GM_CHAT))
{
default:
diff --git a/src/game/Player.h b/src/game/Player.h
index 17b4aeb2bb4..88883bfd666 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -535,7 +535,6 @@ enum PlayerExtraFlags
{
// gm abilities
PLAYER_EXTRA_GM_ON = 0x0001,
- PLAYER_EXTRA_GM_ACCEPT_TICKETS = 0x0002,
PLAYER_EXTRA_ACCEPT_WHISPERS = 0x0004,
PLAYER_EXTRA_TAXICHEAT = 0x0008,
PLAYER_EXTRA_GM_INVISIBLE = 0x0010,
@@ -1023,8 +1022,6 @@ class TRINITY_DLL_SPEC Player : public Unit
void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }
bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_id = 0 , Creature* npc = NULL);
// mount_id can be used in scripting calls
- bool isAcceptTickets() const { return GetSession()->GetSecurity() >= SEC_GAMEMASTER && (m_ExtraFlags & PLAYER_EXTRA_GM_ACCEPT_TICKETS); }
- void SetAcceptTicket(bool on) { if(on) m_ExtraFlags |= PLAYER_EXTRA_GM_ACCEPT_TICKETS; else m_ExtraFlags &= ~PLAYER_EXTRA_GM_ACCEPT_TICKETS; }
bool isAcceptWhispers() const { return m_ExtraFlags & PLAYER_EXTRA_ACCEPT_WHISPERS; }
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; }
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index f188ab46465..e31d9f06b07 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1964,6 +1964,11 @@ void Spell::SetTargetMap(uint32 i,uint32 cur,std::list<Unit*> &TagUnitMap)
void Spell::prepare(SpellCastTargets * targets, Aura* triggeredByAura)
{
+ if(m_CastItem)
+ m_castItemGUID = m_CastItem->GetGUID();
+ else
+ m_castItemGUID = 0;
+
m_targets = *targets;
m_spellState = SPELL_STATE_PREPARING;
@@ -3774,14 +3779,15 @@ uint8 Spell::CanCast(bool strict)
if(uint8 castResult = CheckRange(strict))
return castResult;
+ if(!m_IsTriggeredSpell)
{
if(uint8 castResult = CheckPower())
return castResult;
- }
- if(!m_triggeredByAuraSpell) // triggered spell not affected by stun/etc
+ //if(!m_triggeredByAuraSpell) // triggered spell not affected by stun/etc
if(uint8 castResult = CheckCasterAuras())
return castResult;
+ }
for (int i = 0; i < 3; i++)
{
@@ -4663,7 +4669,12 @@ uint8 Spell::CheckItems()
uint32 itemid, itemcount;
Player* p_caster = (Player*)m_caster;
- if(m_CastItem)
+ if(!m_CastItem)
+ {
+ if(m_castItemGUID)
+ return SPELL_FAILED_ITEM_NOT_READY;
+ }
+ else
{
itemid = m_CastItem->GetEntry();
if( !p_caster->HasItemCount(itemid,1) )
@@ -5141,6 +5152,9 @@ void Spell::UpdatePointers()
if(m_originalCaster && !m_originalCaster->IsInWorld()) m_originalCaster = NULL;
}
+ if(m_castItemGUID && m_caster->GetTypeId() == TYPEID_PLAYER)
+ m_CastItem = ((Player*)m_caster)->GetItemByGuid(m_castItemGUID);
+
m_targets.Update(m_caster);
}
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 588d5cf01a8..206145087d1 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -416,6 +416,7 @@ class Spell
SpellEntry const* m_spellInfo;
int32 m_currentBasePoints[3]; // cache SpellEntry::EffectBasePoints and use for set custom base points
Item* m_CastItem;
+ uint64 m_castItemGUID;
uint8 m_cast_count;
uint32 m_glyphIndex;
SpellCastTargets m_targets;
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index fb4ea35f1fc..91b85df1a39 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -672,11 +672,15 @@ void AreaAura::Update(uint32 diff)
if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
{
- int32 actualBasePoints = m_currentBasePoints;
+ //int32 actualBasePoints = m_currentBasePoints;
// recalculate basepoints for lower rank (all AreaAura spell not use custom basepoints?)
- if(actualSpellInfo != GetSpellProto())
- actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
- AreaAura *aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, (*tIter), caster, NULL);
+ //if(actualSpellInfo != GetSpellProto())
+ // actualBasePoints = actualSpellInfo->EffectBasePoints[m_effIndex];
+ AreaAura *aur;
+ if(actualSpellInfo == GetSpellProto())
+ aur = new AreaAura(actualSpellInfo, m_effIndex, &m_modifier.m_amount, (*tIter), caster, NULL);
+ else
+ aur = new AreaAura(actualSpellInfo, m_effIndex, NULL, (*tIter), caster, NULL);
(*tIter)->AddAura(aur);
}
}
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 76687a48711..e10bd98c3c8 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3662,7 +3662,7 @@ void Spell::EffectSummonGuardian(uint32 i)
}
// trigger
- if(m_spellInfo->Id == 40276)
+ if(!m_originalCaster || m_originalCaster->GetTypeId() != TYPEID_PLAYER /*m_spellInfo->Id == 40276*/)
{
EffectSummonWild(i);
return;
@@ -3907,7 +3907,7 @@ void Spell::EffectEnchantItemTmp(uint32 i)
// Shaman Rockbiter Weapon
if(i==0 && m_spellInfo->Effect[1]==SPELL_EFFECT_DUMMY)
{
- int32 enchnting_damage = damage;//+1;
+ int32 enchnting_damage = CalculateDamage(1, NULL);//+1;
// enchanting id selected by calculated damage-per-sec stored in Effect[1] base value
// with already applied percent bonus from Elemental Weapons talent
@@ -4076,6 +4076,12 @@ void Spell::EffectTameCreature(uint32 /*i*/)
void Spell::EffectSummonPet(uint32 i)
{
+ if(!m_originalCaster || m_originalCaster->GetTypeId() != TYPEID_PLAYER)
+ {
+ EffectSummonWild(i);
+ return;
+ }
+
uint32 petentry = m_spellInfo->EffectMiscValue[i];
Pet *OldSummon = m_caster->GetPet();
@@ -5953,6 +5959,7 @@ void Spell::EffectSummonCritter(uint32 i)
// summon new pet
Pet* critter = new Pet(MINI_PET);
+ critter->setActive(m_caster->isActive());
Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber();
diff --git a/src/game/TicketHandler.cpp b/src/game/TicketHandler.cpp
new file mode 100644
index 00000000000..2a0fa4760b6
--- /dev/null
+++ b/src/game/TicketHandler.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS
+ *
+ * Copyright (C) 2008 Trinity
+ *
+ * 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 "Language.h"
+#include "ObjectAccessor.h"
+#include "WorldPacket.h"
+#include "Common.h"
+#include "Log.h"
+#include "ObjectAccessor.h"
+#include "Player.h"
+#include "Chat.h"
+#include "TicketMgr.h"
+#include "World.h"
+#include "Chat.h"
+
+
+void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
+{
+ // always do a packet check
+ CHECK_PACKET_SIZE(recv_data, 4*4+1+2*4);
+
+ uint32 map;
+ float x, y, z;
+ std::string ticketText = "";
+ std::string ticketText2 = "";
+ GM_Ticket *ticket = new GM_Ticket;
+
+ WorldPacket data(SMSG_GMTICKET_CREATE, 4);
+
+ // recv Data
+ recv_data >> map;
+ recv_data >> x;
+ recv_data >> y;
+ recv_data >> z;
+ recv_data >> ticketText;
+
+ // get additional data
+ recv_data >> ticketText2;
+
+ // assign values
+ ticket->name = GetPlayer()->GetName();
+ ticket->guid = ticketmgr.GenerateTicketID();
+ ticket->playerGuid = GetPlayer()->GetGUID();
+ ticket->message = ticketText;
+ ticket->timestamp = time(NULL);
+ ticket->closed = false;
+ ticket->assignedToGM = 0;
+ ticket->comment = "";
+
+ // remove ticket by player, shouldn't happen
+ ticketmgr.RemoveGMTicketByPlayer(GetPlayer()->GetGUID());
+
+ // add ticket
+ ticketmgr.AddGMTicket(ticket, false);
+
+ // Response - no errors
+ data << uint32(2);
+
+ // Send ticket creation
+ SendPacket(&data);
+
+ sWorld.SendGMText(LANG_COMMAND_TICKETNEW, ticket->name.c_str(), ticket->guid);
+
+}
+
+void WorldSession::HandleGMTicketUpdateOpcode( WorldPacket & recv_data)
+{
+ // always do a packet check
+ CHECK_PACKET_SIZE(recv_data,1);
+
+ std::string message = "";
+ time_t t = time(NULL);
+
+ WorldPacket data(SMSG_GMTICKET_UPDATETEXT, 4);
+
+ // recv Data
+ recv_data >> message;
+
+ // Update Ticket
+ GM_Ticket *ticket = ticketmgr.GetGMTicketByPlayer(GetPlayer()->GetGUID());
+
+ // Check if player has a GM Ticket yet
+ if(!ticket)
+ {
+ // Response - error couldnt find existing Ticket
+ data << uint32(1);
+
+ // Send packet
+ SendPacket(&data);
+ return;
+ }
+
+ ticket->message = message;
+ ticket->timestamp = (uint32)t;
+
+ ticketmgr.UpdateGMTicket(ticket);
+
+ // Response - no errors
+ data << uint32(2);
+
+ // Send packet
+ SendPacket(&data);
+
+ sWorld.SendGMText(LANG_COMMAND_TICKETUPDATED, GetPlayer()->GetName(), ticket->guid);
+
+}
+
+void WorldSession::HandleGMTicketDeleteOpcode( WorldPacket & /*recv_data*/)
+{
+ // NO recv_data, NO packet check size
+
+ GM_Ticket* ticket = ticketmgr.GetGMTicketByPlayer(GetPlayer()->GetGUID());
+
+ // Remove Tickets from Player
+ ticketmgr.RemoveGMTicketByPlayer(GetPlayer()->GetGUID());
+
+ // Response - no errors
+ WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
+ data << uint32(9);
+ // Send Packet
+ SendPacket(&data);
+
+ sWorld.SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName(), ticket->guid );
+}
+
+void WorldSession::HandleGMTicketGetTicketOpcode( WorldPacket & /*recv_data*/)
+{
+ // NO recv_data NO packet size check
+
+ WorldPacket data(SMSG_GMTICKET_GETTICKET, 400);
+
+ // get Current Ticket
+ GM_Ticket *ticket = ticketmgr.GetGMTicketByPlayer(GetPlayer()->GetGUID());
+
+ // check for existing ticket
+ if(!ticket)
+ {
+ data << uint32(10);
+ // send packet
+ SendPacket(&data);
+ return;
+ }
+
+ // Send current Ticket
+ data << uint32(6); // unk ?
+ data << ticket->message.c_str();
+
+ SendPacket(&data);
+
+
+}
+
+void WorldSession::HandleGMTicketSystemStatusOpcode( WorldPacket & /*recv_data*/)
+{
+ // NO recv_data NO packet size check
+
+ WorldPacket data(SMSG_GMTICKET_SYSTEMSTATUS, 4);
+
+ // Response - System is working Fine
+
+ // No need for checks, ticket system is active
+ // in case of disactivity, this should be set to (0)
+
+ data << uint32(1);
+
+
+ // Send Packet
+ SendPacket(&data);
+} \ No newline at end of file
diff --git a/src/game/TicketMgr.cpp b/src/game/TicketMgr.cpp
new file mode 100644
index 00000000000..9b5e320f443
--- /dev/null
+++ b/src/game/TicketMgr.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS
+ *
+ * Copyright (C) 2008 Trinity
+ *
+ * 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 "TicketMgr.h"
+#include "Policies/SingletonImp.h"
+#include "World.h"
+#include "ObjectMgr.h"
+#include "Language.h"
+#include "Player.h"
+INSTANTIATE_SINGLETON_1( TicketMgr );
+
+#include "Common.h"
+//#include "Log.h"
+#include "ObjectAccessor.h"
+
+
+
+GM_Ticket* TicketMgr::GetGMTicket(uint64 ticketGuid)
+{
+ for(GmTicketList::iterator i = GM_TicketList.begin(); i != GM_TicketList.end();)
+ {
+ if((*i)->guid == ticketGuid)
+ {
+ return (*i);
+ }
+ ++i;
+ }
+ return NULL;
+}
+
+GM_Ticket* TicketMgr::GetGMTicketByPlayer(uint64 playerGuid)
+{
+ for(GmTicketList::iterator i = GM_TicketList.begin(); i != GM_TicketList.end();)
+ {
+ if((*i)->playerGuid == playerGuid && !(*i)->closed)
+ {
+ return (*i);
+ }
+ ++i;
+ }
+ return NULL;
+}
+
+GM_Ticket* TicketMgr::GetGMTicketByName(const char* name)
+{
+ std::string pname = name;
+ if(!normalizePlayerName(pname))
+ return NULL;
+
+ Player *plr = objmgr.GetPlayer(pname.c_str());
+ if(!plr)
+ return NULL;
+
+ uint64 playerGuid = plr->GetGUID();
+
+ for(GmTicketList::iterator i = GM_TicketList.begin(); i != GM_TicketList.end();)
+ {
+ if((*i)->playerGuid == playerGuid && !(*i)->closed)
+ {
+ return (*i);
+ }
+ ++i;
+ }
+ return NULL;
+}
+
+void TicketMgr::AddGMTicket(GM_Ticket *ticket, bool startup)
+{
+ ASSERT( ticket );
+ GM_TicketList.push_back(ticket);
+
+ // save
+ if(!startup)
+ SaveGMTicket(ticket);
+}
+
+void TicketMgr::DeleteGMTicketPermanently(uint64 ticketGuid)
+{
+ for(GmTicketList::iterator i = GM_TicketList.begin(); i != GM_TicketList.end();)
+ {
+ if((*i)->guid == ticketGuid)
+ {
+ i = GM_TicketList.erase(i);
+ }
+ else
+ {
+ ++i;
+ }
+ }
+
+ // delete database record
+ CharacterDatabase.PExecute("DELETE FROM gm_tickets WHERE guid=%u", ticketGuid);
+}
+
+
+void TicketMgr::LoadGMTickets()
+{
+ // Delete all out of object holder
+ GM_TicketList.clear();
+ QueryResult *result = CharacterDatabase.Query( "SELECT `guid`, `playerGuid`, `name`, `message`, `timestamp`, `closed`, `assignedto`, `comment` FROM gm_tickets WHERE deleted = '0'" );
+ GM_Ticket *ticket;
+
+ //ticket = NULL;
+ if(!result)
+ return;
+
+ do
+ {
+ Field *fields = result->Fetch();
+ ticket = new GM_Ticket;
+ ticket->guid = fields[0].GetUInt64();
+ ticket->playerGuid = fields[1].GetUInt64();
+ ticket->name = fields[2].GetString();
+ ticket->message = fields[3].GetString();
+ ticket->timestamp = fields[4].GetUInt32();
+ ticket->closed = fields[5].GetUInt16();
+ ticket->assignedToGM = fields[6].GetUInt64();
+ ticket->comment = fields[7].GetString();
+
+ AddGMTicket(ticket, true);
+
+ } while( result->NextRow() );
+
+ sWorld.SendGMText(LANG_COMMAND_TICKETRELOAD, result->GetRowCount());
+
+ delete result;
+}
+
+void TicketMgr::RemoveGMTicket(uint64 ticketGuid)
+{
+ for(GmTicketList::iterator i = GM_TicketList.begin(); i != GM_TicketList.end();)
+ {
+ if((*i)->guid == ticketGuid && !(*i)->closed)
+ {
+ (*i)->closed = true;
+ SaveGMTicket((*i));
+ }
+ ++i;
+ }
+}
+
+
+void TicketMgr::RemoveGMTicketByPlayer(uint64 playerGuid)
+{
+ for(GmTicketList::iterator i = GM_TicketList.begin(); i != GM_TicketList.end();)
+ {
+ if((*i)->playerGuid == playerGuid && !(*i)->closed)
+ {
+ (*i)->closed = true;
+ SaveGMTicket((*i));
+ }
+ ++i;
+ }
+}
+
+void TicketMgr::SaveGMTicket(GM_Ticket* ticket)
+{
+ std::stringstream ss;
+ ss << "REPLACE INTO gm_tickets (`guid`, `playerGuid`, `name`, `message`, `timestamp`, `closed`, `assignedto`, `comment`) VALUES(";
+ ss << ticket->guid << ", ";
+ ss << ticket->playerGuid << ", '";
+ ss << ticket->name << "', '";
+ ss << ticket->message << "', " ;
+ ss << ticket->timestamp << ", ";
+ ss << ticket->closed << ", '";
+ ss << ticket->assignedToGM << "', '";
+ ss << ticket->comment << "');";
+
+ CharacterDatabase.BeginTransaction();
+ CharacterDatabase.Execute(ss.str().c_str());
+ CharacterDatabase.CommitTransaction();
+
+}
+
+void TicketMgr::UpdateGMTicket(GM_Ticket *ticket)
+{
+ SaveGMTicket(ticket);
+}
+
+uint64 TicketMgr::GenerateTicketID()
+{
+ QueryResult *result = CharacterDatabase.Query("SELECT MAX(guid) FROM gm_tickets");
+ if(result)
+ {
+ m_ticketid = result->Fetch()[0].GetUInt64() + 1;
+ delete result;
+ }
+
+ return m_ticketid;
+} \ No newline at end of file
diff --git a/src/game/TicketMgr.h b/src/game/TicketMgr.h
new file mode 100644
index 00000000000..0c9f27e1044
--- /dev/null
+++ b/src/game/TicketMgr.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS
+ *
+ * Copyright (C) 2008 Trinity
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _TICKETMGR_H
+#define _TICKETMGR_H
+
+#include "Policies/Singleton.h"
+#include "Database/DatabaseEnv.h"
+#include "Util.h"
+#include "Config/ConfigEnv.h"
+#include <map>
+
+struct GM_Ticket
+{
+ uint64 guid;
+ uint64 playerGuid;
+ std::string name;
+ std::string message;
+ uint64 timestamp;
+ bool closed;
+ uint64 assignedToGM;
+ std::string comment;
+};
+
+enum GMticketType
+{
+ GM_TICKET_TYPE_STUCK = 1,
+ GM_TICKET_TYPE_BEHAVIOR_HARASSMENT = 2,
+ GM_TICKET_TYPE_GUILD = 3,
+ GM_TICKET_TYPE_ITEM = 4,
+ GM_TICKET_TYPE_ENVIRONMENTAL = 5,
+ GM_TICKET_TYPE_NON_QUEST_CREEP = 6,
+ GM_TICKET_TYPE_QUEST_QUEST_NPC = 7,
+ GM_TICKET_TYPE_TECHNICAL = 8,
+ GM_TICKET_TYPE_ACCOUNT_BILLING = 9,
+ GM_TICKET_TYPE_CHARACTER = 10
+};
+
+// Map Typedef
+typedef std::list<GM_Ticket*> GmTicketList;
+
+class TicketMgr
+{
+ public:
+ TicketMgr(){} //constructor
+ ~TicketMgr(){} //destructor
+
+ // Object Holder
+ GmTicketList GM_TicketList;
+
+ void AddGMTicket(GM_Ticket *ticket, bool startup);
+ void DeleteAllRemovedGMTickets();
+ void DeleteGMTicketPermanently(uint64 ticketGuid);
+ void LoadGMTickets();
+ void RemoveGMTicketByPlayer(uint64 playerGuid);
+ void RemoveGMTicket(uint64 ticketGuid);
+ void UpdateGMTicket(GM_Ticket *ticket);
+ void SaveGMTicket(GM_Ticket* ticket);
+
+ uint64 TicketMgr::GenerateTicketID();
+ GM_Ticket* GetGMTicket(uint64 ticketGuid);
+ GM_Ticket* GetGMTicketByPlayer(uint64 playerGuid);
+ GM_Ticket* GetGMTicketByName(const char *name);
+
+
+ protected:
+ uint64 m_ticketid;
+};
+
+#endif
+#define ticketmgr Trinity::Singleton<TicketMgr>::Instance()
+
diff --git a/src/game/World.cpp b/src/game/World.cpp
index fc7f113a3c2..5e7240817ff 100644
--- a/src/game/World.cpp
+++ b/src/game/World.cpp
@@ -59,7 +59,7 @@
#include "CellImpl.h"
#include "InstanceSaveMgr.h"
#include "WaypointManager.h"
-#include "GMTicketMgr.h"
+#include "TicketMgr.h"
#include "Util.h"
#include "Language.h"
#include "CreatureGroups.h"
@@ -407,6 +407,12 @@ void World::LoadConfigSettings(bool reload)
SetPlayerLimit( sConfig.GetIntDefault("PlayerLimit", DEFAULT_PLAYER_LIMIT), true );
SetMotd( sConfig.GetStringDefault("Motd", "Welcome to the Massive Network Game Object Server." ) );
+ ///- Get string for new logins (newly created characters)
+ SetNewCharString(sConfig.GetStringDefault("PlayerStart.String", ""));
+
+ ///- Send server info on login?
+ m_configs[CONFIG_ENABLE_SINFO_LOGIN] = sConfig.GetIntDefault("Server.LoginInfo", 0);
+
///- Read all rates from the config file
rate_values[RATE_HEALTH] = sConfig.GetFloatDefault("Rate.Health", 1);
if(rate_values[RATE_HEALTH] < 0)
@@ -761,14 +767,12 @@ void World::LoadConfigSettings(bool reload)
}
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_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_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1);
if(m_configs[CONFIG_START_GM_LEVEL] < m_configs[CONFIG_START_PLAYER_LEVEL])
{
diff --git a/src/game/World.h b/src/game/World.h
index 89a82545c64..756343064ed 100644
--- a/src/game/World.h
+++ b/src/game/World.h
@@ -124,7 +124,6 @@ enum WorldConfigs
CONFIG_MAX_PRIMARY_TRADE_SKILL,
CONFIG_MIN_PETITION_SIGNS,
CONFIG_GM_LOGIN_STATE,
- CONFIG_GM_ACCEPT_TICKETS,
CONFIG_GM_CHAT,
CONFIG_GM_WISPERING_TO,
CONFIG_GM_IN_GM_LIST,
@@ -204,6 +203,7 @@ enum WorldConfigs
CONFIG_NO_RESET_TALENT_COST,
CONFIG_SHOW_KICK_IN_WORLD,
CONFIG_INTERVAL_LOG_UPDATE,
+ CONFIG_ENABLE_SINFO_LOGIN,
CONFIG_VALUE_COUNT
};
@@ -404,6 +404,11 @@ class World
/// Get the current Message of the Day
const char* GetMotd() const { return m_motd.c_str(); }
+ /// Set the string for new characters (first login)
+ void SetNewCharString(std::string str) { m_newCharString = str; }
+ /// Get the string for new characters (first login)
+ const std::string& GetNewCharString() const { return m_newCharString; }
+
uint32 GetDefaultDbcLocale() const { return m_defaultDbcLocale; }
/// Get the path where data (dbc, maps) are stored on disk
@@ -546,6 +551,8 @@ class World
std::multimap<time_t, ScriptAction> m_scriptSchedule;
+ std::string m_newCharString;
+
float rate_values[MAX_RATES];
uint32 m_configs[CONFIG_VALUE_COUNT];
int32 m_playerLimit;
diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h
index 034036db887..d1f4a877dbb 100644
--- a/src/game/WorldSession.h
+++ b/src/game/WorldSession.h
@@ -285,14 +285,15 @@ class TRINITY_DLL_SPEC WorldSession
void HandleLogoutRequestOpcode(WorldPacket& recvPacket);
void HandlePlayerLogoutOpcode(WorldPacket& recvPacket);
void HandleLogoutCancelOpcode(WorldPacket& recvPacket);
- void HandleGMTicketGetTicketOpcode(WorldPacket& recvPacket);
- void HandleGMTicketCreateOpcode(WorldPacket& recvPacket);
- void HandleGMTicketSystemStatusOpcode(WorldPacket& recvPacket);
- void HandleGMTicketDeleteOpcode(WorldPacket& recvPacket);
- void HandleGMTicketUpdateTextOpcode(WorldPacket& recvPacket);
-
- void HandleGMSurveySubmit(WorldPacket& recvPacket);
+ // GM Ticket opcodes
+ void HandleGMTicketCreateOpcode(WorldPacket& recvPacket);
+ void HandleGMTicketUpdateOpcode(WorldPacket& recvPacket);
+ void HandleGMTicketDeleteOpcode(WorldPacket& recvPacket);
+ void HandleGMTicketGetTicketOpcode(WorldPacket& recvPacket);
+ void HandleGMTicketSystemStatusOpcode(WorldPacket& recvPacket);
+
+ //void HandleGMSurveySubmit(WorldPacket& recvPacket);
void HandleTogglePvP(WorldPacket& recvPacket);
@@ -542,6 +543,7 @@ class TRINITY_DLL_SPEC WorldSession
void HandleChannelRosterQuery(WorldPacket& recvPacket);
void HandleChannelInfoQuery(WorldPacket& recvPacket);
void HandleChannelJoinNotify(WorldPacket& recvPacket);
+ void HandleChannelDeclineInvite(WorldPacket& recvPacket);
void HandleCompleteCinema(WorldPacket& recvPacket);
void HandleNextCinematicCamera(WorldPacket& recvPacket);
diff --git a/src/trinitycore/WorldRunnable.cpp b/src/trinitycore/WorldRunnable.cpp
new file mode 100644
index 00000000000..3edb96c2e8b
--- /dev/null
+++ b/src/trinitycore/WorldRunnable.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * Copyright (C) 2008 Trinity <http://www.trinitycore.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
+ */
+
+/** \file
+ \ingroup Trinityd
+*/
+
+#include "WorldSocketMgr.h"
+#include "Common.h"
+#include "World.h"
+#include "WorldRunnable.h"
+#include "Timer.h"
+#include "ObjectAccessor.h"
+#include "MapManager.h"
+
+#include "Database/DatabaseEnv.h"
+
+#if (defined(SHORT_SLEEP) || defined(WIN32))
+#define WORLD_SLEEP_CONST 50
+#else
+#define WORLD_SLEEP_CONST 100 //Is this still needed?? [On linux some time ago not working 50ms]
+#endif
+
+/// Heartbeat for the World
+void WorldRunnable::run()
+{
+ ///- Init new SQL thread for the world database
+ WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough)
+ sWorld.InitResultQueue();
+
+ uint32 realCurrTime = 0;
+ uint32 realPrevTime = getMSTime();
+
+ uint32 prevSleepTime = 0; // used for balanced full tick time length near WORLD_SLEEP_CONST
+
+ ///- While we have not World::m_stopEvent, update the world
+ while (!World::IsStopped())
+ {
+ ++World::m_worldLoopCounter;
+ realCurrTime = getMSTime();
+
+ uint32 diff = getMSTimeDiff(realPrevTime,realCurrTime);
+
+ sWorld.Update( diff );
+ realPrevTime = realCurrTime;
+
+ // diff (D0) include time of previous sleep (d0) + tick time (t0)
+ // we want that next d1 + t1 == WORLD_SLEEP_CONST
+ // we can't know next t1 and then can use (t0 + d1) == WORLD_SLEEP_CONST requirement
+ // d1 = WORLD_SLEEP_CONST - t0 = WORLD_SLEEP_CONST - (D0 - d0) = WORLD_SLEEP_CONST + d0 - D0
+ if (diff <= WORLD_SLEEP_CONST+prevSleepTime)
+ {
+ prevSleepTime = WORLD_SLEEP_CONST+prevSleepTime-diff;
+ ZThread::Thread::sleep(prevSleepTime);
+ }
+ else
+ prevSleepTime = 0;
+ }
+
+ sWorld.KickAll(); // save and kick all players
+ sWorld.UpdateSessions( 1 ); // real players unload required UpdateSessions call
+
+ sWorldSocketMgr->StopNetwork();
+
+ MapManager::Instance().UnloadAll(); // unload all grids (including locked in memory)
+
+ ///- End the database thread
+ WorldDatabase.ThreadEnd(); // free mySQL thread resources
+}
diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist
index 7855b616082..db4a22fe223 100644
--- a/src/trinitycore/trinitycore.conf.dist
+++ b/src/trinitycore/trinitycore.conf.dist
@@ -572,6 +572,11 @@ LogColors = ""
# Motd
# Message of the Day. Displayed at worldlogin for every user ('@' for a newline).
#
+# Server.LoginInfo
+# Enable/disable sending server info (core version) on login.
+# Default: 0 - disable
+# 1 - enable
+#
###################################################################################################################
GameType = 1
@@ -617,6 +622,7 @@ SkillChance.Prospecting = 0
Event.Announce = 0
BeepAtStart = 1
Motd = "Welcome to a Trinity Core server."
+Server.LoginInfo = 0
###################################################################################################################
# PLAYER INTERACTION
@@ -672,7 +678,7 @@ TalentsInspecting = 1
# ThreatRadius
# Radius for creature to evade after being pulled away from combat start point
# If ThreatRadius is less than creature aggro radius then aggro radius will be used
-# Default: 100 yards
+# Default: 60 yards
#
# Rate.Creature.Aggro
# Aggro radius percent or off.
@@ -703,7 +709,7 @@ TalentsInspecting = 1
#
# Rate.Corpse.Decay.Looted
# Controls how long the creature corpse stays after it had been looted, as a multiplier of its Corpse.Decay.* config.
-# Default: 0.1
+# Default: 0.5
#
# Rate.Creature.Normal.Damage
# Rate.Creature.Elite.Elite.Damage
@@ -743,7 +749,7 @@ TalentsInspecting = 1
#
###################################################################################################################
-ThreatRadius = 100
+ThreatRadius = 60
Rate.Creature.Aggro = 1
CreatureFamilyAssistanceRadius = 10
CreatureFamilyAssistanceDelay = 1500
@@ -753,7 +759,7 @@ Corpse.Decay.RARE = 300
Corpse.Decay.ELITE = 300
Corpse.Decay.RAREELITE = 300
Corpse.Decay.WORLDBOSS = 3600
-Rate.Corpse.Decay.Looted = 0.1
+Rate.Corpse.Decay.Looted = 0.5
Rate.Creature.Normal.Damage = 1
Rate.Creature.Elite.Elite.Damage = 1
Rate.Creature.Elite.RAREELITE.Damage = 1
@@ -824,12 +830,6 @@ Channel.SilentlyGMJoin = 0
# 0 (disable)
# 1 (enable)
#
-# GM.AcceptTickets
-# Is GM accepting tickets from player by default or not.
-# Default: 2 (last save state)
-# 0 (disable)
-# 1 (enable)
-#
# GM.Chat
# GM chat mode at login
# Default: 2 (last save state)
@@ -864,7 +864,6 @@ Channel.SilentlyGMJoin = 0
###################################################################################################################
GM.LoginState = 2
-GM.AcceptTickets = 2
GM.Chat = 2
GM.WhisperingTo = 2
GM.InGMList = 0
@@ -1265,6 +1264,12 @@ Ra.Secure = 1
# Default: 60000 (diff is written into log every 60000 ms or 1 minute.
# >0 = Interval
# 0 = Disable
+#
+# PlayerStart.String
+# If set to anything else than "", this string will be displayed to players when they login
+# to a newly created character.
+# Default: "" - send no text
+#
###################################################################################################################
PlayerStart.AllReputation = 0
@@ -1280,3 +1285,4 @@ PvPToken.ItemCount = 1
NoResetTalentsCost = 0
ShowKickInWorld = 0
RecordUpdateTimeDiffInterval = 60000
+PlayerStart.String = "" \ No newline at end of file
diff --git a/win/VC71/game.vcproj b/win/VC71/game.vcproj
index 83506f0d820..53464487248 100644
--- a/win/VC71/game.vcproj
+++ b/win/VC71/game.vcproj
@@ -264,9 +264,6 @@
RelativePath="..\..\src\game\GameEvent.h">
</File>
<File
- RelativePath="..\..\src\game\GMTicketHandler.cpp">
- </File>
- <File
RelativePath="..\..\src\game\GossipDef.cpp">
</File>
<File
@@ -502,6 +499,9 @@
RelativePath="..\..\src\game\TaxiHandler.cpp">
</File>
<File
+ RelativePath="..\..\src\game\TicketHandler.cpp">
+ </File>
+ <File
RelativePath="..\..\src\game\TradeHandler.cpp">
</File>
<File
@@ -645,12 +645,7 @@
<File
RelativePath="..\..\src\game\GameObject.h">
</File>
- <File
- RelativePath="..\..\src\game\GMTicketMgr.cpp">
- </File>
- <File
- RelativePath="..\..\src\game\GMTicketMgr.h">
- </File>
+
<File
RelativePath="..\..\src\game\GuardAI.cpp">
</File>
@@ -815,6 +810,14 @@
RelativePath="..\..\src\game\TemporarySummon.h">
</File>
<File
+ RelativePath="..\..\src\game\TicketMgr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\game\TicketMgr.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\game\Totem.cpp">
</File>
<File
diff --git a/win/VC80/game.vcproj b/win/VC80/game.vcproj
index 4d6219d1677..010c6dfe43e 100644
--- a/win/VC80/game.vcproj
+++ b/win/VC80/game.vcproj
@@ -523,10 +523,6 @@
>
</File>
<File
- RelativePath="..\..\src\game\GMTicketHandler.cpp"
- >
- </File>
- <File
RelativePath="..\..\src\game\GossipDef.cpp"
>
</File>
@@ -811,6 +807,10 @@
>
</File>
<File
+ RelativePath="..\..\src\game\TicketHandler.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\src\game\TradeHandler.cpp"
>
</File>
@@ -1003,14 +1003,6 @@
>
</File>
<File
- RelativePath="..\..\src\game\GMTicketMgr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\src\game\GMTicketMgr.h"
- >
- </File>
- <File
RelativePath="..\..\src\game\GuardAI.cpp"
>
</File>
@@ -1223,6 +1215,14 @@
>
</File>
<File
+ RelativePath="..\..\src\game\TicketMgr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\game\TicketMgr.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\game\Totem.cpp"
>
</File>
diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj
index 261803e8cb0..2fdbc62f502 100644
--- a/win/VC90/game.vcproj
+++ b/win/VC90/game.vcproj
@@ -525,10 +525,6 @@
>
</File>
<File
- RelativePath="..\..\src\game\GMTicketHandler.cpp"
- >
- </File>
- <File
RelativePath="..\..\src\game\GossipDef.cpp"
>
</File>
@@ -813,6 +809,10 @@
>
</File>
<File
+ RelativePath="..\..\src\game\TicketHandler.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\src\game\TradeHandler.cpp"
>
</File>
@@ -1005,14 +1005,6 @@
>
</File>
<File
- RelativePath="..\..\src\game\GMTicketMgr.cpp"
- >
- </File>
- <File
- RelativePath="..\..\src\game\GMTicketMgr.h"
- >
- </File>
- <File
RelativePath="..\..\src\game\GuardAI.cpp"
>
</File>
@@ -1225,6 +1217,14 @@
>
</File>
<File
+ RelativePath="..\..\src\game\TicketMgr.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\game\TicketMgr.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\game\Totem.cpp"
>
</File>