Merge commit 'origin/master' into 310

Hope it works with live 3.1.2.9901 client
This commit is contained in:
tomrus88 2009-05-20 10:47:48 +04:00
commit ebb03b7b9f
32 changed files with 1709 additions and 2123 deletions

View file

@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` ( CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`required_7830_01_mangos_spell_chain` bit(1) default NULL `required_7855_01_mangos_pools` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -271,9 +271,9 @@ INSERT INTO `command` VALUES
('ban account',3,'Syntax: .ban account $Name $bantime $reason\r\nBan account kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'), ('ban account',3,'Syntax: .ban account $Name $bantime $reason\r\nBan account kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'),
('ban character',3,'Syntax: .ban character $Name $bantime $reason\r\nBan account and kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'), ('ban character',3,'Syntax: .ban character $Name $bantime $reason\r\nBan account and kick player.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'),
('ban ip',3,'Syntax: .ban ip $Ip $bantime $reason\r\nBan IP.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'), ('ban ip',3,'Syntax: .ban ip $Ip $bantime $reason\r\nBan IP.\r\n$bantime: negative value leads to permban, otherwise use a timestring like \"4d20h3s\".'),
('baninfo account',3,'Syntax: .baninfo account\r\nWatch full information about a specific ban.'), ('baninfo account',3,'Syntax: .baninfo account $accountid\r\nWatch full information about a specific ban.'),
('baninfo character',3,'Syntax: .baninfo character\r\nWatch full information about a specific ban.'), ('baninfo character',3,'Syntax: .baninfo character $charactername \r\nWatch full information about a specific ban.'),
('baninfo ip',3,'Syntax: .baninfo ip\r\nWatch full information about a specific ban.'), ('baninfo ip',3,'Syntax: .baninfo ip $ip\r\nWatch full information about a specific ban.'),
('bank',3,'Syntax: .bank\r\n\r\nShow your bank inventory.'), ('bank',3,'Syntax: .bank\r\n\r\nShow your bank inventory.'),
('banlist account',3,'Syntax: .banlist account [$Name]\r\nSearches the banlist for a account name pattern or show full list account bans.'), ('banlist account',3,'Syntax: .banlist account [$Name]\r\nSearches the banlist for a account name pattern or show full list account bans.'),
('banlist character',3,'Syntax: .banlist character $Name\r\nSearches the banlist for a character name pattern. Pattern required.'), ('banlist character',3,'Syntax: .banlist character $Name\r\nSearches the banlist for a character name pattern. Pattern required.'),
@ -287,6 +287,7 @@ INSERT INTO `command` VALUES
('character delete',4,'Syntax: .character delete $name\r\n\r\nDelete character $name.'), ('character delete',4,'Syntax: .character delete $name\r\n\r\nDelete character $name.'),
('character level',3,'Syntax: .character level [$playername] [#level]\r\n\r\nSet the level of character with $playername (or the selected if not name provided) by #numberoflevels Or +1 if no #numberoflevels provided). If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected and name not provided, increase your level. Command can be used for offline character. All stats and dependent values recalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.'), ('character level',3,'Syntax: .character level [$playername] [#level]\r\n\r\nSet the level of character with $playername (or the selected if not name provided) by #numberoflevels Or +1 if no #numberoflevels provided). If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected and name not provided, increase your level. Command can be used for offline character. All stats and dependent values recalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.'),
('character rename',2,'Syntax: .character rename [$name]\r\n\r\nMark selected in game or by $name in command character for rename at next login.'), ('character rename',2,'Syntax: .character rename [$name]\r\n\r\nMark selected in game or by $name in command character for rename at next login.'),
('character reputation',2,'Syntax: .character reputation [$player_name]\r\n\r\nShow reputation information for selected player or player find by $player_name.'),
('combatstop',2,'Syntax: .combatstop [$playername]\r\nStop combat for selected character. If selected non-player then command applied to self. If $playername provided then attempt applied to online player $playername.'), ('combatstop',2,'Syntax: .combatstop [$playername]\r\nStop combat for selected character. If selected non-player then command applied to self. If $playername provided then attempt applied to online player $playername.'),
('commands',0,'Syntax: .commands\r\n\r\nDisplay a list of available commands for your account level.'), ('commands',0,'Syntax: .commands\r\n\r\nDisplay a list of available commands for your account level.'),
('cooldown',3,'Syntax: .cooldown [#spell_id]\r\n\r\nRemove all (if spell_id not provided) or #spel_id spell cooldown from selected character or you (if no selection).'), ('cooldown',3,'Syntax: .cooldown [#spell_id]\r\n\r\nRemove all (if spell_id not provided) or #spel_id spell cooldown from selected character or you (if no selection).'),
@ -335,15 +336,15 @@ INSERT INTO `command` VALUES
('gobject setphase',2,'Syntax: .gobject setphase #guid #phasemask\r\n\r\nGameobject with DB guid #guid phasemask changed to #phasemask with related world vision update for players. Gameobject state saved to DB and persistent.'), ('gobject setphase',2,'Syntax: .gobject setphase #guid #phasemask\r\n\r\nGameobject with DB guid #guid phasemask changed to #phasemask with related world vision update for players. Gameobject state saved to DB and persistent.'),
('gobject turn',2,'Syntax: .gobject turn #goguid \r\n\r\nSet for gameobject #goguid orientation same as current character orientation.'), ('gobject turn',2,'Syntax: .gobject turn #goguid \r\n\r\nSet for gameobject #goguid orientation same as current character orientation.'),
('gobject target',2,'Syntax: .gobject target [#go_id|#go_name_part]\r\n\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'), ('gobject target',2,'Syntax: .gobject target [#go_id|#go_name_part]\r\n\r\nLocate and show position nearest gameobject. If #go_id or #go_name_part provide then locate and show position of nearest gameobject with gameobject template id #go_id or name included #go_name_part as part.'),
('goname',1,'Syntax: .goname $charactername\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group.'), ('goname',1,'Syntax: .goname [$charactername]\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group. Character can be offline.'),
('gps',1,'Syntax: .gps [$name|$shift-link]\r\n\r\nDisplay the position information for a selected character or creature (also if player name $name provided then for named player, or if creature/gameobject shift-link provided then pointed creature/gameobject if it loaded). Position information includes X, Y, Z, and orientation, map Id and zone Id'), ('gps',1,'Syntax: .gps [$name|$shift-link]\r\n\r\nDisplay the position information for a selected character or creature (also if player name $name provided then for named player, or if creature/gameobject shift-link provided then pointed creature/gameobject if it loaded). Position information includes X, Y, Z, and orientation, map Id and zone Id'),
('groupgo',1,'Syntax: .groupgo $charactername\r\n\r\nTeleport the given character and his group to you.'), ('groupgo',1,'Syntax: .groupgo [$charactername]\r\n\r\nTeleport the given character and his group to you. Teleported only online characters but original selected group member can be offline.'),
('guid',2,'Syntax: .guid\r\n\r\nDisplay the GUID for the selected character.'), ('guid',2,'Syntax: .guid\r\n\r\nDisplay the GUID for the selected character.'),
('guild create',2,'Syntax: .guild create $GuildLeaderName $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName as leader.'), ('guild create',2,'Syntax: .guild create [$GuildLeaderName] $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName (or selected) as leader.'),
('guild delete',2,'Syntax: .guild delete $GuildName\r\n\r\nDelete guild $GuildName.'), ('guild delete',2,'Syntax: .guild delete $GuildName\r\n\r\nDelete guild $GuildName.'),
('guild invite',2,'Syntax: .guild invite $CharacterName $GuildName\r\n\r\nAdd $CharacterName into a guild $GuildName.'), ('guild invite',2,'Syntax: .guild invite [$CharacterName] $GuildName\r\n\r\nAdd player $CharacterName (or selected) into a guild $GuildName.'),
('guild rank',2,'Syntax: .guild rank $CharacterName #Rank\r\n\r\nSet for $CharacterName rank #Rank in a guild.'), ('guild rank',2,'Syntax: .guild rank $CharacterName #Rank\r\n\r\nSet for $CharacterName rank #Rank in a guild.'),
('guild uninvite',2,'Syntax: .guild uninvite $CharacterName\r\n\r\nRemove $CharacterName from a guild.'), ('guild uninvite',2,'Syntax: .guild uninvite [$CharacterName]\r\n\r\nRemove player $CharacterName (or selected) from a guild.'),
('help',0,'Syntax: .help [$command]\r\n\r\nDisplay usage instructions for the given $command. If no $command provided show list available commands.'), ('help',0,'Syntax: .help [$command]\r\n\r\nDisplay usage instructions for the given $command. If no $command provided show list available commands.'),
('hidearea',3,'Syntax: .hidearea #areaid\r\n\r\nHide the area of #areaid to the selected character. If no character is selected, hide this area to you.'), ('hidearea',3,'Syntax: .hidearea #areaid\r\n\r\nHide the area of #areaid to the selected character. If no character is selected, hide this area to you.'),
('honor add',2,'Syntax: .honor add $amount\r\n\r\nAdd a certain amount of honor (gained today) to the selected player.'), ('honor add',2,'Syntax: .honor add $amount\r\n\r\nAdd a certain amount of honor (gained today) to the selected player.'),
@ -414,8 +415,8 @@ INSERT INTO `command` VALUES
('modify swim',1,'Syntax: .modify swim #rate\r\n\r\nModify the swim speed of the selected player to \"normal swim speed\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'), ('modify swim',1,'Syntax: .modify swim #rate\r\n\r\nModify the swim speed of the selected player to \"normal swim speed\"*rate. If no player is selected, modify your speed.\r\n\r\n #rate may range from 0.1 to 10.'),
('modify titles',1,'Syntax: .modify titles #mask\r\n\r\nAllows user to use all titles from #mask.\r\n\r\n #mask=0 disables the title-choose-field'), ('modify titles',1,'Syntax: .modify titles #mask\r\n\r\nAllows user to use all titles from #mask.\r\n\r\n #mask=0 disables the title-choose-field'),
('movegens',3,'Syntax: .movegens\r\n Show movement generators stack for selected creature or player.'), ('movegens',3,'Syntax: .movegens\r\n Show movement generators stack for selected creature or player.'),
('mute',1,'Syntax: .mute $playerName $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName at $timeInMinutes minutes.'), ('mute',1,'Syntax: .mute [$playerName] $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName (or currently selected) at $timeInMinutes minutes. Player can be offline.'),
('namego',1,'Syntax: .namego $charactername\r\n\r\nTeleport the given character to you.'), ('namego',1,'Syntax: .namego [$charactername]\r\n\r\nTeleport the given character to you. Character can be offline.'),
('neargrave',3,'Syntax: .neargrave [alliance|horde]\r\n\r\nFind nearest graveyard linked to zone (or only nearest from accepts alliance or horde faction ghosts).'), ('neargrave',3,'Syntax: .neargrave [alliance|horde]\r\n\r\nFind nearest graveyard linked to zone (or only nearest from accepts alliance or horde faction ghosts).'),
('notify',1,'Syntax: .notify $MessageToBroadcast\r\n\r\nSend a global message to all players online in screen.'), ('notify',1,'Syntax: .notify $MessageToBroadcast\r\n\r\nSend a global message to all players online in screen.'),
('npc add',2,'Syntax: .npc add #creatureid\r\n\r\nSpawn a creature by the given template id of #creatureid.'), ('npc add',2,'Syntax: .npc add #creatureid\r\n\r\nSpawn a creature by the given template id of #creatureid.'),
@ -446,7 +447,7 @@ INSERT INTO `command` VALUES
('npc unfollow',2,'Syntax: .npc unfollow\r\n\r\nSelected creature (non pet) stop follow you.'), ('npc unfollow',2,'Syntax: .npc unfollow\r\n\r\nSelected creature (non pet) stop follow you.'),
('pdump write',3,'Syntax: .pdump write $filename $playerNameOrGUID\r\nWrite character dump with name/guid $playerNameOrGUID to file $filename.'), ('pdump write',3,'Syntax: .pdump write $filename $playerNameOrGUID\r\nWrite character dump with name/guid $playerNameOrGUID to file $filename.'),
('pdump load',3,'Syntax: .pdump load $filename $account [$newname] [$newguid]\r\nLoad character dump from dump file into character list of $account with saved or $newname, with saved (or first free) or $newguid guid.'), ('pdump load',3,'Syntax: .pdump load $filename $account [$newname] [$newguid]\r\nLoad character dump from dump file into character list of $account with saved or $newname, with saved (or first free) or $newguid guid.'),
('pinfo',2,'Syntax: .pinfo [$player_name] [rep]\r\n\r\nOutput account information for selected player or player find by $player_name. If \"rep\" parameter provided show reputation information for player.'), ('pinfo',2,'Syntax: .pinfo [$player_name]\r\n\r\nOutput account information for selected player or player find by $player_name.'),
('quest add',3,'Syntax: .quest add #quest_id\r\n\r\nAdd to character quest log quest #quest_id. Quest started from item can\'t be added by this command but correct .additem call provided in command output.'), ('quest add',3,'Syntax: .quest add #quest_id\r\n\r\nAdd to character quest log quest #quest_id. Quest started from item can\'t be added by this command but correct .additem call provided in command output.'),
('quest complete',3,'Syntax: .quest complete #questid\r\nMark all quest objectives as completed for target character active quest. After this target character can go and get quest reward.'), ('quest complete',3,'Syntax: .quest complete #questid\r\nMark all quest objectives as completed for target character active quest. After this target character can go and get quest reward.'),
('quest remove',3,'Syntax: .quest remove #quest_id\r\n\r\nSet quest #quest_id state to not completed and not active (and remove from active quest list) for selected player.'), ('quest remove',3,'Syntax: .quest remove #quest_id\r\n\r\nSet quest #quest_id state to not completed and not active (and remove from active quest list) for selected player.'),
@ -497,7 +498,7 @@ INSERT INTO `command` VALUES
('tele add',3,'Syntax: .tele add $name\r\n\r\nAdd current your position to .tele command target locations list with name $name.'), ('tele add',3,'Syntax: .tele add $name\r\n\r\nAdd current your position to .tele command target locations list with name $name.'),
('tele del',3,'Syntax: .tele del $name\r\n\r\nRemove location with name $name for .tele command locations list.'), ('tele del',3,'Syntax: .tele del $name\r\n\r\nRemove location with name $name for .tele command locations list.'),
('tele group',1,'Syntax: .tele group#location\r\n\r\nTeleport a selected player and his group members to a given location.'), ('tele group',1,'Syntax: .tele group#location\r\n\r\nTeleport a selected player and his group members to a given location.'),
('tele name',1,'Syntax: .tele name #playername #location\r\n\r\nTeleport a player to a given location.'), ('tele name',1,'Syntax: .tele name [#playername] #location\r\n\r\nTeleport the given character to a given location. Character can be offline.'),
('ticket',2,'Syntax: .ticket on\r\n .ticket off\r\n .ticket #num\r\n .ticket $character_name\r\n\r\non/off for GMs to show or not a new ticket directly, $character_name to show ticket of this character, #num to show ticket #num.'), ('ticket',2,'Syntax: .ticket on\r\n .ticket off\r\n .ticket #num\r\n .ticket $character_name\r\n\r\non/off for GMs to show or not a new ticket directly, $character_name to show ticket of this character, #num to show ticket #num.'),
('unaura',3,'Syntax: .unaura #spellid\r\n\r\nRemove aura due to spell #spellid from the selected Unit.'), ('unaura',3,'Syntax: .unaura #spellid\r\n\r\nRemove aura due to spell #spellid from the selected Unit.'),
('unban account',3,'Syntax: .unban account $Name\r\nUnban accounts for account name pattern.'), ('unban account',3,'Syntax: .unban account $Name\r\nUnban accounts for account name pattern.'),
@ -2540,6 +2541,7 @@ INSERT INTO `mangos_string` VALUES
(168,'Locations found are:\n %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (168,'Locations found are:\n %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(169,'Mail sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (169,'Mail sent to %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(170,'You try to hear sound %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (170,'You try to hear sound %u but it doesn\'t exist.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(171,'You can\'t teleport self to self!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(172,'server console command',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (172,'server console command',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(173,'You changed runic power of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (173,'You changed runic power of %s to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(174,'%s changed your runic power to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (174,'%s changed your runic power to %i/%i.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
@ -2627,7 +2629,6 @@ INSERT INTO `mangos_string` VALUES
(280,'Vendor has too many items (max 128)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (280,'Vendor has too many items (max 128)',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(281,'You can\'t kick self, logout instead',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (281,'You can\'t kick self, logout instead',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(282,'Player %s kicked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (282,'Player %s kicked.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(283,'Player %s not found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(284,'Accepting Whisper: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (284,'Accepting Whisper: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(285,'Accepting Whisper: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (285,'Accepting Whisper: ON',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(286,'Accepting Whisper: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (286,'Accepting Whisper: OFF',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
@ -12959,6 +12960,7 @@ CREATE TABLE `pool_creature` (
`guid` int(10) unsigned NOT NULL default '0', `guid` int(10) unsigned NOT NULL default '0',
`pool_entry` mediumint(8) unsigned NOT NULL default '0', `pool_entry` mediumint(8) unsigned NOT NULL default '0',
`chance` float unsigned NOT NULL default '0', `chance` float unsigned NOT NULL default '0',
`description` varchar(255) NOT NULL,
PRIMARY KEY (`pool_entry`,`guid`) PRIMARY KEY (`pool_entry`,`guid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@ -12981,6 +12983,7 @@ CREATE TABLE `pool_gameobject` (
`guid` int(10) unsigned NOT NULL default '0', `guid` int(10) unsigned NOT NULL default '0',
`pool_entry` mediumint(8) unsigned NOT NULL default '0', `pool_entry` mediumint(8) unsigned NOT NULL default '0',
`chance` float unsigned NOT NULL default '0', `chance` float unsigned NOT NULL default '0',
`description` varchar(255) NOT NULL,
PRIMARY KEY (`guid`,`pool_entry`) PRIMARY KEY (`guid`,`pool_entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@ -13002,6 +13005,7 @@ CREATE TABLE `pool_pool` (
`pool_id` mediumint(8) unsigned NOT NULL default '0', `pool_id` mediumint(8) unsigned NOT NULL default '0',
`mother_pool` mediumint(8) unsigned NOT NULL default '0', `mother_pool` mediumint(8) unsigned NOT NULL default '0',
`chance` float NOT NULL default '0', `chance` float NOT NULL default '0',
`description` varchar(255) NOT NULL,
PRIMARY KEY (`pool_id`,`mother_pool`) PRIMARY KEY (`pool_id`,`mother_pool`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@ -13022,6 +13026,7 @@ DROP TABLE IF EXISTS `pool_template`;
CREATE TABLE `pool_template` ( CREATE TABLE `pool_template` (
`entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Pool entry', `entry` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Pool entry',
`max_limit` int(10) unsigned NOT NULL default '0' COMMENT 'Max number of objects (0) is no limit', `max_limit` int(10) unsigned NOT NULL default '0' COMMENT 'Max number of objects (0) is no limit',
`description` varchar(255) NOT NULL,
PRIMARY KEY (`entry`) PRIMARY KEY (`entry`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

View file

@ -0,0 +1,6 @@
ALTER TABLE db_version CHANGE COLUMN required_7830_01_mangos_spell_chain required_7839_01_mangos_mangos_string bit;
DELETE FROM mangos_string WHERE entry IN(171,283);
INSERT INTO mangos_string VALUES
(171,'You can\'t teleport self to self!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

View file

@ -0,0 +1,22 @@
ALTER TABLE db_version CHANGE COLUMN required_7839_01_mangos_mangos_string required_7839_02_mangos_command bit;
DELETE FROM `command` WHERE `name` IN (
'baninfo account','baninfo character','baninfo ip','goname','groupgo',
'guild create','guild invite','guild rank','guild uninvite','mute',
'namego','tele name','unmute'
);
INSERT INTO `command` VALUES
('baninfo account',3,'Syntax: .baninfo account $accountid\r\nWatch full information about a specific ban.'),
('baninfo character',3,'Syntax: .baninfo character $charactername \r\nWatch full information about a specific ban.'),
('baninfo ip',3,'Syntax: .baninfo ip $ip\r\nWatch full information about a specific ban.'),
('goname',1,'Syntax: .goname [$charactername]\r\n\r\nTeleport to the given character. Either specify the character name or click on the character\'s portrait, e.g. when you are in a group. Character can be offline.'),
('groupgo',1,'Syntax: .groupgo [$charactername]\r\n\r\nTeleport the given character and his group to you. Teleported only online characters but original selected group member can be offline.'),
('guild create',2,'Syntax: .guild create [$GuildLeaderName] $GuildName\r\n\r\nCreate a guild named $GuildName with the player $GuildLeaderName (or selected) as leader.'),
('guild invite',2,'Syntax: .guild invite [$CharacterName] $GuildName\r\n\r\nAdd player $CharacterName (or selected) into a guild $GuildName.'),
('guild rank',2,'Syntax: .guild rank [$CharacterName] #Rank\r\n\r\nSet for player $CharacterName (or selected) rank #Rank in a guild.'),
('guild uninvite',2,'Syntax: .guild uninvite [$CharacterName]\r\n\r\nRemove player $CharacterName (or selected) from a guild.'),
('mute',1,'Syntax: .mute [$playerName] $timeInMinutes\r\n\r\nDisible chat messaging for any character from account of character $playerName (or currently selected) at $timeInMinutes minutes. Player can be offline.'),
('namego',1,'Syntax: .namego [$charactername]\r\n\r\nTeleport the given character to you. Character can be offline.'),
('tele name',1,'Syntax: .tele name [#playername] #location\r\n\r\nTeleport the given character to a given location. Character can be offline.'),
('unmute',1,'Syntax: .unmute [$playerName]\r\n\r\nRestore chat messaging for any character from account of character $playerName (or selected). Character can be ofline.');

View file

@ -0,0 +1,7 @@
ALTER TABLE db_version CHANGE COLUMN required_7839_02_mangos_command required_7850_01_mangos_command bit;
DELETE FROM `command` WHERE `name` IN ('character reputation','pinfo');
INSERT INTO `command` VALUES
('pinfo',2,'Syntax: .pinfo [$player_name]\r\n\r\nOutput account information for selected player or player find by $player_name.'),
('character reputation',2,'Syntax: .character reputation [$player_name]\r\n\r\nShow reputation information for selected player or player find by $player_name.');

View file

@ -0,0 +1,13 @@
ALTER TABLE db_version CHANGE COLUMN required_7850_01_mangos_command required_7855_01_mangos_pools bit;
ALTER TABLE pool_creature
ADD COLUMN description varchar(255) NOT NULL AFTER chance;
ALTER TABLE pool_gameobject
ADD COLUMN description varchar(255) NOT NULL AFTER chance;
ALTER TABLE pool_pool
ADD COLUMN description varchar(255) NOT NULL AFTER chance;
ALTER TABLE pool_template
ADD COLUMN description varchar(255) NOT NULL AFTER max_limit;

View file

@ -186,6 +186,10 @@ pkgdata_DATA = \
7802_02_characters_character_achievement_progress.sql \ 7802_02_characters_character_achievement_progress.sql \
7823_01_mangos_item_template.sql \ 7823_01_mangos_item_template.sql \
7830_01_mangos_spell_chain.sql \ 7830_01_mangos_spell_chain.sql \
7839_01_mangos_mangos_string.sql \
7839_02_mangos_command.sql \
7850_01_mangos_command.sql \
7855_01_mangos_pools.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -352,4 +356,8 @@ EXTRA_DIST = \
7802_02_characters_character_achievement_progress.sql \ 7802_02_characters_character_achievement_progress.sql \
7823_01_mangos_item_template.sql \ 7823_01_mangos_item_template.sql \
7830_01_mangos_spell_chain.sql \ 7830_01_mangos_spell_chain.sql \
7839_01_mangos_mangos_string.sql \
7839_02_mangos_command.sql \
7850_01_mangos_command.sql \
7855_01_mangos_pools.sql \
README README

View file

@ -159,8 +159,8 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ )
// ------- Query Without Declined Names -------- // ------- Query Without Declined Names --------
// 0 1 2 3 4 5 6 7 8 // 0 1 2 3 4 5 6 7 8
"SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
// 9 10 11 12 13 // 9 10 11 12 13 14
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid " "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid "
"FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' " "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid " "LEFT JOIN guild_member ON characters.guid = guild_member.guid "
"WHERE characters.account = '%u' ORDER BY characters.guid" "WHERE characters.account = '%u' ORDER BY characters.guid"
@ -168,8 +168,8 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ )
// --------- Query With Declined Names --------- // --------- Query With Declined Names ---------
// 0 1 2 3 4 5 6 7 8 // 0 1 2 3 4 5 6 7 8
"SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, "
// 9 10 11 12 13 14 // 9 10 11 12 13 14 15
"characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive " "characters.at_login, characters.zone, character_pet.entry, character_pet.modelid, character_pet.level, guild_member.guildid, character_declinedname.genitive "
"FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='%u' "
"LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid "
"LEFT JOIN guild_member ON characters.guid = guild_member.guid " "LEFT JOIN guild_member ON characters.guid = guild_member.guid "

View file

@ -114,6 +114,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL }, { "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
{ "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterLevelCommand, "", NULL }, { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterLevelCommand, "", NULL },
{ "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterRenameCommand, "", NULL }, { "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterRenameCommand, "", NULL },
{ "reputation", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterReputationCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL } { NULL, 0, false, NULL, "", NULL }
}; };
@ -375,28 +376,32 @@ ChatCommand * ChatHandler::getCommandTable()
{ "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL }, { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllCommand, "", NULL },
{ "all_achievement",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAchievementCommand,"", NULL }, { "all_achievement",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAchievementCommand,"", NULL },
{ "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL }, { "all_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllAreaCommand, "", NULL },
{ "all_eventai", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllEventAICommand, "", NULL },
{ "all_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllItemCommand, "", NULL },
{ "all_locales", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL },
{ "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL }, { "all_loot", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLootCommand, "", NULL },
{ "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL }, { "all_npc", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllNpcCommand, "", NULL },
{ "all_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllQuestCommand, "", NULL }, { "all_quest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllQuestCommand, "", NULL },
{ "all_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL }, { "all_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllScriptsCommand, "", NULL },
{ "all_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllSpellCommand, "", NULL }, { "all_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllSpellCommand, "", NULL },
{ "all_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllItemCommand, "", NULL },
{ "all_locales", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAllLocalesCommand, "", NULL },
{ "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL }, { "config", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConfigCommand, "", NULL },
{ "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL }, { "achievement_criteria_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementCriteriaDataCommand, "", NULL },
{ "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL }, { "achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAchievementRewardCommand, "", NULL },
{ "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL },
{ "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL }, { "areatrigger_tavern", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTavernCommand, "", NULL },
{ "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL }, { "areatrigger_teleport", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAreaTriggerTeleportCommand, "", NULL },
{ "areatrigger_involvedrelation",SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestAreaTriggersCommand, "", NULL },
{ "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
{ "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL }, { "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL },
{ "creature_ai_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAIScriptsCommand, "", NULL },
{ "creature_ai_summons", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAISummonsCommand, "", NULL },
{ "creature_ai_texts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAITextsCommand, "", NULL },
{ "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL }, { "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL },
{ "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL }, { "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL },
{ "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, { "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL },
{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL }, { "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL },
{ "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL }, { "disenchant_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesDisenchantCommand, "", NULL },
{ "event_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventScriptsCommand, "", NULL },
{ "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL }, { "fishing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesFishingCommand, "", NULL },
{ "game_graveyard_zone", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL }, { "game_graveyard_zone", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameGraveyardZoneCommand, "", NULL },
{ "game_tele", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameTeleCommand, "", NULL }, { "game_tele", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameTeleCommand, "", NULL },
@ -418,15 +423,15 @@ ChatCommand * ChatHandler::getCommandTable()
{ "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL }, { "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, { "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
{ "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL }, { "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
{ "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL},
{ "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, { "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
{ "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL }, { "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL },
{ "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL }, { "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL },
{ "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL}, { "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesPickpocketingCommand,"",NULL},
{ "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL}, { "points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPointsOfInterestCommand, "",NULL},
{ "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL},
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL }, { "prospecting_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesProspectingCommand,"", NULL },
{ "quest_mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL },
{ "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL }, { "quest_end_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestEndScriptsCommand, "", NULL },
{ "quest_mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesQuestMailCommand, "", NULL },
{ "quest_start_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL }, { "quest_start_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestStartScriptsCommand, "", NULL },
{ "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL }, { "quest_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadQuestTemplateCommand, "", NULL },
{ "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL }, { "reference_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesReferenceCommand, "", NULL },
@ -437,13 +442,13 @@ ChatCommand * ChatHandler::getCommandTable()
{ "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL }, { "skinning_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSkinningCommand, "", NULL },
{ "spell_affect", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL }, { "spell_affect", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAffectCommand, "", NULL },
{ "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", NULL }, { "spell_area", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellAreaCommand, "", NULL },
{ "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
{ "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", NULL }, { "spell_chain", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellChainCommand, "", NULL },
{ "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, { "spell_elixir", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL },
{ "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL }, { "spell_learn_spell", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },
{ "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL }, { "spell_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesSpellCommand, "", NULL },
{ "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, { "spell_pet_auras", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL },
{ "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, { "spell_proc_event", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL },
{ "spell_bonus_data", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellBonusesCommand, "", NULL },
{ "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, { "spell_script_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL },
{ "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL }, { "spell_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },
{ "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL }, { "spell_target_position", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellTargetPositionCommand, "", NULL },
@ -454,13 +459,13 @@ ChatCommand * ChatHandler::getCommandTable()
static ChatCommand resetCommandTable[] = static ChatCommand resetCommandTable[] =
{ {
{ "achievements", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetAchievementsCommand, "", NULL }, { "achievements", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAchievementsCommand, "", NULL },
{ "honor", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetHonorCommand, "", NULL }, { "honor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetHonorCommand, "", NULL },
{ "level", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetLevelCommand, "", NULL }, { "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetLevelCommand, "", NULL },
{ "spells", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetSpellsCommand, "", NULL }, { "spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetSpellsCommand, "", NULL },
{ "stats", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetStatsCommand, "", NULL }, { "stats", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetStatsCommand, "", NULL },
{ "talents", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetTalentsCommand, "", NULL }, { "talents", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetTalentsCommand, "", NULL },
{ "all", SEC_ADMINISTRATOR, false, &ChatHandler::HandleResetAllCommand, "", NULL }, { "all", SEC_ADMINISTRATOR, true, &ChatHandler::HandleResetAllCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL } { NULL, 0, false, NULL, "", NULL }
}; };
@ -573,7 +578,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable }, { "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable },
{ "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable }, { "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable },
{ "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable }, { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
{ "reset", SEC_ADMINISTRATOR, false, NULL, "", resetCommandTable }, { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable },
{ "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable }, { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable },
{ "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable }, { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
@ -633,7 +638,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL }, { "damage", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDamageCommand, "", NULL },
{ "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL }, { "combatstop", SEC_GAMEMASTER, false, &ChatHandler::HandleCombatStopCommand, "", NULL },
{ "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL }, { "flusharenapoints",SEC_ADMINISTRATOR, false, &ChatHandler::HandleFlushArenaPointsCommand, "", NULL },
{ "repairitems", SEC_GAMEMASTER, false, &ChatHandler::HandleRepairitemsCommand, "", NULL }, { "repairitems", SEC_GAMEMASTER, true, &ChatHandler::HandleRepairitemsCommand, "", NULL },
{ "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL }, { "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL } { NULL, 0, false, NULL, "", NULL }
@ -1220,7 +1225,7 @@ char* ChatHandler::extractKeyFromLink(char* text, char const* linkType, char** s
*something1 = strtok(NULL, ":|"); // extract something *something1 = strtok(NULL, ":|"); // extract something
strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces strtok(cKeysTail, "]"); // restart scan tail and skip name with possible spaces
strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after retturn from function strtok(NULL, " "); // skip link tail (to allow continue strtok(NULL,s) use after return from function
return cKey; return cKey;
} }
@ -1498,12 +1503,93 @@ std::string ChatHandler::extractPlayerNameFromLink(char* text)
return name; return name;
} }
bool ChatHandler::extractPlayerTarget(char* args, Player** player, uint64* player_guid /*=NULL*/,std::string* player_name /*= NULL*/)
{
if (args && *args)
{
std::string name = extractPlayerNameFromLink(args);
if (name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
Player* pl = objmgr.GetPlayer(name.c_str());
// if allowed player pointer
if(player)
*player = pl;
// if need guid value from DB (in name case for check player existence)
uint64 guid = !pl && (player_guid || player_name) ? objmgr.GetPlayerGUIDByName(name) : 0;
// if allowed player guid (if no then only online players allowed)
if(player_guid)
*player_guid = pl ? pl->GetGUID() : guid;
if(player_name)
*player_name = pl || guid ? name : "";
}
else
{
Player* pl = getSelectedPlayer();
// if allowed player pointer
if(player)
*player = pl;
// if allowed player guid (if no then only online players allowed)
if(player_guid)
*player_guid = pl ? pl->GetGUID() : 0;
if(player_name)
*player_name = pl ? pl->GetName() : "";
}
// some from req. data must be provided (note: name is empty if player not exist)
if((!player || !*player) && (!player_guid || !*player_guid) && (!player_name || player_name->empty()))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
return true;
}
void ChatHandler::extractOptFirstArg(char* args, char** arg1, char** arg2)
{
char* p1 = strtok(args, " ");
char* p2 = strtok(NULL, " ");
if(!p2)
{
p2 = p1;
p1 = NULL;
}
if(arg1)
*arg1 = p1;
if(arg2)
*arg2 = p2;
}
bool ChatHandler::needReportToTarget(Player* chr) const bool ChatHandler::needReportToTarget(Player* chr) const
{ {
Player* pl = m_session->GetPlayer(); Player* pl = m_session->GetPlayer();
return pl != chr && pl->IsVisibleGloballyFor(chr); return pl != chr && pl->IsVisibleGloballyFor(chr);
} }
LocaleConstant ChatHandler::GetSessionDbcLocale() const
{
return m_session->GetSessionDbcLocale();
}
int ChatHandler::GetSessionDbLocaleIndex() const
{
return m_session->GetSessionDbLocaleIndex();
}
const char *CliHandler::GetMangosString(int32 entry) const const char *CliHandler::GetMangosString(int32 entry) const
{ {
return objmgr.GetMangosStringForDBCLocale(entry); return objmgr.GetMangosStringForDBCLocale(entry);
@ -1531,3 +1617,12 @@ bool CliHandler::needReportToTarget(Player* /*chr*/) const
return true; return true;
} }
LocaleConstant CliHandler::GetSessionDbcLocale() const
{
return sWorld.GetDefaultDbcLocale();
}
int CliHandler::GetSessionDbLocaleIndex() const
{
return objmgr.GetDBCLocaleIndex();
}

View file

@ -60,9 +60,10 @@ class ChatHandler
static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; } static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
// function with different implementation for chat/console
virtual const char *GetMangosString(int32 entry) const; virtual const char *GetMangosString(int32 entry) const;
virtual void SendSysMessage( const char *str); virtual void SendSysMessage( const char *str);
void SendSysMessage( int32 entry); void SendSysMessage( int32 entry);
void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3); void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3);
void PSendSysMessage( int32 entry, ... ); void PSendSysMessage( int32 entry, ... );
@ -73,8 +74,13 @@ class ChatHandler
bool hasStringAbbr(const char* name, const char* part); bool hasStringAbbr(const char* name, const char* part);
// function with different implementation for chat/console
virtual bool isAvailable(ChatCommand const& cmd) const; virtual bool isAvailable(ChatCommand const& cmd) const;
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
virtual bool needReportToTarget(Player* chr) const; virtual bool needReportToTarget(Player* chr) const;
virtual LocaleConstant GetSessionDbcLocale() const;
virtual int GetSessionDbLocaleIndex() const;
bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false); bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false);
bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false); bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);
@ -115,8 +121,9 @@ class ChatHandler
bool HandleCharacterCustomizeCommand(const char * args); bool HandleCharacterCustomizeCommand(const char * args);
bool HandleCharacterDeleteCommand(const char* args); bool HandleCharacterDeleteCommand(const char* args);
bool HandleCharacterRenameCommand(const char * args);
bool HandleCharacterLevelCommand(const char* args); bool HandleCharacterLevelCommand(const char* args);
bool HandleCharacterRenameCommand(const char * args);
bool HandleCharacterReputationCommand(const char* args);
bool HandleDebugAnimCommand(const char* args); bool HandleDebugAnimCommand(const char* args);
bool HandleDebugArenaCommand(const char * args); bool HandleDebugArenaCommand(const char * args);
@ -300,6 +307,7 @@ class ChatHandler
bool HandleReloadAllNpcCommand(const char* args); bool HandleReloadAllNpcCommand(const char* args);
bool HandleReloadAllQuestCommand(const char* args); bool HandleReloadAllQuestCommand(const char* args);
bool HandleReloadAllScriptsCommand(const char* args); bool HandleReloadAllScriptsCommand(const char* args);
bool HandleReloadAllEventAICommand(const char* args);
bool HandleReloadAllSpellCommand(const char* args); bool HandleReloadAllSpellCommand(const char* args);
bool HandleReloadAllLocalesCommand(const char* args); bool HandleReloadAllLocalesCommand(const char* args);
@ -310,6 +318,9 @@ class ChatHandler
bool HandleReloadAreaTriggerTavernCommand(const char* args); bool HandleReloadAreaTriggerTavernCommand(const char* args);
bool HandleReloadAreaTriggerTeleportCommand(const char* args); bool HandleReloadAreaTriggerTeleportCommand(const char* args);
bool HandleReloadEventScriptsCommand(const char* args); bool HandleReloadEventScriptsCommand(const char* args);
bool HandleReloadEventAITextsCommand(const char* args);
bool HandleReloadEventAISummonsCommand(const char* args);
bool HandleReloadEventAIScriptsCommand(const char* args);
bool HandleReloadCommandCommand(const char* args); bool HandleReloadCommandCommand(const char* args);
bool HandleReloadCreatureQuestRelationsCommand(const char* args); bool HandleReloadCreatureQuestRelationsCommand(const char* args);
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args); bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
@ -484,13 +495,17 @@ class ChatHandler
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL); char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL); char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
// if args have single value then it return in arg2 and arg1 == NULL
void extractOptFirstArg(char* args, char** arg1, char** arg2);
uint32 extractSpellIdFromLink(char* text); uint32 extractSpellIdFromLink(char* text);
uint64 extractGuidFromLink(char* text); uint64 extractGuidFromLink(char* text);
GameTele const* extractGameTeleFromLink(char* text); GameTele const* extractGameTeleFromLink(char* text);
std::string extractPlayerNameFromLink(char* text); std::string extractPlayerNameFromLink(char* text);
// select by arg (name/link) or in-game selection online/offline player
bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = NULL);
std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; } std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:"+name+"|h["+name+"]|h|r" : name; }
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); } std::string GetNameLink(Player* chr) const { return playerLink(chr->GetName()); }
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry); GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
@ -525,6 +540,8 @@ class CliHandler : public ChatHandler
void SendSysMessage(const char *str); void SendSysMessage(const char *str);
std::string GetNameLink() const; std::string GetNameLink() const;
bool needReportToTarget(Player* chr) const; bool needReportToTarget(Player* chr) const;
LocaleConstant GetSessionDbcLocale() const;
int GetSessionDbLocaleIndex() const;
private: private:
Print* m_print; Print* m_print;

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,7 @@ class WorldObject;
#define EVENT_UPDATE_TIME 500 #define EVENT_UPDATE_TIME 500
#define SPELL_RUN_AWAY 8225 #define SPELL_RUN_AWAY 8225
#define MAX_ACTIONS 3 #define MAX_ACTIONS 3
#define MAX_PHASE 32
enum EventAI_Type enum EventAI_Type
{ {
@ -43,7 +44,7 @@ enum EventAI_Type
EVENT_T_EVADE = 7, // NONE EVENT_T_EVADE = 7, // NONE
EVENT_T_SPELLHIT = 8, // SpellID, School, RepeatMin, RepeatMax EVENT_T_SPELLHIT = 8, // SpellID, School, RepeatMin, RepeatMax
EVENT_T_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax EVENT_T_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax
EVENT_T_OOC_LOS = 10, // NoHostile, NoFriendly, RepeatMin, RepeatMax EVENT_T_OOC_LOS = 10, // NoHostile, MaxRnage, RepeatMin, RepeatMax
EVENT_T_SPAWNED = 11, // NONE EVENT_T_SPAWNED = 11, // NONE
EVENT_T_TARGET_HP = 12, // HPMax%, HPMin%, RepeatMin, RepeatMax EVENT_T_TARGET_HP = 12, // HPMax%, HPMin%, RepeatMin, RepeatMax
EVENT_T_TARGET_CASTING = 13, // RepeatMin, RepeatMax EVENT_T_TARGET_CASTING = 13, // RepeatMin, RepeatMax
@ -78,7 +79,7 @@ enum EventAI_ActionType
ACTION_T_THREAT_SINGLE_PCT = 13, //*Threat%, Target ACTION_T_THREAT_SINGLE_PCT = 13, //*Threat%, Target
ACTION_T_THREAT_ALL_PCT = 14, //Threat% ACTION_T_THREAT_ALL_PCT = 14, //Threat%
ACTION_T_QUEST_EVENT = 15, //*QuestID, Target ACTION_T_QUEST_EVENT = 15, //*QuestID, Target
ACTION_T_CASTCREATUREGO = 16, //*QuestID, SpellId, Target ACTION_T_CAST_EVENT = 16, //*QuestID, SpellId, Target - must be removed as hack?
ACTION_T_SET_UNIT_FIELD = 17, //*Field_Number, Value, Target ACTION_T_SET_UNIT_FIELD = 17, //*Field_Number, Value, Target
ACTION_T_SET_UNIT_FLAG = 18, //*Flags (may be more than one field OR'd together), Target ACTION_T_SET_UNIT_FLAG = 18, //*Flags (may be more than one field OR'd together), Target
ACTION_T_REMOVE_UNIT_FLAG = 19, //*Flags (may be more than one field OR'd together), Target ACTION_T_REMOVE_UNIT_FLAG = 19, //*Flags (may be more than one field OR'd together), Target
@ -89,7 +90,7 @@ enum EventAI_ActionType
ACTION_T_EVADE = 24, //No Params ACTION_T_EVADE = 24, //No Params
ACTION_T_FLEE = 25, //No Params ACTION_T_FLEE = 25, //No Params
ACTION_T_QUEST_EVENT_ALL = 26, //*QuestID ACTION_T_QUEST_EVENT_ALL = 26, //*QuestID
ACTION_T_CASTCREATUREGO_ALL = 27, //*QuestId, SpellId ACTION_T_CAST_EVENT_ALL = 27, //*QuestId, SpellId
ACTION_T_REMOVEAURASFROMSPELL = 28, //*Target, Spellid ACTION_T_REMOVEAURASFROMSPELL = 28, //*Target, Spellid
ACTION_T_RANGED_MOVEMENT = 29, //Distance, Angle ACTION_T_RANGED_MOVEMENT = 29, //Distance, Angle
ACTION_T_RANDOM_PHASE = 30, //PhaseId1, PhaseId2, PhaseId3 ACTION_T_RANDOM_PHASE = 30, //PhaseId1, PhaseId2, PhaseId3
@ -165,6 +166,202 @@ struct StringTextData
// Text Maps // Text Maps
typedef UNORDERED_MAP<int32, StringTextData> CreatureEventAI_TextMap; typedef UNORDERED_MAP<int32, StringTextData> CreatureEventAI_TextMap;
struct CreatureEventAI_Action
{
EventAI_ActionType type: 16;
union
{
// ACTION_T_TEXT = 1
struct
{
int32 TextId1;
int32 TextId2;
int32 TextId3;
} text;
// ACTION_T_SET_FACTION = 2
struct
{
uint32 factionId; // faction or 0 for default)
} set_faction;
// ACTION_T_MORPH_TO_ENTRY_OR_MODEL = 3
struct
{
uint32 creatireId; // set one from fields (or 0 for both to demorph)
uint32 modelId;
} morph;
// ACTION_T_SOUND = 4
struct
{
uint32 soundId;
} sound;
// ACTION_T_EMOTE = 5
struct
{
uint32 emoteId;
} emote;
// ACTION_T_RANDOM_SOUND = 9
struct
{
int32 soundId1; // (-1 in any field means no output if randomed that field)
int32 soundId2;
int32 soundId3;
} random_sound;
// ACTION_T_RANDOM_EMOTE = 10
struct
{
int32 emoteId1; // (-1 in any field means no output if randomed that field)
int32 emoteId2;
int32 emoteId3;
} random_emote;
// ACTION_T_CAST = 11
struct
{
uint32 spellId;
uint32 target;
uint32 castFlags;
} cast;
// ACTION_T_SUMMON = 12
struct
{
uint32 creatured;
uint32 target;
uint32 duration;
} summon;
// ACTION_T_THREAT_SINGLE_PCT = 13
struct
{
int32 percent;
uint32 target;
} threat_single_pct;
// ACTION_T_THREAT_ALL_PCT = 14
struct
{
int32 percent;
} threat_all_pct;
// ACTION_T_QUEST_EVENT = 15
struct
{
uint32 questId;
uint32 target;
} quest_event;
// ACTION_T_CAST_EVENT = 16
struct
{
uint32 creatureId;
uint32 spellId;
uint32 target;
} cast_event;
// ACTION_T_SET_UNIT_FIELD = 17
struct
{
uint32 field;
uint32 value;
uint32 target;
} set_unit_field;
// ACTION_T_SET_UNIT_FLAG = 18, // value provided mask bits that will be set
// ACTION_T_REMOVE_UNIT_FLAG = 19, // value provided mask bits that will be clear
struct
{
uint32 value;
uint32 target;
} unit_flag;
// ACTION_T_AUTO_ATTACK = 20
struct
{
uint32 state; // 0 = stop attack, anything else means continue attacking
} auto_attack;
// ACTION_T_COMBAT_MOVEMENT = 21
struct
{
uint32 state; // 0 = stop combat based movement, anything else continue attacking
} combat_movement;
// ACTION_T_SET_PHASE = 22
struct
{
uint32 phase;
} set_phase;
// ACTION_T_INC_PHASE = 23
struct
{
int32 step;
} set_inc_phase;
// ACTION_T_QUEST_EVENT_ALL = 26
struct
{
uint32 questId;
} quest_event_all;
// ACTION_T_CAST_EVENT_ALL = 27
struct
{
uint32 creatureId;
uint32 spellId;
} cast_event_all;
// ACTION_T_REMOVEAURASFROMSPELL = 28
struct
{
uint32 target;
uint32 spellId;
} remove_aura;
// ACTION_T_RANGED_MOVEMENT = 29
struct
{
uint32 distance;
int32 angle;
} ranged_movement;
// ACTION_T_RANDOM_PHASE = 30
struct
{
uint32 phase1;
uint32 phase2;
uint32 phase3;
} random_phase;
// ACTION_T_RANDOM_PHASE_RANGE = 31
struct
{
uint32 phaseMin;
uint32 phaseMax;
} random_phase_range;
// ACTION_T_SUMMON_ID = 32
struct
{
uint32 creatureId;
uint32 target;
uint32 spawnId;
} summon_id;
// ACTION_T_KILLED_MONSTER = 33
struct
{
uint32 creatureId;
uint32 target;
} killed_monster;
// ACTION_T_SET_INST_DATA = 34
struct
{
uint32 field;
uint32 value;
} set_inst_data;
// ACTION_T_SET_INST_DATA64 = 35
struct
{
uint32 field;
uint32 target;
} set_inst_data64;
// ACTION_T_UPDATE_TEMPLATE = 36, //*Entry, Team
struct
{
uint32 creatureId;
uint32 team;
} update_template;
// RAW
struct
{
uint32 param1;
uint32 param2;
uint32 param3;
} raw;
};
};
struct CreatureEventAI_Event struct CreatureEventAI_Event
{ {
uint32 event_id; uint32 event_id;
@ -179,44 +376,119 @@ struct CreatureEventAI_Event
union union
{ {
uint32 event_param1; // EVENT_T_TIMER = 0
int32 event_param1_s; // EVENT_T_TIMER_OOC = 1
}; struct
union
{ {
uint32 event_param2; uint32 initialMin;
int32 event_param2_s; uint32 initialMax;
}; uint32 repeatMin;
union uint32 repeatMax;
} timer;
// EVENT_T_HP = 2
// EVENT_T_MANA = 3
// EVENT_T_TARGET_HP = 12
// EVENT_T_TARGET_MANA = 18
struct
{ {
uint32 event_param3; uint32 percentMax;
int32 event_param3_s; uint32 percentMin;
}; uint32 repeatMin;
union uint32 repeatMax;
} percent_range;
// EVENT_T_KILL = 5
struct
{ {
uint32 event_param4; uint32 repeatMin;
int32 event_param4_s; uint32 repeatMax;
}; } kill;
// EVENT_T_SPELLHIT = 8
struct
{
uint32 spellId;
uint32 schoolMask; // -1 (==0xffffffff) is ok value for full mask, or must be more limited mask like (0 < 1) = 1 for normal/physical school
uint32 repeatMin;
uint32 repeatMax;
} spell_hit;
// EVENT_T_RANGE = 9
struct
{
uint32 minDist;
uint32 maxDist;
uint32 repeatMin;
uint32 repeatMax;
} range;
// EVENT_T_OOC_LOS = 10
struct
{
uint32 noHostile;
uint32 maxRange;
uint32 repeatMin;
uint32 repeatMax;
} ooc_los;
// EVENT_T_TARGET_CASTING = 13
struct
{
uint32 repeatMin;
uint32 repeatMax;
} target_casting;
// EVENT_T_FRIENDLY_HP = 14
struct
{
uint32 hpDeficit;
uint32 radius;
uint32 repeatMin;
uint32 repeatMax;
} friendly_hp;
// EVENT_T_FRIENDLY_IS_CC = 15
struct
{
uint32 dispelType; // unused ?
uint32 radius;
uint32 repeatMin;
uint32 repeatMax;
} friendly_is_cc;
// EVENT_T_FRIENDLY_MISSING_BUFF = 16
struct
{
uint32 spellId;
uint32 radius;
uint32 repeatMin;
uint32 repeatMax;
} friendly_buff;
// EVENT_T_SUMMONED_UNIT = 17
struct
{
uint32 creatureId;
uint32 repeatMin;
uint32 repeatMax;
} summon_unit;
// EVENT_T_QUEST_ACCEPT = 19
// EVENT_T_QUEST_COMPLETE = 20
struct
{
uint32 questId;
} quest;
// EVENT_T_RECEIVE_EMOTE = 22
struct
{
uint32 emoteId;
uint32 condition;
uint32 conditionValue1;
uint32 conditionValue2;
} receive_emote;
struct _action // RAW
{ struct
EventAI_ActionType type: 16;
union
{ {
uint32 param1; uint32 param1;
int32 param1_s;
};
union
{
uint32 param2; uint32 param2;
int32 param2_s;
};
union
{
uint32 param3; uint32 param3;
int32 param3_s; uint32 param4;
} raw;
}; };
}action[MAX_ACTIONS];
CreatureEventAI_Action action[MAX_ACTIONS];
}; };
//Event_Map //Event_Map
typedef UNORDERED_MAP<uint32, std::vector<CreatureEventAI_Event> > CreatureEventAI_Event_Map; typedef UNORDERED_MAP<uint32, std::vector<CreatureEventAI_Event> > CreatureEventAI_Event_Map;
@ -242,6 +514,9 @@ struct CreatureEventAIHolder
CreatureEventAI_Event Event; CreatureEventAI_Event Event;
uint32 Time; uint32 Time;
bool Enabled; bool Enabled;
// helper
bool UpdateRepeatTimer(Creature* creature, uint32 repeatMin, uint32 repeatMax);
}; };
class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
@ -270,8 +545,9 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
static int Permissible(const Creature *); static int Permissible(const Creature *);
bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL); bool ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pActionInvoker = NULL);
void ProcessAction(uint16 type, uint32 param1, uint32 param2, uint32 param3, uint32 rnd, uint32 EventId, Unit* pActionInvoker); void ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker);
inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3); inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3);
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker); inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker);
inline Unit* SelectUnit(AttackingTarget target, uint32 position); inline Unit* SelectUnit(AttackingTarget target, uint32 position);

View file

@ -205,10 +205,10 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
temp.event_inverse_phase_mask = fields[3].GetUInt32(); temp.event_inverse_phase_mask = fields[3].GetUInt32();
temp.event_chance = fields[4].GetUInt8(); temp.event_chance = fields[4].GetUInt8();
temp.event_flags = fields[5].GetUInt8(); temp.event_flags = fields[5].GetUInt8();
temp.event_param1 = fields[6].GetUInt32(); temp.raw.param1 = fields[6].GetUInt32();
temp.event_param2 = fields[7].GetUInt32(); temp.raw.param2 = fields[7].GetUInt32();
temp.event_param3 = fields[8].GetUInt32(); temp.raw.param3 = fields[8].GetUInt32();
temp.event_param4 = fields[9].GetUInt32(); temp.raw.param4 = fields[9].GetUInt32();
//Creature does not exist in database //Creature does not exist in database
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id)) if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.creature_id))
@ -232,87 +232,97 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
{ {
case EVENT_T_TIMER: case EVENT_T_TIMER:
case EVENT_T_TIMER_OOC: case EVENT_T_TIMER_OOC:
{ if (temp.timer.initialMax < temp.timer.initialMin)
if (temp.event_param2 < temp.event_param1)
sLog.outErrorDb("CreatureEventAI: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);
if (temp.timer.repeatMax < temp.timer.repeatMin)
if (temp.event_param4 < temp.event_param3)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break; break;
}
case EVENT_T_HP: case EVENT_T_HP:
case EVENT_T_MANA: case EVENT_T_MANA:
case EVENT_T_TARGET_HP: case EVENT_T_TARGET_HP:
{ case EVENT_T_TARGET_MANA:
if (temp.event_param2 > 100) if (temp.percent_range.percentMax > 100)
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i);
if (temp.event_param1 <= temp.event_param2) if (temp.percent_range.percentMax <= temp.percent_range.percentMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i);
if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4) if (temp.event_flags & EFLAG_REPEATABLE && !temp.percent_range.repeatMin && !temp.percent_range.repeatMax)
{ {
sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i);
temp.event_flags &= ~EFLAG_REPEATABLE; temp.event_flags &= ~EFLAG_REPEATABLE;
} }
break; break;
}
case EVENT_T_SPELLHIT: case EVENT_T_SPELLHIT:
if (temp.spell_hit.spellId)
{ {
if (temp.event_param1) SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId);
{
SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.event_param1);
if (!pSpell) if (!pSpell)
{ {
sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i); sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
continue; continue;
} }
if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask) if ((temp.spell_hit.schoolMask & pSpell->SchoolMask) != pSpell->SchoolMask)
sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i); sLog.outErrorDb("CreatureEventAI: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.spell_hit.schoolMask, i);
} }
//TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0 if (!temp.spell_hit.schoolMask)
//SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit() sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.spell_hit.schoolMask, i);
if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL)
sLog.outErrorDb("CreatureEventAI: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i);
if (temp.event_param4 < temp.event_param3) if (temp.spell_hit.repeatMax < temp.spell_hit.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break; break;
}
case EVENT_T_RANGE: case EVENT_T_RANGE:
if (temp.range.maxDist < temp.range.minDist)
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (MaxDist < MinDist). Event will never repeat.", temp.creature_id, i);
if (temp.range.repeatMax < temp.range.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
case EVENT_T_OOC_LOS: case EVENT_T_OOC_LOS:
if (temp.ooc_los.repeatMax < temp.ooc_los.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
case EVENT_T_FRIENDLY_HP: case EVENT_T_FRIENDLY_HP:
if (temp.friendly_hp.repeatMax < temp.friendly_hp.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
case EVENT_T_FRIENDLY_IS_CC: case EVENT_T_FRIENDLY_IS_CC:
if (temp.friendly_is_cc.repeatMax < temp.friendly_is_cc.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
case EVENT_T_FRIENDLY_MISSING_BUFF: case EVENT_T_FRIENDLY_MISSING_BUFF:
{ {
//Disabled check for now. Check code related to events and adjust accordingly before enable. SpellEntry const* pSpell = sSpellStore.LookupEntry(temp.spell_hit.spellId);
//Events should have min/max or alternative set to a static value. if (!pSpell)
/*if (!temp.event_param3 && !temp.event_param4)
{ {
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) without param3/param4 (RepeatMin/RepeatMax). Using minimum values.", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.spell_hit.spellId, i);
temp.event_param3 = 2500; continue;
temp.event_param4 = 2500; }
}*/ if (temp.friendly_buff.repeatMax < temp.friendly_buff.repeatMin)
if (temp.event_param4 < temp.event_param3)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break; break;
} }
case EVENT_T_KILL: case EVENT_T_KILL:
case EVENT_T_TARGET_CASTING: if (temp.kill.repeatMax < temp.kill.repeatMin)
{
if (temp.event_param2 < temp.event_param1)
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break; break;
} case EVENT_T_TARGET_CASTING:
if (temp.target_casting.repeatMax < temp.target_casting.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
case EVENT_T_SUMMONED_UNIT:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.summon_unit.creatureId))
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.summon_unit.creatureId);
if (temp.summon_unit.repeatMax < temp.summon_unit.repeatMin)
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
case EVENT_T_QUEST_ACCEPT:
case EVENT_T_QUEST_COMPLETE:
if (!objmgr.GetQuestTemplate(temp.quest.questId))
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed qyest id (%u) in param1, skipped.", temp.creature_id, i, temp.quest.questId);
sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i);
continue;
case EVENT_T_AGGRO: case EVENT_T_AGGRO:
case EVENT_T_DEATH: case EVENT_T_DEATH:
@ -331,21 +341,15 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
case EVENT_T_RECEIVE_EMOTE: case EVENT_T_RECEIVE_EMOTE:
{ {
if (!sEmotesTextStore.LookupEntry(temp.event_param1)) if (!sEmotesTextStore.LookupEntry(temp.receive_emote.emoteId))
{ {
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.event_param1); sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param1 (EmoteTextId: %u) are not valid.",temp.creature_id, i, temp.receive_emote.emoteId);
continue; continue;
} }
if (temp.event_param2 == CONDITION_AD_COMMISSION_AURA || temp.event_param2 == CONDITION_NO_AURA) if (!PlayerCondition::IsValid(ConditionType(temp.receive_emote.condition), temp.receive_emote.conditionValue1, temp.receive_emote.conditionValue2))
{ {
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not implemented for EventAI.",temp.creature_id, i, temp.event_param2); sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.receive_emote.condition);
continue;
}
if (!PlayerCondition::IsValid(ConditionType(temp.event_param2), temp.event_param3, temp.event_param4))
{
sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.event_param2);
continue; continue;
} }
@ -358,21 +362,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
break; break;
} }
case EVENT_T_SUMMONED_UNIT:
{
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.event_param1))
sLog.outErrorDb("CreatureEventAI: Creature %u are using event(%u) with not existed creature template id (%u) in param1, skipped.", temp.creature_id, i, temp.event_param1);
if (temp.event_param3 < temp.event_param2)
sLog.outErrorDb("CreatureEventAI: Creature %u are using repeatable event(%u) with param3 < param2 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);
break;
}
case EVENT_T_QUEST_ACCEPT:
case EVENT_T_QUEST_COMPLETE:
sLog.outErrorDb("CreatureEventAI: Creature %u using not implemented event (%u) in event %u.", temp.creature_id, temp.event_id, i);
continue;
default: default:
sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i); sLog.outErrorDb("CreatureEventAI: Creature %u using not checked at load event (%u) in event %u. Need check code update?", temp.creature_id, temp.event_id, i);
break; break;
@ -388,251 +377,254 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
continue; continue;
} }
temp.action[j].type = EventAI_ActionType(action_type); CreatureEventAI_Action& action = temp.action[j];
temp.action[j].param1 = fields[11+(j*4)].GetUInt32();
temp.action[j].param2 = fields[12+(j*4)].GetUInt32(); action.type = EventAI_ActionType(action_type);
temp.action[j].param3 = fields[13+(j*4)].GetUInt32(); action.raw.param1 = fields[11+(j*4)].GetUInt32();
action.raw.param2 = fields[12+(j*4)].GetUInt32();
action.raw.param3 = fields[13+(j*4)].GetUInt32();
//Report any errors in actions //Report any errors in actions
switch (temp.action[j].type) switch (action.type)
{ {
case ACTION_T_NONE: case ACTION_T_NONE:
break; break;
case ACTION_T_TEXT: case ACTION_T_TEXT:
{ {
if (temp.action[j].param1_s < 0) if (action.text.TextId1 < 0)
{ {
if (m_CreatureEventAI_TextMap.find(temp.action[j].param1_s) == m_CreatureEventAI_TextMap.end()) if (m_CreatureEventAI_TextMap.find(action.text.TextId1) == m_CreatureEventAI_TextMap.end())
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 refrences non-existing entry in texts table.", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 refrences non-existing entry in texts table.", i, j+1);
} }
if (temp.action[j].param2_s < 0) if (action.text.TextId2 < 0)
{ {
if (m_CreatureEventAI_TextMap.find(temp.action[j].param2_s) == m_CreatureEventAI_TextMap.end()) if (m_CreatureEventAI_TextMap.find(action.text.TextId2) == m_CreatureEventAI_TextMap.end())
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 refrences non-existing entry in texts table.", i, j+1);
if (!temp.action[j].param1_s) if (!action.text.TextId1)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param2, but param1 is not set. Required for randomized text.", i, j+1);
} }
if (temp.action[j].param3_s < 0) if (action.text.TextId3 < 0)
{ {
if (m_CreatureEventAI_TextMap.find(temp.action[j].param3_s) == m_CreatureEventAI_TextMap.end()) if (m_CreatureEventAI_TextMap.find(action.text.TextId3) == m_CreatureEventAI_TextMap.end())
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 refrences non-existing entry in texts table.", i, j+1);
if (!temp.action[j].param1_s || !temp.action[j].param2_s) if (!action.text.TextId1 || !action.text.TextId2)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u has param3, but param1 and/or param2 is not set. Required for randomized text.", i, j+1);
} }
break; break;
} }
case ACTION_T_SET_FACTION: case ACTION_T_SET_FACTION:
if (temp.action[j].param1 !=0 && !sFactionStore.LookupEntry(temp.action[j].param1)) if (action.set_faction.factionId !=0 && !sFactionStore.LookupEntry(action.set_faction.factionId))
{ {
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant FactionId %u.", i, j+1, temp.action[j].param1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent FactionId %u.", i, j+1, action.set_faction.factionId);
temp.action[j].param1 = 0; action.set_faction.factionId = 0;
} }
break; break;
case ACTION_T_MORPH_TO_ENTRY_OR_MODEL: case ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
if (temp.action[j].param1 !=0 || temp.action[j].param2 !=0) if (action.morph.creatireId !=0 || action.morph.modelId !=0)
{ {
if (temp.action[j].param1 && !sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1)) if (action.morph.creatireId && !sCreatureStorage.LookupEntry<CreatureInfo>(action.morph.creatireId))
{ {
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, temp.action[j].param1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Creature entry %u.", i, j+1, action.morph.creatireId);
temp.action[j].param1 = 0; action.morph.creatireId = 0;
} }
if (temp.action[j].param2 && !sCreatureDisplayInfoStore.LookupEntry(temp.action[j].param2)) if (action.morph.modelId)
{ {
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant ModelId %u.", i, j+1, temp.action[j].param2); if (action.morph.creatireId)
temp.action[j].param2 = 0; {
sLog.outErrorDb("CreatureEventAI: Event %u Action %u have unused ModelId %u with also set creature id %u.", i, j+1, action.morph.modelId,action.morph.creatireId);
action.morph.modelId = 0;
}
else if (!sCreatureDisplayInfoStore.LookupEntry(action.morph.modelId))
{
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant ModelId %u.", i, j+1, action.morph.modelId);
action.morph.modelId = 0;
} }
} }
break; break;
}
case ACTION_T_SOUND: case ACTION_T_SOUND:
if (!sSoundEntriesStore.LookupEntry(temp.action[j].param1)) if (!sSoundEntriesStore.LookupEntry(action.sound.soundId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SoundID %u.", i, j+1, action.sound.soundId);
break;
case ACTION_T_RANDOM_SOUND:
if (!sSoundEntriesStore.LookupEntry(temp.action[j].param1))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, temp.action[j].param1);
if (temp.action[j].param2_s >= 0 && !sSoundEntriesStore.LookupEntry(temp.action[j].param2))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, temp.action[j].param2);
if (temp.action[j].param3_s >= 0 && !sSoundEntriesStore.LookupEntry(temp.action[j].param3))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, temp.action[j].param3);
break; break;
case ACTION_T_EMOTE: case ACTION_T_EMOTE:
if (!sEmotesStore.LookupEntry(temp.action[j].param1)) if (!sEmotesStore.LookupEntry(action.emote.emoteId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, action.emote.emoteId);
break;
case ACTION_T_RANDOM_SOUND:
if (!sSoundEntriesStore.LookupEntry(action.random_sound.soundId1))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId1);
if (action.random_sound.soundId2 >= 0 && !sSoundEntriesStore.LookupEntry(action.random_sound.soundId2))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId2);
if (action.random_sound.soundId3 >= 0 && !sSoundEntriesStore.LookupEntry(action.random_sound.soundId3))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 uses non-existant SoundID %u.", i, j+1, action.random_sound.soundId3);
break; break;
case ACTION_T_RANDOM_EMOTE: case ACTION_T_RANDOM_EMOTE:
if (!sEmotesStore.LookupEntry(temp.action[j].param1)) if (!sEmotesStore.LookupEntry(action.random_emote.emoteId1))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId1);
if (temp.action[j].param2_s >= 0 && !sEmotesStore.LookupEntry(temp.action[j].param2)) if (action.random_emote.emoteId2 >= 0 && !sEmotesStore.LookupEntry(action.random_emote.emoteId2))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param2); sLog.outErrorDb("CreatureEventAI: Event %u Action %u param2 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId2);
if (temp.action[j].param3_s >= 0 && !sEmotesStore.LookupEntry(temp.action[j].param3)) if (action.random_emote.emoteId3 >= 0 && !sEmotesStore.LookupEntry(action.random_emote.emoteId3))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 (EmoteId: %u) are not valid.", i, j+1, temp.action[j].param3); sLog.outErrorDb("CreatureEventAI: Event %u Action %u param3 (EmoteId: %u) are not valid.", i, j+1, action.random_emote.emoteId3);
break; break;
case ACTION_T_CAST: case ACTION_T_CAST:
{ {
const SpellEntry *spell = sSpellStore.LookupEntry(temp.action[j].param1); const SpellEntry *spell = sSpellStore.LookupEntry(action.cast.spellId);
if (!spell) if (!spell)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast.spellId);
/* FIXME: temp.raw.param3 not have event tipes with recovery time in it....
else else
{ {
if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE) if (spell->RecoveryTime > 0 && temp.event_flags & EFLAG_REPEATABLE)
{ {
//output as debug for now, also because there's no general rule all spells have RecoveryTime //output as debug for now, also because there's no general rule all spells have RecoveryTime
if (temp.event_param3 < spell->RecoveryTime) if (temp.event_param3 < spell->RecoveryTime)
sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,temp.action[j].param1, spell->RecoveryTime, temp.event_param3); sLog.outDebug("CreatureEventAI: Event %u Action %u uses SpellID %u but cooldown is longer(%u) than minumum defined in event param3(%u).", i, j+1,action.cast.spellId, spell->RecoveryTime, temp.event_param3);
} }
} }
*/
if (temp.action[j].param2 >= TARGET_T_END) //Cast is always triggered if target is forced to cast on self
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); if (action.cast.castFlags & CAST_FORCE_TARGET_SELF)
break; action.cast.castFlags |= CAST_TRIGGERED;
}
case ACTION_T_REMOVEAURASFROMSPELL:
{
if (!sSpellStore.LookupEntry(temp.action[j].param2))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
if (temp.action[j].param1 >= TARGET_T_END) if (action.cast.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
}
case ACTION_T_QUEST_EVENT:
{
if (Quest const* qid = objmgr.GetQuestTemplate(temp.action[j].param1))
{
if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
}
else
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
if (temp.action[j].param2 >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
}
case ACTION_T_QUEST_EVENT_ALL:
{
if (Quest const* qid = objmgr.GetQuestTemplate(temp.action[j].param1))
{
if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, temp.action[j].param1);
}
else
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
break;
}
case ACTION_T_CASTCREATUREGO:
{
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
if (!sSpellStore.LookupEntry(temp.action[j].param2))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
if (temp.action[j].param3 >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
}
case ACTION_T_CASTCREATUREGO_ALL:
{
if (!objmgr.GetQuestTemplate(temp.action[j].param1))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant Quest entry %u.", i, j+1, temp.action[j].param1);
if (!sSpellStore.LookupEntry(temp.action[j].param2))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2);
break;
}
//2nd param target
case ACTION_T_SUMMON_ID:
{
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
if (m_CreatureEventAI_Summon_Map.find(temp.action[j].param3) == m_CreatureEventAI_Summon_Map.end())
sLog.outErrorDb("CreatureEventAI: Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j+1, temp.action[j].param3);
if (temp.action[j].param2 >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
}
case ACTION_T_KILLED_MONSTER:
{
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
if (temp.action[j].param2 >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break; break;
} }
case ACTION_T_SUMMON: case ACTION_T_SUMMON:
{ if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.summon.creatured))
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1)) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.summon.creatured);
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1);
if (temp.action[j].param2 >= TARGET_T_END) if (action.summon.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break; break;
}
case ACTION_T_THREAT_SINGLE_PCT: case ACTION_T_THREAT_SINGLE_PCT:
if (std::abs(action.threat_single_pct.percent) > 100)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, action.threat_single_pct.percent);
if (action.threat_single_pct.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_THREAT_ALL_PCT:
if (std::abs(action.threat_all_pct.percent) > 100)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, action.threat_all_pct.percent);
break;
case ACTION_T_QUEST_EVENT:
if (Quest const* qid = objmgr.GetQuestTemplate(action.quest_event.questId))
{
if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, action.quest_event.questId);
}
else
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event.questId);
if (action.quest_event.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_CAST_EVENT:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.cast_event.creatureId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.cast_event.creatureId);
if (!sSpellStore.LookupEntry(action.cast_event.spellId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast_event.spellId);
if (action.cast_event.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_SET_UNIT_FIELD:
if (action.set_unit_field.field < OBJECT_END || action.set_unit_field.field >= UNIT_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1);
if (action.set_unit_field.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_SET_UNIT_FLAG: case ACTION_T_SET_UNIT_FLAG:
case ACTION_T_REMOVE_UNIT_FLAG: case ACTION_T_REMOVE_UNIT_FLAG:
if (temp.action[j].param2 >= TARGET_T_END) if (action.unit_flag.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break; break;
//3rd param target
case ACTION_T_SET_UNIT_FIELD:
if (temp.action[j].param1 < OBJECT_END || temp.action[j].param1 >= UNIT_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u param1 (UNIT_FIELD*). Index out of range for intended use.", i, j+1);
if (temp.action[j].param3 >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_SET_PHASE: case ACTION_T_SET_PHASE:
if (temp.action[j].param1 > 31) if (action.set_phase.phase >= MAX_PHASE)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
break; break;
case ACTION_T_INC_PHASE: case ACTION_T_INC_PHASE:
if (!temp.action[j].param1) if (action.set_inc_phase.step == 0)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1);
else if (std::abs(action.set_inc_phase.step) > MAX_PHASE-1)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u is change phase by too large for any use %i.", i, j+1, action.set_inc_phase.step);
break; break;
case ACTION_T_QUEST_EVENT_ALL:
case ACTION_T_SET_INST_DATA: if (Quest const* qid = objmgr.GetQuestTemplate(action.quest_event_all.questId))
{ {
if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC)) if (!qid->HasFlag(QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u. SpecialFlags for quest entry %u does not include |2, Action will not have any effect.", i, j+1, action.quest_event_all.questId);
if (temp.action[j].param2 > 4/*SPECIAL*/)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1);
break;
} }
case ACTION_T_SET_INST_DATA64: else
{ sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent Quest entry %u.", i, j+1, action.quest_event_all.questId);
if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC)) break;
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1); case ACTION_T_CAST_EVENT_ALL:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.cast_event_all.creatureId))
if (temp.action[j].param2 >= TARGET_T_END) sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent creature entry %u.", i, j+1, action.cast_event_all.creatureId);
if (!sSpellStore.LookupEntry(action.cast_event_all.spellId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.cast_event_all.spellId);
break;
case ACTION_T_REMOVEAURASFROMSPELL:
if (!sSpellStore.LookupEntry(action.remove_aura.spellId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existent SpellID %u.", i, j+1, action.remove_aura.spellId);
if (action.remove_aura.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1); sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break; break;
} case ACTION_T_RANDOM_PHASE: //PhaseId1, PhaseId2, PhaseId3
case ACTION_T_UPDATE_TEMPLATE: if (action.random_phase.phase1 >= MAX_PHASE)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase1 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
if (action.random_phase.phase2 >= MAX_PHASE)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase2 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
if (action.random_phase.phase3 >= MAX_PHASE)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phase3 >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
break;
case ACTION_T_RANDOM_PHASE_RANGE: //PhaseMin, PhaseMax
if (action.random_phase_range.phaseMin >= MAX_PHASE)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMin >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
if (action.random_phase_range.phaseMin >= MAX_PHASE)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMax >= %u. Phase mask cannot be used past phase %u.", i, j+1, MAX_PHASE, MAX_PHASE-1);
if (action.random_phase_range.phaseMin >= action.random_phase_range.phaseMax)
{ {
if (!sCreatureStorage.LookupEntry<CreatureInfo>(temp.action[j].param1)) sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set phaseMax <= phaseMin.", i, j+1);
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, temp.action[j].param1); std::swap(action.random_phase_range.phaseMin,action.random_phase_range.phaseMax);
break; // equal case processed at call
} }
case ACTION_T_THREAT_ALL_PCT:
if (abs(temp.action[j].param1_s) > 100)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses invalid percent value %u.", i, j+1, temp.action[j].param1);
break; break;
case ACTION_T_SUMMON_ID:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.summon_id.creatureId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.summon_id.creatureId);
if (action.summon_id.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
if (m_CreatureEventAI_Summon_Map.find(action.summon_id.spawnId) == m_CreatureEventAI_Summon_Map.end())
sLog.outErrorDb("CreatureEventAI: Event %u Action %u summons missing CreatureEventAI_Summon %u", i, j+1, action.summon_id.spawnId);
break;
case ACTION_T_KILLED_MONSTER:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.killed_monster.creatureId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.killed_monster.creatureId);
if (action.killed_monster.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_SET_INST_DATA:
if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
if (action.set_inst_data.value > 4/*SPECIAL*/)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u attempts to set instance data above encounter state 4. Custom case?", i, j+1);
break;
case ACTION_T_SET_INST_DATA64:
if (!(temp.event_flags & EFLAG_NORMAL) && !(temp.event_flags & EFLAG_HEROIC))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u. Cannot set instance data without event flags (normal/heroic).", i, j+1);
if (action.set_inst_data64.target >= TARGET_T_END)
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses incorrect Target type", i, j+1);
break;
case ACTION_T_UPDATE_TEMPLATE:
if (!sCreatureStorage.LookupEntry<CreatureInfo>(action.update_template.creatureId))
sLog.outErrorDb("CreatureEventAI: Event %u Action %u uses non-existant creature entry %u.", i, j+1, action.update_template.creatureId);
break;
case ACTION_T_EVADE: //No Params case ACTION_T_EVADE: //No Params
case ACTION_T_FLEE: //No Params case ACTION_T_FLEE: //No Params
case ACTION_T_DIE: //No Params case ACTION_T_DIE: //No Params
@ -642,11 +634,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
case ACTION_T_RANGED_MOVEMENT: //Distance, Angle case ACTION_T_RANGED_MOVEMENT: //Distance, Angle
break; break;
case ACTION_T_RANDOM_PHASE: //PhaseId1, PhaseId2, PhaseId3
case ACTION_T_RANDOM_PHASE_RANGE: //PhaseMin, PhaseMax
// check not implemented
break;
case ACTION_T_RANDOM_SAY: case ACTION_T_RANDOM_SAY:
case ACTION_T_RANDOM_YELL: case ACTION_T_RANDOM_YELL:
case ACTION_T_RANDOM_TEXTEMOTE: case ACTION_T_RANDOM_TEXTEMOTE:

View file

@ -540,7 +540,7 @@ void MaNGOS::PlayerSearcher<Check>::Visit(PlayerMapType &m)
template<class Builder> template<class Builder>
void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p ) void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p )
{ {
uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
uint32 cache_idx = loc_idx+1; uint32 cache_idx = loc_idx+1;
WorldPacket* data; WorldPacket* data;
@ -565,7 +565,7 @@ void MaNGOS::LocalizedPacketDo<Builder>::operator()( Player* p )
template<class Builder> template<class Builder>
void MaNGOS::LocalizedPacketListDo<Builder>::operator()( Player* p ) void MaNGOS::LocalizedPacketListDo<Builder>::operator()( Player* p )
{ {
uint32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex(); int32 loc_idx = p->GetSession()->GetSessionDbLocaleIndex();
uint32 cache_idx = loc_idx+1; uint32 cache_idx = loc_idx+1;
WorldPacketList* data_list; WorldPacketList* data_list;

View file

@ -94,7 +94,6 @@ enum MangosStrings
LANG_CANNOT_GO_TO_INST_GM = 105, LANG_CANNOT_GO_TO_INST_GM = 105,
LANG_CANNOT_GO_INST_INST = 106, LANG_CANNOT_GO_INST_INST = 106,
LANG_CANNOT_SUMMON_INST_INST = 107, LANG_CANNOT_SUMMON_INST_INST = 107,
LANG_SUMMONING = 108, LANG_SUMMONING = 108,
LANG_SUMMONED_BY = 109, LANG_SUMMONED_BY = 109,
LANG_TELEPORTING_TO = 110, LANG_TELEPORTING_TO = 110,
@ -102,7 +101,6 @@ enum MangosStrings
LANG_NO_PLAYER = 112, LANG_NO_PLAYER = 112,
LANG_APPEARING_AT = 113, LANG_APPEARING_AT = 113,
LANG_APPEARING_TO = 114, LANG_APPEARING_TO = 114,
LANG_BAD_VALUE = 115, LANG_BAD_VALUE = 115,
LANG_NO_CHAR_SELECTED = 116, LANG_NO_CHAR_SELECTED = 116,
LANG_NOT_IN_GROUP = 117, LANG_NOT_IN_GROUP = 117,
@ -167,7 +165,7 @@ enum MangosStrings
LANG_MAIL_SENT = 169, LANG_MAIL_SENT = 169,
LANG_SOUND_NOT_EXIST = 170, LANG_SOUND_NOT_EXIST = 170,
// 171, // not used LANG_CANT_TELEPORT_SELF = 171,
LANG_CONSOLE_COMMAND = 172, LANG_CONSOLE_COMMAND = 172,
LANG_YOU_CHANGE_RUNIC_POWER = 173, LANG_YOU_CHANGE_RUNIC_POWER = 173,
LANG_YOURS_RUNIC_POWER_CHANGED = 174, LANG_YOURS_RUNIC_POWER_CHANGED = 174,
@ -266,7 +264,7 @@ enum MangosStrings
LANG_COMMAND_ADDVENDORITEMITEMS = 280, LANG_COMMAND_ADDVENDORITEMITEMS = 280,
LANG_COMMAND_KICKSELF = 281, LANG_COMMAND_KICKSELF = 281,
LANG_COMMAND_KICKMESSAGE = 282, LANG_COMMAND_KICKMESSAGE = 282,
LANG_COMMAND_KICKNOTFOUNDPLAYER = 283, // 283, not used
LANG_COMMAND_WHISPERACCEPTING = 284, LANG_COMMAND_WHISPERACCEPTING = 284,
LANG_COMMAND_WHISPERON = 285, LANG_COMMAND_WHISPERON = 285,
LANG_COMMAND_WHISPEROFF = 286, LANG_COMMAND_WHISPEROFF = 286,

View file

@ -309,9 +309,9 @@ bool ChatHandler::HandleGPSCommand(const char* args)
uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0; uint32 have_vmap = Map::ExistVMap(obj->GetMapId(),gx,gy) ? 1 : 0;
PSendSysMessage(LANG_MAP_POSITION, PSendSysMessage(LANG_MAP_POSITION,
obj->GetMapId(), (mapEntry ? mapEntry->name[m_session->GetSessionDbcLocale()] : "<unknown>" ), obj->GetMapId(), (mapEntry ? mapEntry->name[GetSessionDbcLocale()] : "<unknown>" ),
zone_id, (zoneEntry ? zoneEntry->area_name[m_session->GetSessionDbcLocale()] : "<unknown>" ), zone_id, (zoneEntry ? zoneEntry->area_name[GetSessionDbcLocale()] : "<unknown>" ),
area_id, (areaEntry ? areaEntry->area_name[m_session->GetSessionDbcLocale()] : "<unknown>" ), area_id, (areaEntry ? areaEntry->area_name[GetSessionDbcLocale()] : "<unknown>" ),
obj->GetPhaseMask(), obj->GetPhaseMask(),
obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(), cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), obj->GetInstanceId(),
@ -343,26 +343,28 @@ bool ChatHandler::HandleGPSCommand(const char* args)
//Summon Player //Summon Player
bool ChatHandler::HandleNamegoCommand(const char* args) bool ChatHandler::HandleNamegoCommand(const char* args)
{ {
if(!*args) Player* target;
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
return false; return false;
std::string name = extractPlayerNameFromLink((char*)args); Player* _player = m_session->GetPlayer();
if(name.empty()) if (target == _player || target_guid == _player->GetGUID())
{ {
SendSysMessage(LANG_PLAYER_NOT_FOUND); PSendSysMessage(LANG_CANT_TELEPORT_SELF);
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
Player *chr = objmgr.GetPlayer(name.c_str()); if (target)
if (chr)
{ {
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
// check online security // check online security
if (HasLowerSecurity(chr, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
if(chr->IsBeingTeleported()) if (target->IsBeingTeleported())
{ {
PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str());
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -374,28 +376,28 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
if (pMap->IsBattleGroundOrArena()) if (pMap->IsBattleGroundOrArena())
{ {
// only allow if gm mode is on // only allow if gm mode is on
if (!chr->isGameMaster()) if (!target->isGameMaster())
{ {
PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,chr->GetName()); PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,nameLink.c_str());
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
// if both players are in different bgs // if both players are in different bgs
else if (chr->GetBattleGroundId() && m_session->GetPlayer()->GetBattleGroundId() != chr->GetBattleGroundId()) else if (target->GetBattleGroundId() && m_session->GetPlayer()->GetBattleGroundId() != target->GetBattleGroundId())
{ {
PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chr->GetName()); PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,nameLink.c_str());
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
// all's well, set bg id // all's well, set bg id
// when porting out from the bg, it will be reset to 0 // when porting out from the bg, it will be reset to 0
chr->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId(), m_session->GetPlayer()->GetBattleGroundTypeId()); target->SetBattleGroundId(m_session->GetPlayer()->GetBattleGroundId(), m_session->GetPlayer()->GetBattleGroundTypeId());
// remember current position as entry point for return at bg end teleportation // remember current position as entry point for return at bg end teleportation
chr->SetBattleGroundEntryPoint(chr->GetMapId(),chr->GetPositionX(),chr->GetPositionY(),chr->GetPositionZ(),chr->GetOrientation()); target->SetBattleGroundEntryPoint(target->GetMapId(),target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),target->GetOrientation());
} }
else if (pMap->IsDungeon()) else if (pMap->IsDungeon())
{ {
Map* cMap = chr->GetMap(); Map* cMap = target->GetMap();
if (cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId()) if (cMap->Instanceable() && cMap->GetInstanceId() != pMap->GetInstanceId())
{ {
// cannot summon from instance to instance // cannot summon from instance to instance
@ -405,8 +407,8 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
} }
// we are in instance, and can summon only player in our group with us as lead // we are in instance, and can summon only player in our group with us as lead
if ( !m_session->GetPlayer()->GetGroup() || !chr->GetGroup() || if (!m_session->GetPlayer()->GetGroup() || !target->GetGroup() ||
(chr->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) || (target->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()) ||
(m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID())) (m_session->GetPlayer()->GetGroup()->GetLeaderGUID() != m_session->GetPlayer()->GetGUID()))
// the last check is a bit excessive, but let it be, just in case // the last check is a bit excessive, but let it be, just in case
{ {
@ -417,31 +419,31 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
} }
PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),""); PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),"");
if (needReportToTarget(chr)) if (needReportToTarget(target))
ChatHandler(chr).PSendSysMessage(LANG_SUMMONED_BY, nameLink.c_str()); ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, nameLink.c_str());
// stop flight if need // stop flight if need
if(chr->isInFlight()) if (target->isInFlight())
{ {
chr->GetMotionMaster()->MovementExpired(); target->GetMotionMaster()->MovementExpired();
chr->m_taxi.ClearTaxiDestinations(); target->m_taxi.ClearTaxiDestinations();
} }
// save only in non-flight case // save only in non-flight case
else else
chr->SaveRecallPosition(); target->SaveRecallPosition();
// before GM // before GM
float x,y,z; float x,y,z;
m_session->GetPlayer()->GetClosePoint(x,y,z,chr->GetObjectSize()); m_session->GetPlayer()->GetClosePoint(x,y,z,target->GetObjectSize());
chr->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,chr->GetOrientation()); target->TeleportTo(m_session->GetPlayer()->GetMapId(),x,y,z,target->GetOrientation());
} }
else if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) else
{ {
// check offline security // check offline security
if (HasLowerSecurity(NULL, guid)) if (HasLowerSecurity(NULL, target_guid))
return false; return false;
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),GetMangosString(LANG_OFFLINE)); PSendSysMessage(LANG_SUMMONING, nameLink.c_str(),GetMangosString(LANG_OFFLINE));
@ -452,12 +454,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
m_session->GetPlayer()->GetPositionZ(), m_session->GetPlayer()->GetPositionZ(),
m_session->GetPlayer()->GetOrientation(), m_session->GetPlayer()->GetOrientation(),
m_session->GetPlayer()->GetZoneId(), m_session->GetPlayer()->GetZoneId(),
guid); target_guid);
}
else
{
PSendSysMessage(LANG_NO_PLAYER, args);
SetSentErrorMessage(true);
} }
return true; return true;
@ -466,29 +463,30 @@ bool ChatHandler::HandleNamegoCommand(const char* args)
//Teleport to Player //Teleport to Player
bool ChatHandler::HandleGonameCommand(const char* args) bool ChatHandler::HandleGonameCommand(const char* args)
{ {
if(!*args) Player* target;
uint64 target_guid;
std::string target_name;
if (!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
return false; return false;
Player* _player = m_session->GetPlayer(); Player* _player = m_session->GetPlayer();
if (target == _player || target_guid == _player->GetGUID())
std::string name = extractPlayerNameFromLink((char*)args);
if(name.empty())
{ {
SendSysMessage(LANG_PLAYER_NOT_FOUND); SendSysMessage(LANG_CANT_TELEPORT_SELF);
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
Player *chr = objmgr.GetPlayer(name.c_str());
if (chr) if (target)
{ {
// check online security // check online security
if (HasLowerSecurity(chr, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
std::string chrNameLink = playerLink(name); std::string chrNameLink = playerLink(target_name);
Map* cMap = chr->GetMap(); Map* cMap = target->GetMap();
if (cMap->IsBattleGroundOrArena()) if (cMap->IsBattleGroundOrArena())
{ {
// only allow if gm mode is on // only allow if gm mode is on
@ -499,7 +497,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
return false; return false;
} }
// if both players are in different bgs // if both players are in different bgs
else if (_player->GetBattleGroundId() && _player->GetBattleGroundId() != chr->GetBattleGroundId()) else if (_player->GetBattleGroundId() && _player->GetBattleGroundId() != target->GetBattleGroundId())
{ {
PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chrNameLink.c_str()); PSendSysMessage(LANG_CANNOT_GO_TO_BG_FROM_BG,chrNameLink.c_str());
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -507,7 +505,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
} }
// all's well, set bg id // all's well, set bg id
// when porting out from the bg, it will be reset to 0 // when porting out from the bg, it will be reset to 0
_player->SetBattleGroundId(chr->GetBattleGroundId(), chr->GetBattleGroundTypeId()); _player->SetBattleGroundId(target->GetBattleGroundId(), target->GetBattleGroundTypeId());
// remember current position as entry point for return at bg end teleportation // remember current position as entry point for return at bg end teleportation
_player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation()); _player->SetBattleGroundEntryPoint(_player->GetMapId(),_player->GetPositionX(),_player->GetPositionY(),_player->GetPositionZ(),_player->GetOrientation());
} }
@ -519,7 +517,7 @@ bool ChatHandler::HandleGonameCommand(const char* args)
if (_player->GetGroup()) if (_player->GetGroup())
{ {
// we are in group, we can go only if we are in the player group // we are in group, we can go only if we are in the player group
if (_player->GetGroup() != chr->GetGroup()) if (_player->GetGroup() != target->GetGroup())
{ {
PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chrNameLink.c_str()); PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY,chrNameLink.c_str());
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -539,25 +537,24 @@ bool ChatHandler::HandleGonameCommand(const char* args)
// if the player or the player's group is bound to another instance // if the player or the player's group is bound to another instance
// the player will not be bound to another one // the player will not be bound to another one
InstancePlayerBind *pBind = _player->GetBoundInstance(chr->GetMapId(), chr->GetDifficulty()); InstancePlayerBind *pBind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty());
if (!pBind) if (!pBind)
{ {
Group *group = _player->GetGroup(); Group *group = _player->GetGroup();
InstanceGroupBind *gBind = group ? group->GetBoundInstance(chr->GetMapId(), chr->GetDifficulty()) : NULL;
if(!gBind)
{
// if no bind exists, create a solo bind // if no bind exists, create a solo bind
InstanceSave *save = sInstanceSaveManager.GetInstanceSave(chr->GetInstanceId()); InstanceGroupBind *gBind = group ? group->GetBoundInstance(target->GetMapId(), target->GetDifficulty()) : NULL;
if(save) _player->BindToInstance(save, !save->CanReset()); // if no bind exists, create a solo bind
} if (!gBind)
if (InstanceSave *save = sInstanceSaveManager.GetInstanceSave(target->GetInstanceId()))
_player->BindToInstance(save, !save->CanReset());
} }
_player->SetDifficulty(chr->GetDifficulty()); _player->SetDifficulty(target->GetDifficulty());
} }
PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str());
if (_player->IsVisibleGloballyFor(chr)) if (needReportToTarget(target))
ChatHandler(chr).PSendSysMessage(LANG_APPEARING_TO, GetNameLink().c_str()); ChatHandler(target).PSendSysMessage(LANG_APPEARING_TO, GetNameLink().c_str());
// stop flight if need // stop flight if need
if (_player->isInFlight()) if (_player->isInFlight())
@ -571,20 +568,17 @@ bool ChatHandler::HandleGonameCommand(const char* args)
// to point to see at target with same orientation // to point to see at target with same orientation
float x,y,z; float x,y,z;
chr->GetContactPoint(m_session->GetPlayer(),x,y,z); target->GetContactPoint(_player,x,y,z);
_player->TeleportTo(chr->GetMapId(), x, y, z, _player->GetAngle( chr ), TELE_TO_GM_MODE); _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE);
return true;
} }
else
if (uint64 guid = objmgr.GetPlayerGUIDByName(name))
{ {
// check offline security // check offline security
if (HasLowerSecurity(NULL, guid)) if (HasLowerSecurity(NULL, target_guid))
return false; return false;
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str());
@ -592,8 +586,9 @@ bool ChatHandler::HandleGonameCommand(const char* args)
float x,y,z,o; float x,y,z,o;
uint32 map; uint32 map;
bool in_flight; bool in_flight;
if(Player::LoadPositionFromDB(map,x,y,z,o,in_flight,guid)) if (!Player::LoadPositionFromDB(map,x,y,z,o,in_flight,target_guid))
{ return false;
// stop flight if need // stop flight if need
if (_player->isInFlight()) if (_player->isInFlight())
{ {
@ -605,70 +600,37 @@ bool ChatHandler::HandleGonameCommand(const char* args)
_player->SaveRecallPosition(); _player->SaveRecallPosition();
_player->TeleportTo(map, x, y, z,_player->GetOrientation()); _player->TeleportTo(map, x, y, z,_player->GetOrientation());
}
return true; return true;
} }
}
PSendSysMessage(LANG_NO_PLAYER, args);
SetSentErrorMessage(true);
return false;
}
// Teleport player to last position // Teleport player to last position
bool ChatHandler::HandleRecallCommand(const char* args) bool ChatHandler::HandleRecallCommand(const char* args)
{ {
Player* chr = NULL; Player* target;
if(!extractPlayerTarget((char*)args,&target))
if(!*args) return false;
{
chr = getSelectedPlayer();
if(!chr)
chr = m_session->GetPlayer();
// check online security // check online security
else if (HasLowerSecurity(chr, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
}
else
{
std::string name = extractPlayerNameFromLink((char*)args);
if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
chr = objmgr.GetPlayer(name.c_str()); if (target->IsBeingTeleported())
if(!chr)
{ {
PSendSysMessage(LANG_NO_PLAYER, args); PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(target).c_str());
SetSentErrorMessage(true);
return false;
}
// check online security
if (HasLowerSecurity(chr, 0))
return false;
}
if(chr->IsBeingTeleported())
{
PSendSysMessage(LANG_IS_TELEPORTED, GetNameLink(chr).c_str());
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
// stop flight if need // stop flight if need
if(chr->isInFlight()) if(target->isInFlight())
{ {
chr->GetMotionMaster()->MovementExpired(); target->GetMotionMaster()->MovementExpired();
chr->m_taxi.ClearTaxiDestinations(); target->m_taxi.ClearTaxiDestinations();
} }
chr->TeleportTo(chr->m_recallMap, chr->m_recallX, chr->m_recallY, chr->m_recallZ, chr->m_recallO); target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO);
return true; return true;
} }
@ -1856,7 +1818,7 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args)
AreaTableEntry const *areaEntry = sAreaStore.LookupEntry (areaflag); AreaTableEntry const *areaEntry = sAreaStore.LookupEntry (areaflag);
if (areaEntry) if (areaEntry)
{ {
int loc = m_session ? m_session->GetSessionDbcLocale () : sWorld.GetDefaultDbcLocale(); int loc = GetSessionDbcLocale ();
std::string name = areaEntry->area_name[loc]; std::string name = areaEntry->area_name[loc];
if (name.empty()) if (name.empty())
continue; continue;
@ -1866,7 +1828,7 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args)
loc = 0; loc = 0;
for(; loc < MAX_LOCALE; ++loc) for(; loc < MAX_LOCALE; ++loc)
{ {
if (m_session && loc==m_session->GetSessionDbcLocale ()) if (loc==GetSessionDbcLocale ())
continue; continue;
name = areaEntry->area_name[loc]; name = areaEntry->area_name[loc];
@ -1989,18 +1951,12 @@ bool ChatHandler::HandleSaveAllCommand(const char* /*args*/)
//Send mail by command //Send mail by command
bool ChatHandler::HandleSendMailCommand(const char* args) bool ChatHandler::HandleSendMailCommand(const char* args)
{ {
if(!*args)
return false;
// format: name "subject text" "mail text" // format: name "subject text" "mail text"
Player* target;
std::string name = extractPlayerNameFromLink((char*)args); uint64 target_guid;
if(name.empty()) std::string target_name;
{ if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false; return false;
}
char* tail1 = strtok(NULL, ""); char* tail1 = strtok(NULL, "");
if(!tail1) if(!tail1)
@ -2042,14 +1998,6 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
std::string subject = msgSubject; std::string subject = msgSubject;
std::string text = msgText; std::string text = msgText;
uint64 receiver_guid = objmgr.GetPlayerGUIDByName(name);
if(!receiver_guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
// from console show not existed sender // from console show not existed sender
uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0;
@ -2057,11 +2005,9 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
uint32 stationery = MAIL_STATIONERY_GM; uint32 stationery = MAIL_STATIONERY_GM;
uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0; uint32 itemTextId = !text.empty() ? objmgr.CreateItemText( text ) : 0;
Player *receiver = objmgr.GetPlayer(receiver_guid); WorldSession::SendMailTo(target,messagetype, stationery, sender_guidlo, GUID_LOPART(target_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE);
WorldSession::SendMailTo(receiver,messagetype, stationery, sender_guidlo, GUID_LOPART(receiver_guid), subject, itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_NONE); std::string nameLink = playerLink(target_name);
std::string nameLink = playerLink(name);
PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
return true; return true;
} }
@ -2069,23 +2015,20 @@ bool ChatHandler::HandleSendMailCommand(const char* args)
// teleport player to given game_tele.entry // teleport player to given game_tele.entry
bool ChatHandler::HandleTeleNameCommand(const char * args) bool ChatHandler::HandleTeleNameCommand(const char * args)
{ {
if(!*args) char* nameStr;
char* teleStr;
extractOptFirstArg((char*)args,&nameStr,&teleStr);
if(!teleStr)
return false; return false;
std::string name = extractPlayerNameFromLink((char*)args); Player* target;
if(name.empty()) uint64 target_guid;
{ std::string target_name;
SendSysMessage(LANG_PLAYER_NOT_FOUND); if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
SetSentErrorMessage(true);
return false;
}
char* tail = strtok(NULL, "");
if(!tail)
return false; return false;
// id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
GameTele const* tele = extractGameTeleFromLink(tail); GameTele const* tele = extractGameTeleFromLink(teleStr);
if(!tele) if(!tele)
{ {
SendSysMessage(LANG_COMMAND_TELE_NOTFOUND); SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
@ -2093,16 +2036,15 @@ bool ChatHandler::HandleTeleNameCommand(const char * args)
return false; return false;
} }
Player *chr = objmgr.GetPlayer(name.c_str()); if (target)
if (chr)
{ {
// check online security // check online security
if (HasLowerSecurity(chr, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
std::string chrNameLink = playerLink(name); std::string chrNameLink = playerLink(target_name);
if(chr->IsBeingTeleported()==true) if(target->IsBeingTeleported()==true)
{ {
PSendSysMessage(LANG_IS_TELEPORTED, chrNameLink.c_str()); PSendSysMessage(LANG_IS_TELEPORTED, chrNameLink.c_str());
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -2110,35 +2052,33 @@ bool ChatHandler::HandleTeleNameCommand(const char * args)
} }
PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(),"", tele->name.c_str()); PSendSysMessage(LANG_TELEPORTING_TO, chrNameLink.c_str(),"", tele->name.c_str());
if (needReportToTarget(chr)) if (needReportToTarget(target))
ChatHandler(chr).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str()); ChatHandler(target).PSendSysMessage(LANG_TELEPORTED_TO_BY, GetNameLink().c_str());
// stop flight if need // stop flight if need
if(chr->isInFlight()) if(target->isInFlight())
{ {
chr->GetMotionMaster()->MovementExpired(); target->GetMotionMaster()->MovementExpired();
chr->m_taxi.ClearTaxiDestinations(); target->m_taxi.ClearTaxiDestinations();
} }
// save only in non-flight case // save only in non-flight case
else else
chr->SaveRecallPosition(); target->SaveRecallPosition();
chr->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation); target->TeleportTo(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation);
} }
else if (uint64 guid = objmgr.GetPlayerGUIDByName(name)) else
{ {
// check offline security // check offline security
if (HasLowerSecurity(NULL, guid)) if (HasLowerSecurity(NULL, target_guid))
return false; return false;
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetMangosString(LANG_OFFLINE), tele->name.c_str()); PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetMangosString(LANG_OFFLINE), tele->name.c_str());
Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation, Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation,
MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),guid); MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),target_guid);
} }
else
PSendSysMessage(LANG_NO_PLAYER, name.c_str());
return true; return true;
} }
@ -2222,32 +2162,17 @@ bool ChatHandler::HandleTeleGroupCommand(const char * args)
//Summon group of player //Summon group of player
bool ChatHandler::HandleGroupgoCommand(const char* args) bool ChatHandler::HandleGroupgoCommand(const char* args)
{ {
if(!*args) Player* target;
if(!extractPlayerTarget((char*)args,&target))
return false; return false;
std::string name = extractPlayerNameFromLink((char*)args);
if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
Player *player = objmgr.GetPlayer(name.c_str());
if (!player)
{
PSendSysMessage(LANG_NO_PLAYER, args);
SetSentErrorMessage(true);
return false;
}
// check online security // check online security
if (HasLowerSecurity(player, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
Group *grp = player->GetGroup(); Group *grp = target->GetGroup();
std::string nameLink = playerLink(name); std::string nameLink = GetNameLink(target);
if(!grp) if(!grp)
{ {
@ -2281,7 +2206,7 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)
if (HasLowerSecurity(pl, 0)) if (HasLowerSecurity(pl, 0))
return false; return false;
std::string plNameLink = playerLink(name); std::string plNameLink = GetNameLink(pl);
if(pl->IsBeingTeleported()==true) if(pl->IsBeingTeleported()==true)
{ {
@ -2507,7 +2432,7 @@ bool ChatHandler::HandleGoZoneXYCommand(const char* args)
if(map->Instanceable()) if(map->Instanceable())
{ {
PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[m_session->GetSessionDbcLocale()],map->GetId(),map->GetMapName()); PSendSysMessage(LANG_INVALID_ZONE_MAP,areaEntry->ID,areaEntry->area_name[GetSessionDbcLocale()],map->GetId(),map->GetMapName());
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }

View file

@ -52,104 +52,89 @@ static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
//mute player for some times //mute player for some times
bool ChatHandler::HandleMuteCommand(const char* args) bool ChatHandler::HandleMuteCommand(const char* args)
{ {
if (!*args) char* nameStr;
char* delayStr;
extractOptFirstArg((char*)args,&nameStr,&delayStr);
if(!delayStr)
return false; return false;
std::string name = extractPlayerNameFromLink((char*)args); Player* target;
if(name.empty()) uint64 target_guid;
{ std::string target_name;
SendSysMessage(LANG_PLAYER_NOT_FOUND); if(!extractPlayerTarget(nameStr,&target,&target_guid,&target_name))
SetSentErrorMessage(true);
return false; return false;
uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
// find only player from same account if any
if(!target)
{
if(WorldSession* session = sWorld.FindSession(account_id))
target = session->GetPlayer();
} }
char *timetonotspeak = strtok(NULL, " "); uint32 notspeaktime = (uint32) atoi(delayStr);
if(!timetonotspeak)
return false;
uint32 notspeaktime = (uint32) atoi(timetonotspeak);
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
Player *chr = objmgr.GetPlayer(guid);
// must have strong lesser security level // must have strong lesser security level
if(HasLowerSecurity (chr,guid,true)) if(HasLowerSecurity (target,target_guid,true))
return false; return false;
uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid);
time_t mutetime = time(NULL) + notspeaktime*60; time_t mutetime = time(NULL) + notspeaktime*60;
if (chr) if (target)
chr->GetSession()->m_muteTime = mutetime; target->GetSession()->m_muteTime = mutetime;
loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id ); loginDatabase.PExecute("UPDATE account SET mutetime = " I64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
if(chr) if(target)
ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime); ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime);
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime); PSendSysMessage(LANG_YOU_DISABLE_CHAT, nameLink.c_str(), notspeaktime);
return true; return true;
} }
//unmute player //unmute player
bool ChatHandler::HandleUnmuteCommand(const char* args) bool ChatHandler::HandleUnmuteCommand(const char* args)
{ {
if (!*args) Player* target;
uint64 target_guid;
std::string target_name;
if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
return false; return false;
std::string name = extractPlayerNameFromLink((char*)args); uint32 account_id = target ? target->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(target_guid);
if(name.empty())
// find only player from same account if any
if(!target)
{ {
SendSysMessage(LANG_PLAYER_NOT_FOUND); if(WorldSession* session = sWorld.FindSession(account_id))
SetSentErrorMessage(true); target = session->GetPlayer();
return false;
} }
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
Player *chr = objmgr.GetPlayer(guid);
// must have strong lesser security level // must have strong lesser security level
if(HasLowerSecurity (chr,guid,true)) if(HasLowerSecurity (target,target_guid,true))
return false; return false;
uint32 account_id = chr ? chr->GetSession()->GetAccountId() : objmgr.GetPlayerAccountIdByGUID(guid); if (target)
if (chr)
{ {
if(chr->CanSpeak()) if(target->CanSpeak())
{ {
SendSysMessage(LANG_CHAT_ALREADY_ENABLED); SendSysMessage(LANG_CHAT_ALREADY_ENABLED);
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
chr->GetSession()->m_muteTime = 0; target->GetSession()->m_muteTime = 0;
} }
loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id ); loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
if(chr) if(target)
ChatHandler(chr).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str());
return true; return true;
@ -889,7 +874,7 @@ bool ChatHandler::HandleLookupFactionCommand(const char* args)
{ {
FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL; FactionState const* repState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL;
int loc = m_session ? m_session->GetSessionDbcLocale() : sWorld.GetDefaultDbcLocale(); int loc = GetSessionDbcLocale();
std::string name = factionEntry->name[loc]; std::string name = factionEntry->name[loc];
if(name.empty()) if(name.empty())
continue; continue;
@ -899,7 +884,7 @@ bool ChatHandler::HandleLookupFactionCommand(const char* args)
loc = 0; loc = 0;
for(; loc < MAX_LOCALE; ++loc) for(; loc < MAX_LOCALE; ++loc)
{ {
if(m_session && loc==m_session->GetSessionDbcLocale()) if(loc==GetSessionDbcLocale())
continue; continue;
name = factionEntry->name[loc]; name = factionEntry->name[loc];
@ -1044,13 +1029,13 @@ bool ChatHandler::HandleModifyRepCommand(const char * args)
if (factionEntry->reputationListID < 0) if (factionEntry->reputationListID < 0)
{ {
PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[m_session->GetSessionDbcLocale()], factionId); PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[GetSessionDbcLocale()], factionId);
SetSentErrorMessage(true); SetSentErrorMessage(true);
return false; return false;
} }
target->GetReputationMgr().SetReputation(factionEntry,amount); target->GetReputationMgr().SetReputation(factionEntry,amount);
PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[m_session->GetSessionDbcLocale()], factionId, PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[GetSessionDbcLocale()], factionId,
GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry)); GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry));
return true; return true;
} }
@ -2071,18 +2056,11 @@ bool ChatHandler::HandleModifyMorphCommand(const char* args)
//kick player //kick player
bool ChatHandler::HandleKickPlayerCommand(const char *args) bool ChatHandler::HandleKickPlayerCommand(const char *args)
{ {
if (!*args) Player* target;
{ if(!extractPlayerTarget((char*)args,&target))
Player* player = getSelectedPlayer();
if(!player)
{
SendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false; return false;
}
if(player==m_session->GetPlayer()) if (m_session && target==m_session->GetPlayer())
{ {
SendSysMessage(LANG_COMMAND_KICKSELF); SendSysMessage(LANG_COMMAND_KICKSELF);
SetSentErrorMessage(true); SetSentErrorMessage(true);
@ -2090,43 +2068,12 @@ bool ChatHandler::HandleKickPlayerCommand(const char *args)
} }
// check online security // check online security
if (HasLowerSecurity(player, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
player->GetSession()->KickPlayer(); // send before target pointer invalidate
} PSendSysMessage(LANG_COMMAND_KICKMESSAGE,GetNameLink(target).c_str());
else target->GetSession()->KickPlayer();
{
std::string name = extractPlayerNameFromLink((char*)args);
if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
if(m_session && name==m_session->GetPlayer()->GetName())
{
SendSysMessage(LANG_COMMAND_KICKSELF);
SetSentErrorMessage(true);
return false;
}
// check online security
Player* player = ObjectAccessor::Instance().FindPlayerByName(name.c_str());
if (player && HasLowerSecurity(player, 0))
return false;
std::string nameLink = playerLink(name);
if(sWorld.KickPlayer(name))
{
PSendSysMessage(LANG_COMMAND_KICKMESSAGE,nameLink.c_str());
}
else
PSendSysMessage(LANG_COMMAND_KICKNOTFOUNDPLAYER,nameLink.c_str());
}
return true; return true;
} }
@ -2154,48 +2101,11 @@ bool ChatHandler::HandleModifyPhaseCommand(const char* args)
//show info of player //show info of player
bool ChatHandler::HandlePInfoCommand(const char* args) bool ChatHandler::HandlePInfoCommand(const char* args)
{ {
Player* target = NULL; Player* target;
uint64 targetGUID = 0; uint64 target_guid;
std::string target_name;
char* px = strtok((char*)args, " "); if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
char* py = NULL;
std::string name;
if (px)
{
name = extractPlayerNameFromLink(px);
if(name.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false; return false;
}
target = objmgr.GetPlayer(name.c_str());
if (target)
py = strtok(NULL, " ");
else
{
targetGUID = objmgr.GetPlayerGUIDByName(name);
if(targetGUID)
py = strtok(NULL, " ");
else
py = px;
}
}
if(!target && !targetGUID)
{
target = getSelectedPlayer();
}
if(!target && !targetGUID)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
uint32 accId = 0; uint32 accId = 0;
uint32 money = 0; uint32 money = 0;
@ -2210,8 +2120,6 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
if (HasLowerSecurity(target, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
targetGUID = target->GetGUID();
name = target->GetName(); // re-read for case getSelectedPlayer() target
accId = target->GetSession()->GetAccountId(); accId = target->GetSession()->GetAccountId();
money = target->GetMoney(); money = target->GetMoney();
total_player_time = target->GetTotalPlayedTime(); total_player_time = target->GetTotalPlayedTime();
@ -2222,33 +2130,25 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
else else
{ {
// check offline security // check offline security
if (HasLowerSecurity(NULL, targetGUID)) if (HasLowerSecurity(NULL, target_guid))
return false; return false;
// 0 // 0
QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(targetGUID)); QueryResult *result = CharacterDatabase.PQuery("SELECT totaltime FROM characters WHERE guid = '%u'", GUID_LOPART(target_guid));
if (!result) if (!result)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false; return false;
}
Field *fields = result->Fetch(); Field *fields = result->Fetch();
total_player_time = fields[0].GetUInt32(); total_player_time = fields[0].GetUInt32();
delete result; delete result;
Tokens data; Tokens data;
if (!Player::LoadValuesArrayFromDB(data,targetGUID)) if (!Player::LoadValuesArrayFromDB(data,target_guid))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false; return false;
}
money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE); money = Player::GetUInt32ValueFromArray(data, PLAYER_FIELD_COINAGE);
level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL); level = Player::GetUInt32ValueFromArray(data, UNIT_FIELD_LEVEL);
accId = objmgr.GetPlayerAccountIdByGUID(target_guid);
accId = objmgr.GetPlayerAccountIdByGUID(targetGUID);
} }
std::string username = GetMangosString(LANG_ERROR); std::string username = GetMangosString(LANG_ERROR);
@ -2277,9 +2177,9 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
delete result; delete result;
} }
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGUID), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency); PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetMangosString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, security, last_ip.c_str(), last_login.c_str(), latency);
std::string timeStr = secsToTimeString(total_player_time,true,true); std::string timeStr = secsToTimeString(total_player_time,true,true);
uint32 gold = money /GOLD; uint32 gold = money /GOLD;
@ -2287,43 +2187,6 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
uint32 copp = (money % GOLD) % SILVER; uint32 copp = (money % GOLD) % SILVER;
PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp ); PSendSysMessage(LANG_PINFO_LEVEL, timeStr.c_str(), level, gold,silv,copp );
if ( py && strncmp(py, "rep", 3) == 0 )
{
if(!target)
{
// rep option not implemented for offline case
SendSysMessage(LANG_PINFO_NO_REP);
SetSentErrorMessage(true);
return false;
}
FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
{
FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
char const* factionName = factionEntry ? factionEntry->name[m_session->GetSessionDbcLocale()] : "#Not found#";
ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
std::ostringstream ss;
ss << itr->second.ID << ": |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << "]|h|r " << rankName << "|h|r ("
<< target->GetReputationMgr().GetReputation(factionEntry) << ")";
if(itr->second.Flags & FACTION_FLAG_VISIBLE)
ss << GetMangosString(LANG_FACTION_VISIBLE);
if(itr->second.Flags & FACTION_FLAG_AT_WAR)
ss << GetMangosString(LANG_FACTION_ATWAR);
if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
if(itr->second.Flags & FACTION_FLAG_HIDDEN)
ss << GetMangosString(LANG_FACTION_HIDDEN);
if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
if(itr->second.Flags & FACTION_FLAG_INACTIVE)
ss << GetMangosString(LANG_FACTION_INACTIVE);
SendSysMessage(ss.str().c_str());
}
}
return true; return true;
} }
@ -2416,27 +2279,18 @@ bool ChatHandler::HandleTicketCommand(const char* args)
return true; return true;
} }
std::string name = extractPlayerNameFromLink(px); uint64 target_guid;
if(name.empty()) if(!extractPlayerTarget(px,NULL,&target_guid))
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
return false; return false;
// ticket $char_name // ticket $char_name
GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(guid)); GMTicket* ticket = ticketmgr.GetGMTicket(GUID_LOPART(target_guid));
if(!ticket) if(!ticket)
return false; return false;
std::string time = TimeToTimestampStr(ticket->GetLastUpdate()); std::string time = TimeToTimestampStr(ticket->GetLastUpdate());
ShowTicket(guid, ticket->GetText(), time.c_str()); ShowTicket(target_guid, ticket->GetText(), time.c_str());
return true; return true;
} }
@ -2486,27 +2340,20 @@ bool ChatHandler::HandleDelTicketCommand(const char *args)
return true; return true;
} }
std::string name = extractPlayerNameFromLink(px); Player* target;
if(name.empty()) uint64 target_guid;
{ std::string target_name;
SendSysMessage(LANG_PLAYER_NOT_FOUND); if(!extractPlayerTarget(px,&target,&target_guid,&target_name))
SetSentErrorMessage(true);
return false;
}
uint64 guid = objmgr.GetPlayerGUIDByName(name);
if(!guid)
return false; return false;
// delticket $char_name // delticket $char_name
ticketmgr.Delete(GUID_LOPART(guid)); ticketmgr.Delete(GUID_LOPART(target_guid));
// notify players about ticket deleting // notify players about ticket deleting
if(Player* sender = objmgr.GetPlayer(guid)) if(target)
sender->GetSession()->SendGMTicketGetTicket(0x0A,0); target->GetSession()->SendGMTicketGetTicket(0x0A,0);
std::string nameLink = playerLink(name); std::string nameLink = playerLink(target_name);
PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str()); PSendSysMessage(LANG_COMMAND_TICKETPLAYERDEL,nameLink.c_str());
return true; return true;
@ -3657,39 +3504,11 @@ bool ChatHandler::HandleWpImportCommand(const char *args)
//rename characters //rename characters
bool ChatHandler::HandleCharacterRenameCommand(const char* args) bool ChatHandler::HandleCharacterRenameCommand(const char* args)
{ {
Player* target = NULL; Player* target;
uint64 targetGUID = 0; uint64 target_guid;
std::string oldname; std::string target_name;
if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
char* px = strtok((char*)args, " ");
if(px)
{
oldname = extractPlayerNameFromLink(px);
if(oldname.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false; return false;
}
target = objmgr.GetPlayer(oldname.c_str());
if (!target)
targetGUID = objmgr.GetPlayerGUIDByName(oldname);
}
if(!target && !targetGUID)
{
target = getSelectedPlayer();
}
if(!target && !targetGUID)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
if(target) if(target)
{ {
@ -3704,13 +3523,13 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args)
else else
{ {
// check offline security // check offline security
if (HasLowerSecurity(NULL, targetGUID)) if (HasLowerSecurity(NULL, target_guid))
return false; return false;
std::string oldNameLink = playerLink(oldname); std::string oldNameLink = playerLink(target_name);
PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID)); PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(targetGUID)); CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '1' WHERE guid = '%u'", GUID_LOPART(target_guid));
} }
return true; return true;
@ -3719,39 +3538,11 @@ bool ChatHandler::HandleCharacterRenameCommand(const char* args)
// customize characters // customize characters
bool ChatHandler::HandleCharacterCustomizeCommand(const char* args) bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
{ {
Player* target = NULL; Player* target;
uint64 targetGUID = 0; uint64 target_guid;
std::string oldname; std::string target_name;
if(!extractPlayerTarget((char*)args,&target,&target_guid,&target_name))
char* px = strtok((char*)args, " ");
if(px)
{
oldname = extractPlayerNameFromLink(px);
if(oldname.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false; return false;
}
target = objmgr.GetPlayer(oldname.c_str());
if (!target)
targetGUID = objmgr.GetPlayerGUIDByName(oldname);
}
if(!target && !targetGUID)
{
target = getSelectedPlayer();
}
if(!target && !targetGUID)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
if(target) if(target)
{ {
@ -3761,15 +3552,56 @@ bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
} }
else else
{ {
std::string oldNameLink = playerLink(oldname); std::string oldNameLink = playerLink(target_name);
PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGUID)); PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(target_guid));
CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID)); CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(target_guid));
} }
return true; return true;
} }
bool ChatHandler::HandleCharacterReputationCommand(const char* args)
{
Player* target;
if(!extractPlayerTarget((char*)args,&target))
return false;
LocaleConstant loc = GetSessionDbcLocale();
FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
for(FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
{
FactionEntry const *factionEntry = sFactionStore.LookupEntry(itr->second.ID);
char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#";
ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
std::string rankName = GetMangosString(ReputationRankStrIndex[rank]);
std::ostringstream ss;
if (m_session)
ss << itr->second.ID << " - |cffffffff|Hfaction:" << itr->second.ID << "|h[" << factionName << " " << localeNames[loc] << "]|h|r";
else
ss << itr->second.ID << " - " << factionName << " " << localeNames[loc];
ss << " " << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ")";
if(itr->second.Flags & FACTION_FLAG_VISIBLE)
ss << GetMangosString(LANG_FACTION_VISIBLE);
if(itr->second.Flags & FACTION_FLAG_AT_WAR)
ss << GetMangosString(LANG_FACTION_ATWAR);
if(itr->second.Flags & FACTION_FLAG_PEACE_FORCED)
ss << GetMangosString(LANG_FACTION_PEACE_FORCED);
if(itr->second.Flags & FACTION_FLAG_HIDDEN)
ss << GetMangosString(LANG_FACTION_HIDDEN);
if(itr->second.Flags & FACTION_FLAG_INVISIBLE_FORCED)
ss << GetMangosString(LANG_FACTION_INVISIBLE_FORCED);
if(itr->second.Flags & FACTION_FLAG_INACTIVE)
ss << GetMangosString(LANG_FACTION_INACTIVE);
SendSysMessage(ss.str().c_str());
}
return true;
}
//change standstate //change standstate
bool ChatHandler::HandleModifyStandStateCommand(const char* args) bool ChatHandler::HandleModifyStandStateCommand(const char* args)
{ {
@ -4048,41 +3880,16 @@ bool ChatHandler::HandleEventStopCommand(const char* args)
bool ChatHandler::HandleCombatStopCommand(const char* args) bool ChatHandler::HandleCombatStopCommand(const char* args)
{ {
Player *player; Player* target;
if(!extractPlayerTarget((char*)args,&target))
if(*args)
{
std::string playername = extractPlayerNameFromLink((char*)args);
if(playername.empty())
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false; return false;
}
player = objmgr.GetPlayer(playername.c_str());
if(!player)
{
SendSysMessage(LANG_PLAYER_NOT_FOUND);
SetSentErrorMessage(true);
return false;
}
}
else
{
player = getSelectedPlayer();
if (!player)
player = m_session->GetPlayer();
}
// check online security // check online security
if (HasLowerSecurity(player, 0)) if (HasLowerSecurity(target, 0))
return false; return false;
player->CombatStop(); target->CombatStop();
player->getHostilRefManager().deleteReferences(); target->getHostilRefManager().deleteReferences();
return true; return true;
} }
@ -4163,7 +3970,7 @@ bool ChatHandler::HandleLearnAllRecipesCommand(const char* args)
skillInfo->categoryId != SKILL_CATEGORY_SECONDARY ) skillInfo->categoryId != SKILL_CATEGORY_SECONDARY )
continue; continue;
int loc = m_session->GetSessionDbcLocale(); int loc = GetSessionDbcLocale();
std::string name = skillInfo->name[loc]; std::string name = skillInfo->name[loc];
if(Utf8FitTo(name, wnamepart)) if(Utf8FitTo(name, wnamepart))
@ -4314,16 +4121,11 @@ bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
return true; return true;
} }
bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/) bool ChatHandler::HandleRepairitemsCommand(const char* args)
{ {
Player *target = getSelectedPlayer(); Player* target;
if(!extractPlayerTarget((char*)args,&target))
if(!target)
{
PSendSysMessage(LANG_NO_CHAR_SELECTED);
SetSentErrorMessage(true);
return false; return false;
}
// check online security // check online security
if (HasLowerSecurity(target, 0)) if (HasLowerSecurity(target, 0))

File diff suppressed because it is too large Load diff

View file

@ -1227,9 +1227,13 @@ bool WorldObject::IsInRange(WorldObject const* obj, float minRange, float maxRan
float sizefactor = GetObjectSize() + obj->GetObjectSize(); float sizefactor = GetObjectSize() + obj->GetObjectSize();
// check only for real range
if(minRange > 0.0f)
{
float mindist = minRange + sizefactor; float mindist = minRange + sizefactor;
if(distsq < mindist * mindist) if(distsq < mindist * mindist)
return false; return false;
}
float maxdist = maxRange + sizefactor; float maxdist = maxRange + sizefactor;
return distsq < maxdist * maxdist; return distsq < maxdist * maxdist;
@ -1243,9 +1247,13 @@ bool WorldObject::IsInRange2d(float x, float y, float minRange, float maxRange)
float sizefactor = GetObjectSize(); float sizefactor = GetObjectSize();
// check only for real range
if(minRange > 0.0f)
{
float mindist = minRange + sizefactor; float mindist = minRange + sizefactor;
if(distsq < mindist * mindist) if(distsq < mindist * mindist)
return false; return false;
}
float maxdist = maxRange + sizefactor; float maxdist = maxRange + sizefactor;
return distsq < maxdist * maxdist; return distsq < maxdist * maxdist;
@ -1260,9 +1268,13 @@ bool WorldObject::IsInRange3d(float x, float y, float z, float minRange, float m
float sizefactor = GetObjectSize(); float sizefactor = GetObjectSize();
// check only for real range
if(minRange > 0.0f)
{
float mindist = minRange + sizefactor; float mindist = minRange + sizefactor;
if(distsq < mindist * mindist) if(distsq < mindist * mindist)
return false; return false;
}
float maxdist = maxRange + sizefactor; float maxdist = maxRange + sizefactor;
return distsq < maxdist * maxdist; return distsq < maxdist * maxdist;

View file

@ -6571,11 +6571,7 @@ bool ObjectMgr::LoadMangosStrings(DatabaseType& db, char const* table, int32 min
for(MangosStringLocaleMap::iterator itr = mMangosStringLocaleMap.begin(); itr != mMangosStringLocaleMap.end();) for(MangosStringLocaleMap::iterator itr = mMangosStringLocaleMap.begin(); itr != mMangosStringLocaleMap.end();)
{ {
if (itr->first >= start_value && itr->first < end_value) if (itr->first >= start_value && itr->first < end_value)
{ mMangosStringLocaleMap.erase(itr++);
MangosStringLocaleMap::iterator itr2 = itr;
++itr;
mMangosStringLocaleMap.erase(itr2);
}
else else
++itr; ++itr;
} }

View file

@ -156,7 +156,7 @@ typedef UNORDERED_MAP<uint32,ItemLocale> ItemLocaleMap;
typedef UNORDERED_MAP<uint32,QuestLocale> QuestLocaleMap; typedef UNORDERED_MAP<uint32,QuestLocale> QuestLocaleMap;
typedef UNORDERED_MAP<uint32,NpcTextLocale> NpcTextLocaleMap; typedef UNORDERED_MAP<uint32,NpcTextLocale> NpcTextLocaleMap;
typedef UNORDERED_MAP<uint32,PageTextLocale> PageTextLocaleMap; typedef UNORDERED_MAP<uint32,PageTextLocale> PageTextLocaleMap;
typedef UNORDERED_MAP<uint32,MangosStringLocale> MangosStringLocaleMap; typedef UNORDERED_MAP<int32,MangosStringLocale> MangosStringLocaleMap;
typedef UNORDERED_MAP<uint32,NpcOptionLocale> NpcOptionLocaleMap; typedef UNORDERED_MAP<uint32,NpcOptionLocale> NpcOptionLocaleMap;
typedef UNORDERED_MAP<uint32,PointOfInterestLocale> PointOfInterestLocaleMap; typedef UNORDERED_MAP<uint32,PointOfInterestLocale> PointOfInterestLocaleMap;

View file

@ -340,6 +340,8 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
} }
} }
InitLevelupSpellsForLevel();
m_loading = false; m_loading = false;
SynchronizeLevelWithOwner(); SynchronizeLevelWithOwner();
@ -653,6 +655,9 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)
for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
{ {
if(itr->second.state == PETSPELL_REMOVED)
continue;
if(IsPassiveSpell(itr->first)) if(IsPassiveSpell(itr->first))
continue; continue;
@ -746,6 +751,7 @@ void Pet::GivePetLevel(uint32 level)
return; return;
InitStatsForLevel(level); InitStatsForLevel(level);
InitLevelupSpellsForLevel();
InitTalentForLevel(); InitTalentForLevel();
} }
@ -847,7 +853,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
else if (getLevel() <= cFamily->minScaleLevel) else if (getLevel() <= cFamily->minScaleLevel)
scale = cFamily->minScale; scale = cFamily->minScale;
else else
scale = cFamily->minScale + (getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale); scale = cFamily->minScale + float(getLevel() - cFamily->minScaleLevel) / cFamily->maxScaleLevel * (cFamily->maxScale - cFamily->minScale);
SetFloatValue(OBJECT_FIELD_SCALE_X, scale); SetFloatValue(OBJECT_FIELD_SCALE_X, scale);
} }
@ -994,9 +1000,6 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i])); SetModifierValue(UnitMods(UNIT_MOD_RESISTANCE_START + i), BASE_VALUE, float(createResistance[i]));
if(cinfo->family)
learnLevelupSpells();
UpdateAllStats(); UpdateAllStats();
SetHealth(GetMaxHealth()); SetHealth(GetMaxHealth());
@ -1118,7 +1121,7 @@ void Pet::_LoadSpells()
{ {
Field *fields = result->Fetch(); Field *fields = result->Fetch();
addSpell(fields[0].GetUInt32(), fields[1].GetUInt16(), PETSPELL_UNCHANGED); addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED);
} }
while( result->NextRow() ); while( result->NextRow() );
@ -1284,7 +1287,7 @@ void Pet::_SaveAuras()
} }
} }
bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/) bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpellState state /*= PETSPELL_NEW*/, PetSpellType type /*= PETSPELL_NORMAL*/)
{ {
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id); SpellEntry const *spellInfo = sSpellStore.LookupEntry(spell_id);
if (!spellInfo) if (!spellInfo)
@ -1356,17 +1359,20 @@ bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState
// skip unknown ranks // skip unknown ranks
if(!HasSpell(rankSpellId)) if(!HasSpell(rankSpellId))
continue; continue;
removeSpell(rankSpellId); removeSpell(rankSpellId,false);
} }
} }
} }
else if(uint32 chainstart = spellmgr.GetFirstSpellInChain(spell_id)) else if(spellmgr.GetSpellRank(spell_id)!=0)
{ {
for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2) for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2)
{ {
if(itr2->second.state == PETSPELL_REMOVED) continue; if(itr2->second.state == PETSPELL_REMOVED) continue;
if(spellmgr.GetFirstSpellInChain(itr2->first) == chainstart) if( spellmgr.IsRankSpellDueToSpell(spellInfo,itr2->first) )
{
// replace by new high rank
if(spellmgr.IsHighRankOfSpell(spell_id,itr2->first))
{ {
newspell.active = itr2->second.active; newspell.active = itr2->second.active;
@ -1374,9 +1380,13 @@ bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState
ToggleAutocast(itr2->first, false); ToggleAutocast(itr2->first, false);
oldspell_id = itr2->first; oldspell_id = itr2->first;
unlearnSpell(itr2->first); unlearnSpell(itr2->first,false);
break; break;
} }
// ignore new lesser rank
else if(spellmgr.IsHighRankOfSpell(itr2->first,spell_id))
return false;
}
} }
} }
@ -1384,7 +1394,7 @@ bool Pet::addSpell(uint32 spell_id,uint16 active /*= ACT_DECIDE*/, PetSpellState
if (IsPassiveSpell(spell_id)) if (IsPassiveSpell(spell_id))
CastSpell(this, spell_id, true); CastSpell(this, spell_id, true);
else if(state == PETSPELL_NEW) else
m_charmInfo->AddSpellToAB(oldspell_id, spell_id); m_charmInfo->AddSpellToAB(oldspell_id, spell_id);
if(newspell.active == ACT_ENABLED) if(newspell.active == ACT_ENABLED)
@ -1422,26 +1432,33 @@ bool Pet::learnSpell(uint32 spell_id)
return true; return true;
} }
void Pet::learnLevelupSpells() void Pet::InitLevelupSpellsForLevel()
{ {
PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family); uint32 family = GetCreatureInfo()->family;
if(!family)
return;
PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(family);
if(!levelupSpells) if(!levelupSpells)
return; return;
uint32 level = getLevel(); uint32 level = getLevel();
for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr) // PetLevelupSpellSet ordered by levels, process in reversed order
for(PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr)
{ {
if(itr->first <= level) // will called first if level down
learnSpell(itr->second); if(itr->first > level)
unlearnSpell(itr->second,true); // will learn prev rank if any
// will called if level up
else else
unlearnSpell(itr->second); learnSpell(itr->second); // will unlearn prev rank if any
} }
} }
bool Pet::unlearnSpell(uint32 spell_id) bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev)
{ {
if(removeSpell(spell_id)) if(removeSpell(spell_id,learn_prev))
{ {
if(GetOwner()->GetTypeId() == TYPEID_PLAYER) if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
{ {
@ -1457,7 +1474,7 @@ bool Pet::unlearnSpell(uint32 spell_id)
return false; return false;
} }
bool Pet::removeSpell(uint32 spell_id) bool Pet::removeSpell(uint32 spell_id, bool learn_prev)
{ {
PetSpellMap::iterator itr = m_spells.find(spell_id); PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end()) if (itr == m_spells.end())
@ -1485,6 +1502,27 @@ bool Pet::removeSpell(uint32 spell_id)
SetFreeTalentPoints(free_points > 0 ? free_points : 0); SetFreeTalentPoints(free_points > 0 ? free_points : 0);
} }
if (learn_prev)
{
if (uint32 prev_id = spellmgr.GetPrevSpellInChain (spell_id))
{
// replace to next spell
if(!talentCost && !IsPassiveSpell(prev_id))
m_charmInfo->AddSpellToAB(spell_id, prev_id);
learnSpell(prev_id);
}
else
{
m_charmInfo->AddSpellToAB(spell_id, 0);
// need update action bar for last removed rank
if (Unit* owner = GetOwner())
if (owner->GetTypeId() == TYPEID_PLAYER)
((Player*)owner)->PetSpellInitialize();
}
}
return true; return true;
} }
@ -1620,7 +1658,7 @@ bool Pet::resetTalents(bool no_cost)
// unlearn if first rank is talent or learned by talent // unlearn if first rank is talent or learned by talent
if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId)) if (itrFirstId == talentInfo->RankID[j] || spellmgr.IsSpellLearnToSpell(talentInfo->RankID[j],itrFirstId))
{ {
removeSpell(itr->first); removeSpell(itr->first,false);
itr = m_spells.begin(); itr = m_spells.begin();
continue; continue;
} }

View file

@ -69,7 +69,7 @@ enum PetSpellType
struct PetSpell struct PetSpell
{ {
uint16 active; ActiveStates active : 16;
PetSpellState state : 8; PetSpellState state : 8;
PetSpellType type : 8; PetSpellType type : 8;
@ -196,12 +196,12 @@ class Pet : public Creature
void _LoadSpells(); void _LoadSpells();
void _SaveSpells(); void _SaveSpells();
bool addSpell(uint32 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL); bool addSpell(uint32 spell_id,ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id); bool learnSpell(uint32 spell_id);
void learnSpellHighRank(uint32 spellid); void learnSpellHighRank(uint32 spellid);
void learnLevelupSpells(); void InitLevelupSpellsForLevel();
bool unlearnSpell(uint32 spell_id); bool unlearnSpell(uint32 spell_id, bool learn_prev);
bool removeSpell(uint32 spell_id); bool removeSpell(uint32 spell_id, bool learn_prev);
PetSpellMap m_spells; PetSpellMap m_spells;
TeachSpellMap m_teachspells; TeachSpellMap m_teachspells;

View file

@ -1421,8 +1421,8 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << uint8(getLevel()); // player level *p_data << uint8(getLevel()); // player level
// do not use GetMap! it will spawn a new instance since the bound instances are not loaded // do not use GetMap! it will spawn a new instance since the bound instances are not loaded
uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY(),GetPositionZ()); uint32 zoneId = fields[10].GetUInt32();
sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId); sLog.outDebug("Player::BuildEnumData: map:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId);
*p_data << uint32(zoneId); *p_data << uint32(zoneId);
*p_data << uint32(GetMapId()); *p_data << uint32(GetMapId());
@ -1431,7 +1431,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
*p_data << GetPositionZ(); *p_data << GetPositionZ();
// guild id // guild id
*p_data << (result ? fields[13].GetUInt32() : 0); *p_data << uint32(fields[14].GetUInt32());
uint32 char_flags = 0; uint32 char_flags = 0;
if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM))
@ -1444,7 +1444,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
char_flags |= CHARACTER_FLAG_RENAME; char_flags |= CHARACTER_FLAG_RENAME;
if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED)) if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED))
{ {
if(!fields[14].GetCppString().empty()) if(!fields[15].GetCppString().empty())
char_flags |= CHARACTER_FLAG_DECLINED; char_flags |= CHARACTER_FLAG_DECLINED;
} }
else else
@ -1464,12 +1464,12 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )
// show pet at selection character in character list only for non-ghost character // show pet at selection character in character list only for non-ghost character
if (result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER || pClass == CLASS_DEATH_KNIGHT)) if (result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER || pClass == CLASS_DEATH_KNIGHT))
{ {
uint32 entry = fields[10].GetUInt32(); uint32 entry = fields[11].GetUInt32();
CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry);
if(cInfo) if(cInfo)
{ {
petDisplayId = fields[11].GetUInt32(); petDisplayId = fields[12].GetUInt32();
petLevel = fields[12].GetUInt32(); petLevel = fields[13].GetUInt32();
petFamily = cInfo->family; petFamily = cInfo->family;
} }
} }
@ -2070,11 +2070,17 @@ void Player::SetGameMaster(bool on)
setFaction(35); setFaction(35);
SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
if (Pet* pet = GetPet())
{
pet->setFaction(35);
pet->getHostilRefManager().setOnlineOfflineState(false);
}
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
ResetContestedPvP(); ResetContestedPvP();
getHostilRefManager().setOnlineOfflineState(false); getHostilRefManager().setOnlineOfflineState(false);
CombatStop(); CombatStopWithPets();
SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases
} }
@ -2088,6 +2094,12 @@ void Player::SetGameMaster(bool on)
setFactionForRace(getRace()); setFactionForRace(getRace());
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
if (Pet* pet = GetPet())
{
pet->setFaction(getFaction());
pet->getHostilRefManager().setOnlineOfflineState(true);
}
// restore FFA PvP Server state // restore FFA PvP Server state
if(sWorld.IsFFAPvPRealm()) if(sWorld.IsFFAPvPRealm())
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
@ -11583,6 +11595,14 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot, bool apply, bool
sLog.outDebug("Adding %u to stat nb %u",enchant_amount,enchant_spell_id); sLog.outDebug("Adding %u to stat nb %u",enchant_amount,enchant_spell_id);
switch (enchant_spell_id) switch (enchant_spell_id)
{ {
case ITEM_MOD_MANA:
sLog.outDebug("+ %u MANA",enchant_amount);
HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(enchant_amount), apply);
break;
case ITEM_MOD_HEALTH:
sLog.outDebug("+ %u HEALTH",enchant_amount);
HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, float(enchant_amount), apply);
break;
case ITEM_MOD_AGILITY: case ITEM_MOD_AGILITY:
sLog.outDebug("+ %u AGILITY",enchant_amount); sLog.outDebug("+ %u AGILITY",enchant_amount);
HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply); HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, float(enchant_amount), apply);
@ -13634,18 +13654,21 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
bool delete_result = true; bool delete_result = true;
if (!result) if (!result)
{ {
// 0 1 2 3 4 5 6 7 8 9 // 0 1 2 3 4 5 6 7 8 9 10
result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login FROM characters WHERE guid = '%u'",guid); result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login, zone FROM characters WHERE guid = '%u'",guid);
if(!result) return false; if (!result)
return false;
} }
else delete_result = false; else
delete_result = false;
Field *fields = result->Fetch(); Field *fields = result->Fetch();
if (!LoadValues( fields[1].GetString())) if (!LoadValues( fields[1].GetString()))
{ {
sLog.outError("Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid)); sLog.outError("Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid));
if(delete_result) delete result; if (delete_result)
delete result;
return false; return false;
} }
@ -13668,7 +13691,8 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )
_LoadBoundInstances();*/ _LoadBoundInstances();*/
if (delete_result) delete result; if (delete_result)
delete result;
for (int i = 0; i < PLAYER_SLOTS_COUNT; ++i) for (int i = 0; i < PLAYER_SLOTS_COUNT; ++i)
m_items[i] = NULL; m_items[i] = NULL;

View file

@ -2417,18 +2417,19 @@ void Spell::cast(bool skipCheck)
((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id);
} }
FillTargetMap();
if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in FillTargetMap
{
SetExecutedCurrently(false);
return;
}
// CAST SPELL // CAST SPELL
SendSpellCooldown(); SendSpellCooldown();
TakePower(); TakePower();
TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
FillTargetMap();
if(m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
{
SetExecutedCurrently(false);
return;
}
SendCastResult(castResult); SendCastResult(castResult);
SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()... SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...

View file

@ -1081,6 +1081,7 @@ void Aura::_RemoveAura()
m_target->ModifyAuraState(AURA_STATE_ENRAGE, false); m_target->ModifyAuraState(AURA_STATE_ENRAGE, false);
uint32 removeState = 0; uint32 removeState = 0;
uint64 removeFamilyFlag = m_spellProto->SpellFamilyFlags;
switch(m_spellProto->SpellFamilyName) switch(m_spellProto->SpellFamilyName)
{ {
case SPELLFAMILY_PALADIN: case SPELLFAMILY_PALADIN:
@ -1095,7 +1096,10 @@ void Aura::_RemoveAura()
if(m_spellProto->SpellFamilyFlags & 0x0000000000000400LL) if(m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions) removeState = AURA_STATE_FAERIE_FIRE; // Faerie Fire (druid versions)
else if(m_spellProto->SpellFamilyFlags & 0x50) else if(m_spellProto->SpellFamilyFlags & 0x50)
{
removeFamilyFlag = 0x50;
removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state removeState = AURA_STATE_SWIFTMEND; // Swiftmend aura state
}
break; break;
case SPELLFAMILY_WARRIOR: case SPELLFAMILY_WARRIOR:
if(m_spellProto->SpellFamilyFlags & 0x0004000000000000LL) if(m_spellProto->SpellFamilyFlags & 0x0004000000000000LL)
@ -1119,7 +1123,7 @@ void Aura::_RemoveAura()
{ {
SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto(); SpellEntry const *auraSpellInfo = (*i).second->GetSpellProto();
if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName && if(auraSpellInfo->SpellFamilyName == m_spellProto->SpellFamilyName &&
auraSpellInfo->SpellFamilyFlags == m_spellProto->SpellFamilyFlags ) auraSpellInfo->SpellFamilyFlags & removeFamilyFlag)
{ {
found = true; found = true;
break; break;

View file

@ -3262,6 +3262,7 @@ void Spell::EffectSummon(uint32 i)
spawnCreature->AIM_Initialize(); spawnCreature->AIM_Initialize();
spawnCreature->InitPetCreateSpells(); spawnCreature->InitPetCreateSpells();
spawnCreature->InitLevelupSpellsForLevel();
spawnCreature->SetHealth(spawnCreature->GetMaxHealth()); spawnCreature->SetHealth(spawnCreature->GetMaxHealth());
spawnCreature->SetPower(POWER_MANA, spawnCreature->GetMaxPower(POWER_MANA)); spawnCreature->SetPower(POWER_MANA, spawnCreature->GetMaxPower(POWER_MANA));
@ -4174,6 +4175,7 @@ void Spell::EffectSummonPet(uint32 i)
NewSummon->InitStatsForLevel(petlevel); NewSummon->InitStatsForLevel(petlevel);
NewSummon->InitPetCreateSpells(); NewSummon->InitPetCreateSpells();
NewSummon->InitLevelupSpellsForLevel();
NewSummon->InitTalentForLevel(); NewSummon->InitTalentForLevel();
if(NewSummon->getPetType()==SUMMON_PET) if(NewSummon->getPetType()==SUMMON_PET)
@ -5971,6 +5973,7 @@ void Spell::EffectSummonCritter(uint32 i)
critter->AIM_Initialize(); critter->AIM_Initialize();
critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter... critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter...
//critter->InitLevelupSpellsForLevel(); // none?
critter->SelectLevel(critter->GetCreatureInfo()); // some summoned creaters have different from 1 DB data for level/hp critter->SelectLevel(critter->GetCreatureInfo()); // some summoned creaters have different from 1 DB data for level/hp
critter->SetUInt32Value(UNIT_NPC_FLAGS, critter->GetCreatureInfo()->npcflag); critter->SetUInt32Value(UNIT_NPC_FLAGS, critter->GetCreatureInfo()->npcflag);
// some mini-pets have quests // some mini-pets have quests

View file

@ -5949,7 +5949,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
default: default:
return false; return false;
} }
CastSpell(this, spell, true, castItem, triggeredByAura); CastSpell(target, spell, true, castItem, triggeredByAura);
if ((*itr)->DropAuraCharge()) if ((*itr)->DropAuraCharge())
RemoveAurasDueToSpell((*itr)->GetId()); RemoveAurasDueToSpell((*itr)->GetId());
return true; return true;
@ -10403,9 +10403,18 @@ void CharmInfo::InitCharmCreateSpells()
bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate) bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
{ {
// new spell already listed for example in case prepered switch to lesser rank in Pet::removeSpell
for(uint8 i = 0; i < 10; ++i)
if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE)
if (newid && PetActionBar[i].SpellOrAction == newid)
return true;
// old spell can be leasted for example in case learn high rank
for(uint8 i = 0; i < 10; ++i) for(uint8 i = 0; i < 10; ++i)
{ {
if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid) if (PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE)
{
if (PetActionBar[i].SpellOrAction == oldid)
{ {
PetActionBar[i].SpellOrAction = newid; PetActionBar[i].SpellOrAction = newid;
if (!oldid) if (!oldid)
@ -10419,6 +10428,7 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
return true; return true;
} }
} }
}
return false; return false;
} }
@ -11406,6 +11416,7 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)
// this enables pet details window (Shift+P) // this enables pet details window (Shift+P)
pet->AIM_Initialize(); pet->AIM_Initialize();
pet->InitPetCreateSpells(); pet->InitPetCreateSpells();
pet->InitLevelupSpellsForLevel();
pet->InitTalentForLevel(); pet->InitTalentForLevel();
pet->SetHealth(pet->GetMaxHealth()); pet->SetHealth(pet->GetMaxHealth());

View file

@ -2454,31 +2454,6 @@ void World::KickAllLess(AccountTypes sec)
itr->second->KickPlayer(); itr->second->KickPlayer();
} }
/// Kick (and save) the designated player
bool World::KickPlayer(const std::string& playerName)
{
SessionMap::const_iterator itr;
// session not removed at kick and will removed in next update tick
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
{
if(!itr->second)
continue;
Player *player = itr->second->GetPlayer();
if(!player)
continue;
if( player->IsInWorld() )
{
if (playerName == player->GetName())
{
itr->second->KickPlayer();
return true;
}
}
}
return false;
}
/// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban /// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban
BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author) BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author)
{ {

View file

@ -406,7 +406,7 @@ class World
/// Get the current Message of the Day /// Get the current Message of the Day
const char* GetMotd() const { return m_motd.c_str(); } const char* GetMotd() const { return m_motd.c_str(); }
uint32 GetDefaultDbcLocale() const { return m_defaultDbcLocale; } LocaleConstant GetDefaultDbcLocale() const { return m_defaultDbcLocale; }
/// Get the path where data (dbc, maps) are stored on disk /// Get the path where data (dbc, maps) are stored on disk
std::string GetDataPath() const { return m_dataPath; } std::string GetDataPath() const { return m_dataPath; }
@ -472,7 +472,6 @@ class World
bool IsPvPRealm() { return (getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); } bool IsPvPRealm() { return (getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); }
bool IsFFAPvPRealm() { return getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; } bool IsFFAPvPRealm() { return getConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; }
bool KickPlayer(const std::string& playerName);
void KickAll(); void KickAll();
void KickAllLess(AccountTypes sec); void KickAllLess(AccountTypes sec);
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author); BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);

View file

@ -90,7 +90,7 @@ inline void ApplyModFloatVar(float& var, float val, bool apply)
inline void ApplyPercentModFloatVar(float& var, float val, bool apply) inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
{ {
if (!apply && val == -100.0f) if (val == -100.0f) // prevent set var to zero
val = -99.99f; val = -99.99f;
var *= (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val)); var *= (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val));
} }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7835" #define REVISION_NR "7856"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__