diff options
author | Paradox iamparadox@netscape.net <none@none> | 2009-02-26 11:11:57 -0500 |
---|---|---|
committer | Paradox iamparadox@netscape.net <none@none> | 2009-02-26 11:11:57 -0500 |
commit | 2376e04a3a21f795dc4e6ab2ae6186e1374c7977 (patch) | |
tree | 264a2299381f613f260617e241df79bcf5495522 | |
parent | 64540eff85465fca81121cc3de85fecc7315cf3e (diff) |
change CRLF files to LF This needs to be done in the main TC2 repo too
--HG--
branch : trunk
8 files changed, 3281 insertions, 3281 deletions
diff --git a/sql/TBC-WLK converter/TBC-WLK_world_run_only_once.sql b/sql/TBC-WLK converter/TBC-WLK_world_run_only_once.sql index 5882d1a0b3c..798d296370c 100644 --- a/sql/TBC-WLK converter/TBC-WLK_world_run_only_once.sql +++ b/sql/TBC-WLK converter/TBC-WLK_world_run_only_once.sql @@ -1,189 +1,189 @@ -DROP TABLE IF EXISTS `achievement_reward`;
-CREATE TABLE `achievement_reward` (
- `entry` mediumint(8) unsigned NOT NULL default '0',
- `title_A` mediumint(8) unsigned NOT NULL default '0',
- `title_H` mediumint(8) unsigned NOT NULL default '0',
- `item` mediumint(8) unsigned NOT NULL default '0',
- `sender` mediumint(8) unsigned NOT NULL default '0',
- `subject` varchar(255) default NULL,
- `text` text,
- PRIMARY KEY (`entry`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System';
-
-
-DROP TABLE IF EXISTS `locales_achievement_reward`;
-CREATE TABLE `locales_achievement_reward` (
- `entry` mediumint(8) unsigned NOT NULL default '0',
- `subject_loc1` varchar(100) NOT NULL default '',
- `subject_loc2` varchar(100) NOT NULL default '',
- `subject_loc3` varchar(100) NOT NULL default '',
- `subject_loc4` varchar(100) NOT NULL default '',
- `subject_loc5` varchar(100) NOT NULL default '',
- `subject_loc6` varchar(100) NOT NULL default '',
- `subject_loc7` varchar(100) NOT NULL default '',
- `subject_loc8` varchar(100) NOT NULL default '',
- `text_loc1` text default NULL,
- `text_loc2` text default NULL,
- `text_loc3` text default NULL,
- `text_loc4` text default NULL,
- `text_loc5` text default NULL,
- `text_loc6` text default NULL,
- `text_loc7` text default NULL,
- `text_loc8` text default NULL,
- PRIMARY KEY (`entry`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-TRUNCATE `creature_equip_template`;
-ALTER TABLE `creature_equip_template`
- DROP COLUMN `equipinfo1`,
- DROP COLUMN `equipinfo2`,
- DROP COLUMN `equipinfo3`,
- DROP COLUMN `equipslot1`,
- DROP COLUMN `equipslot2`,
- DROP COLUMN `equipslot3`,
- CHANGE COLUMN `equipmodel1` `equipentry1` mediumint(8) UNSIGNED default '0' NOT NULL,
- CHANGE COLUMN `equipmodel2` `equipentry2` mediumint(8) UNSIGNED default '0' NOT NULL,
- CHANGE COLUMN `equipmodel3` `equipentry3` mediumint(8) UNSIGNED default '0' NOT NULL;
-UPDATE `creature_template` set equipment_id = 0;
-
-ALTER TABLE `item_template`
- ADD COLUMN `ScalingStatDistribution` smallint(6) DEFAULT '0' NOT NULL after `stat_value10`,
- ADD COLUMN `ScalingStatValue` smallint(6) DEFAULT '0' NOT NULL after `ScalingStatDistribution`,
- ADD COLUMN `ItemLimitCategory` smallint(6) DEFAULT '0' NOT NULL after `ArmorDamageModifier`,
- CHANGE COLUMN `Duration` `Duration` int(11) NOT NULL default '0' COMMENT 'Duration in seconds. Negative value means realtime, postive value ingame time' after ArmorDamageModifier,
- ADD COLUMN `StatsCount` tinyint(3) UNSIGNED DEFAULT '0' NOT NULL after `ContainerSlots`,
- CHANGE COLUMN `TotemCategory` `TotemCategory` mediumint(9) NOT NULL default '0';
-
-UPDATE `item_template`
- SET `maxcount`=0 WHERE `maxcount` > 32000;
-UPDATE `item_template`
- SET `stackable`=0 WHERE `stackable` > 32000;
-ALTER TABLE `item_template`
- CHANGE COLUMN `maxcount` `maxcount` smallint(5) NOT NULL default '-1',
- CHANGE COLUMN `stackable` `stackable` smallint(5) NOT NULL default '1';
-UPDATE `item_template`
- SET `stackable`=-1 WHERE `stackable` = 0;
-
-ALTER TABLE `quest_template`
- ADD COLUMN `PlayersSlain` tinyint(3) UNSIGNED DEFAULT '0' NOT NULL after `CharTitleId`,
- ADD COLUMN `BonusTalents` tinyint(3) UNSIGNED DEFAULT '0' NOT NULL after `PlayersSlain`,
- CHANGE COLUMN `RewHonorableKills` `RewHonorableKills` int unsigned NOT NULL default '0';
-
-DROP TABLE IF EXISTS `milling_loot_template`;
-CREATE TABLE `milling_loot_template` (
- `entry` mediumint(8) unsigned NOT NULL default '0',
- `item` mediumint(8) unsigned NOT NULL default '0',
- `ChanceOrQuestChance` float NOT NULL default '100',
- `groupid` tinyint(3) unsigned NOT NULL default '0',
- `mincountOrRef` mediumint(9) NOT NULL default '1',
- `maxcount` tinyint(3) unsigned NOT NULL default '1',
- `lootcondition` tinyint(3) unsigned NOT NULL default '0',
- `condition_value1` mediumint(8) unsigned NOT NULL default '0',
- `condition_value2` mediumint(8) unsigned NOT NULL default '0',
- PRIMARY KEY (`entry`,`item`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System';
-
-DROP TABLE IF EXISTS `spell_affect`;
-CREATE TABLE `spell_affect` (
- `entry` smallint(5) unsigned NOT NULL default '0',
- `effectId` tinyint(3) unsigned NOT NULL default '0',
- `SpellClassMask0` int(5) unsigned NOT NULL default '0',
- `SpellClassMask1` int(5) unsigned NOT NULL default '0',
- `SpellClassMask2` int(5) unsigned NOT NULL default '0',
- PRIMARY KEY (`entry`,`effectId`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-ALTER TABLE `skill_discovery_template`
- DROP PRIMARY KEY,
- ADD PRIMARY KEY (`spellId`,`reqSpell`),
- ADD COLUMN `reqClass` tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement' AFTER reqSpell;
-ALTER TABLE skill_discovery_template
- DROP COLUMN `reqClass`,
- ADD COLUMN `reqSkillValue` smallint(5) unsigned NOT NULL default '0' COMMENT 'skill points requirement' AFTER reqSpell;
-
-DROP TABLE IF EXISTS `player_classlevelstats`;
-CREATE TABLE `player_classlevelstats` (
- `class` tinyint(3) unsigned NOT NULL,
- `level` tinyint(3) unsigned NOT NULL,
- `basehp` smallint(5) unsigned NOT NULL,
- `basemana` smallint(5) unsigned NOT NULL,
- PRIMARY KEY (`class`,`level`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.';
-
-DROP TABLE IF EXISTS `player_levelstats`;
-CREATE TABLE `player_levelstats` (
- `race` tinyint(3) unsigned NOT NULL,
- `class` tinyint(3) unsigned NOT NULL,
- `level` tinyint(3) unsigned NOT NULL,
- `str` tinyint(3) unsigned NOT NULL,
- `agi` tinyint(3) unsigned NOT NULL,
- `sta` tinyint(3) unsigned NOT NULL,
- `inte` tinyint(3) unsigned NOT NULL,
- `spi` tinyint(3) unsigned NOT NULL,
- PRIMARY KEY (`race`,`class`,`level`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.';
-
-DROP TABLE IF EXISTS `playercreateinfo_spell`;
-CREATE TABLE `playercreateinfo_spell` (
- `race` tinyint(3) unsigned NOT NULL default '0',
- `class` tinyint(3) unsigned NOT NULL default '0',
- `Spell` mediumint(8) unsigned NOT NULL default '0',
- `Note` varchar(255) default NULL,
- PRIMARY KEY (`race`,`class`,`Spell`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-DROP TABLE IF EXISTS `playercreateinfo_action`;
-CREATE TABLE `playercreateinfo_action` (
- `race` tinyint(3) unsigned NOT NULL default '0',
- `class` tinyint(3) unsigned NOT NULL default '0',
- `button` smallint(5) unsigned NOT NULL default '0',
- `action` smallint(5) unsigned NOT NULL default '0',
- `type` smallint(5) unsigned NOT NULL default '0',
- `misc` smallint(5) unsigned NOT NULL default '0',
- KEY `playercreateinfo_race_class_index` (`race`,`class`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-DROP TABLE IF EXISTS `spell_learn_spell`;
-CREATE TABLE `spell_learn_spell` (
- `entry` smallint(5) unsigned NOT NULL default '0',
- `SpellID` smallint(5) unsigned NOT NULL default '0',
- `Active` tinyint(3) unsigned NOT NULL default '1',
- PRIMARY KEY (`entry`,`SpellID`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System';
-
-DROP TABLE IF EXISTS `spell_proc_event`;
-CREATE TABLE `spell_proc_event` (
- `entry` smallint(5) unsigned NOT NULL default '0',
- `SchoolMask` tinyint(4) NOT NULL default '0',
- `SpellFamilyName` smallint(5) unsigned NOT NULL default '0',
- `SpellFamilyMask0` int(10) unsigned NOT NULL default '0',
- `SpellFamilyMask1` int(10) unsigned NOT NULL default '0',
- `SpellFamilyMask2` int(10) unsigned NOT NULL default '0',
- `procFlags` int(10) unsigned NOT NULL default '0',
- `procEx` int(10) unsigned NOT NULL default '0',
- `ppmRate` float NOT NULL default '0',
- `CustomChance` float NOT NULL default '0',
- `Cooldown` int(10) unsigned NOT NULL default '0',
- PRIMARY KEY (`entry`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-DROP TABLE IF EXISTS `player_xp_for_level`;
-CREATE TABLE `player_xp_for_level` (
- `lvl` int(3) unsigned NOT NULL,
- `xp_for_next_level` int(10) unsigned NOT NULL,
- PRIMARY KEY (`lvl`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
-DROP TABLE IF EXISTS `spell_loot_template`;
-CREATE TABLE `spell_loot_template` (
- `entry` mediumint(8) unsigned NOT NULL default '0',
- `item` mediumint(8) unsigned NOT NULL default '0',
- `ChanceOrQuestChance` float NOT NULL default '100',
- `groupid` tinyint(3) unsigned NOT NULL default '0',
- `mincountOrRef` mediumint(9) NOT NULL default '1',
- `maxcount` tinyint(3) unsigned NOT NULL default '1',
- `lootcondition` tinyint(3) unsigned NOT NULL default '0',
- `condition_value1` mediumint(8) unsigned NOT NULL default '0',
- `condition_value2` mediumint(8) unsigned NOT NULL default '0',
- PRIMARY KEY (`entry`,`item`)
+DROP TABLE IF EXISTS `achievement_reward`; +CREATE TABLE `achievement_reward` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `title_A` mediumint(8) unsigned NOT NULL default '0', + `title_H` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `sender` mediumint(8) unsigned NOT NULL default '0', + `subject` varchar(255) default NULL, + `text` text, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + + +DROP TABLE IF EXISTS `locales_achievement_reward`; +CREATE TABLE `locales_achievement_reward` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `subject_loc1` varchar(100) NOT NULL default '', + `subject_loc2` varchar(100) NOT NULL default '', + `subject_loc3` varchar(100) NOT NULL default '', + `subject_loc4` varchar(100) NOT NULL default '', + `subject_loc5` varchar(100) NOT NULL default '', + `subject_loc6` varchar(100) NOT NULL default '', + `subject_loc7` varchar(100) NOT NULL default '', + `subject_loc8` varchar(100) NOT NULL default '', + `text_loc1` text default NULL, + `text_loc2` text default NULL, + `text_loc3` text default NULL, + `text_loc4` text default NULL, + `text_loc5` text default NULL, + `text_loc6` text default NULL, + `text_loc7` text default NULL, + `text_loc8` text default NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +TRUNCATE `creature_equip_template`; +ALTER TABLE `creature_equip_template` + DROP COLUMN `equipinfo1`, + DROP COLUMN `equipinfo2`, + DROP COLUMN `equipinfo3`, + DROP COLUMN `equipslot1`, + DROP COLUMN `equipslot2`, + DROP COLUMN `equipslot3`, + CHANGE COLUMN `equipmodel1` `equipentry1` mediumint(8) UNSIGNED default '0' NOT NULL, + CHANGE COLUMN `equipmodel2` `equipentry2` mediumint(8) UNSIGNED default '0' NOT NULL, + CHANGE COLUMN `equipmodel3` `equipentry3` mediumint(8) UNSIGNED default '0' NOT NULL; +UPDATE `creature_template` set equipment_id = 0; + +ALTER TABLE `item_template` + ADD COLUMN `ScalingStatDistribution` smallint(6) DEFAULT '0' NOT NULL after `stat_value10`, + ADD COLUMN `ScalingStatValue` smallint(6) DEFAULT '0' NOT NULL after `ScalingStatDistribution`, + ADD COLUMN `ItemLimitCategory` smallint(6) DEFAULT '0' NOT NULL after `ArmorDamageModifier`, + CHANGE COLUMN `Duration` `Duration` int(11) NOT NULL default '0' COMMENT 'Duration in seconds. Negative value means realtime, postive value ingame time' after ArmorDamageModifier, + ADD COLUMN `StatsCount` tinyint(3) UNSIGNED DEFAULT '0' NOT NULL after `ContainerSlots`, + CHANGE COLUMN `TotemCategory` `TotemCategory` mediumint(9) NOT NULL default '0'; + +UPDATE `item_template` + SET `maxcount`=0 WHERE `maxcount` > 32000; +UPDATE `item_template` + SET `stackable`=0 WHERE `stackable` > 32000; +ALTER TABLE `item_template` + CHANGE COLUMN `maxcount` `maxcount` smallint(5) NOT NULL default '-1', + CHANGE COLUMN `stackable` `stackable` smallint(5) NOT NULL default '1'; +UPDATE `item_template` + SET `stackable`=-1 WHERE `stackable` = 0; + +ALTER TABLE `quest_template` + ADD COLUMN `PlayersSlain` tinyint(3) UNSIGNED DEFAULT '0' NOT NULL after `CharTitleId`, + ADD COLUMN `BonusTalents` tinyint(3) UNSIGNED DEFAULT '0' NOT NULL after `PlayersSlain`, + CHANGE COLUMN `RewHonorableKills` `RewHonorableKills` int unsigned NOT NULL default '0'; + +DROP TABLE IF EXISTS `milling_loot_template`; +CREATE TABLE `milling_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + +DROP TABLE IF EXISTS `spell_affect`; +CREATE TABLE `spell_affect` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `effectId` tinyint(3) unsigned NOT NULL default '0', + `SpellClassMask0` int(5) unsigned NOT NULL default '0', + `SpellClassMask1` int(5) unsigned NOT NULL default '0', + `SpellClassMask2` int(5) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`effectId`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +ALTER TABLE `skill_discovery_template` + DROP PRIMARY KEY, + ADD PRIMARY KEY (`spellId`,`reqSpell`), + ADD COLUMN `reqClass` tinyint(2) unsigned NOT NULL default '0' COMMENT 'class requirement' AFTER reqSpell; +ALTER TABLE skill_discovery_template + DROP COLUMN `reqClass`, + ADD COLUMN `reqSkillValue` smallint(5) unsigned NOT NULL default '0' COMMENT 'skill points requirement' AFTER reqSpell; + +DROP TABLE IF EXISTS `player_classlevelstats`; +CREATE TABLE `player_classlevelstats` ( + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `basehp` smallint(5) unsigned NOT NULL, + `basemana` smallint(5) unsigned NOT NULL, + PRIMARY KEY (`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +DROP TABLE IF EXISTS `player_levelstats`; +CREATE TABLE `player_levelstats` ( + `race` tinyint(3) unsigned NOT NULL, + `class` tinyint(3) unsigned NOT NULL, + `level` tinyint(3) unsigned NOT NULL, + `str` tinyint(3) unsigned NOT NULL, + `agi` tinyint(3) unsigned NOT NULL, + `sta` tinyint(3) unsigned NOT NULL, + `inte` tinyint(3) unsigned NOT NULL, + `spi` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`race`,`class`,`level`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0 COMMENT='Stores levels stats.'; + +DROP TABLE IF EXISTS `playercreateinfo_spell`; +CREATE TABLE `playercreateinfo_spell` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `Spell` mediumint(8) unsigned NOT NULL default '0', + `Note` varchar(255) default NULL, + PRIMARY KEY (`race`,`class`,`Spell`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `playercreateinfo_action`; +CREATE TABLE `playercreateinfo_action` ( + `race` tinyint(3) unsigned NOT NULL default '0', + `class` tinyint(3) unsigned NOT NULL default '0', + `button` smallint(5) unsigned NOT NULL default '0', + `action` smallint(5) unsigned NOT NULL default '0', + `type` smallint(5) unsigned NOT NULL default '0', + `misc` smallint(5) unsigned NOT NULL default '0', + KEY `playercreateinfo_race_class_index` (`race`,`class`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `spell_learn_spell`; +CREATE TABLE `spell_learn_spell` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `SpellID` smallint(5) unsigned NOT NULL default '0', + `Active` tinyint(3) unsigned NOT NULL default '1', + PRIMARY KEY (`entry`,`SpellID`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Item System'; + +DROP TABLE IF EXISTS `spell_proc_event`; +CREATE TABLE `spell_proc_event` ( + `entry` smallint(5) unsigned NOT NULL default '0', + `SchoolMask` tinyint(4) NOT NULL default '0', + `SpellFamilyName` smallint(5) unsigned NOT NULL default '0', + `SpellFamilyMask0` int(10) unsigned NOT NULL default '0', + `SpellFamilyMask1` int(10) unsigned NOT NULL default '0', + `SpellFamilyMask2` int(10) unsigned NOT NULL default '0', + `procFlags` int(10) unsigned NOT NULL default '0', + `procEx` int(10) unsigned NOT NULL default '0', + `ppmRate` float NOT NULL default '0', + `CustomChance` float NOT NULL default '0', + `Cooldown` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `player_xp_for_level`; +CREATE TABLE `player_xp_for_level` ( + `lvl` int(3) unsigned NOT NULL, + `xp_for_next_level` int(10) unsigned NOT NULL, + PRIMARY KEY (`lvl`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `spell_loot_template`; +CREATE TABLE `spell_loot_template` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `item` mediumint(8) unsigned NOT NULL default '0', + `ChanceOrQuestChance` float NOT NULL default '100', + `groupid` tinyint(3) unsigned NOT NULL default '0', + `mincountOrRef` mediumint(9) NOT NULL default '1', + `maxcount` tinyint(3) unsigned NOT NULL default '1', + `lootcondition` tinyint(3) unsigned NOT NULL default '0', + `condition_value1` mediumint(8) unsigned NOT NULL default '0', + `condition_value2` mediumint(8) unsigned NOT NULL default '0', + PRIMARY KEY (`entry`,`item`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System';
\ No newline at end of file diff --git a/src/bindings/scripts/docs/EventAI.txt b/src/bindings/scripts/docs/EventAI.txt index b9ec9225829..780e817993d 100644 --- a/src/bindings/scripts/docs/EventAI.txt +++ b/src/bindings/scripts/docs/EventAI.txt @@ -1,699 +1,699 @@ -=========================================
-Event AI documentation
-=========================================
-
-Scriptdev2 Revision 220 introduces a new database defined AI named EventAI.
-This system allows users to create new creature scripts entierly within the Database.
-ScriptName must still be set to "mob_eventai" within the MaNGOS database creature_template.scriptname field.
-
-=========================================
-Basic Structure of EventAI
-=========================================
-Event AI follows a basic if (Event) then do {Action} format.
-Below is a the list of current fields within the Eventai_scripts table.
-
-(Field_Name Discription)
-id This value is mearly an incrementing counter of the current Event number. Required for sql queries.
-creature_id Creature id which this event should occur on.
-
-event_type Type of event (See Event Types below)
-event_inverse_phase_mask Mask which phases this event should NOT trigger in*
-event_chance Percent chance of this event occuring (1 - 100)
-event_flags Event flags such as if the event is repeatable (see below)
-event_param1 Variable for event (dependant on Event type)
-event_param2
-event_param3
-event_param4
-
-action1_type First Type of Action to take when event occurs (See Action Types below)
-action1_param1 Variables used for Action1 (dependant on Action type)
-action1_param2
-action1_param3
-
-action2_type Second Type of Action to take when event occurs (See Action Types below)
-action2_param1 Variables used for Action2 (dependant on Action type)
-action2_param2
-action2_param3
-
-action3_type Third Type of Action to take when event occurs (See Action Types below)
-action3_param1 Variables used for Action3 (dependant on Action type)
-action3_param2
-action3_param3
-
-All params are signed 32 bit values (+/- 2147483647). If param specifies time then time is in milliseconds. If param specifies percentage then percentages are value/100 (ex: if param = 500 then that means 500%, -50 = -50%)
-
-*Phase mask is a bit mask of which phases this event should not trigger in. Example: Phase mask value of 12 (1100) would mean that this event would trigger 0, 1 and all other phases except for 2 and 3 (0 counts as the first phase).
-
-=========================================
-Event Types
-=========================================
-Below is the list of current Event types that EventAI can handle.
-Each event type has its own specific interpretation of the params that accompany it.
-Params are always read from Param1, then Param2, then Param3.
-Events will not repeat until the creature exits combat unless EFLAG_REPEATABLE is set. Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_EVADE cannot repeat.
-
-# Internal Name Pamarm usage Description
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-0 EVENT_T_TIMER InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only in combat.
-1 EVENT_T_TIMER_OOC InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only out of combat.
-2 EVENT_T_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
-3 EVENT_T_MANA ManaMax%,ManaMin% RepeatMin, RepeatMax Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
-4 EVENT_T_AGGRO NONE Expires upon initial aggro (does not repeat).
-5 EVENT_T_KILL RepeatMin, RepeatMax Expires upon killing a player. Will repeat between every (Param1) and (Param2).
-6 EVENT_T_DEATH NONE Expires upon Death of the Creature.
-7 EVENT_T_EVADE NONE Expires upon creature EnterEvadeMode().
-8 EVENT_T_SPELLHIT SpellID, School, RepeatMin, RepeatMax Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school (-1 for all). Will repeat every (Param3) and (Param4) .
-9 EVENT_T_RANGE MinDist, MaxDist, RepeatMin, RepeatMax Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4) .
-10 EVENT_T_OOC_LOS NoHostile, NoFriendly, RepeatMin, RepeatMax Expires when a Player moves within visible distance to creature. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4) . Does not expire for creatures or pet or when the creature is in combat.
-11 EVENT_T_SPAWNED NONE Expires at initial spawn and at creature respawn (useful for setting ranged movement type)
-12 EVENT_T_TARGET_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when Current Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4) .
-13 EVENT_T_TARGET_CASTING RepeatMin, RepeatatMax Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2) .
-14 EVENT_T_FRIENDLY_HP HPDeficit, Radius, RepeatMin, RepeatMax Expires when a friendly unit in radius has at least (param1) hp missing. Will repeat every (Param3) and (Param4) .
-15 EVENT_T_FRIENDLY_IS_CC DispelType, Radius, RepeatMin, RepeatMax Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4) .
-16 EVENT_T_MISSING_BUFF SpellId, Radius, RepeatMin, RepeatMax Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4) .
-17 EVENT_T_SUMMONED_UNIT CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3).
-18 EVENT_T_TARGET_MANA ManaMax%, ManaMin%, RepeatMin, RepeatMax
-21 EVENT_T_REACHED_HOME NONE Expires when creature reach it's home(spawn) location after Evade.
-
-=========================================
-Action Types
-=========================================
-Below is the list of current Action types that EventAI can handle.
-Each event type has its own specific interpretation of the params that accompany it.
-Params are always read from Param1, then Param2, then Param3.
-
-(# Internal Name Param usage Discription)
-0 ACTION_T_NONE No Action Does Nothing
-1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Displays the -TextId as defined. In case -TextId2 and optionally -TextId3, the output will be randomized. Type text are defined in the text table itself(say, yell, whisper, etc) along with other options for the text. All values are required to be negative.
-2 ACTION_T_SET_FACTION FactionId Change faction for creature. If param1==0, creature will revert to default faction.
-3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set model from creature_template.entry(param1) OR set explicit modelId(param2). If param1 AND param2 both 0, demorph and revert to default model for creature.
-4 ACTION_T_SOUND SoundId Plays Sound
-5 ACTION_T_EMOTE EmoteId Does emote
-6 ACTION_T_RANDOM_SAY UNUSED
-7 ACTION_T_RANDOM_YELL UNUSED
-8 ACTION_T_RANDOM_TEXTEMOTE UNUSED
-9 ACTION_T_RANDOM_SOUND SoundId1, SoundId2, SoundId3 Plays random sound between 3 params*
-10 ACTION_T_RANDOM_EMOTE EmoteId1, EmoteId2, EmoteId3 Emotes random emote between 3 params
-11 ACTION_T_CAST SpellId, Target, CastFlags Casts spell (param1) on target type (param2). Uses Cast Flags (specified below target types)
-12 ACTION_T_SUMMON CreatureID, Target, Duration Summons creature (param1) to attack target (param2) for (param3) duration. Spawns on top of current creature.
-13 ACTION_T_THREAT_SINGLE_PCT Threat%, Target Modifies threat by (param1) on target type (param2)
-14 ACTION_T_THREAT_ALL_PCT Threat% Modifies threat by (param1) on all targets (using -100% on all will result in full aggro dump)
-15 ACTION_T_QUEST_EVENT QuestID, Target Calls AreaExploredOrEventHappens with (param1) for target type (Param2)
-16 ACTION_T_QUEST_CASTCREATUREGO CreatureID, SpellId, Target Sends CastCreatureOrGo for CreatureId (param1) with SpellId (param2) for target (param3)
-17 ACTION_T_SET_UNIT_FIELD Field_Number, Value, Target Sets Unit Field (param1) to Value (param2) on target type (param3)
-18 ACTION_T_SET_UNIT_FLAG Flags, Target Sets flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2)
-19 ACTION_T_REMOVE_UNIT_FLAG Flags, Target Removes flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2)
-20 ACTION_T_AUTO_ATTACK AllowAutoAttack 0 = stop melee attack, anything else means continue attacking/allow melee attacking
-21 ACTION_T_COMBAT_MOVEMENT AllowCombatMovement 0 = stop combat based movement, anything else continue/allow combat based movement (targeted movement generator)
-22 ACTION_T_SET_PHASE Phase Sets the current phase to (param1)
-23 ACTION_T_INC_PHASE Value Increments the phase by (param1). May be negative to decrement phase but should not be 0.
-24 ACTION_T_EVADE No Params Forces the creature to evade. Wiping all threat and dropping combat.
-25 ACTION_T_FLEE No Params Causes the .creature to flee. Please use this action instead of directly casting this spell so we may change this when a more correct approach is found.
-26 ACTION_T_QUEST_EVENT_ALL QuestId Calls GroupEventHappens with (param1). Only used if it's _expected_ event should complete for all players in current party
-27 ACTION_T_CASTCREATUREGO_ALL QuestId, SpellId Calls CastedCreatureOrGo for all players on the threat list with QuestID(Param1) and SpellId(Param2)
-28 ACTION_T_REMOVEAURASFROMSPELL Target, Spellid Removes all auras on Target caused by Spellid
-29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator type to a ranged type. Note: Default melee type can still be done with this. Specify 0 angle and 0 distance.
-30 ACTION_T_RANDOM_PHASE PhaseId1, PhaseId2, PhaseId3 Sets the phase to the id between 3 params*
-31 ACTION_T_RANDOM_PHASE_RANGE PhaseMin, PhaseMax Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). PhaseMax must be greater than PhaseMin.
-32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
-33 ACTION_T_KILLED_MONSTER CreatureID, Target Calls KilledMonster (param1) for target of type (param2)
-34 ACTION_T_SET_INST_DATA Field, Data Calls ScriptedInstance::SetData with field (param1) and data (param2)
-35 ACTION_T_SET_INST_DATA64 Field, Target Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
-36 ACTION_T_UPDATE_TEMPLATE TemplateId, Team Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true
-37 ACTION_T_DIE No Params Kills the creature
-38 ACTION_T_ZONE_COMBAT_PULSE No Params Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
-
-* = Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
-
-=========================================
-Event Types
-=========================================
-Note:
-COMBAT ONLY - Means that this event will only trigger durring combat.
-OUT OF COMBAT ONLY - Means that this event will only trigger while out of combat.
-BOTH - This event can trigger both in and out of combat.
-
-Events that do not have lables on them are events that are directly involved with the in and out of combat state.
-
-------------------
-0 = EVENT_T_TIMER:
-------------------
-Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire
-Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
-This is commonly used for spells that repeat cast during combat (Simulate Spell Cooldown).
-
-----------------------
-1 = EVENT_T_TIMER_OOC:
-----------------------
-Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire
-Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-OUT OF COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on.
-This is commonly used for events that occur and repeat outside of combat.
-
----------------
-2 = EVENT_T_HP:
----------------
-Parameter 1: HPMax% - Maximum HP% That this Event will Expire
-Parameter 2: HPMin% - Minimum HP% That this Event will Expire
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-BOTH - Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
-This is commonly used for events that trigger at a specific HP% (Such as Heal/Enrage Spells or NPC's that Flee).
-
------------------
-3 = EVENT_T_MANA:
------------------
-Parameter 1: ManaMax% - Maximum Mana% That this Event will Expire
-Parameter 2: ManaMin% - Minimum Mana% That this Event will Expire
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-BOTH - Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
-This is commonly used for events where an NPC low on Mana will do something (Such as stop casting spells and switch to melee).
-
-------------------
-4 = EVENT_T_AGGRO:
-------------------
-This Event Expires upon initial aggro (does not repeat).
-
------------------
-5 = EVENT_T_KILL:
------------------
-Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-COMBAT ONLY! - Expires upon killing a player. Will repeat every (Param1) and (Param2).
-This Event Expires upon killing a player. It is commonly used for NPC's who yell or do something after killing a player.
-
-------------------
-6 = EVENT_T_DEATH:
-------------------
-This Event Expires upon Death of the Scripted NPC.
-This is commonly used for NPC's who have a yell on death or cast some kind if summon spell when they die.
-
-------------------
-7 = EVENT_T_EVADE:
-------------------
-This Event Expires upon the creature EnterEvadeMode().
-This is commonly used for NPC's who use phases, allows you to reset their phase to 0 upon evade to prevent possible strange behavior.
-
----------------------
-8 = EVENT_T_SPELLHIT:
----------------------
-Parameter 1: SpellID - The Spell ID that will trigger the event to occur (NOTE: If you use Spell School as the trigger set this value to 0)
-Parameter 2: School - Spell School to trigger the event (NOTE: If you use a SpellID then set this value to -1) - *See Below for Spell School Bitmask Values*
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-BOTH - Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school. Will repeat every (Param3) and (Param4).
-This Event is commonly used for NPC's who can do special things when you cast a spell (Or specific spell) on them.
-
-------------------
-9 = EVENT_T_RANGE:
-------------------
-Parameter 1: MinDist - This Distance is the Minimum Distance between the NPC and it's target to allow this Event to Expire
-Parameter 2: MaxDist - This Distance is the Maximum Distance between the NPC and it's target to allow this Event to Expire
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-COMBAT ONLY! - Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4).
-This Event is commonly used for NPC's who have Ranged Combat and will Throw/Shoot between a certian distance.
-
----------------------
-10 = EVENT_T_OOC_LOS:
----------------------
-Parameter 1: NoHostile - This Value is to Prevent this Action from Expiring When Caused by a Player/Creature Hostile to them (0 = Prevent Event from Expiring, 1 = Allow Event to Expire)
-Parameter 2: NoFriendly - This Value is to Prevent this Action from Expiring When Caused by a Player/Creature Friendly to them (0 = Prevent Event from Expiring, 1 = Allow Event to Expire)
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-OUT OF COMBAT ONLY! - Expires when a Player moves within visible distance to the NPC. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4). Does not expire for creatures or pets when they are in combat.
-This Event is commonly used for NPC's who Do Something or Say Something when you walk past them Out of Combat.
-
----------------------
-11 = EVENT_T_SPAWNED:
----------------------
-Expires at initial spawn and at creature respawn.
-This Event is commonly used for setting ranged movement type or Summoning a Pet on Spawn
-
------------------------
-12 = EVENT_T_TARGET_HP:
------------------------
-Parameter 1: HPMax% - Maximum HP% That this Event will Expire
-Parameter 2: HPMin% - Minimum HP% That this Event will Expire
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-COMBAT ONLY! - Expires when Current NPC's Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4).
-This Event is commonly used for NPC's who have a special ability (Like Execute) that only casts when a Player HP is low.
-
-----------------------------
-13 = EVENT_T_TARGET_CASTING:
-----------------------------
-Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-COMBAT ONLY! - Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2).
-This event is commonly used for NPC's who will cast a counter spell when their target starts to cast a spell.
-
--------------------------
-14 = EVENT_T_FRIENDLY_HP:
--------------------------
-Parameter 1: HPDeficit - This is the Amount of HP Missing from Full HP to trigger this event (You would need to calculate the amount of HP the event happens and subtract that from Full HP Value to get this number)
-Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing amount of HP in Param1.
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-COMBAT ONLY! - Expires when a friendly unit in radius(param2) has at least (param1) hp missing. Will repeat every (Param3) and (Param4).
-This is commonly used when an NPC in Combat will heal a nearby Friendly NPC in Combat with a Heal/Renew Spell.
-
-----------------------------
-15 = EVENT_T_FRIENDLY_IS_CC:
-----------------------------
-Parameter 1: DispelType - Dispel Type to trigger the event - *See Below for Dispel Bitmask Values*
-Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies being Crowd Controlled
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-COMBAT ONLY! - Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4).
-This is commonly used for NPC's who can come to the resule of other Friendly NPC's if being Crowd Controlled
-
---------------------------
-16 = EVENT_T_MISSING_BUFF:
---------------------------
-Parameter 1: SpellId - This is the SpellID That the Aura Check will look for (If it is missing this Aura)
-Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing Aura.
-Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-BOTH - Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4).
-This is commonly used for NPC's who watch friendly units for a debuff to end so they can recast it on them again.
-
----------------------------
-17 = EVENT_T_SUMMONED_UNIT:
----------------------------
-Parameter 1: CreatureId - The CreatureID that the NPC is watching to spawn to trigger this event
-Parameter 2: RepeatMin - Minimum Time used to calculate Random Repeat Expire
-Parameter 3: RepeatMax - Maximum Time used to calculate Random Repeat Expire
-
-BOTH - Expires after creature with entry(Param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) .
-This is commonly used for NPC's who will do something special once another NPC is summoned. Usually used is Complex Scripts or Special Events.
-
----------------------------
-21 = EVENT_T_REACHED_HOME:
----------------------------
-Expires only when creature has returned to it's home location after Evade. Out of combat event.
-Most commonly used to cast spells that can not be casted in EVENT_T_EVADE and other effects that does not fit in while still running back to spawn/home location.
-
-
-=========================================
-Action Types
-=========================================
-
------------------
-1 = ACTION_T_TEXT:
------------------
-Parameter 1: The entry of the text that the NPC should use from eventai_texts table. Optionally a entry from other tables can be used (such as custom_texts).
- Entry are required to be negative and exist in a *_texts-table. The type text to be displayed are defined in the texts-table itself (Say, Yell, Whisper, Emote Text, Boss Whisper, Boss Emote)
- Other options are also to be defined in the texts-table, such as a sound to be heard with the text and the language used in output (common, dwarvish, etc).
- In case this entry has a localized version of the text, the localized text will be displayed in client that support this locale.
-
-Parameter 2: Optional. TextId can be defined in addition. The same apply to this as explained above, however eventAI will randomize between the two.
-Parameter 3: Optional, if Parameter 2 exist. In this case, eventAI will randomize between three.
-
-See Text-tables.txt for documentation of eventai_texts-table.
-
-------------------
-2 = ACTION_T_SET_FACTION:
-------------------
-Parameter 1: FactionId from Faction.dbc OR 0. Changes faction for creature. If 0, creature will revert to it's default faction if previously changed.
-
------------------------
-3 = ACTION_T_MORPH_TO_ENTRY_OR_MODEL:
------------------------
-Parameter 1: Creature entry from creature_template. Action will then change to the model this creature are using.
-Parameter 2: If parameter 1 is 0, then this modelId will be used (in case parameter 1 exist, parameter 2 will not be used)
-
-If both parameter 1 and 2 is 0, the creature will DeMorph, and use it's default model.
-
--------------------
-4 = ACTION_T_SOUND:
--------------------
-Parameter 1: The Sound ID to be played. (Sound IDs are contained in the DBC files.)
-
-The creature will play the specified sound.
-This is commonly used for Bosses who Yell and then also have a Voice for the same thing.
-
--------------------
-5 = ACTION_T_EMOTE:
--------------------
-Parameter 1: The Emote ID that the creature should perform. (Emote IDs are also contained in the DBC but they can be found in the mangos source as well).
-
-The creature will perform a visual emote. Unlike a text emote, a visual emote is one where the creature will actually move or perform a gesture.
-This is commonly used for NPC's who may perform a special action (Salute, Roar, ect...). Not all player emotes work for creature models.
-
-------------------------
-6 = ACTION_T_RANDOM_SAY:
-------------------------
-UNUSED Can be reused to create new action type
-
--------------------------
-7 = ACTION_T_RANDOM_YELL:
--------------------------
-UNUSED Can be reused to create new action type
-
-------------------------------
-8 = ACTION_T_RANDOM_TEXTEMOTE:
-------------------------------
-UNUSED Can be reused to create new action type
-
---------------------------
-9 = ACTION_T_RANDOM_SOUND:
---------------------------
-Parameter 1: The Sound ID to be played as Random Choice #1.
-Parameter 2: The Sound ID to be played as Random Choice #2.
-Parameter 3: The Sound ID to be played as Random Choice #3.
-
-Similar to the ACTION_T_SOUND action, it will choose at random a sound to play.
-
----------------------------
-10 = ACTION_T_RANDOM_EMOTE:
----------------------------
-Parameter 1: The Emote ID to be played as Random Choice #1.
-Parameter 2: The Emote ID to be played as Random Choice #2.
-Parameter 3: The Emote ID to be played as Random Choice #3.
-
-Similar to the ACTION_T_EMOTE action, it will choose at random an Emote to Visually Perform.
-
--------------------
-11 = ACTION_T_CAST:
--------------------
-Parameter 1: SpellId - The Spell ID to use for the NPC to cast. The value used in this field needs to be a valid Spell ID.
-Parameter 2: Target - The Target Type defining who the creature should cast the spell at. The value in this field needs to be a valid Target Type as specified in the reference tables below.
-Parameter 3: CastFlags - See Table Below for Cast Flag Bitmask Values. If you are unsure what to set this value at leave it at 0.
-
-The creature will cast a spell specified by a spell ID on a target specified by the target type.
-This is commonly used for NPC's who cast spells.
-
----------------------
-12 = ACTION_T_SUMMON:
----------------------
-Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
-Parameter 2: Target - The Target Type defining who the Summoned creature will attack once spawned. The value in this field needs to be a valid Target Type as specified in the reference tables below.
-Parameter 3: Duration - The duration until the summoned creature should be unsummoned AFTER Combat ends. The value in this field is in milliseconds or 0.
-
-The NPC will Summon another creature at the same spot as itself that will attack the specified target.
-NOTE: Almost all Creature Summons have proper Summon Spells that should be used when possible. This Action is a powerful last resort option only to be used if nothing else works.
-NOTE: Using Target Type 0 will cause the Summoned creature to not attack anyone.
-NOTE: If Duration is set at 0, then the summoned creature will not despawn until it has died.
-This is used as a manual way to force an NPC to Summon.
---------------------------------
-13 = ACTION_T_THREAT_SINGLE_PCT:
---------------------------------
-Parameter 1: Threat% - Threat percent that should be modified. The value in this field can range from -100 to +100. If it is negative, threat will be taken away and if positive, threat will be added.
-Parameter 2: Target - The Target Type defining on whom the threat change should occur. The value in this field needs to be a valid target type as specified in the reference tables below.
-
-This action will modify the threat of a target in the creature's threat list by the specified percent.
-This is commonly used to allow an NPC to adjust the Threat to a single player.
-
------------------------------
-14 = ACTION_T_THREAT_ALL_PCT:
------------------------------
-Parameter 1: Threat% - The percent that should be used in modifying everyone's threat in the creature's threat list. The value here can range from -100 to +100.
-
-This action will modify the threat for everyone in the creature's threat list by the specified percent.
-NOTE: Using -100 will cause the creature to reset everyone's threat to 0 so that everyone has the same amount of threat. It will NOT remove anyone from the threat list.
-This is commonly used to allow an NPC to drop threat for all players to zero.
-
---------------------------
-15 = ACTION_T_QUEST_EVENT:
---------------------------
-Parameter 1: QuestID - The Quest Template ID. The value here must be a valid quest template ID. Furthermore, the quest should have SpecialFlags | 2 as it would need to be completed by an external event which is the activation of this action.
-Parameter 2: Target - The Target Type defining whom the quest should be completed for. The value in this field needs to be a valid target type as specified in the reference tables below.
-
-This action will satisfy the external completion requirement for the quest for the specified target defined by the target type.
-NOTE: This action can only be used with player targets so it must be ensured that the target type will point to a player.
-This is commonly used for Quests where only ONE player will gain credit for the quest.
-
------------------------------
-16 = ACTION_T_CASTCREATUREGO:
------------------------------
-Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID.
-Parameter 2: SpellId - The Spell ID to use to simulate the cast. The value used in this field needs to be a valid Spell ID.
-Parameter 3: Target - The Target Type defining whom the quest credit should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
-
-This action will call CastedCreatureOrGO() function for the player. It can be used to give quest credit for casting a spell on the creature.
-This is commonly used for NPC's who have a special requirement to have a Spell cast on them to complete a quest.
-
------------------------------
-17 = ACTION_T_SET_UNIT_FIELD:
------------------------------
-Parameter 1: Field_Number - The index of the Field Number to be changed. Use (http://wiki.udbforums.org/index.php/Character_data) for a list of indeces and what they control. Creatures only contain the OBJECT_FIELD_* and UNIT_FIELD_* fields. They do not contain the PLAYER_FIELD_* fields.
-Parameter 2: Value - The new value to be put in the field.
-Parameter 3: Target - The Target Type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
-
-When activated, this action can change the target's unit field values. More information on the field value indeces can be found at (http://wiki.udbforums.org/index.php/Character_data)
-
-----------------------------
-18 = ACTION_T_SET_UNIT_FLAG:
-----------------------------
-Parameter 1: Flags - The flag(s) to be set. Multiple flags can be set by using bitwise-OR on them (adding them together).
-Parameter 2: Target - The Target Type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
-
-When activated, this action changes the target's flags by adding (turning on) more flags. For example, this action can make the creature unattackable/unselectable if the right flags are used.
-
--------------------------------
-19 = ACTION_T_REMOVE_UNIT_FLAG:
--------------------------------
-Parameter 1: Flags - The flag(s) to be removed. Multiple flags can be set by using bitwise-OR on them (adding them together).
-Parameter 2: Target - The target type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below.
-
-When activated, this action changes the target's flags by removing (turning off) flags. For example, this action can make the creature normal after it was unattackable/unselectable if the right flags are used.
-
---------------------------
-20 = ACTION_T_AUTO_ATTACK:
---------------------------
-Parameter 1: AllowAutoAttack - If zero, then the creature will stop its melee attacks. If non-zero, then the creature will either continue its melee attacks (the action would then have no effect) or it will start its melee attacks on the target with the top threat if its melee attacks were previously stopped.
-
-This action controls whether or not the creature should stop or start the auto melee attack.
-NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values (0 = Stop Melee, 1 = Start Melee).
-This is commonly used in combination with EVENT_T_RANGE and ACTION_T_COMBAT_MOVEMENT for Ranged Combat for Mages and Spell Casters.
-
-------------------------------
-21 = ACTION_T_COMBAT_MOVEMENT:
-------------------------------
-Parameter 1: If zero, then the creature will stop moving towards its victim (if its victim gets out of melee range) and will be stationary. If non-zero, then the creature will either continue to follow its victim (the action would have no effect) or it will start to follow the target with the top threat if its movement was disabled before.
-
-This action controls whether or not the creature will always move towards its target.
-NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values. (0 = Stop Movement, 1 = Start Movement)
-This is commonly used with EVENT_T_RANGE and ACTION_T_AUTO_ATTACK for NPC's who engage in Ranged Comabt (Either Spells or Ranged Attacks)
-
-------------------------
-22 = ACTION_T_SET_PHASE:
-------------------------
-Parameter 1: The new phase to set the creature in. This number must be an integer between 0 and 31. Numbers outside of that range will result in an error.
-
-When activated, this action sets the creature's event to the specified value.
-NOTE: The creature's current Phase is NOT reset at creature evade. You must manually set the phase back to 0 at EVENT_T_RESET.
-NOTE: The value used for the Param is the actual Phase Number (Not The Event_Inverse_Phase_Mask)
-This is commonly used for complex scripts with several phases and you need to switch to a different phase.
-
-------------------------
-23 = ACTION_T_INC_PHASE:
-------------------------
-Parameter 1: Value - The number of phases to increase or decrease. Use negative values to decrease the current phase.
-
-When activated, this action will increase (or decrease) the current creature's phase.
-NOTE: After increasing or decreasing the phase by this action, the current phase must NOT be lower than 0 or exceed 31.
-This can be used instead of ACTION_T_SET_PHASE to change phases in scripts. Just a user friendly option for changing phases.
-
---------------------
-24 = ACTION_T_EVADE:
---------------------
-When activated, the creature will immediately exit out of combat, clear its threat list, and move back to its spawn point. Basically, this action will reset the whole encounter.
-NOTE: All Param Values Are 0 for this Action.
-
--------------------
-25 = ACTION_T_FLEE:
--------------------
-When activated, the creature will try to flee from combat. Currently this is done by it casting a fear-like spell on itself called "Run Away". A Better Flee system is in Development but will take time before it is implimented.
-NOTE: All Param Values Are 0 for this Action.
-
-------------------------------
-26 = ACTION_T_QUEST_EVENT_ALL:
-------------------------------
-Parameter 1: QuestId - The quest ID to finish for everyone.
-
-This action does the same thing as the ACTION_T_QUEST_EVENT does but it does it for all players in the creature's threat list.
-NOTE: If a player is not in the NPC's threat list for whatever reason, he/she won't get the quest completed.
-
----------------------------------
-27 = ACTION_T_CASTCREATUREGO_ALL:
----------------------------------
-Parameter 1: QuestId - The quest template ID.
-Parameter 2: SpellId - The spell ID used to simulate the cast.
-
-This action does the same thing as the ACTION_T_CASTCREATUREGO does but it does it for all players in the creature's threat list.
-NOTE: If a player is not in its threat list for whatever reason, he/she won't receive the cast emulation.
-
------------------------------------
-28 = ACTION_T_REMOVEAURASFROMSPELL:
------------------------------------
-Parameter 1: Target - The target type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below.
-Parameter 2: SpellId - The spell ID whose auras will be removed.
-
-This action will remove all auras from a specific spell from the target.
-This is commonly used for NPC's who have an OOC Aura that is removed at combat start or a similar idea (Like Stealth or Shape Shift)
-
-------------------------------
-29 = ACTION_T_RANGED_MOVEMENT:
-------------------------------
-Parameter 1: Distance - The distance the mob should keep between it and its target.
-Parameter 2: Angle - The angle the mob should use.
-
-This action changes the movement type generator to ranged type using the specified values for angle and distance.
-NOTE: Specifying zero angle and distance will make it just melee instead.
-This is commonly used for NPC's who always attack at range and you can specify the distance they will maintain from the target.
-
----------------------------
-30 = ACTION_T_RANDOM_PHASE:
----------------------------
-Parameter 1: PhaseId1 - A possible random phase choice.
-Parameter 2: PhaseId2 - A possible random phase choice.
-Parameter 3: PhaseId3 - A possible random phase choice.
-
-Randomly sets the phase to one from the three parameter choices.
-NOTE: Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2)
-NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
-This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have up to 3 phases used, otherwise use Action 31 for more then 3 phases.
-
----------------------------------
-31 = ACTION_T_RANDOM_PHASE_RANGE:
----------------------------------
-Parameter 1: PhaseMin - The minimum of the phase range.
-Parameter 2: PhaseMax - The maximum of the phase range. The number here must be greater than PhaseMin.
-
-Randomly sets the phase between a range of phases controlled by the parameters. Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax).
-NOTE: PhaseMax must be greater than PhaseMin.
-NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE.
-This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have MORE then 3 phases used, otherwise use Action 30.
-
----------------------
-32 = ACTION_T_SUMMON:
----------------------
-Parameter 1: CreatureID - The creature template ID to be summoned. The value here needs to be a valid creature template ID.
-Parameter 2: Target - The target type defining who the summoned creature will attack. The value in this field needs to be a valid target type as specified in the reference tables below. NOTE: Using target type 0 will cause the summoned creature to not attack anyone.
-Parameter 3: SummonID - The summon ID from the eventai_summons table controlling the position (and spawntime) where the summoned mob should be spawned at.
-
-Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3).
-NOTE: Param3 Value is the ID Value used for the entry used in EventAI_Summons for this action. You MUST have an EventAI_Summons entry to use this action.
-This is commonly used for NPC's who need to Summon a creature at a specific location. (Normally used for complex events)
-
------------------------------
-33 = ACTION_T_KILLED_MONSTER:
------------------------------
-Parameter 1: CreatureID - The creature template ID. The value here must be a valid creature template ID.
-Parameter 2: Target - The target type defining whom the quest kill count should be given to. The value in this field needs to be a valid target type as specified in the reference tables below.
-
-When activated, this action will call KilledMonster() function for the player. It can be used to give creature credit for killing a creature. In general if the quest is set to be accompished on different creatures (e.g. "Credit" templates).
-NOTE: It can be ANY creature including certain quest specific triggers
-This is commonly used for giving the player Quest Credits for NPC kills (Many NPC's may use the same CreatureID for the Kill Credit)
-
-----------------------------
-34 = ACTION_T_SET_INST_DATA:
-----------------------------
-Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
-Parameter 2: Data - The value to put at that field index.
-
-Sets data for the instance. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
-NOTE: Param1 Value is located in "def_<instance name>.h" SD2 File and Param2 value is generally found in the "sc_instance.h" file in SD2
-This is commonly used to link an ACID script with a SD2 C++ Script. You make make things happen like opening doors on specific events that happen. ACID Just triggers the C++ Script to function.
-
-------------------------------
-35 = ACTION_T_SET_INST_DATA64:
-------------------------------
-Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script.
-Parameter 2: Target - The target type to use to get the GUID that will be stored at the field index. The value in this field needs to be a valid target type as specified in the reference tables below.
-
-Sets GUID (64 bits) data for the instance based on the target. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned.
-Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID.
-
-------------------------------
-36 = ACTION_T_UPDATE_TEMPLATE:
-------------------------------
-Parameter 1: TemplateId - The creature template ID. The value here must be a valid creature template ID.
-Parameter 2: Team - Use model_id from team : Alliance(0) or Horde (1).
-
-This function temporarily changes creature entry to new entry, display is changed, loot is changed, but AI is not changed. At respawn creature will be reverted to original entry.
-Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true
-
-------------------
-37 = ACTION_T_DIE:
-------------------
-Kills the creature
-This is commonly used if you need to Instakill the creature for one reason or another.
-
---------------------------------
-38 = ACTION_T_ZONE_COMBAT_PULSE:
---------------------------------
-Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances.
-
-
-=========================================
-Target Types
-=========================================
-Below is the list of current Target types that EventAI can handle.
-Target types are used by certain actions and may effect actions differently
-
-(# Internal Name Discription)
-0 TARGET_T_SELF Self cast
-1 TARGET_T_HOSTILE Our current target (ie: highest aggro)
-2 TARGET_T_HOSTILE_SECOND_AGGRO Second highest aggro (generaly used for cleaves and some special attacks)
-3 TARGET_T_HOSTILE_LAST_AGGRO Dead last on aggro (no idea what this could be used for)
-4 TARGET_T_HOSTILE_RANDOM Just any random target on our threat list
-5 TARGET_T_HOSTILE_RANDOM_NOT_TOP Any random target except top threat
-6 TARGET_T_ACTION_INVOKER Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP)
-
-=========================================
-Cast Flags
-=========================================
-Below is the list of current Cast Flags that EventAI's spell casting can handle.
-Cast flags are handled bitwise. Bit 0 is Interrupt Previous, bit 1 is triggered, etc.
-So for example the number "3" (11 in Binary, selecting first 2 options) would mean that this cast has both CAST_INTURRUPT_PREVIOUS and CAST_TRIGGERED.
-Another example: the number "5" (101 in Binary, selecting first and third options) would mean that this cast has CAST_INTURRUPT_PREVIOUS and CAST_FORCE_CAST.
-
-(bit# Decimal Internal Name Discription)
-0 1 CAST_INTURRUPT_PREVIOUS Interrupts any previous spell casting (basicaly makes sure that this spell goes off)
-1 2 CAST_TRIGGERED Forces the spell to be instant cast and require no mana/reagents.
-2 4 CAST_FORCE_CAST Forces spell to cast even if the target is possibly out of range or the creature is possibly out of mana
-3 8 CAST_NO_MELEE_IF_OOM Prevents creature from entering melee if out of mana or out of range
-4 16 CAST_FORCE_TARGET_SELF Forces the target to cast this spell on itself
-5 32 CAST_AURA_NOT_PRESENT Only casts the spell on the target if the target does not have the aura from that spell on itself already.
-
-NOTE: You can add the numbers in the decimal column to combine flags.
- For example if you wanted to use CAST_NO_MELEE_IF_OOM(8) and CAST_TRIGGERED(2) you would simply use 10 in the cast flags field (8 + 2 = 10).
-
-=========================================
-Event Flags
-=========================================
-Below is the list of current Event Flags that EventAI can handle. Event flags are handled bitwise.
-
-(bit# Decimal Internal Name Discription)
-0 1 EFLAG_REPEATABLE Event repeats (Does not repeat if this flag is not set)
-1 2 EFLAG_NORMAL Event occurs in Normal instance difficulty (will not occur in Normal if not set)
-2 4 EFLAG_HEROIC Event occurs in Heroic instance difficulty (will not occur in Heroic if not set)
-3 8
-4 16
-5 32
-6 64
-7 128 EFLAG_DEBUG_ONLY Prevents events from occuring on Release builds of ScriptDev2. Useful for testing new features.
-
+========================================= +Event AI documentation +========================================= + +Scriptdev2 Revision 220 introduces a new database defined AI named EventAI. +This system allows users to create new creature scripts entierly within the Database. +ScriptName must still be set to "mob_eventai" within the MaNGOS database creature_template.scriptname field. + +========================================= +Basic Structure of EventAI +========================================= +Event AI follows a basic if (Event) then do {Action} format. +Below is a the list of current fields within the Eventai_scripts table. + +(Field_Name Discription) +id This value is mearly an incrementing counter of the current Event number. Required for sql queries. +creature_id Creature id which this event should occur on. + +event_type Type of event (See Event Types below) +event_inverse_phase_mask Mask which phases this event should NOT trigger in* +event_chance Percent chance of this event occuring (1 - 100) +event_flags Event flags such as if the event is repeatable (see below) +event_param1 Variable for event (dependant on Event type) +event_param2 +event_param3 +event_param4 + +action1_type First Type of Action to take when event occurs (See Action Types below) +action1_param1 Variables used for Action1 (dependant on Action type) +action1_param2 +action1_param3 + +action2_type Second Type of Action to take when event occurs (See Action Types below) +action2_param1 Variables used for Action2 (dependant on Action type) +action2_param2 +action2_param3 + +action3_type Third Type of Action to take when event occurs (See Action Types below) +action3_param1 Variables used for Action3 (dependant on Action type) +action3_param2 +action3_param3 + +All params are signed 32 bit values (+/- 2147483647). If param specifies time then time is in milliseconds. If param specifies percentage then percentages are value/100 (ex: if param = 500 then that means 500%, -50 = -50%) + +*Phase mask is a bit mask of which phases this event should not trigger in. Example: Phase mask value of 12 (1100) would mean that this event would trigger 0, 1 and all other phases except for 2 and 3 (0 counts as the first phase). + +========================================= +Event Types +========================================= +Below is the list of current Event types that EventAI can handle. +Each event type has its own specific interpretation of the params that accompany it. +Params are always read from Param1, then Param2, then Param3. +Events will not repeat until the creature exits combat unless EFLAG_REPEATABLE is set. Some events such as EVENT_T_AGGRO, EVENT_T_DEATH, EVENT_T_SPAWNED, and EVENT_T_EVADE cannot repeat. + +# Internal Name Pamarm usage Description +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +0 EVENT_T_TIMER InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only in combat. +1 EVENT_T_TIMER_OOC InitialMin, InitialMax, RepeatMin, RepeatMax Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4). but only out of combat. +2 EVENT_T_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4). +3 EVENT_T_MANA ManaMax%,ManaMin% RepeatMin, RepeatMax Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4). +4 EVENT_T_AGGRO NONE Expires upon initial aggro (does not repeat). +5 EVENT_T_KILL RepeatMin, RepeatMax Expires upon killing a player. Will repeat between every (Param1) and (Param2). +6 EVENT_T_DEATH NONE Expires upon Death of the Creature. +7 EVENT_T_EVADE NONE Expires upon creature EnterEvadeMode(). +8 EVENT_T_SPELLHIT SpellID, School, RepeatMin, RepeatMax Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school (-1 for all). Will repeat every (Param3) and (Param4) . +9 EVENT_T_RANGE MinDist, MaxDist, RepeatMin, RepeatMax Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4) . +10 EVENT_T_OOC_LOS NoHostile, NoFriendly, RepeatMin, RepeatMax Expires when a Player moves within visible distance to creature. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4) . Does not expire for creatures or pet or when the creature is in combat. +11 EVENT_T_SPAWNED NONE Expires at initial spawn and at creature respawn (useful for setting ranged movement type) +12 EVENT_T_TARGET_HP HPMax%, HPMin%, RepeatMin, RepeatMax Expires when Current Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4) . +13 EVENT_T_TARGET_CASTING RepeatMin, RepeatatMax Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2) . +14 EVENT_T_FRIENDLY_HP HPDeficit, Radius, RepeatMin, RepeatMax Expires when a friendly unit in radius has at least (param1) hp missing. Will repeat every (Param3) and (Param4) . +15 EVENT_T_FRIENDLY_IS_CC DispelType, Radius, RepeatMin, RepeatMax Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4) . +16 EVENT_T_MISSING_BUFF SpellId, Radius, RepeatMin, RepeatMax Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4) . +17 EVENT_T_SUMMONED_UNIT CreatureId, RepeatMin, RepeatMax Expires after creature with entry = (param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3). +18 EVENT_T_TARGET_MANA ManaMax%, ManaMin%, RepeatMin, RepeatMax +21 EVENT_T_REACHED_HOME NONE Expires when creature reach it's home(spawn) location after Evade. + +========================================= +Action Types +========================================= +Below is the list of current Action types that EventAI can handle. +Each event type has its own specific interpretation of the params that accompany it. +Params are always read from Param1, then Param2, then Param3. + +(# Internal Name Param usage Discription) +0 ACTION_T_NONE No Action Does Nothing +1 ACTION_T_TEXT -TextId1, -TextId2, -TextId3 Displays the -TextId as defined. In case -TextId2 and optionally -TextId3, the output will be randomized. Type text are defined in the text table itself(say, yell, whisper, etc) along with other options for the text. All values are required to be negative. +2 ACTION_T_SET_FACTION FactionId Change faction for creature. If param1==0, creature will revert to default faction. +3 ACTION_T_MORPH_TO_ENTRY_OR_MODEL CreatureEntry, ModelId Set model from creature_template.entry(param1) OR set explicit modelId(param2). If param1 AND param2 both 0, demorph and revert to default model for creature. +4 ACTION_T_SOUND SoundId Plays Sound +5 ACTION_T_EMOTE EmoteId Does emote +6 ACTION_T_RANDOM_SAY UNUSED +7 ACTION_T_RANDOM_YELL UNUSED +8 ACTION_T_RANDOM_TEXTEMOTE UNUSED +9 ACTION_T_RANDOM_SOUND SoundId1, SoundId2, SoundId3 Plays random sound between 3 params* +10 ACTION_T_RANDOM_EMOTE EmoteId1, EmoteId2, EmoteId3 Emotes random emote between 3 params +11 ACTION_T_CAST SpellId, Target, CastFlags Casts spell (param1) on target type (param2). Uses Cast Flags (specified below target types) +12 ACTION_T_SUMMON CreatureID, Target, Duration Summons creature (param1) to attack target (param2) for (param3) duration. Spawns on top of current creature. +13 ACTION_T_THREAT_SINGLE_PCT Threat%, Target Modifies threat by (param1) on target type (param2) +14 ACTION_T_THREAT_ALL_PCT Threat% Modifies threat by (param1) on all targets (using -100% on all will result in full aggro dump) +15 ACTION_T_QUEST_EVENT QuestID, Target Calls AreaExploredOrEventHappens with (param1) for target type (Param2) +16 ACTION_T_QUEST_CASTCREATUREGO CreatureID, SpellId, Target Sends CastCreatureOrGo for CreatureId (param1) with SpellId (param2) for target (param3) +17 ACTION_T_SET_UNIT_FIELD Field_Number, Value, Target Sets Unit Field (param1) to Value (param2) on target type (param3) +18 ACTION_T_SET_UNIT_FLAG Flags, Target Sets flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2) +19 ACTION_T_REMOVE_UNIT_FLAG Flags, Target Removes flag (flags can be binary OR together to modify multiple flags at once) on for Target type (param2) +20 ACTION_T_AUTO_ATTACK AllowAutoAttack 0 = stop melee attack, anything else means continue attacking/allow melee attacking +21 ACTION_T_COMBAT_MOVEMENT AllowCombatMovement 0 = stop combat based movement, anything else continue/allow combat based movement (targeted movement generator) +22 ACTION_T_SET_PHASE Phase Sets the current phase to (param1) +23 ACTION_T_INC_PHASE Value Increments the phase by (param1). May be negative to decrement phase but should not be 0. +24 ACTION_T_EVADE No Params Forces the creature to evade. Wiping all threat and dropping combat. +25 ACTION_T_FLEE No Params Causes the .creature to flee. Please use this action instead of directly casting this spell so we may change this when a more correct approach is found. +26 ACTION_T_QUEST_EVENT_ALL QuestId Calls GroupEventHappens with (param1). Only used if it's _expected_ event should complete for all players in current party +27 ACTION_T_CASTCREATUREGO_ALL QuestId, SpellId Calls CastedCreatureOrGo for all players on the threat list with QuestID(Param1) and SpellId(Param2) +28 ACTION_T_REMOVEAURASFROMSPELL Target, Spellid Removes all auras on Target caused by Spellid +29 ACTION_T_RANGED_MOVEMENT Distance, Angle Changes the movement generator type to a ranged type. Note: Default melee type can still be done with this. Specify 0 angle and 0 distance. +30 ACTION_T_RANDOM_PHASE PhaseId1, PhaseId2, PhaseId3 Sets the phase to the id between 3 params* +31 ACTION_T_RANDOM_PHASE_RANGE PhaseMin, PhaseMax Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). PhaseMax must be greater than PhaseMin. +32 ACTION_T_SUMMON CreatureID, Target, SummonID Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3). +33 ACTION_T_KILLED_MONSTER CreatureID, Target Calls KilledMonster (param1) for target of type (param2) +34 ACTION_T_SET_INST_DATA Field, Data Calls ScriptedInstance::SetData with field (param1) and data (param2) +35 ACTION_T_SET_INST_DATA64 Field, Target Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID. +36 ACTION_T_UPDATE_TEMPLATE TemplateId, Team Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true +37 ACTION_T_DIE No Params Kills the creature +38 ACTION_T_ZONE_COMBAT_PULSE No Params Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances. + +* = Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2) + +========================================= +Event Types +========================================= +Note: +COMBAT ONLY - Means that this event will only trigger durring combat. +OUT OF COMBAT ONLY - Means that this event will only trigger while out of combat. +BOTH - This event can trigger both in and out of combat. + +Events that do not have lables on them are events that are directly involved with the in and out of combat state. + +------------------ +0 = EVENT_T_TIMER: +------------------ +Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire +Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on. +This is commonly used for spells that repeat cast during combat (Simulate Spell Cooldown). + +---------------------- +1 = EVENT_T_TIMER_OOC: +---------------------- +Parameter 1: InitialMin - Minumum Time used to calculate Random Initial Expire +Parameter 2: InitialMax - Maximum Time used to calculate Random Initial Expire +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +OUT OF COMBAT ONLY! - Expires first between (Param1) and (Param2) and then between every (Param3) and (Param4) from then on. +This is commonly used for events that occur and repeat outside of combat. + +--------------- +2 = EVENT_T_HP: +--------------- +Parameter 1: HPMax% - Maximum HP% That this Event will Expire +Parameter 2: HPMin% - Minimum HP% That this Event will Expire +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +BOTH - Expires when HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4). +This is commonly used for events that trigger at a specific HP% (Such as Heal/Enrage Spells or NPC's that Flee). + +----------------- +3 = EVENT_T_MANA: +----------------- +Parameter 1: ManaMax% - Maximum Mana% That this Event will Expire +Parameter 2: ManaMin% - Minimum Mana% That this Event will Expire +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +BOTH - Expires once Mana% is between (Param1) and (Param2). Will repeat every (Param3) and (Param4). +This is commonly used for events where an NPC low on Mana will do something (Such as stop casting spells and switch to melee). + +------------------ +4 = EVENT_T_AGGRO: +------------------ +This Event Expires upon initial aggro (does not repeat). + +----------------- +5 = EVENT_T_KILL: +----------------- +Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +COMBAT ONLY! - Expires upon killing a player. Will repeat every (Param1) and (Param2). +This Event Expires upon killing a player. It is commonly used for NPC's who yell or do something after killing a player. + +------------------ +6 = EVENT_T_DEATH: +------------------ +This Event Expires upon Death of the Scripted NPC. +This is commonly used for NPC's who have a yell on death or cast some kind if summon spell when they die. + +------------------ +7 = EVENT_T_EVADE: +------------------ +This Event Expires upon the creature EnterEvadeMode(). +This is commonly used for NPC's who use phases, allows you to reset their phase to 0 upon evade to prevent possible strange behavior. + +--------------------- +8 = EVENT_T_SPELLHIT: +--------------------- +Parameter 1: SpellID - The Spell ID that will trigger the event to occur (NOTE: If you use Spell School as the trigger set this value to 0) +Parameter 2: School - Spell School to trigger the event (NOTE: If you use a SpellID then set this value to -1) - *See Below for Spell School Bitmask Values* +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +BOTH - Expires upon Spell hit. If (param1) is set will only expire on that spell. If (param2) will only expire on spells of that school. Will repeat every (Param3) and (Param4). +This Event is commonly used for NPC's who can do special things when you cast a spell (Or specific spell) on them. + +------------------ +9 = EVENT_T_RANGE: +------------------ +Parameter 1: MinDist - This Distance is the Minimum Distance between the NPC and it's target to allow this Event to Expire +Parameter 2: MaxDist - This Distance is the Maximum Distance between the NPC and it's target to allow this Event to Expire +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +COMBAT ONLY! - Expires when the highest threat target distance is greater than (Param1) and less than (Param2). Will repeat every (Param3) and (Param4). +This Event is commonly used for NPC's who have Ranged Combat and will Throw/Shoot between a certian distance. + +--------------------- +10 = EVENT_T_OOC_LOS: +--------------------- +Parameter 1: NoHostile - This Value is to Prevent this Action from Expiring When Caused by a Player/Creature Hostile to them (0 = Prevent Event from Expiring, 1 = Allow Event to Expire) +Parameter 2: NoFriendly - This Value is to Prevent this Action from Expiring When Caused by a Player/Creature Friendly to them (0 = Prevent Event from Expiring, 1 = Allow Event to Expire) +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +OUT OF COMBAT ONLY! - Expires when a Player moves within visible distance to the NPC. Does not expire for Hostile Players if (Param1) is not 0. Does not expire for Friendly Players if (Param2) is not 0. Will repeat every (Param3) and (Param4). Does not expire for creatures or pets when they are in combat. +This Event is commonly used for NPC's who Do Something or Say Something when you walk past them Out of Combat. + +--------------------- +11 = EVENT_T_SPAWNED: +--------------------- +Expires at initial spawn and at creature respawn. +This Event is commonly used for setting ranged movement type or Summoning a Pet on Spawn + +----------------------- +12 = EVENT_T_TARGET_HP: +----------------------- +Parameter 1: HPMax% - Maximum HP% That this Event will Expire +Parameter 2: HPMin% - Minimum HP% That this Event will Expire +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +COMBAT ONLY! - Expires when Current NPC's Target's HP is between (Param1) and (Param2). Will repeat every (Param3) and (Param4). +This Event is commonly used for NPC's who have a special ability (Like Execute) that only casts when a Player HP is low. + +---------------------------- +13 = EVENT_T_TARGET_CASTING: +---------------------------- +Parameter 1: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 2: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +COMBAT ONLY! - Expires when the current target is casting a spell. Will repeat every (Param1) and (Param2). +This event is commonly used for NPC's who will cast a counter spell when their target starts to cast a spell. + +------------------------- +14 = EVENT_T_FRIENDLY_HP: +------------------------- +Parameter 1: HPDeficit - This is the Amount of HP Missing from Full HP to trigger this event (You would need to calculate the amount of HP the event happens and subtract that from Full HP Value to get this number) +Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing amount of HP in Param1. +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +COMBAT ONLY! - Expires when a friendly unit in radius(param2) has at least (param1) hp missing. Will repeat every (Param3) and (Param4). +This is commonly used when an NPC in Combat will heal a nearby Friendly NPC in Combat with a Heal/Renew Spell. + +---------------------------- +15 = EVENT_T_FRIENDLY_IS_CC: +---------------------------- +Parameter 1: DispelType - Dispel Type to trigger the event - *See Below for Dispel Bitmask Values* +Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies being Crowd Controlled +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +COMBAT ONLY! - Expires when a friendly unit is Crowd controlled within the given radius (param2). Will repeat every (Param3) and (Param4). +This is commonly used for NPC's who can come to the resule of other Friendly NPC's if being Crowd Controlled + +-------------------------- +16 = EVENT_T_MISSING_BUFF: +-------------------------- +Parameter 1: SpellId - This is the SpellID That the Aura Check will look for (If it is missing this Aura) +Parameter 2: Radius - This is the Range in Yards the NPC will scan for nearby Friendlies (Faction is Friendly To) for the missing Aura. +Parameter 3: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 4: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +BOTH - Expires when a friendly unit is missing aura's given by spell (param1) within radius (param2). Will repeat every (Param3) and (Param4). +This is commonly used for NPC's who watch friendly units for a debuff to end so they can recast it on them again. + +--------------------------- +17 = EVENT_T_SUMMONED_UNIT: +--------------------------- +Parameter 1: CreatureId - The CreatureID that the NPC is watching to spawn to trigger this event +Parameter 2: RepeatMin - Minimum Time used to calculate Random Repeat Expire +Parameter 3: RepeatMax - Maximum Time used to calculate Random Repeat Expire + +BOTH - Expires after creature with entry(Param1) is spawned or for all spawns if param1 = 0. Will repeat every (Param2) and (Param3) . +This is commonly used for NPC's who will do something special once another NPC is summoned. Usually used is Complex Scripts or Special Events. + +--------------------------- +21 = EVENT_T_REACHED_HOME: +--------------------------- +Expires only when creature has returned to it's home location after Evade. Out of combat event. +Most commonly used to cast spells that can not be casted in EVENT_T_EVADE and other effects that does not fit in while still running back to spawn/home location. + + +========================================= +Action Types +========================================= + +----------------- +1 = ACTION_T_TEXT: +----------------- +Parameter 1: The entry of the text that the NPC should use from eventai_texts table. Optionally a entry from other tables can be used (such as custom_texts). + Entry are required to be negative and exist in a *_texts-table. The type text to be displayed are defined in the texts-table itself (Say, Yell, Whisper, Emote Text, Boss Whisper, Boss Emote) + Other options are also to be defined in the texts-table, such as a sound to be heard with the text and the language used in output (common, dwarvish, etc). + In case this entry has a localized version of the text, the localized text will be displayed in client that support this locale. + +Parameter 2: Optional. TextId can be defined in addition. The same apply to this as explained above, however eventAI will randomize between the two. +Parameter 3: Optional, if Parameter 2 exist. In this case, eventAI will randomize between three. + +See Text-tables.txt for documentation of eventai_texts-table. + +------------------ +2 = ACTION_T_SET_FACTION: +------------------ +Parameter 1: FactionId from Faction.dbc OR 0. Changes faction for creature. If 0, creature will revert to it's default faction if previously changed. + +----------------------- +3 = ACTION_T_MORPH_TO_ENTRY_OR_MODEL: +----------------------- +Parameter 1: Creature entry from creature_template. Action will then change to the model this creature are using. +Parameter 2: If parameter 1 is 0, then this modelId will be used (in case parameter 1 exist, parameter 2 will not be used) + +If both parameter 1 and 2 is 0, the creature will DeMorph, and use it's default model. + +------------------- +4 = ACTION_T_SOUND: +------------------- +Parameter 1: The Sound ID to be played. (Sound IDs are contained in the DBC files.) + +The creature will play the specified sound. +This is commonly used for Bosses who Yell and then also have a Voice for the same thing. + +------------------- +5 = ACTION_T_EMOTE: +------------------- +Parameter 1: The Emote ID that the creature should perform. (Emote IDs are also contained in the DBC but they can be found in the mangos source as well). + +The creature will perform a visual emote. Unlike a text emote, a visual emote is one where the creature will actually move or perform a gesture. +This is commonly used for NPC's who may perform a special action (Salute, Roar, ect...). Not all player emotes work for creature models. + +------------------------ +6 = ACTION_T_RANDOM_SAY: +------------------------ +UNUSED Can be reused to create new action type + +------------------------- +7 = ACTION_T_RANDOM_YELL: +------------------------- +UNUSED Can be reused to create new action type + +------------------------------ +8 = ACTION_T_RANDOM_TEXTEMOTE: +------------------------------ +UNUSED Can be reused to create new action type + +-------------------------- +9 = ACTION_T_RANDOM_SOUND: +-------------------------- +Parameter 1: The Sound ID to be played as Random Choice #1. +Parameter 2: The Sound ID to be played as Random Choice #2. +Parameter 3: The Sound ID to be played as Random Choice #3. + +Similar to the ACTION_T_SOUND action, it will choose at random a sound to play. + +--------------------------- +10 = ACTION_T_RANDOM_EMOTE: +--------------------------- +Parameter 1: The Emote ID to be played as Random Choice #1. +Parameter 2: The Emote ID to be played as Random Choice #2. +Parameter 3: The Emote ID to be played as Random Choice #3. + +Similar to the ACTION_T_EMOTE action, it will choose at random an Emote to Visually Perform. + +------------------- +11 = ACTION_T_CAST: +------------------- +Parameter 1: SpellId - The Spell ID to use for the NPC to cast. The value used in this field needs to be a valid Spell ID. +Parameter 2: Target - The Target Type defining who the creature should cast the spell at. The value in this field needs to be a valid Target Type as specified in the reference tables below. +Parameter 3: CastFlags - See Table Below for Cast Flag Bitmask Values. If you are unsure what to set this value at leave it at 0. + +The creature will cast a spell specified by a spell ID on a target specified by the target type. +This is commonly used for NPC's who cast spells. + +--------------------- +12 = ACTION_T_SUMMON: +--------------------- +Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID. +Parameter 2: Target - The Target Type defining who the Summoned creature will attack once spawned. The value in this field needs to be a valid Target Type as specified in the reference tables below. +Parameter 3: Duration - The duration until the summoned creature should be unsummoned AFTER Combat ends. The value in this field is in milliseconds or 0. + +The NPC will Summon another creature at the same spot as itself that will attack the specified target. +NOTE: Almost all Creature Summons have proper Summon Spells that should be used when possible. This Action is a powerful last resort option only to be used if nothing else works. +NOTE: Using Target Type 0 will cause the Summoned creature to not attack anyone. +NOTE: If Duration is set at 0, then the summoned creature will not despawn until it has died. +This is used as a manual way to force an NPC to Summon. +-------------------------------- +13 = ACTION_T_THREAT_SINGLE_PCT: +-------------------------------- +Parameter 1: Threat% - Threat percent that should be modified. The value in this field can range from -100 to +100. If it is negative, threat will be taken away and if positive, threat will be added. +Parameter 2: Target - The Target Type defining on whom the threat change should occur. The value in this field needs to be a valid target type as specified in the reference tables below. + +This action will modify the threat of a target in the creature's threat list by the specified percent. +This is commonly used to allow an NPC to adjust the Threat to a single player. + +----------------------------- +14 = ACTION_T_THREAT_ALL_PCT: +----------------------------- +Parameter 1: Threat% - The percent that should be used in modifying everyone's threat in the creature's threat list. The value here can range from -100 to +100. + +This action will modify the threat for everyone in the creature's threat list by the specified percent. +NOTE: Using -100 will cause the creature to reset everyone's threat to 0 so that everyone has the same amount of threat. It will NOT remove anyone from the threat list. +This is commonly used to allow an NPC to drop threat for all players to zero. + +-------------------------- +15 = ACTION_T_QUEST_EVENT: +-------------------------- +Parameter 1: QuestID - The Quest Template ID. The value here must be a valid quest template ID. Furthermore, the quest should have SpecialFlags | 2 as it would need to be completed by an external event which is the activation of this action. +Parameter 2: Target - The Target Type defining whom the quest should be completed for. The value in this field needs to be a valid target type as specified in the reference tables below. + +This action will satisfy the external completion requirement for the quest for the specified target defined by the target type. +NOTE: This action can only be used with player targets so it must be ensured that the target type will point to a player. +This is commonly used for Quests where only ONE player will gain credit for the quest. + +----------------------------- +16 = ACTION_T_CASTCREATUREGO: +----------------------------- +Parameter 1: CreatureID - The Creature Template ID to be Summoned. The value here needs to be a valid Creature Template ID. +Parameter 2: SpellId - The Spell ID to use to simulate the cast. The value used in this field needs to be a valid Spell ID. +Parameter 3: Target - The Target Type defining whom the quest credit should be given to. The value in this field needs to be a valid target type as specified in the reference tables below. + +This action will call CastedCreatureOrGO() function for the player. It can be used to give quest credit for casting a spell on the creature. +This is commonly used for NPC's who have a special requirement to have a Spell cast on them to complete a quest. + +----------------------------- +17 = ACTION_T_SET_UNIT_FIELD: +----------------------------- +Parameter 1: Field_Number - The index of the Field Number to be changed. Use (http://wiki.udbforums.org/index.php/Character_data) for a list of indeces and what they control. Creatures only contain the OBJECT_FIELD_* and UNIT_FIELD_* fields. They do not contain the PLAYER_FIELD_* fields. +Parameter 2: Value - The new value to be put in the field. +Parameter 3: Target - The Target Type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below. + +When activated, this action can change the target's unit field values. More information on the field value indeces can be found at (http://wiki.udbforums.org/index.php/Character_data) + +---------------------------- +18 = ACTION_T_SET_UNIT_FLAG: +---------------------------- +Parameter 1: Flags - The flag(s) to be set. Multiple flags can be set by using bitwise-OR on them (adding them together). +Parameter 2: Target - The Target Type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below. + +When activated, this action changes the target's flags by adding (turning on) more flags. For example, this action can make the creature unattackable/unselectable if the right flags are used. + +------------------------------- +19 = ACTION_T_REMOVE_UNIT_FLAG: +------------------------------- +Parameter 1: Flags - The flag(s) to be removed. Multiple flags can be set by using bitwise-OR on them (adding them together). +Parameter 2: Target - The target type defining for whom the flags should be changed. The value in this field needs to be a valid Target Type as specified in the reference tables below. + +When activated, this action changes the target's flags by removing (turning off) flags. For example, this action can make the creature normal after it was unattackable/unselectable if the right flags are used. + +-------------------------- +20 = ACTION_T_AUTO_ATTACK: +-------------------------- +Parameter 1: AllowAutoAttack - If zero, then the creature will stop its melee attacks. If non-zero, then the creature will either continue its melee attacks (the action would then have no effect) or it will start its melee attacks on the target with the top threat if its melee attacks were previously stopped. + +This action controls whether or not the creature should stop or start the auto melee attack. +NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values (0 = Stop Melee, 1 = Start Melee). +This is commonly used in combination with EVENT_T_RANGE and ACTION_T_COMBAT_MOVEMENT for Ranged Combat for Mages and Spell Casters. + +------------------------------ +21 = ACTION_T_COMBAT_MOVEMENT: +------------------------------ +Parameter 1: If zero, then the creature will stop moving towards its victim (if its victim gets out of melee range) and will be stationary. If non-zero, then the creature will either continue to follow its victim (the action would have no effect) or it will start to follow the target with the top threat if its movement was disabled before. + +This action controls whether or not the creature will always move towards its target. +NOTE: The ACID Dev Team has conformed to using either 0 or 1 for the Param values. (0 = Stop Movement, 1 = Start Movement) +This is commonly used with EVENT_T_RANGE and ACTION_T_AUTO_ATTACK for NPC's who engage in Ranged Comabt (Either Spells or Ranged Attacks) + +------------------------ +22 = ACTION_T_SET_PHASE: +------------------------ +Parameter 1: The new phase to set the creature in. This number must be an integer between 0 and 31. Numbers outside of that range will result in an error. + +When activated, this action sets the creature's event to the specified value. +NOTE: The creature's current Phase is NOT reset at creature evade. You must manually set the phase back to 0 at EVENT_T_RESET. +NOTE: The value used for the Param is the actual Phase Number (Not The Event_Inverse_Phase_Mask) +This is commonly used for complex scripts with several phases and you need to switch to a different phase. + +------------------------ +23 = ACTION_T_INC_PHASE: +------------------------ +Parameter 1: Value - The number of phases to increase or decrease. Use negative values to decrease the current phase. + +When activated, this action will increase (or decrease) the current creature's phase. +NOTE: After increasing or decreasing the phase by this action, the current phase must NOT be lower than 0 or exceed 31. +This can be used instead of ACTION_T_SET_PHASE to change phases in scripts. Just a user friendly option for changing phases. + +-------------------- +24 = ACTION_T_EVADE: +-------------------- +When activated, the creature will immediately exit out of combat, clear its threat list, and move back to its spawn point. Basically, this action will reset the whole encounter. +NOTE: All Param Values Are 0 for this Action. + +------------------- +25 = ACTION_T_FLEE: +------------------- +When activated, the creature will try to flee from combat. Currently this is done by it casting a fear-like spell on itself called "Run Away". A Better Flee system is in Development but will take time before it is implimented. +NOTE: All Param Values Are 0 for this Action. + +------------------------------ +26 = ACTION_T_QUEST_EVENT_ALL: +------------------------------ +Parameter 1: QuestId - The quest ID to finish for everyone. + +This action does the same thing as the ACTION_T_QUEST_EVENT does but it does it for all players in the creature's threat list. +NOTE: If a player is not in the NPC's threat list for whatever reason, he/she won't get the quest completed. + +--------------------------------- +27 = ACTION_T_CASTCREATUREGO_ALL: +--------------------------------- +Parameter 1: QuestId - The quest template ID. +Parameter 2: SpellId - The spell ID used to simulate the cast. + +This action does the same thing as the ACTION_T_CASTCREATUREGO does but it does it for all players in the creature's threat list. +NOTE: If a player is not in its threat list for whatever reason, he/she won't receive the cast emulation. + +----------------------------------- +28 = ACTION_T_REMOVEAURASFROMSPELL: +----------------------------------- +Parameter 1: Target - The target type defining for whom the unit field should be changed. The value in this field needs to be a valid target type as specified in the reference tables below. +Parameter 2: SpellId - The spell ID whose auras will be removed. + +This action will remove all auras from a specific spell from the target. +This is commonly used for NPC's who have an OOC Aura that is removed at combat start or a similar idea (Like Stealth or Shape Shift) + +------------------------------ +29 = ACTION_T_RANGED_MOVEMENT: +------------------------------ +Parameter 1: Distance - The distance the mob should keep between it and its target. +Parameter 2: Angle - The angle the mob should use. + +This action changes the movement type generator to ranged type using the specified values for angle and distance. +NOTE: Specifying zero angle and distance will make it just melee instead. +This is commonly used for NPC's who always attack at range and you can specify the distance they will maintain from the target. + +--------------------------- +30 = ACTION_T_RANDOM_PHASE: +--------------------------- +Parameter 1: PhaseId1 - A possible random phase choice. +Parameter 2: PhaseId2 - A possible random phase choice. +Parameter 3: PhaseId3 - A possible random phase choice. + +Randomly sets the phase to one from the three parameter choices. +NOTE: Use -1 to specify that if this param is picked to do nothing. Random is constant between actions within an event. So if you have a random Yell and a random Sound they will match up (ex: param2 with param2) +NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE. +This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have up to 3 phases used, otherwise use Action 31 for more then 3 phases. + +--------------------------------- +31 = ACTION_T_RANDOM_PHASE_RANGE: +--------------------------------- +Parameter 1: PhaseMin - The minimum of the phase range. +Parameter 2: PhaseMax - The maximum of the phase range. The number here must be greater than PhaseMin. + +Randomly sets the phase between a range of phases controlled by the parameters. Sets the phase to a random id (Phase = PhaseMin + rnd % PhaseMin-PhaseMax). +NOTE: PhaseMax must be greater than PhaseMin. +NOTE 2: PLEASE NOTE THAT EACH OF THE PARAM VALUES ARE ACTUAL PHASE NUMBERS NOT THE INVERSE PHASE MASK VALUE. +This is commonly used for Spellcasting NPC's who on Aggro may select at random a school of spells to use for the fight. Use this if you have MORE then 3 phases used, otherwise use Action 30. + +--------------------- +32 = ACTION_T_SUMMON: +--------------------- +Parameter 1: CreatureID - The creature template ID to be summoned. The value here needs to be a valid creature template ID. +Parameter 2: Target - The target type defining who the summoned creature will attack. The value in this field needs to be a valid target type as specified in the reference tables below. NOTE: Using target type 0 will cause the summoned creature to not attack anyone. +Parameter 3: SummonID - The summon ID from the eventai_summons table controlling the position (and spawntime) where the summoned mob should be spawned at. + +Summons creature (param1) to attack target (param2) at location specified by EventAI_Summons (param3). +NOTE: Param3 Value is the ID Value used for the entry used in EventAI_Summons for this action. You MUST have an EventAI_Summons entry to use this action. +This is commonly used for NPC's who need to Summon a creature at a specific location. (Normally used for complex events) + +----------------------------- +33 = ACTION_T_KILLED_MONSTER: +----------------------------- +Parameter 1: CreatureID - The creature template ID. The value here must be a valid creature template ID. +Parameter 2: Target - The target type defining whom the quest kill count should be given to. The value in this field needs to be a valid target type as specified in the reference tables below. + +When activated, this action will call KilledMonster() function for the player. It can be used to give creature credit for killing a creature. In general if the quest is set to be accompished on different creatures (e.g. "Credit" templates). +NOTE: It can be ANY creature including certain quest specific triggers +This is commonly used for giving the player Quest Credits for NPC kills (Many NPC's may use the same CreatureID for the Kill Credit) + +---------------------------- +34 = ACTION_T_SET_INST_DATA: +---------------------------- +Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script. +Parameter 2: Data - The value to put at that field index. + +Sets data for the instance. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned. +NOTE: Param1 Value is located in "def_<instance name>.h" SD2 File and Param2 value is generally found in the "sc_instance.h" file in SD2 +This is commonly used to link an ACID script with a SD2 C++ Script. You make make things happen like opening doors on specific events that happen. ACID Just triggers the C++ Script to function. + +------------------------------ +35 = ACTION_T_SET_INST_DATA64: +------------------------------ +Parameter 1: Field - The field to change in the instance script. Again, this field needs to be a valid field that has been already defined in the instance's script. +Parameter 2: Target - The target type to use to get the GUID that will be stored at the field index. The value in this field needs to be a valid target type as specified in the reference tables below. + +Sets GUID (64 bits) data for the instance based on the target. Note that this will only work when the creature is inside an instantiable zone that has a valid script (ScriptedInstance) assigned. +Calls ScriptedInstance::SetData64 with field (param1) and data (param2) target's GUID. + +------------------------------ +36 = ACTION_T_UPDATE_TEMPLATE: +------------------------------ +Parameter 1: TemplateId - The creature template ID. The value here must be a valid creature template ID. +Parameter 2: Team - Use model_id from team : Alliance(0) or Horde (1). + +This function temporarily changes creature entry to new entry, display is changed, loot is changed, but AI is not changed. At respawn creature will be reverted to original entry. +Changes the creature to a new creature template of (param1) with team = Alliance if (param2) = false or Horde if (param2) = true + +------------------ +37 = ACTION_T_DIE: +------------------ +Kills the creature +This is commonly used if you need to Instakill the creature for one reason or another. + +-------------------------------- +38 = ACTION_T_ZONE_COMBAT_PULSE: +-------------------------------- +Places all players within the instance into combat with the creature. Only works in combat and only works inside of instances. + + +========================================= +Target Types +========================================= +Below is the list of current Target types that EventAI can handle. +Target types are used by certain actions and may effect actions differently + +(# Internal Name Discription) +0 TARGET_T_SELF Self cast +1 TARGET_T_HOSTILE Our current target (ie: highest aggro) +2 TARGET_T_HOSTILE_SECOND_AGGRO Second highest aggro (generaly used for cleaves and some special attacks) +3 TARGET_T_HOSTILE_LAST_AGGRO Dead last on aggro (no idea what this could be used for) +4 TARGET_T_HOSTILE_RANDOM Just any random target on our threat list +5 TARGET_T_HOSTILE_RANDOM_NOT_TOP Any random target except top threat +6 TARGET_T_ACTION_INVOKER Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP) + +========================================= +Cast Flags +========================================= +Below is the list of current Cast Flags that EventAI's spell casting can handle. +Cast flags are handled bitwise. Bit 0 is Interrupt Previous, bit 1 is triggered, etc. +So for example the number "3" (11 in Binary, selecting first 2 options) would mean that this cast has both CAST_INTURRUPT_PREVIOUS and CAST_TRIGGERED. +Another example: the number "5" (101 in Binary, selecting first and third options) would mean that this cast has CAST_INTURRUPT_PREVIOUS and CAST_FORCE_CAST. + +(bit# Decimal Internal Name Discription) +0 1 CAST_INTURRUPT_PREVIOUS Interrupts any previous spell casting (basicaly makes sure that this spell goes off) +1 2 CAST_TRIGGERED Forces the spell to be instant cast and require no mana/reagents. +2 4 CAST_FORCE_CAST Forces spell to cast even if the target is possibly out of range or the creature is possibly out of mana +3 8 CAST_NO_MELEE_IF_OOM Prevents creature from entering melee if out of mana or out of range +4 16 CAST_FORCE_TARGET_SELF Forces the target to cast this spell on itself +5 32 CAST_AURA_NOT_PRESENT Only casts the spell on the target if the target does not have the aura from that spell on itself already. + +NOTE: You can add the numbers in the decimal column to combine flags. + For example if you wanted to use CAST_NO_MELEE_IF_OOM(8) and CAST_TRIGGERED(2) you would simply use 10 in the cast flags field (8 + 2 = 10). + +========================================= +Event Flags +========================================= +Below is the list of current Event Flags that EventAI can handle. Event flags are handled bitwise. + +(bit# Decimal Internal Name Discription) +0 1 EFLAG_REPEATABLE Event repeats (Does not repeat if this flag is not set) +1 2 EFLAG_NORMAL Event occurs in Normal instance difficulty (will not occur in Normal if not set) +2 4 EFLAG_HEROIC Event occurs in Heroic instance difficulty (will not occur in Heroic if not set) +3 8 +4 16 +5 32 +6 64 +7 128 EFLAG_DEBUG_ONLY Prevents events from occuring on Release builds of ScriptDev2. Useful for testing new features. + NOTE: You can add the numbers in the decimal column to combine flags.
\ No newline at end of file diff --git a/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp b/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp index 036d576c8e9..b2cec0bda09 100644 --- a/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp +++ b/src/bindings/scripts/scripts/zone/blades_edge_mountains/blades_edge_mountains.cpp @@ -1,450 +1,450 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* ScriptData
-SDName: Blades_Edge_Mountains
-SD%Complete: 90
-SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10821, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete)
-SDCategory: Blade's Edge Mountains
-EndScriptData */
-
-/* ContentData
-mobs_bladespire_ogre
-mobs_nether_drake
-npc_daranelle
-npc_overseer_nuaar
-npc_saikkal_the_elder
-npc_skyguard_handler_irena
-go_legion_obelisk
-EndContentData */
-
-#include "precompiled.h"
-
-//Support for quest: You're Fired! (10821)
-bool obelisk_one, obelisk_two, obelisk_three, obelisk_four, obelisk_five;
-
-#define LEGION_OBELISK_ONE 185193
-#define LEGION_OBELISK_TWO 185195
-#define LEGION_OBELISK_THREE 185196
-#define LEGION_OBELISK_FOUR 185197
-#define LEGION_OBELISK_FIVE 185198
-
-/*######
-## mobs_bladespire_ogre
-######*/
-
-//TODO: add support for quest 10512 + creature abilities
-struct TRINITY_DLL_DECL mobs_bladespire_ogreAI : public ScriptedAI
-{
- mobs_bladespire_ogreAI(Creature *c) : ScriptedAI(c) {Reset();}
-
- void Reset()
- {
- }
-
- void Aggro(Unit* who)
- {
- }
-
- void JustDied(Unit* Killer)
- {
- if (Killer->GetTypeId() == TYPEID_PLAYER)
- ((Player*)Killer)->KilledMonster(19995, m_creature->GetGUID());
- }
-};
-CreatureAI* GetAI_mobs_bladespire_ogre(Creature *_Creature)
-{
- return new mobs_bladespire_ogreAI (_Creature);
-}
-
-/*######
-## mobs_nether_drake
-######*/
-
-#define SAY_NIHIL_1 -1000396
-#define SAY_NIHIL_2 -1000397
-#define SAY_NIHIL_3 -1000398
-#define SAY_NIHIL_4 -1000399
-#define SAY_NIHIL_INTERRUPT -1000400
-
-#define ENTRY_WHELP 20021
-#define ENTRY_PROTO 21821
-#define ENTRY_ADOLE 21817
-#define ENTRY_MATUR 21820
-#define ENTRY_NIHIL 21823
-
-#define SPELL_T_PHASE_MODULATOR 37573
-
-#define SPELL_ARCANE_BLAST 38881
-#define SPELL_MANA_BURN 38884
-#define SPELL_INTANGIBLE_PRESENCE 36513
-
-struct TRINITY_DLL_DECL mobs_nether_drakeAI : public ScriptedAI
-{
- mobs_nether_drakeAI(Creature *c) : ScriptedAI(c) {Reset();}
-
- bool IsNihil;
- uint32 NihilSpeech_Timer;
- uint32 NihilSpeech_Phase;
-
- uint32 ArcaneBlast_Timer;
- uint32 ManaBurn_Timer;
- uint32 IntangiblePresence_Timer;
-
- void Reset()
- {
- IsNihil = false;
- NihilSpeech_Timer = 3000;
- NihilSpeech_Phase = 0;
-
- ArcaneBlast_Timer = 7500;
- ManaBurn_Timer = 10000;
- IntangiblePresence_Timer = 15000;
- }
-
- void Aggro(Unit* who) { }
-
- void MoveInLineOfSight(Unit *who)
- {
- if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
-
- ScriptedAI::MoveInLineOfSight(who);
- }
-
- //in case creature was not summoned (not expected)
- void MovementInform(uint32 type, uint32 id)
- {
- if (type != POINT_MOTION_TYPE)
- return;
-
- if (id == 0)
- {
- m_creature->setDeathState(JUST_DIED);
- m_creature->RemoveCorpse();
- m_creature->SetHealth(0);
- }
- }
-
- void SpellHit(Unit *caster, const SpellEntry *spell)
- {
- if (spell->Id == SPELL_T_PHASE_MODULATOR && caster->GetTypeId() == TYPEID_PLAYER)
- {
- const uint32 entry_list[4] = {ENTRY_PROTO, ENTRY_ADOLE, ENTRY_MATUR, ENTRY_NIHIL};
- int cid = rand()%(4-1);
-
- if (entry_list[cid] == m_creature->GetEntry())
- ++cid;
-
- //we are nihil, so say before transform
- if (m_creature->GetEntry() == ENTRY_NIHIL)
- {
- DoScriptText(SAY_NIHIL_INTERRUPT, m_creature);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- IsNihil = false;
- }
-
- if (m_creature->UpdateEntry(entry_list[cid]))
- {
- if (entry_list[cid] == ENTRY_NIHIL)
- {
- EnterEvadeMode();
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- IsNihil = true;
- }else
- AttackStart(caster);
- }
- }
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (IsNihil)
- {
- if (NihilSpeech_Timer <= diff)
- {
- switch(NihilSpeech_Phase)
- {
- case 0:
- DoScriptText(SAY_NIHIL_1, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 1:
- DoScriptText(SAY_NIHIL_2, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 2:
- DoScriptText(SAY_NIHIL_3, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 3:
- DoScriptText(SAY_NIHIL_4, m_creature);
- ++NihilSpeech_Phase;
- break;
- case 4:
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- //take off to location above
- m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+50.0f, m_creature->GetPositionY(), m_creature->GetPositionZ()+50.0f);
- ++NihilSpeech_Phase;
- break;
- }
- NihilSpeech_Timer = 5000;
- }else NihilSpeech_Timer -=diff;
-
- //anything below here is not interesting for Nihil, so skip it
- return;
- }
-
- if (!UpdateVictim() )
- return;
-
- if (IntangiblePresence_Timer <= diff)
- {
- DoCast(m_creature->getVictim(),SPELL_INTANGIBLE_PRESENCE);
- IntangiblePresence_Timer = 15000+rand()%15000;
- }else IntangiblePresence_Timer -= diff;
-
- if (ManaBurn_Timer <= diff)
- {
- Unit* target = m_creature->getVictim();
- if (target && target->getPowerType() == POWER_MANA)
- DoCast(target,SPELL_MANA_BURN);
- ManaBurn_Timer = 8000+rand()%8000;
- }else ManaBurn_Timer -= diff;
-
- if (ArcaneBlast_Timer <= diff)
- {
- DoCast(m_creature->getVictim(),SPELL_ARCANE_BLAST);
- ArcaneBlast_Timer = 2500+rand()%5000;
- }else ArcaneBlast_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
-};
-
-CreatureAI* GetAI_mobs_nether_drake(Creature *_Creature)
-{
- return new mobs_nether_drakeAI (_Creature);
-}
-
-/*######
-## npc_daranelle
-######*/
-
-#define SAY_SPELL_INFLUENCE -1000174
-
-struct TRINITY_DLL_DECL npc_daranelleAI : public ScriptedAI
-{
- npc_daranelleAI(Creature *c) : ScriptedAI(c) {Reset();}
-
- void Reset() { }
-
- void Aggro(Unit* who) { }
-
- void MoveInLineOfSight(Unit *who)
- {
- if (who->GetTypeId() == TYPEID_PLAYER)
- {
- if (who->HasAura(36904,0) && m_creature->IsWithinDistInMap(who, 10.0f))
- {
- DoScriptText(SAY_SPELL_INFLUENCE, m_creature, who);
- //TODO: Move the below to updateAI and run if this statement == true
- ((Player*)who)->KilledMonster(21511, m_creature->GetGUID());
- ((Player*)who)->RemoveAurasDueToSpell(36904);
- }
- }
-
- ScriptedAI::MoveInLineOfSight(who);
- }
-};
-
-CreatureAI* GetAI_npc_daranelle(Creature *_Creature)
-{
- return new npc_daranelleAI (_Creature);
-}
-
-/*######
-## npc_overseer_nuaar
-######*/
-
-bool GossipHello_npc_overseer_nuaar(Player *player, Creature *_Creature)
-{
- if (player->GetQuestStatus(10682) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM( 0, "Overseer, I am here to negotiate on behalf of the Cenarion Expedition.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(10532, _Creature->GetGUID());
-
- return true;
-}
-
-bool GossipSelect_npc_overseer_nuaar(Player *player, Creature *_Creature, uint32 sender, uint32 action)
-{
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->SEND_GOSSIP_MENU(10533, _Creature->GetGUID());
- player->AreaExploredOrEventHappens(10682);
- }
- return true;
-}
-
-/*######
-## npc_saikkal_the_elder
-######*/
-
-bool GossipHello_npc_saikkal_the_elder(Player *player, Creature *_Creature)
-{
- if (player->GetQuestStatus(10980) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM( 0, "Yes... yes, it's me.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(10794, _Creature->GetGUID());
-
- return true;
-}
-
-bool GossipSelect_npc_saikkal_the_elder(Player *player, Creature *_Creature, uint32 sender, uint32 action)
-{
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM( 0, "Yes elder. Tell me more of the book.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->SEND_GOSSIP_MENU(10795, _Creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->TalkedToCreature(_Creature->GetEntry(), _Creature->GetGUID());
- player->SEND_GOSSIP_MENU(10796, _Creature->GetGUID());
- break;
- }
- return true;
-}
-
-/*######
-## npc_skyguard_handler_irena
-######*/
-
-#define GOSSIP_SKYGUARD "Fly me to Skettis please"
-
-bool GossipHello_npc_skyguard_handler_irena(Player *player, Creature *_Creature )
-{
- if (_Creature->isQuestGiver())
- player->PrepareQuestMenu( _Creature->GetGUID() );
-
- if (player->GetReputationRank(1031) >= REP_HONORED)
- player->ADD_GOSSIP_ITEM( 2, GOSSIP_SKYGUARD, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
-
- return true;
-}
-
-bool GossipSelect_npc_skyguard_handler_irena(Player *player, Creature *_Creature, uint32 sender, uint32 action )
-{
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->CLOSE_GOSSIP_MENU();
- player->CastSpell(player,41278,true); //TaxiPath 706
- }
- return true;
-}
-
-/*######
-## go_legion_obelisk
-######*/
-
-bool GOHello_go_legion_obelisk(Player *player, GameObject* _GO)
-{
- if ( player->GetQuestStatus(10821) == QUEST_STATUS_INCOMPLETE )
- {
- switch( _GO->GetEntry() )
- {
- case LEGION_OBELISK_ONE:
- obelisk_one = true;
- break;
- case LEGION_OBELISK_TWO:
- obelisk_two = true;
- break;
- case LEGION_OBELISK_THREE:
- obelisk_three = true;
- break;
- case LEGION_OBELISK_FOUR:
- obelisk_four = true;
- break;
- case LEGION_OBELISK_FIVE:
- obelisk_five = true;
- break;
- }
-
- if ( obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true )
- {
- _GO->SummonCreature(19963,2943.40f,4778.20f,284.49f,0.94f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000);
- //reset global var
- obelisk_one = false;
- obelisk_two = false;
- obelisk_three = false;
- obelisk_four = false;
- obelisk_five = false;
- }
- }
-
- return true;
-}
-
-/*######
-## AddSC
-######*/
-
-void AddSC_blades_edge_mountains()
-{
- Script *newscript;
-
- newscript = new Script;
- newscript->Name="mobs_bladespire_ogre";
- newscript->GetAI = &GetAI_mobs_bladespire_ogre;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="mobs_nether_drake";
- newscript->GetAI = &GetAI_mobs_nether_drake;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_daranelle";
- newscript->GetAI = &GetAI_npc_daranelle;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_overseer_nuaar";
- newscript->pGossipHello = &GossipHello_npc_overseer_nuaar;
- newscript->pGossipSelect = &GossipSelect_npc_overseer_nuaar;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_saikkal_the_elder";
- newscript->pGossipHello = &GossipHello_npc_saikkal_the_elder;
- newscript->pGossipSelect = &GossipSelect_npc_saikkal_the_elder;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="go_legion_obelisk";
- newscript->pGOHello = &GOHello_go_legion_obelisk;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_skyguard_handler_irena";
- newscript->pGossipHello = &GossipHello_npc_skyguard_handler_irena;
- newscript->pGossipSelect = &GossipSelect_npc_skyguard_handler_irena;
- newscript->RegisterSelf();
-}
-
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>.sourceforge.net/> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Blades_Edge_Mountains +SD%Complete: 90 +SDComment: Quest support: 10503, 10504, 10556, 10609, 10682, 10821, 10980. Ogri'la->Skettis Flight. (npc_daranelle needs bit more work before consider complete) +SDCategory: Blade's Edge Mountains +EndScriptData */ + +/* ContentData +mobs_bladespire_ogre +mobs_nether_drake +npc_daranelle +npc_overseer_nuaar +npc_saikkal_the_elder +npc_skyguard_handler_irena +go_legion_obelisk +EndContentData */ + +#include "precompiled.h" + +//Support for quest: You're Fired! (10821) +bool obelisk_one, obelisk_two, obelisk_three, obelisk_four, obelisk_five; + +#define LEGION_OBELISK_ONE 185193 +#define LEGION_OBELISK_TWO 185195 +#define LEGION_OBELISK_THREE 185196 +#define LEGION_OBELISK_FOUR 185197 +#define LEGION_OBELISK_FIVE 185198 + +/*###### +## mobs_bladespire_ogre +######*/ + +//TODO: add support for quest 10512 + creature abilities +struct TRINITY_DLL_DECL mobs_bladespire_ogreAI : public ScriptedAI +{ + mobs_bladespire_ogreAI(Creature *c) : ScriptedAI(c) {Reset();} + + void Reset() + { + } + + void Aggro(Unit* who) + { + } + + void JustDied(Unit* Killer) + { + if (Killer->GetTypeId() == TYPEID_PLAYER) + ((Player*)Killer)->KilledMonster(19995, m_creature->GetGUID()); + } +}; +CreatureAI* GetAI_mobs_bladespire_ogre(Creature *_Creature) +{ + return new mobs_bladespire_ogreAI (_Creature); +} + +/*###### +## mobs_nether_drake +######*/ + +#define SAY_NIHIL_1 -1000396 +#define SAY_NIHIL_2 -1000397 +#define SAY_NIHIL_3 -1000398 +#define SAY_NIHIL_4 -1000399 +#define SAY_NIHIL_INTERRUPT -1000400 + +#define ENTRY_WHELP 20021 +#define ENTRY_PROTO 21821 +#define ENTRY_ADOLE 21817 +#define ENTRY_MATUR 21820 +#define ENTRY_NIHIL 21823 + +#define SPELL_T_PHASE_MODULATOR 37573 + +#define SPELL_ARCANE_BLAST 38881 +#define SPELL_MANA_BURN 38884 +#define SPELL_INTANGIBLE_PRESENCE 36513 + +struct TRINITY_DLL_DECL mobs_nether_drakeAI : public ScriptedAI +{ + mobs_nether_drakeAI(Creature *c) : ScriptedAI(c) {Reset();} + + bool IsNihil; + uint32 NihilSpeech_Timer; + uint32 NihilSpeech_Phase; + + uint32 ArcaneBlast_Timer; + uint32 ManaBurn_Timer; + uint32 IntangiblePresence_Timer; + + void Reset() + { + IsNihil = false; + NihilSpeech_Timer = 3000; + NihilSpeech_Phase = 0; + + ArcaneBlast_Timer = 7500; + ManaBurn_Timer = 10000; + IntangiblePresence_Timer = 15000; + } + + void Aggro(Unit* who) { } + + void MoveInLineOfSight(Unit *who) + { + if (m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) + return; + + ScriptedAI::MoveInLineOfSight(who); + } + + //in case creature was not summoned (not expected) + void MovementInform(uint32 type, uint32 id) + { + if (type != POINT_MOTION_TYPE) + return; + + if (id == 0) + { + m_creature->setDeathState(JUST_DIED); + m_creature->RemoveCorpse(); + m_creature->SetHealth(0); + } + } + + void SpellHit(Unit *caster, const SpellEntry *spell) + { + if (spell->Id == SPELL_T_PHASE_MODULATOR && caster->GetTypeId() == TYPEID_PLAYER) + { + const uint32 entry_list[4] = {ENTRY_PROTO, ENTRY_ADOLE, ENTRY_MATUR, ENTRY_NIHIL}; + int cid = rand()%(4-1); + + if (entry_list[cid] == m_creature->GetEntry()) + ++cid; + + //we are nihil, so say before transform + if (m_creature->GetEntry() == ENTRY_NIHIL) + { + DoScriptText(SAY_NIHIL_INTERRUPT, m_creature); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + IsNihil = false; + } + + if (m_creature->UpdateEntry(entry_list[cid])) + { + if (entry_list[cid] == ENTRY_NIHIL) + { + EnterEvadeMode(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + IsNihil = true; + }else + AttackStart(caster); + } + } + } + + void UpdateAI(const uint32 diff) + { + if (IsNihil) + { + if (NihilSpeech_Timer <= diff) + { + switch(NihilSpeech_Phase) + { + case 0: + DoScriptText(SAY_NIHIL_1, m_creature); + ++NihilSpeech_Phase; + break; + case 1: + DoScriptText(SAY_NIHIL_2, m_creature); + ++NihilSpeech_Phase; + break; + case 2: + DoScriptText(SAY_NIHIL_3, m_creature); + ++NihilSpeech_Phase; + break; + case 3: + DoScriptText(SAY_NIHIL_4, m_creature); + ++NihilSpeech_Phase; + break; + case 4: + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + //take off to location above + m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+50.0f, m_creature->GetPositionY(), m_creature->GetPositionZ()+50.0f); + ++NihilSpeech_Phase; + break; + } + NihilSpeech_Timer = 5000; + }else NihilSpeech_Timer -=diff; + + //anything below here is not interesting for Nihil, so skip it + return; + } + + if (!UpdateVictim() ) + return; + + if (IntangiblePresence_Timer <= diff) + { + DoCast(m_creature->getVictim(),SPELL_INTANGIBLE_PRESENCE); + IntangiblePresence_Timer = 15000+rand()%15000; + }else IntangiblePresence_Timer -= diff; + + if (ManaBurn_Timer <= diff) + { + Unit* target = m_creature->getVictim(); + if (target && target->getPowerType() == POWER_MANA) + DoCast(target,SPELL_MANA_BURN); + ManaBurn_Timer = 8000+rand()%8000; + }else ManaBurn_Timer -= diff; + + if (ArcaneBlast_Timer <= diff) + { + DoCast(m_creature->getVictim(),SPELL_ARCANE_BLAST); + ArcaneBlast_Timer = 2500+rand()%5000; + }else ArcaneBlast_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mobs_nether_drake(Creature *_Creature) +{ + return new mobs_nether_drakeAI (_Creature); +} + +/*###### +## npc_daranelle +######*/ + +#define SAY_SPELL_INFLUENCE -1000174 + +struct TRINITY_DLL_DECL npc_daranelleAI : public ScriptedAI +{ + npc_daranelleAI(Creature *c) : ScriptedAI(c) {Reset();} + + void Reset() { } + + void Aggro(Unit* who) { } + + void MoveInLineOfSight(Unit *who) + { + if (who->GetTypeId() == TYPEID_PLAYER) + { + if (who->HasAura(36904,0) && m_creature->IsWithinDistInMap(who, 10.0f)) + { + DoScriptText(SAY_SPELL_INFLUENCE, m_creature, who); + //TODO: Move the below to updateAI and run if this statement == true + ((Player*)who)->KilledMonster(21511, m_creature->GetGUID()); + ((Player*)who)->RemoveAurasDueToSpell(36904); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } +}; + +CreatureAI* GetAI_npc_daranelle(Creature *_Creature) +{ + return new npc_daranelleAI (_Creature); +} + +/*###### +## npc_overseer_nuaar +######*/ + +bool GossipHello_npc_overseer_nuaar(Player *player, Creature *_Creature) +{ + if (player->GetQuestStatus(10682) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM( 0, "Overseer, I am here to negotiate on behalf of the Cenarion Expedition.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(10532, _Creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_overseer_nuaar(Player *player, Creature *_Creature, uint32 sender, uint32 action) +{ + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->SEND_GOSSIP_MENU(10533, _Creature->GetGUID()); + player->AreaExploredOrEventHappens(10682); + } + return true; +} + +/*###### +## npc_saikkal_the_elder +######*/ + +bool GossipHello_npc_saikkal_the_elder(Player *player, Creature *_Creature) +{ + if (player->GetQuestStatus(10980) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM( 0, "Yes... yes, it's me.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(10794, _Creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_saikkal_the_elder(Player *player, Creature *_Creature, uint32 sender, uint32 action) +{ + switch (action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM( 0, "Yes elder. Tell me more of the book.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(10795, _Creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->TalkedToCreature(_Creature->GetEntry(), _Creature->GetGUID()); + player->SEND_GOSSIP_MENU(10796, _Creature->GetGUID()); + break; + } + return true; +} + +/*###### +## npc_skyguard_handler_irena +######*/ + +#define GOSSIP_SKYGUARD "Fly me to Skettis please" + +bool GossipHello_npc_skyguard_handler_irena(Player *player, Creature *_Creature ) +{ + if (_Creature->isQuestGiver()) + player->PrepareQuestMenu( _Creature->GetGUID() ); + + if (player->GetReputationRank(1031) >= REP_HONORED) + player->ADD_GOSSIP_ITEM( 2, GOSSIP_SKYGUARD, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_skyguard_handler_irena(Player *player, Creature *_Creature, uint32 sender, uint32 action ) +{ + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + player->CastSpell(player,41278,true); //TaxiPath 706 + } + return true; +} + +/*###### +## go_legion_obelisk +######*/ + +bool GOHello_go_legion_obelisk(Player *player, GameObject* _GO) +{ + if ( player->GetQuestStatus(10821) == QUEST_STATUS_INCOMPLETE ) + { + switch( _GO->GetEntry() ) + { + case LEGION_OBELISK_ONE: + obelisk_one = true; + break; + case LEGION_OBELISK_TWO: + obelisk_two = true; + break; + case LEGION_OBELISK_THREE: + obelisk_three = true; + break; + case LEGION_OBELISK_FOUR: + obelisk_four = true; + break; + case LEGION_OBELISK_FIVE: + obelisk_five = true; + break; + } + + if ( obelisk_one == true && obelisk_two == true && obelisk_three == true && obelisk_four == true && obelisk_five == true ) + { + _GO->SummonCreature(19963,2943.40f,4778.20f,284.49f,0.94f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000); + //reset global var + obelisk_one = false; + obelisk_two = false; + obelisk_three = false; + obelisk_four = false; + obelisk_five = false; + } + } + + return true; +} + +/*###### +## AddSC +######*/ + +void AddSC_blades_edge_mountains() +{ + Script *newscript; + + newscript = new Script; + newscript->Name="mobs_bladespire_ogre"; + newscript->GetAI = &GetAI_mobs_bladespire_ogre; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="mobs_nether_drake"; + newscript->GetAI = &GetAI_mobs_nether_drake; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_daranelle"; + newscript->GetAI = &GetAI_npc_daranelle; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_overseer_nuaar"; + newscript->pGossipHello = &GossipHello_npc_overseer_nuaar; + newscript->pGossipSelect = &GossipSelect_npc_overseer_nuaar; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_saikkal_the_elder"; + newscript->pGossipHello = &GossipHello_npc_saikkal_the_elder; + newscript->pGossipSelect = &GossipSelect_npc_saikkal_the_elder; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="go_legion_obelisk"; + newscript->pGOHello = &GOHello_go_legion_obelisk; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_skyguard_handler_irena"; + newscript->pGossipHello = &GossipHello_npc_skyguard_handler_irena; + newscript->pGossipSelect = &GossipSelect_npc_skyguard_handler_irena; + newscript->RegisterSelf(); +} + diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp index 206862c17c5..217a1002e5d 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/hyjal/boss_archimonde.cpp @@ -1,656 +1,656 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* ScriptData
-SDName: Boss_Archimonde
-SD%Complete: 85
-SDComment: Doomfires not completely offlike due to core limitations for random moving. Tyrande and second phase not fully implemented.
-SDCategory: Caverns of Time, Mount Hyjal
-EndScriptData */
-
-#include "precompiled.h"
-#include "def_hyjal.h"
-#include "SpellAuras.h"
-
-//text id -1534018 are the text used when previous events complete. Not part of this script.
-#define SAY_AGGRO -1534019
-#define SAY_DOOMFIRE1 -1534020
-#define SAY_DOOMFIRE2 -1534021
-#define SAY_AIR_BURST1 -1534022
-#define SAY_AIR_BURST2 -1534023
-#define SAY_SLAY1 -1534024
-#define SAY_SLAY2 -1534025
-#define SAY_SLAY3 -1534026
-#define SAY_ENRAGE -1534027
-#define SAY_DEATH -1534028
-#define SAY_SOUL_CHARGE1 -1534029
-#define SAY_SOUL_CHARGE2 -1534030
-
-#define SPELL_DENOUEMENT_WISP 32124
-#define SPELL_ANCIENT_SPARK 39349
-#define SPELL_PROTECTION_OF_ELUNE 38528
-
-#define SPELL_DRAIN_WORLD_TREE 39140
-#define SPELL_DRAIN_WORLD_TREE_2 39141
-
-#define SPELL_FINGER_OF_DEATH 31984
-#define SPELL_HAND_OF_DEATH 35354
-#define SPELL_AIR_BURST 32014
-#define SPELL_GRIP_OF_THE_LEGION 31972
-#define SPELL_DOOMFIRE_STRIKE 31903 //summons two creatures
-#define SPELL_DOOMFIRE_SPAWN 32074
-#define SPELL_DOOMFIRE 31945
-#define SPELL_SOUL_CHARGE_YELLOW 32045
-#define SPELL_SOUL_CHARGE_GREEN 32051
-#define SPELL_SOUL_CHARGE_RED 32052
-#define SPELL_UNLEASH_SOUL_YELLOW 32054
-#define SPELL_UNLEASH_SOUL_GREEN 32057
-#define SPELL_UNLEASH_SOUL_RED 32053
-#define SPELL_FEAR 31970
-
-#define CREATURE_ARCHIMONDE 17968
-#define CREATURE_DOOMFIRE 18095
-#define CREATURE_DOOMFIRE_SPIRIT 18104
-#define CREATURE_ANCIENT_WISP 17946
-#define CREATURE_CHANNEL_TARGET 22418
-
-#define NORDRASSIL_X 5503.713
-#define NORDRASSIL_Y -3523.436
-#define NORDRASSIL_Z 1608.781
-
-struct mob_ancient_wispAI : public ScriptedAI
-{
- mob_ancient_wispAI(Creature* c) : ScriptedAI(c)
- {
- pInstance = ((ScriptedInstance*)c->GetInstanceData());
- Reset();
- }
-
- ScriptedInstance* pInstance;
- uint64 ArchimondeGUID;
- uint32 CheckTimer;
-
- void Reset()
- {
- ArchimondeGUID = 0;
- CheckTimer = 1000;
-
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
-
- void Aggro(Unit* who) {}
-
- void DamageTaken(Unit* done_by, uint32 &damage) { damage = 0; }
-
- void UpdateAI(const uint32 diff)
- {
- if (!ArchimondeGUID)
- {
- if (pInstance)
- ArchimondeGUID = pInstance->GetData64(DATA_ARCHIMONDE);
- }
-
- if (CheckTimer < diff)
- {
- if (ArchimondeGUID)
- {
- Unit* Archimonde = Unit::GetUnit((*m_creature), ArchimondeGUID);
- if (Archimonde)
- {
- if ((((Archimonde->GetHealth()*100) / Archimonde->GetMaxHealth()) < 2) || !Archimonde->isAlive())
- DoCast(m_creature, SPELL_DENOUEMENT_WISP);
- else
- DoCast(Archimonde, SPELL_ANCIENT_SPARK);
- }
- }
- CheckTimer = 1000;
- }else CheckTimer -= diff;
- }
-};
-
-/* This script is merely a placeholder for the Doomfire that triggers Doomfire spell. It will
- MoveChase the Doomfire Spirit always, until despawn (AttackStart is called upon it's spawn) */
-struct TRINITY_DLL_DECL mob_doomfireAI : public ScriptedAI
-{
- mob_doomfireAI(Creature* c) : ScriptedAI(c) { Reset(); }
-
- void Reset() { }
-
- void MoveInLineOfSight(Unit* who) { }
- void Aggro(Unit* who) { }
- void DamageTaken(Unit *done_by, uint32 &damage) { damage = 0; }
-};
-
-/* This is the script for the Doomfire Spirit Mob. This mob simply follow players or
- travels in random directions if target cannot be found. */
-struct TRINITY_DLL_DECL mob_doomfire_targettingAI : public ScriptedAI
-{
- mob_doomfire_targettingAI(Creature* c) : ScriptedAI(c) { Reset(); }
-
- uint64 TargetGUID;
- uint32 ChangeTargetTimer;
-
- void Reset()
- {
- TargetGUID = 0;
- ChangeTargetTimer = 5000;
- }
-
- void MoveInLineOfSight(Unit* who)
- {
- //will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0
- //when UpdateAI needs it, it will be forced to select randomPoint
- if (!TargetGUID && who->GetTypeId() == TYPEID_PLAYER)
- TargetGUID = who->GetGUID();
- }
-
- void Aggro(Unit* who) {}
-
- void DamageTaken(Unit *done_by, uint32 &damage) { damage = 0; }
-
- void UpdateAI(const uint32 diff)
- {
- if (ChangeTargetTimer < diff)
- {
- if (Unit *temp = Unit::GetUnit(*m_creature,TargetGUID))
- {
- m_creature->GetMotionMaster()->MoveFollow(temp,0.0f,0.0f);
- TargetGUID = 0;
- }
- else
- {
- float x,y,z = 0.0;
- m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 40, x, y, z);
- m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
- }
-
- ChangeTargetTimer = 5000;
- }else ChangeTargetTimer -= diff;
- }
-};
-
-/* Finally, Archimonde's script. His script isn't extremely complex, most are simply spells on timers.
- The only complicated aspect of the battle is Finger of Death and Doomfire, with Doomfire being the
- hardest bit to code. Finger of Death is simply a distance check - if no one is in melee range, then
- select a random target and cast the spell on them. However, if someone IS in melee range, and this
- is NOT the main tank (creature's victim), then we aggro that player and they become the new victim.
- For Doomfire, we summon a mob (Doomfire Spirit) for the Doomfire mob to follow. It's spirit will
- randomly select it's target to follow and then we create the random movement making it unpredictable. */
-
-// This is used to sort by distance in order to see who is the closest target, when checking for Finger of Death
-struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
-{
- const Unit* MainTarget;
- TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
- // functor for operator "<"
- bool operator()(const Unit* _Left, const Unit* _Right) const
- {
- return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right));
- }
-};
-
-struct TRINITY_DLL_DECL boss_archimondeAI : public ScriptedAI
-{
- boss_archimondeAI(Creature *c) : ScriptedAI(c)
- {
- pInstance = ((ScriptedInstance*)c->GetInstanceData());
- Reset();
- }
-
- ScriptedInstance* pInstance;
-
- uint64 DoomfireSpiritGUID;
- uint64 WorldTreeGUID;
-
- uint32 DrainNordrassilTimer;
- uint32 FearTimer;
- uint32 AirBurstTimer;
- uint32 GripOfTheLegionTimer;
- uint32 DoomfireTimer;
- uint32 SoulChargeTimer;
- uint32 SoulChargeCount;
- uint32 MeleeRangeCheckTimer;
- uint32 HandOfDeathTimer;
- uint32 SummonWispTimer;
- uint32 WispCount;
- uint32 EnrageTimer;
- uint32 CheckDistanceTimer;
-
- bool Enraged;
- bool BelowTenPercent;
- bool HasProtected;
- bool IsChanneling;
-
- void Reset()
- {
- if (pInstance)
- pInstance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED);
-
- DoomfireSpiritGUID = 0;
- WorldTreeGUID = 0;
-
- DrainNordrassilTimer = 0;
- FearTimer = 42000;
- AirBurstTimer = 30000;
- GripOfTheLegionTimer = 5000 + rand()%20000;
- DoomfireTimer = 20000;
- SoulChargeTimer = 2000 + rand()%27000;
- SoulChargeCount = 0;
- MeleeRangeCheckTimer = 15000;
- HandOfDeathTimer = 2000;
- WispCount = 0; // When ~30 wisps are summoned, Archimonde dies
- EnrageTimer = 600000; // 10 minutes
- CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
-
- Enraged = false;
- BelowTenPercent = false;
- HasProtected = false;
- IsChanneling = false;
- }
-
- void Aggro(Unit *who)
- {
- m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL);
- DoScriptText(SAY_AGGRO, m_creature);
- DoZoneInCombat();
-
- if (pInstance)
- pInstance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS);
- }
-
- void KilledUnit(Unit *victim)
- {
- switch(rand()%2)
- {
- case 0: DoScriptText(SAY_SLAY1, m_creature); break;
- case 1: DoScriptText(SAY_SLAY2, m_creature); break;
- case 2: DoScriptText(SAY_SLAY3, m_creature); break;
- }
-
- if (victim && (victim->GetTypeId() == TYPEID_PLAYER))
- GainSoulCharge(((Player*)victim));
- }
-
- void GainSoulCharge(Player* victim)
- {
- switch(victim->getClass())
- {
- case CLASS_PRIEST:
- case CLASS_PALADIN:
- case CLASS_WARLOCK:
- victim->CastSpell(m_creature, SPELL_SOUL_CHARGE_RED, true);
- break;
- case CLASS_MAGE:
- case CLASS_ROGUE:
- case CLASS_WARRIOR:
- victim->CastSpell(m_creature, SPELL_SOUL_CHARGE_YELLOW, true);
- break;
- case CLASS_DRUID:
- case CLASS_SHAMAN:
- case CLASS_HUNTER:
- victim->CastSpell(m_creature, SPELL_SOUL_CHARGE_GREEN, true);
- break;
- }
-
- SoulChargeTimer = 2000 + rand()%28000;
- ++SoulChargeCount;
- }
-
- void JustDied(Unit *victim)
- {
- DoScriptText(SAY_DEATH, m_creature);
-
- if (pInstance)
- pInstance->SetData(DATA_ARCHIMONDEEVENT, DONE);
- }
-
- bool CanUseFingerOfDeath()
- {
- // First we check if our current victim is in melee range or not.
- Unit* victim = m_creature->getVictim();
- if (victim && m_creature->IsWithinDistInMap(victim, m_creature->GetAttackDistance(victim)))
- return false;
-
- std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
- if (m_threatlist.empty())
- return false;
-
- std::list<Unit*> targets;
- std::list<HostilReference*>::iterator itr = m_threatlist.begin();
- for( ; itr != m_threatlist.end(); ++itr)
- {
- Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());
- if (pUnit && pUnit->isAlive())
- targets.push_back(pUnit);
- }
-
- if (targets.empty())
- return false;
-
- targets.sort(TargetDistanceOrder(m_creature));
- Unit* target = targets.front();
- if (target)
- {
- if (!m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target)))
- return true; // Cast Finger of Death
- else // This target is closest, he is our new tank
- m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim()));
- }
-
- return false;
- }
-
- void JustSummoned(Creature *summoned)
- {
- summoned->setFaction(m_creature->getFaction());
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
- if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
- {
- DoomfireSpiritGUID = summoned->GetGUID();
- }
-
- if (summoned->GetEntry() == CREATURE_DOOMFIRE)
- {
- summoned->CastSpell(summoned,SPELL_DOOMFIRE_SPAWN,false);
- summoned->CastSpell(summoned,SPELL_DOOMFIRE,true,0,0,m_creature->GetGUID());
-
- if (Unit *DoomfireSpirit = Unit::GetUnit(*m_creature, DoomfireSpiritGUID))
- {
- summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit,0.0f,0.0f);
- DoomfireSpiritGUID = 0;
- }
- }
- }
-
- //this is code doing close to what the summoning spell would do (spell 31903)
- void SummonDoomfire(Unit* target)
- {
- m_creature->SummonCreature(CREATURE_DOOMFIRE_SPIRIT,
- target->GetPositionX()+15.0,target->GetPositionY()+15.0,target->GetPositionZ(),0,
- TEMPSUMMON_TIMED_DESPAWN, 27000);
-
- m_creature->SummonCreature(CREATURE_DOOMFIRE,
- target->GetPositionX()-15.0,target->GetPositionY()-15.0,target->GetPositionZ(),0,
- TEMPSUMMON_TIMED_DESPAWN, 27000);
- }
-
- void UnleashSoulCharge()
- {
- m_creature->InterruptNonMeleeSpells(false);
-
- bool HasCast = false;
- uint32 chargeSpell = 0;
- uint32 unleashSpell = 0;
-
- switch(rand()%3)
- {
- case 0:
- chargeSpell = SPELL_SOUL_CHARGE_RED;
- unleashSpell = SPELL_UNLEASH_SOUL_RED;
- break;
- case 1:
- chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
- unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
- break;
- case 2:
- chargeSpell = SPELL_SOUL_CHARGE_GREEN;
- unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
- break;
- }
-
- if (m_creature->HasAura(chargeSpell, 0))
- {
- m_creature->RemoveSingleAuraFromStack(chargeSpell, 0);
- DoCast(m_creature->getVictim(), unleashSpell);
- HasCast = true;
- SoulChargeCount--;
- }
-
- if (HasCast)
- SoulChargeTimer = 2000 + rand()%28000;
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (!InCombat)
- {
- if (pInstance)
- {
- // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished.
- if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && ((m_creature->GetVisibility() != VISIBILITY_OFF) || (m_creature->getFaction() != 35)))
- {
- m_creature->SetVisibility(VISIBILITY_OFF);
- m_creature->setFaction(35);
- }
- else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && ((m_creature->GetVisibility() != VISIBILITY_ON) || (m_creature->getFaction() == 35)))
- {
- m_creature->setFaction(1720);
- m_creature->SetVisibility(VISIBILITY_ON);
- }
- }
-
- if (DrainNordrassilTimer < diff)
- {
- if (!IsChanneling)
- {
- Creature *temp = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000);
-
- if (temp)
- WorldTreeGUID = temp->GetGUID();
-
- if (Unit *Nordrassil = Unit::GetUnit(*m_creature, WorldTreeGUID))
- {
- Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Nordrassil->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);
- DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE);
- IsChanneling = true;
- }
- }
-
- if (Unit *Nordrassil = Unit::GetUnit(*m_creature, WorldTreeGUID))
- {
- Nordrassil->CastSpell(m_creature, SPELL_DRAIN_WORLD_TREE_2, true);
- DrainNordrassilTimer = 1000;
- }
- }else DrainNordrassilTimer -= diff;
- }
-
- if (!UpdateVictim() )
- return;
-
- if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !BelowTenPercent && !Enraged)
- BelowTenPercent = true;
-
- if (!Enraged)
- {
- if (EnrageTimer < diff)
- {
- if((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 10)
- {
- m_creature->GetMotionMaster()->Clear(false);
- m_creature->GetMotionMaster()->MoveIdle();
- Enraged = true;
- DoScriptText(SAY_ENRAGE, m_creature);
- }
- }else EnrageTimer -= diff;
-
- if (CheckDistanceTimer < diff)
- {
- // To simplify the check, we simply summon a creature in the location and then check how far we are from the creature
- Creature* Check = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000);
- if (Check)
- {
- Check->SetVisibility(VISIBILITY_OFF);
-
- if (m_creature->IsWithinDistInMap(Check, 75))
- {
- m_creature->GetMotionMaster()->Clear(false);
- m_creature->GetMotionMaster()->MoveIdle();
- Enraged = true;
- DoScriptText(SAY_ENRAGE, m_creature);
- }
- }
- CheckDistanceTimer = 5000;
- }else CheckDistanceTimer -= diff;
- }
-
- if (BelowTenPercent)
- {
- if (!HasProtected)
- {
- m_creature->GetMotionMaster()->Clear(false);
- m_creature->GetMotionMaster()->MoveIdle();
-
- //all members of raid must get this buff
- DoCast(m_creature->getVictim(), SPELL_PROTECTION_OF_ELUNE);
- HasProtected = true;
- Enraged = true;
- }
-
- if (SummonWispTimer < diff)
- {
- Creature* Wisp = DoSpawnCreature(CREATURE_ANCIENT_WISP, rand()%40, rand()%40, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (Wisp)
- {
- Wisp->AI()->AttackStart(m_creature);
- ((mob_ancient_wispAI*)Wisp->AI())->ArchimondeGUID = m_creature->GetGUID();
- }
- SummonWispTimer = 1500;
- ++WispCount;
- }else SummonWispTimer -= diff;
-
- if (WispCount >= 30)
- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
-
- if (Enraged)
- {
- if (HandOfDeathTimer < diff)
- {
- DoCast(m_creature->getVictim(), SPELL_HAND_OF_DEATH);
- HandOfDeathTimer = 2000;
- }else HandOfDeathTimer -= diff;
- return; // Don't do anything after this point.
- }
-
- if (SoulChargeCount)
- {
- if (SoulChargeTimer < diff)
- UnleashSoulCharge();
- else SoulChargeTimer -= diff;
- }
-
- if (GripOfTheLegionTimer < diff)
- {
- DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION);
- GripOfTheLegionTimer = 5000 + rand()%20000;
- }else GripOfTheLegionTimer -= diff;
-
- if (AirBurstTimer < diff)
- {
- if (rand()%2 == 0)
- DoScriptText(SAY_AIR_BURST1, m_creature);
- else
- DoScriptText(SAY_AIR_BURST2, m_creature);
-
- DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_AIR_BURST);
- AirBurstTimer = 25000 + rand()%15000;
- }else AirBurstTimer -= diff;
-
- if (FearTimer < diff)
- {
- DoCast(m_creature->getVictim(), SPELL_FEAR);
- FearTimer = 42000;
- }else FearTimer -= diff;
-
- if (DoomfireTimer < diff)
- {
- if (rand()%2 == 0)
- DoScriptText(SAY_DOOMFIRE1, m_creature);
- else
- DoScriptText(SAY_DOOMFIRE2, m_creature);
-
- Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 1);
- if (!temp)
- temp = m_creature->getVictim();
-
- //replace with spell cast 31903 once implicitTarget 73 implemented
- SummonDoomfire(temp);
-
- //supposedly three doomfire can be up at the same time
- DoomfireTimer = 20000;
- }else DoomfireTimer -= diff;
-
- if (MeleeRangeCheckTimer < diff)
- {
- if (CanUseFingerOfDeath())
- {
- DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
- MeleeRangeCheckTimer = 1000;
- }
-
- MeleeRangeCheckTimer = 5000;
- }else MeleeRangeCheckTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
-};
-
-CreatureAI* GetAI_boss_archimonde(Creature *_Creature)
-{
- return new boss_archimondeAI (_Creature);
-}
-
-CreatureAI* GetAI_mob_doomfire(Creature* _Creature)
-{
- return new mob_doomfireAI(_Creature);
-}
-
-CreatureAI* GetAI_mob_doomfire_targetting(Creature* _Creature)
-{
- return new mob_doomfire_targettingAI(_Creature);
-}
-
-CreatureAI* GetAI_mob_ancient_wisp(Creature* _Creature)
-{
- return new mob_ancient_wispAI(_Creature);
-}
-
-void AddSC_boss_archimonde()
-{
- Script *newscript;
- newscript = new Script;
- newscript->Name = "boss_archimonde";
- newscript->GetAI = &GetAI_boss_archimonde;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name = "mob_doomfire";
- newscript->GetAI = &GetAI_mob_doomfire;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name = "mob_doomfire_targetting";
- newscript->GetAI = &GetAI_mob_doomfire_targetting;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name = "mob_ancient_wisp";
- newscript->GetAI = &GetAI_mob_ancient_wisp;
- newscript->RegisterSelf();
-}
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Archimonde +SD%Complete: 85 +SDComment: Doomfires not completely offlike due to core limitations for random moving. Tyrande and second phase not fully implemented. +SDCategory: Caverns of Time, Mount Hyjal +EndScriptData */ + +#include "precompiled.h" +#include "def_hyjal.h" +#include "SpellAuras.h" + +//text id -1534018 are the text used when previous events complete. Not part of this script. +#define SAY_AGGRO -1534019 +#define SAY_DOOMFIRE1 -1534020 +#define SAY_DOOMFIRE2 -1534021 +#define SAY_AIR_BURST1 -1534022 +#define SAY_AIR_BURST2 -1534023 +#define SAY_SLAY1 -1534024 +#define SAY_SLAY2 -1534025 +#define SAY_SLAY3 -1534026 +#define SAY_ENRAGE -1534027 +#define SAY_DEATH -1534028 +#define SAY_SOUL_CHARGE1 -1534029 +#define SAY_SOUL_CHARGE2 -1534030 + +#define SPELL_DENOUEMENT_WISP 32124 +#define SPELL_ANCIENT_SPARK 39349 +#define SPELL_PROTECTION_OF_ELUNE 38528 + +#define SPELL_DRAIN_WORLD_TREE 39140 +#define SPELL_DRAIN_WORLD_TREE_2 39141 + +#define SPELL_FINGER_OF_DEATH 31984 +#define SPELL_HAND_OF_DEATH 35354 +#define SPELL_AIR_BURST 32014 +#define SPELL_GRIP_OF_THE_LEGION 31972 +#define SPELL_DOOMFIRE_STRIKE 31903 //summons two creatures +#define SPELL_DOOMFIRE_SPAWN 32074 +#define SPELL_DOOMFIRE 31945 +#define SPELL_SOUL_CHARGE_YELLOW 32045 +#define SPELL_SOUL_CHARGE_GREEN 32051 +#define SPELL_SOUL_CHARGE_RED 32052 +#define SPELL_UNLEASH_SOUL_YELLOW 32054 +#define SPELL_UNLEASH_SOUL_GREEN 32057 +#define SPELL_UNLEASH_SOUL_RED 32053 +#define SPELL_FEAR 31970 + +#define CREATURE_ARCHIMONDE 17968 +#define CREATURE_DOOMFIRE 18095 +#define CREATURE_DOOMFIRE_SPIRIT 18104 +#define CREATURE_ANCIENT_WISP 17946 +#define CREATURE_CHANNEL_TARGET 22418 + +#define NORDRASSIL_X 5503.713 +#define NORDRASSIL_Y -3523.436 +#define NORDRASSIL_Z 1608.781 + +struct mob_ancient_wispAI : public ScriptedAI +{ + mob_ancient_wispAI(Creature* c) : ScriptedAI(c) + { + pInstance = ((ScriptedInstance*)c->GetInstanceData()); + Reset(); + } + + ScriptedInstance* pInstance; + uint64 ArchimondeGUID; + uint32 CheckTimer; + + void Reset() + { + ArchimondeGUID = 0; + CheckTimer = 1000; + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + void Aggro(Unit* who) {} + + void DamageTaken(Unit* done_by, uint32 &damage) { damage = 0; } + + void UpdateAI(const uint32 diff) + { + if (!ArchimondeGUID) + { + if (pInstance) + ArchimondeGUID = pInstance->GetData64(DATA_ARCHIMONDE); + } + + if (CheckTimer < diff) + { + if (ArchimondeGUID) + { + Unit* Archimonde = Unit::GetUnit((*m_creature), ArchimondeGUID); + if (Archimonde) + { + if ((((Archimonde->GetHealth()*100) / Archimonde->GetMaxHealth()) < 2) || !Archimonde->isAlive()) + DoCast(m_creature, SPELL_DENOUEMENT_WISP); + else + DoCast(Archimonde, SPELL_ANCIENT_SPARK); + } + } + CheckTimer = 1000; + }else CheckTimer -= diff; + } +}; + +/* This script is merely a placeholder for the Doomfire that triggers Doomfire spell. It will + MoveChase the Doomfire Spirit always, until despawn (AttackStart is called upon it's spawn) */ +struct TRINITY_DLL_DECL mob_doomfireAI : public ScriptedAI +{ + mob_doomfireAI(Creature* c) : ScriptedAI(c) { Reset(); } + + void Reset() { } + + void MoveInLineOfSight(Unit* who) { } + void Aggro(Unit* who) { } + void DamageTaken(Unit *done_by, uint32 &damage) { damage = 0; } +}; + +/* This is the script for the Doomfire Spirit Mob. This mob simply follow players or + travels in random directions if target cannot be found. */ +struct TRINITY_DLL_DECL mob_doomfire_targettingAI : public ScriptedAI +{ + mob_doomfire_targettingAI(Creature* c) : ScriptedAI(c) { Reset(); } + + uint64 TargetGUID; + uint32 ChangeTargetTimer; + + void Reset() + { + TargetGUID = 0; + ChangeTargetTimer = 5000; + } + + void MoveInLineOfSight(Unit* who) + { + //will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0 + //when UpdateAI needs it, it will be forced to select randomPoint + if (!TargetGUID && who->GetTypeId() == TYPEID_PLAYER) + TargetGUID = who->GetGUID(); + } + + void Aggro(Unit* who) {} + + void DamageTaken(Unit *done_by, uint32 &damage) { damage = 0; } + + void UpdateAI(const uint32 diff) + { + if (ChangeTargetTimer < diff) + { + if (Unit *temp = Unit::GetUnit(*m_creature,TargetGUID)) + { + m_creature->GetMotionMaster()->MoveFollow(temp,0.0f,0.0f); + TargetGUID = 0; + } + else + { + float x,y,z = 0.0; + m_creature->GetRandomPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 40, x, y, z); + m_creature->GetMotionMaster()->MovePoint(0, x, y, z); + } + + ChangeTargetTimer = 5000; + }else ChangeTargetTimer -= diff; + } +}; + +/* Finally, Archimonde's script. His script isn't extremely complex, most are simply spells on timers. + The only complicated aspect of the battle is Finger of Death and Doomfire, with Doomfire being the + hardest bit to code. Finger of Death is simply a distance check - if no one is in melee range, then + select a random target and cast the spell on them. However, if someone IS in melee range, and this + is NOT the main tank (creature's victim), then we aggro that player and they become the new victim. + For Doomfire, we summon a mob (Doomfire Spirit) for the Doomfire mob to follow. It's spirit will + randomly select it's target to follow and then we create the random movement making it unpredictable. */ + +// This is used to sort by distance in order to see who is the closest target, when checking for Finger of Death +struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> +{ + const Unit* MainTarget; + TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {}; + // functor for operator "<" + bool operator()(const Unit* _Left, const Unit* _Right) const + { + return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right)); + } +}; + +struct TRINITY_DLL_DECL boss_archimondeAI : public ScriptedAI +{ + boss_archimondeAI(Creature *c) : ScriptedAI(c) + { + pInstance = ((ScriptedInstance*)c->GetInstanceData()); + Reset(); + } + + ScriptedInstance* pInstance; + + uint64 DoomfireSpiritGUID; + uint64 WorldTreeGUID; + + uint32 DrainNordrassilTimer; + uint32 FearTimer; + uint32 AirBurstTimer; + uint32 GripOfTheLegionTimer; + uint32 DoomfireTimer; + uint32 SoulChargeTimer; + uint32 SoulChargeCount; + uint32 MeleeRangeCheckTimer; + uint32 HandOfDeathTimer; + uint32 SummonWispTimer; + uint32 WispCount; + uint32 EnrageTimer; + uint32 CheckDistanceTimer; + + bool Enraged; + bool BelowTenPercent; + bool HasProtected; + bool IsChanneling; + + void Reset() + { + if (pInstance) + pInstance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED); + + DoomfireSpiritGUID = 0; + WorldTreeGUID = 0; + + DrainNordrassilTimer = 0; + FearTimer = 42000; + AirBurstTimer = 30000; + GripOfTheLegionTimer = 5000 + rand()%20000; + DoomfireTimer = 20000; + SoulChargeTimer = 2000 + rand()%27000; + SoulChargeCount = 0; + MeleeRangeCheckTimer = 15000; + HandOfDeathTimer = 2000; + WispCount = 0; // When ~30 wisps are summoned, Archimonde dies + EnrageTimer = 600000; // 10 minutes + CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage + + Enraged = false; + BelowTenPercent = false; + HasProtected = false; + IsChanneling = false; + } + + void Aggro(Unit *who) + { + m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL); + DoScriptText(SAY_AGGRO, m_creature); + DoZoneInCombat(); + + if (pInstance) + pInstance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS); + } + + void KilledUnit(Unit *victim) + { + switch(rand()%2) + { + case 0: DoScriptText(SAY_SLAY1, m_creature); break; + case 1: DoScriptText(SAY_SLAY2, m_creature); break; + case 2: DoScriptText(SAY_SLAY3, m_creature); break; + } + + if (victim && (victim->GetTypeId() == TYPEID_PLAYER)) + GainSoulCharge(((Player*)victim)); + } + + void GainSoulCharge(Player* victim) + { + switch(victim->getClass()) + { + case CLASS_PRIEST: + case CLASS_PALADIN: + case CLASS_WARLOCK: + victim->CastSpell(m_creature, SPELL_SOUL_CHARGE_RED, true); + break; + case CLASS_MAGE: + case CLASS_ROGUE: + case CLASS_WARRIOR: + victim->CastSpell(m_creature, SPELL_SOUL_CHARGE_YELLOW, true); + break; + case CLASS_DRUID: + case CLASS_SHAMAN: + case CLASS_HUNTER: + victim->CastSpell(m_creature, SPELL_SOUL_CHARGE_GREEN, true); + break; + } + + SoulChargeTimer = 2000 + rand()%28000; + ++SoulChargeCount; + } + + void JustDied(Unit *victim) + { + DoScriptText(SAY_DEATH, m_creature); + + if (pInstance) + pInstance->SetData(DATA_ARCHIMONDEEVENT, DONE); + } + + bool CanUseFingerOfDeath() + { + // First we check if our current victim is in melee range or not. + Unit* victim = m_creature->getVictim(); + if (victim && m_creature->IsWithinDistInMap(victim, m_creature->GetAttackDistance(victim))) + return false; + + std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); + if (m_threatlist.empty()) + return false; + + std::list<Unit*> targets; + std::list<HostilReference*>::iterator itr = m_threatlist.begin(); + for( ; itr != m_threatlist.end(); ++itr) + { + Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid()); + if (pUnit && pUnit->isAlive()) + targets.push_back(pUnit); + } + + if (targets.empty()) + return false; + + targets.sort(TargetDistanceOrder(m_creature)); + Unit* target = targets.front(); + if (target) + { + if (!m_creature->IsWithinDistInMap(target, m_creature->GetAttackDistance(target))) + return true; // Cast Finger of Death + else // This target is closest, he is our new tank + m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim())); + } + + return false; + } + + void JustSummoned(Creature *summoned) + { + summoned->setFaction(m_creature->getFaction()); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT) + { + DoomfireSpiritGUID = summoned->GetGUID(); + } + + if (summoned->GetEntry() == CREATURE_DOOMFIRE) + { + summoned->CastSpell(summoned,SPELL_DOOMFIRE_SPAWN,false); + summoned->CastSpell(summoned,SPELL_DOOMFIRE,true,0,0,m_creature->GetGUID()); + + if (Unit *DoomfireSpirit = Unit::GetUnit(*m_creature, DoomfireSpiritGUID)) + { + summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit,0.0f,0.0f); + DoomfireSpiritGUID = 0; + } + } + } + + //this is code doing close to what the summoning spell would do (spell 31903) + void SummonDoomfire(Unit* target) + { + m_creature->SummonCreature(CREATURE_DOOMFIRE_SPIRIT, + target->GetPositionX()+15.0,target->GetPositionY()+15.0,target->GetPositionZ(),0, + TEMPSUMMON_TIMED_DESPAWN, 27000); + + m_creature->SummonCreature(CREATURE_DOOMFIRE, + target->GetPositionX()-15.0,target->GetPositionY()-15.0,target->GetPositionZ(),0, + TEMPSUMMON_TIMED_DESPAWN, 27000); + } + + void UnleashSoulCharge() + { + m_creature->InterruptNonMeleeSpells(false); + + bool HasCast = false; + uint32 chargeSpell = 0; + uint32 unleashSpell = 0; + + switch(rand()%3) + { + case 0: + chargeSpell = SPELL_SOUL_CHARGE_RED; + unleashSpell = SPELL_UNLEASH_SOUL_RED; + break; + case 1: + chargeSpell = SPELL_SOUL_CHARGE_YELLOW; + unleashSpell = SPELL_UNLEASH_SOUL_YELLOW; + break; + case 2: + chargeSpell = SPELL_SOUL_CHARGE_GREEN; + unleashSpell = SPELL_UNLEASH_SOUL_GREEN; + break; + } + + if (m_creature->HasAura(chargeSpell, 0)) + { + m_creature->RemoveSingleAuraFromStack(chargeSpell, 0); + DoCast(m_creature->getVictim(), unleashSpell); + HasCast = true; + SoulChargeCount--; + } + + if (HasCast) + SoulChargeTimer = 2000 + rand()%28000; + } + + void UpdateAI(const uint32 diff) + { + if (!InCombat) + { + if (pInstance) + { + // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished. + if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && ((m_creature->GetVisibility() != VISIBILITY_OFF) || (m_creature->getFaction() != 35))) + { + m_creature->SetVisibility(VISIBILITY_OFF); + m_creature->setFaction(35); + } + else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && ((m_creature->GetVisibility() != VISIBILITY_ON) || (m_creature->getFaction() == 35))) + { + m_creature->setFaction(1720); + m_creature->SetVisibility(VISIBILITY_ON); + } + } + + if (DrainNordrassilTimer < diff) + { + if (!IsChanneling) + { + Creature *temp = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000); + + if (temp) + WorldTreeGUID = temp->GetGUID(); + + if (Unit *Nordrassil = Unit::GetUnit(*m_creature, WorldTreeGUID)) + { + Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + Nordrassil->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); + DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE); + IsChanneling = true; + } + } + + if (Unit *Nordrassil = Unit::GetUnit(*m_creature, WorldTreeGUID)) + { + Nordrassil->CastSpell(m_creature, SPELL_DRAIN_WORLD_TREE_2, true); + DrainNordrassilTimer = 1000; + } + }else DrainNordrassilTimer -= diff; + } + + if (!UpdateVictim() ) + return; + + if (((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 10) && !BelowTenPercent && !Enraged) + BelowTenPercent = true; + + if (!Enraged) + { + if (EnrageTimer < diff) + { + if((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 10) + { + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); + Enraged = true; + DoScriptText(SAY_ENRAGE, m_creature); + } + }else EnrageTimer -= diff; + + if (CheckDistanceTimer < diff) + { + // To simplify the check, we simply summon a creature in the location and then check how far we are from the creature + Creature* Check = m_creature->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000); + if (Check) + { + Check->SetVisibility(VISIBILITY_OFF); + + if (m_creature->IsWithinDistInMap(Check, 75)) + { + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); + Enraged = true; + DoScriptText(SAY_ENRAGE, m_creature); + } + } + CheckDistanceTimer = 5000; + }else CheckDistanceTimer -= diff; + } + + if (BelowTenPercent) + { + if (!HasProtected) + { + m_creature->GetMotionMaster()->Clear(false); + m_creature->GetMotionMaster()->MoveIdle(); + + //all members of raid must get this buff + DoCast(m_creature->getVictim(), SPELL_PROTECTION_OF_ELUNE); + HasProtected = true; + Enraged = true; + } + + if (SummonWispTimer < diff) + { + Creature* Wisp = DoSpawnCreature(CREATURE_ANCIENT_WISP, rand()%40, rand()%40, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); + if (Wisp) + { + Wisp->AI()->AttackStart(m_creature); + ((mob_ancient_wispAI*)Wisp->AI())->ArchimondeGUID = m_creature->GetGUID(); + } + SummonWispTimer = 1500; + ++WispCount; + }else SummonWispTimer -= diff; + + if (WispCount >= 30) + m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + if (Enraged) + { + if (HandOfDeathTimer < diff) + { + DoCast(m_creature->getVictim(), SPELL_HAND_OF_DEATH); + HandOfDeathTimer = 2000; + }else HandOfDeathTimer -= diff; + return; // Don't do anything after this point. + } + + if (SoulChargeCount) + { + if (SoulChargeTimer < diff) + UnleashSoulCharge(); + else SoulChargeTimer -= diff; + } + + if (GripOfTheLegionTimer < diff) + { + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION); + GripOfTheLegionTimer = 5000 + rand()%20000; + }else GripOfTheLegionTimer -= diff; + + if (AirBurstTimer < diff) + { + if (rand()%2 == 0) + DoScriptText(SAY_AIR_BURST1, m_creature); + else + DoScriptText(SAY_AIR_BURST2, m_creature); + + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_AIR_BURST); + AirBurstTimer = 25000 + rand()%15000; + }else AirBurstTimer -= diff; + + if (FearTimer < diff) + { + DoCast(m_creature->getVictim(), SPELL_FEAR); + FearTimer = 42000; + }else FearTimer -= diff; + + if (DoomfireTimer < diff) + { + if (rand()%2 == 0) + DoScriptText(SAY_DOOMFIRE1, m_creature); + else + DoScriptText(SAY_DOOMFIRE2, m_creature); + + Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 1); + if (!temp) + temp = m_creature->getVictim(); + + //replace with spell cast 31903 once implicitTarget 73 implemented + SummonDoomfire(temp); + + //supposedly three doomfire can be up at the same time + DoomfireTimer = 20000; + }else DoomfireTimer -= diff; + + if (MeleeRangeCheckTimer < diff) + { + if (CanUseFingerOfDeath()) + { + DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH); + MeleeRangeCheckTimer = 1000; + } + + MeleeRangeCheckTimer = 5000; + }else MeleeRangeCheckTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_archimonde(Creature *_Creature) +{ + return new boss_archimondeAI (_Creature); +} + +CreatureAI* GetAI_mob_doomfire(Creature* _Creature) +{ + return new mob_doomfireAI(_Creature); +} + +CreatureAI* GetAI_mob_doomfire_targetting(Creature* _Creature) +{ + return new mob_doomfire_targettingAI(_Creature); +} + +CreatureAI* GetAI_mob_ancient_wisp(Creature* _Creature) +{ + return new mob_ancient_wispAI(_Creature); +} + +void AddSC_boss_archimonde() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_archimonde"; + newscript->GetAI = &GetAI_boss_archimonde; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_doomfire"; + newscript->GetAI = &GetAI_mob_doomfire; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_doomfire_targetting"; + newscript->GetAI = &GetAI_mob_doomfire_targetting; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_ancient_wisp"; + newscript->GetAI = &GetAI_mob_ancient_wisp; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp index f662004a346..affe771babb 100644 --- a/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp +++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/blood_furnace/boss_broggok.cpp @@ -1,121 +1,121 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* ScriptData
-SDName: Boss_Broggok
-SD%Complete: 70
-SDComment: pre-event not made
-SDCategory: Hellfire Citadel, Blood Furnace
-EndScriptData */
-
-#include "precompiled.h"
-
-#define SAY_AGGRO -1542008
-
-#define SPELL_SLIME_SPRAY 30913
-#define SPELL_POISON_CLOUD 30916
-#define SPELL_POISON_BOLT 30917
-
-#define SPELL_POISON 30914
-
-struct TRINITY_DLL_DECL boss_broggokAI : public ScriptedAI
-{
- boss_broggokAI(Creature *c) : ScriptedAI(c) {Reset();}
-
- uint32 AcidSpray_Timer;
- uint32 PoisonSpawn_Timer;
- uint32 PoisonBolt_Timer;
-
- void Reset()
- {
- AcidSpray_Timer = 10000;
- PoisonSpawn_Timer = 5000;
- PoisonBolt_Timer = 7000;
- }
-
- void Aggro(Unit *who)
- {
- DoScriptText(SAY_AGGRO, m_creature);
- }
-
- void JustSummoned(Creature *summoned)
- {
- summoned->setFaction(16);
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- summoned->CastSpell(summoned,SPELL_POISON,false,0,0,m_creature->GetGUID());
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (!UpdateVictim() )
- return;
-
- if (AcidSpray_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_SLIME_SPRAY);
- AcidSpray_Timer = 4000+rand()%8000;
- }else AcidSpray_Timer -=diff;
-
- if (PoisonBolt_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_POISON_BOLT);
- PoisonBolt_Timer = 4000+rand()%8000;
- }else PoisonBolt_Timer -=diff;
-
- if (PoisonSpawn_Timer < diff)
- {
- DoCast(m_creature,SPELL_POISON_CLOUD);
- PoisonSpawn_Timer = 20000;
- }else PoisonSpawn_Timer -=diff;
-
- DoMeleeAttackIfReady();
- }
-};
-
-struct TRINITY_DLL_DECL mob_broggok_poisoncloudAI : public ScriptedAI
-{
- mob_broggok_poisoncloudAI(Creature *c) : ScriptedAI(c) {Reset();}
-
- void Reset() { }
- void MoveInLineOfSight(Unit *who) { }
- void AttackStart(Unit *who) { }
- void Aggro(Unit* who) { }
-};
-
-CreatureAI* GetAI_boss_broggok(Creature *_Creature)
-{
- return new boss_broggokAI (_Creature);
-}
-
-CreatureAI* GetAI_mob_broggok_poisoncloud(Creature *_Creature)
-{
- return new mob_broggok_poisoncloudAI (_Creature);
-}
-
-void AddSC_boss_broggok()
-{
- Script *newscript;
- newscript = new Script;
- newscript->Name = "boss_broggok";
- newscript->GetAI = &GetAI_boss_broggok;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name = "mob_broggok_poisoncloud";
- newscript->GetAI = &GetAI_mob_broggok_poisoncloud;
- newscript->RegisterSelf();
-}
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Broggok +SD%Complete: 70 +SDComment: pre-event not made +SDCategory: Hellfire Citadel, Blood Furnace +EndScriptData */ + +#include "precompiled.h" + +#define SAY_AGGRO -1542008 + +#define SPELL_SLIME_SPRAY 30913 +#define SPELL_POISON_CLOUD 30916 +#define SPELL_POISON_BOLT 30917 + +#define SPELL_POISON 30914 + +struct TRINITY_DLL_DECL boss_broggokAI : public ScriptedAI +{ + boss_broggokAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 AcidSpray_Timer; + uint32 PoisonSpawn_Timer; + uint32 PoisonBolt_Timer; + + void Reset() + { + AcidSpray_Timer = 10000; + PoisonSpawn_Timer = 5000; + PoisonBolt_Timer = 7000; + } + + void Aggro(Unit *who) + { + DoScriptText(SAY_AGGRO, m_creature); + } + + void JustSummoned(Creature *summoned) + { + summoned->setFaction(16); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + summoned->CastSpell(summoned,SPELL_POISON,false,0,0,m_creature->GetGUID()); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim() ) + return; + + if (AcidSpray_Timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_SLIME_SPRAY); + AcidSpray_Timer = 4000+rand()%8000; + }else AcidSpray_Timer -=diff; + + if (PoisonBolt_Timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_POISON_BOLT); + PoisonBolt_Timer = 4000+rand()%8000; + }else PoisonBolt_Timer -=diff; + + if (PoisonSpawn_Timer < diff) + { + DoCast(m_creature,SPELL_POISON_CLOUD); + PoisonSpawn_Timer = 20000; + }else PoisonSpawn_Timer -=diff; + + DoMeleeAttackIfReady(); + } +}; + +struct TRINITY_DLL_DECL mob_broggok_poisoncloudAI : public ScriptedAI +{ + mob_broggok_poisoncloudAI(Creature *c) : ScriptedAI(c) {Reset();} + + void Reset() { } + void MoveInLineOfSight(Unit *who) { } + void AttackStart(Unit *who) { } + void Aggro(Unit* who) { } +}; + +CreatureAI* GetAI_boss_broggok(Creature *_Creature) +{ + return new boss_broggokAI (_Creature); +} + +CreatureAI* GetAI_mob_broggok_poisoncloud(Creature *_Creature) +{ + return new mob_broggok_poisoncloudAI (_Creature); +} + +void AddSC_boss_broggok() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_broggok"; + newscript->GetAI = &GetAI_boss_broggok; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_broggok_poisoncloud"; + newscript->GetAI = &GetAI_mob_broggok_poisoncloud; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp index 1e67e6b766d..50eb20371f1 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_curator.cpp @@ -1,201 +1,201 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* ScriptData
-SDName: Boss_Curator
-SD%Complete: 100
-SDComment:
-SDCategory: Karazhan
-EndScriptData */
-
-#include "precompiled.h"
-
-#define SAY_AGGRO -1532057
-#define SAY_SUMMON1 -1532058
-#define SAY_SUMMON2 -1532059
-#define SAY_EVOCATE -1532060
-#define SAY_ENRAGE -1532061
-#define SAY_KILL1 -1532062
-#define SAY_KILL2 -1532063
-#define SAY_DEATH -1532064
-
-//Flare spell info
-#define SPELL_ASTRAL_FLARE_PASSIVE 30234 //Visual effect + Flare damage
-
-//Curator spell info
-#define SPELL_HATEFUL_BOLT 30383
-#define SPELL_EVOCATION 30254
-#define SPELL_ENRAGE 30403 //Arcane Infusion: Transforms Curator and adds damage.
-#define SPELL_BERSERK 26662
-
-struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI
-{
- boss_curatorAI(Creature *c) : ScriptedAI(c) {Reset();}
-
- uint32 AddTimer;
- uint32 HatefulBoltTimer;
- uint32 BerserkTimer;
-
- bool Enraged;
- bool Evocating;
-
- void Reset()
- {
- AddTimer = 10000;
- HatefulBoltTimer = 15000; //This time may be wrong
- BerserkTimer = 720000; //12 minutes
- Enraged = false;
- Evocating = false;
- }
-
- void KilledUnit(Unit *victim)
- {
- switch(rand()%2)
- {
- case 0: DoScriptText(SAY_KILL1, m_creature); break;
- case 1: DoScriptText(SAY_KILL2, m_creature); break;
- }
- }
-
- void JustDied(Unit *victim)
- {
- DoScriptText(SAY_DEATH, m_creature);
- }
-
- void Aggro(Unit *who)
- {
- DoScriptText(SAY_AGGRO, m_creature);
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (!UpdateVictim() )
- return;
-
- //always decrease BerserkTimer
- if (BerserkTimer < diff)
- {
- //if evocate, then break evocate
- if (Evocating)
- {
- if (m_creature->HasAura(SPELL_EVOCATION))
- m_creature->RemoveAurasDueToSpell(SPELL_EVOCATION);
-
- Evocating = false;
- }
-
- //may not be correct SAY (generic hard enrage)
- DoScriptText(SAY_ENRAGE, m_creature);
-
- m_creature->InterruptNonMeleeSpells(true);
- DoCast(m_creature, SPELL_BERSERK);
-
- //don't know if he's supposed to do summon/evocate after hard enrage (probably not)
- Enraged = true;
- }else BerserkTimer -= diff;
-
- if (Evocating)
- {
- //not supposed to do anything while evocate
- if (m_creature->HasAura(SPELL_EVOCATION))
- return;
- else
- Evocating = false;
- }
-
- if (!Enraged)
- {
- if (AddTimer < diff)
- {
- //Summon Astral Flare
- Creature* AstralFlare = DoSpawnCreature(17096, rand()%37, rand()%37, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-
- if (AstralFlare && target)
- {
- AstralFlare->CastSpell(AstralFlare, SPELL_ASTRAL_FLARE_PASSIVE, false);
- AstralFlare->AI()->AttackStart(target);
- AstralFlare->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
- AstralFlare->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
- }
-
- //Reduce Mana by 10% of max health
- if (int32 mana = m_creature->GetMaxPower(POWER_MANA))
- {
- mana /= 10;
- m_creature->ModifyPower(POWER_MANA, -mana);
-
- //if this get's us below 10%, then we evocate (the 10th should be summoned now)
- if (m_creature->GetPower(POWER_MANA)*100 / m_creature->GetMaxPower(POWER_MANA) < 10)
- {
- DoScriptText(SAY_EVOCATE, m_creature);
- m_creature->InterruptNonMeleeSpells(false);
- DoCast(m_creature, SPELL_EVOCATION);
- Evocating = true;
- //no AddTimer cooldown, this will make first flare appear instantly after evocate end, like expected
- return;
- }
- else
- {
- switch(rand()%4)
- {
- case 0: DoScriptText(SAY_SUMMON1, m_creature); break;
- case 1: DoScriptText(SAY_SUMMON2, m_creature); break;
- }
- }
- }
-
- AddTimer = 10000;
- }else AddTimer -= diff;
-
- if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 15)
- {
- Enraged = true;
- DoCast(m_creature, SPELL_ENRAGE);
- DoScriptText(SAY_ENRAGE, m_creature);
- }
- }
-
- if (HatefulBoltTimer < diff)
- {
- if (Enraged)
- HatefulBoltTimer = 7000;
- else
- HatefulBoltTimer = 15000;
-
- if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1))
- DoCast(target, SPELL_HATEFUL_BOLT);
-
- }else HatefulBoltTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
-};
-
-CreatureAI* GetAI_boss_curator(Creature *_Creature)
-{
- return new boss_curatorAI (_Creature);
-}
-
-void AddSC_boss_curator()
-{
- Script *newscript;
- newscript = new Script;
- newscript->Name = "boss_curator";
- newscript->GetAI = &GetAI_boss_curator;
- newscript->RegisterSelf();
-}
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Curator +SD%Complete: 100 +SDComment: +SDCategory: Karazhan +EndScriptData */ + +#include "precompiled.h" + +#define SAY_AGGRO -1532057 +#define SAY_SUMMON1 -1532058 +#define SAY_SUMMON2 -1532059 +#define SAY_EVOCATE -1532060 +#define SAY_ENRAGE -1532061 +#define SAY_KILL1 -1532062 +#define SAY_KILL2 -1532063 +#define SAY_DEATH -1532064 + +//Flare spell info +#define SPELL_ASTRAL_FLARE_PASSIVE 30234 //Visual effect + Flare damage + +//Curator spell info +#define SPELL_HATEFUL_BOLT 30383 +#define SPELL_EVOCATION 30254 +#define SPELL_ENRAGE 30403 //Arcane Infusion: Transforms Curator and adds damage. +#define SPELL_BERSERK 26662 + +struct TRINITY_DLL_DECL boss_curatorAI : public ScriptedAI +{ + boss_curatorAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 AddTimer; + uint32 HatefulBoltTimer; + uint32 BerserkTimer; + + bool Enraged; + bool Evocating; + + void Reset() + { + AddTimer = 10000; + HatefulBoltTimer = 15000; //This time may be wrong + BerserkTimer = 720000; //12 minutes + Enraged = false; + Evocating = false; + } + + void KilledUnit(Unit *victim) + { + switch(rand()%2) + { + case 0: DoScriptText(SAY_KILL1, m_creature); break; + case 1: DoScriptText(SAY_KILL2, m_creature); break; + } + } + + void JustDied(Unit *victim) + { + DoScriptText(SAY_DEATH, m_creature); + } + + void Aggro(Unit *who) + { + DoScriptText(SAY_AGGRO, m_creature); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim() ) + return; + + //always decrease BerserkTimer + if (BerserkTimer < diff) + { + //if evocate, then break evocate + if (Evocating) + { + if (m_creature->HasAura(SPELL_EVOCATION)) + m_creature->RemoveAurasDueToSpell(SPELL_EVOCATION); + + Evocating = false; + } + + //may not be correct SAY (generic hard enrage) + DoScriptText(SAY_ENRAGE, m_creature); + + m_creature->InterruptNonMeleeSpells(true); + DoCast(m_creature, SPELL_BERSERK); + + //don't know if he's supposed to do summon/evocate after hard enrage (probably not) + Enraged = true; + }else BerserkTimer -= diff; + + if (Evocating) + { + //not supposed to do anything while evocate + if (m_creature->HasAura(SPELL_EVOCATION)) + return; + else + Evocating = false; + } + + if (!Enraged) + { + if (AddTimer < diff) + { + //Summon Astral Flare + Creature* AstralFlare = DoSpawnCreature(17096, rand()%37, rand()%37, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); + Unit* target = NULL; + target = SelectUnit(SELECT_TARGET_RANDOM, 0); + + if (AstralFlare && target) + { + AstralFlare->CastSpell(AstralFlare, SPELL_ASTRAL_FLARE_PASSIVE, false); + AstralFlare->AI()->AttackStart(target); + AstralFlare->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); + AstralFlare->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); + } + + //Reduce Mana by 10% of max health + if (int32 mana = m_creature->GetMaxPower(POWER_MANA)) + { + mana /= 10; + m_creature->ModifyPower(POWER_MANA, -mana); + + //if this get's us below 10%, then we evocate (the 10th should be summoned now) + if (m_creature->GetPower(POWER_MANA)*100 / m_creature->GetMaxPower(POWER_MANA) < 10) + { + DoScriptText(SAY_EVOCATE, m_creature); + m_creature->InterruptNonMeleeSpells(false); + DoCast(m_creature, SPELL_EVOCATION); + Evocating = true; + //no AddTimer cooldown, this will make first flare appear instantly after evocate end, like expected + return; + } + else + { + switch(rand()%4) + { + case 0: DoScriptText(SAY_SUMMON1, m_creature); break; + case 1: DoScriptText(SAY_SUMMON2, m_creature); break; + } + } + } + + AddTimer = 10000; + }else AddTimer -= diff; + + if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 15) + { + Enraged = true; + DoCast(m_creature, SPELL_ENRAGE); + DoScriptText(SAY_ENRAGE, m_creature); + } + } + + if (HatefulBoltTimer < diff) + { + if (Enraged) + HatefulBoltTimer = 7000; + else + HatefulBoltTimer = 15000; + + if (Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 1)) + DoCast(target, SPELL_HATEFUL_BOLT); + + }else HatefulBoltTimer -= diff; + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_curator(Creature *_Creature) +{ + return new boss_curatorAI (_Creature); +} + +void AddSC_boss_curator() +{ + Script *newscript; + newscript = new Script; + newscript->Name = "boss_curator"; + newscript->GetAI = &GetAI_boss_curator; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp index 0529dfdfe45..57ccde94bf0 100644 --- a/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp +++ b/src/bindings/scripts/scripts/zone/magisters_terrace/boss_vexallus.cpp @@ -1,227 +1,227 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* ScriptData
-SDName: Boss_Vexallus
-SD%Complete: 90
-SDComment: Heroic and Normal support. Needs further testing.
-SDCategory: Magister's Terrace
-EndScriptData */
-
-#include "precompiled.h"
-#include "def_magisters_terrace.h"
-
-#define SAY_AGGRO -1585007
-#define SAY_ENERGY -1585008
-#define SAY_OVERLOAD -1585009
-#define SAY_KILL -1585010
-#define EMOTE_DISCHARGE_ENERGY -1585011
-
-//is this text for real?
-//#define SAY_DEATH "What...happen...ed."
-
-//Pure energy spell info
-#define SPELL_ENERGY_BOLT 46156
-#define SPELL_ENERGY_FEEDBACK 44335
-
-//Vexallus spell info
-#define SPELL_CHAIN_LIGHTNING 44318
-#define SPELL_OVERLOAD 44353
-#define SPELL_ARCANE_SHOCK 44319
-
-#define SPELL_SUMMON_PURE_ENERGY 44322 //mod scale -10
-#define H_SPELL_SUMMON_PURE_ENERGY1 46154 //mod scale -5
-#define H_SPELL_SUMMON_PURE_ENERGY2 46159 //mod scale -5
-
-//Creatures
-#define CREATURE_PURE_ENERGY 24745
-
-struct TRINITY_DLL_DECL boss_vexallusAI : public ScriptedAI
-{
- boss_vexallusAI(Creature *c) : ScriptedAI(c)
- {
- pInstance = ((ScriptedInstance*)c->GetInstanceData());
- Heroic = c->GetMap()->IsHeroic();
- Reset();
- }
-
- ScriptedInstance* pInstance;
- bool Heroic;
-
- uint32 ChainLightningTimer;
- uint32 ArcaneShockTimer;
- uint32 OverloadTimer;
- uint32 SpawnAddInterval;
- uint32 AlreadySpawnedAmount;
- bool Enraged;
-
- void Reset()
- {
- ChainLightningTimer = 10000;
- ArcaneShockTimer = 8000;
- OverloadTimer = 2200;
- SpawnAddInterval = 15;
- AlreadySpawnedAmount = 0;
- Enraged = false;
-
- if (pInstance)
- pInstance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED);
- }
-
- void KilledUnit(Unit *victim)
- {
- DoScriptText(SAY_KILL, m_creature);
- }
-
- void JustDied(Unit *victim)
- {
- if (pInstance)
- {
- pInstance->SetData(DATA_VEXALLUS_EVENT, DONE);
-
- if (GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_VEXALLUS_DOOR)))
- Door->SetGoState(0);
- }
- }
-
- void Aggro(Unit *who)
- {
- DoScriptText(SAY_AGGRO, m_creature);
-
- if (pInstance)
- pInstance->SetData(DATA_VEXALLUS_EVENT, IN_PROGRESS);
- }
-
- void JustSummoned(Creature *summoned)
- {
- if (Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 0))
- summoned->GetMotionMaster()->MoveFollow(temp,0,0);
-
- //spells are SUMMON_TYPE_GUARDIAN, so using setOwner should be ok
- summoned->SetOwnerGUID(m_creature->GetGUID());
- summoned->CastSpell(summoned,SPELL_ENERGY_BOLT,false,0,0,m_creature->GetGUID());
- }
-
- void UpdateAI(const uint32 diff)
- {
- if (!UpdateVictim() )
- return;
-
- if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 10)
- {
- Enraged = true;
- }
-
- if (!Enraged)
- {
- //used for check, when Vexallus cast adds 85%, 70%, 55%, 40%, 25%
- if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(SpawnAddInterval*(AlreadySpawnedAmount+1))))
- {
- DoScriptText(SAY_ENERGY, m_creature);
- DoScriptText(EMOTE_DISCHARGE_ENERGY, m_creature);
-
- if (Heroic)
- {
- m_creature->CastSpell(m_creature,H_SPELL_SUMMON_PURE_ENERGY1,false);
- m_creature->CastSpell(m_creature,H_SPELL_SUMMON_PURE_ENERGY2,false);
- }
- else
- m_creature->CastSpell(m_creature,SPELL_SUMMON_PURE_ENERGY,false);
-
- //below are workaround summons, remove when summoning spells w/implicitTarget 73 implemented in Mangos
- DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-
- if (Heroic)
- DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
-
- ++AlreadySpawnedAmount;
- }
-
- if (ChainLightningTimer < diff)
- {
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CHAIN_LIGHTNING);
-
- ChainLightningTimer = 10000;
- }else ChainLightningTimer -= diff;
-
- if (ArcaneShockTimer < diff)
- {
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_ARCANE_SHOCK);
-
- ArcaneShockTimer = 8000;
- }else ArcaneShockTimer -= diff;
- }
- else
- {
- if (OverloadTimer < diff)
- {
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_OVERLOAD);
-
- OverloadTimer = 2200;
- }else OverloadTimer -= diff;
- }
-
- DoMeleeAttackIfReady();
- }
-};
-
-CreatureAI* GetAI_boss_vexallus(Creature *_Creature)
-{
- return new boss_vexallusAI (_Creature);
-};
-
-struct TRINITY_DLL_DECL mob_pure_energyAI : public ScriptedAI
-{
- mob_pure_energyAI(Creature *c) : ScriptedAI(c) {Reset();}
-
- void Reset() { }
-
- void JustDied(Unit* slayer)
- {
- if (Unit *temp = m_creature->GetOwner())
- {
- if (temp && temp->isAlive())
- slayer->CastSpell(slayer, SPELL_ENERGY_FEEDBACK, true, 0, 0, temp->GetGUID());
- }
- }
-
- void Aggro(Unit *who) { }
- void MoveInLineOfSight(Unit *who) { }
- void AttackStart(Unit *who) { }
-};
-
-CreatureAI* GetAI_mob_pure_energy(Creature *_Creature)
-{
- return new mob_pure_energyAI (_Creature);
-};
-
-void AddSC_boss_vexallus()
-{
- Script *newscript;
-
- newscript = new Script;
- newscript->Name = "boss_vexallus";
- newscript->GetAI = &GetAI_boss_vexallus;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name = "mob_pure_energy";
- newscript->GetAI = &GetAI_mob_pure_energy;
- newscript->RegisterSelf();
-}
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Vexallus +SD%Complete: 90 +SDComment: Heroic and Normal support. Needs further testing. +SDCategory: Magister's Terrace +EndScriptData */ + +#include "precompiled.h" +#include "def_magisters_terrace.h" + +#define SAY_AGGRO -1585007 +#define SAY_ENERGY -1585008 +#define SAY_OVERLOAD -1585009 +#define SAY_KILL -1585010 +#define EMOTE_DISCHARGE_ENERGY -1585011 + +//is this text for real? +//#define SAY_DEATH "What...happen...ed." + +//Pure energy spell info +#define SPELL_ENERGY_BOLT 46156 +#define SPELL_ENERGY_FEEDBACK 44335 + +//Vexallus spell info +#define SPELL_CHAIN_LIGHTNING 44318 +#define SPELL_OVERLOAD 44353 +#define SPELL_ARCANE_SHOCK 44319 + +#define SPELL_SUMMON_PURE_ENERGY 44322 //mod scale -10 +#define H_SPELL_SUMMON_PURE_ENERGY1 46154 //mod scale -5 +#define H_SPELL_SUMMON_PURE_ENERGY2 46159 //mod scale -5 + +//Creatures +#define CREATURE_PURE_ENERGY 24745 + +struct TRINITY_DLL_DECL boss_vexallusAI : public ScriptedAI +{ + boss_vexallusAI(Creature *c) : ScriptedAI(c) + { + pInstance = ((ScriptedInstance*)c->GetInstanceData()); + Heroic = c->GetMap()->IsHeroic(); + Reset(); + } + + ScriptedInstance* pInstance; + bool Heroic; + + uint32 ChainLightningTimer; + uint32 ArcaneShockTimer; + uint32 OverloadTimer; + uint32 SpawnAddInterval; + uint32 AlreadySpawnedAmount; + bool Enraged; + + void Reset() + { + ChainLightningTimer = 10000; + ArcaneShockTimer = 8000; + OverloadTimer = 2200; + SpawnAddInterval = 15; + AlreadySpawnedAmount = 0; + Enraged = false; + + if (pInstance) + pInstance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED); + } + + void KilledUnit(Unit *victim) + { + DoScriptText(SAY_KILL, m_creature); + } + + void JustDied(Unit *victim) + { + if (pInstance) + { + pInstance->SetData(DATA_VEXALLUS_EVENT, DONE); + + if (GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_VEXALLUS_DOOR))) + Door->SetGoState(0); + } + } + + void Aggro(Unit *who) + { + DoScriptText(SAY_AGGRO, m_creature); + + if (pInstance) + pInstance->SetData(DATA_VEXALLUS_EVENT, IN_PROGRESS); + } + + void JustSummoned(Creature *summoned) + { + if (Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 0)) + summoned->GetMotionMaster()->MoveFollow(temp,0,0); + + //spells are SUMMON_TYPE_GUARDIAN, so using setOwner should be ok + summoned->SetOwnerGUID(m_creature->GetGUID()); + summoned->CastSpell(summoned,SPELL_ENERGY_BOLT,false,0,0,m_creature->GetGUID()); + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim() ) + return; + + if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 10) + { + Enraged = true; + } + + if (!Enraged) + { + //used for check, when Vexallus cast adds 85%, 70%, 55%, 40%, 25% + if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(SpawnAddInterval*(AlreadySpawnedAmount+1)))) + { + DoScriptText(SAY_ENERGY, m_creature); + DoScriptText(EMOTE_DISCHARGE_ENERGY, m_creature); + + if (Heroic) + { + m_creature->CastSpell(m_creature,H_SPELL_SUMMON_PURE_ENERGY1,false); + m_creature->CastSpell(m_creature,H_SPELL_SUMMON_PURE_ENERGY2,false); + } + else + m_creature->CastSpell(m_creature,SPELL_SUMMON_PURE_ENERGY,false); + + //below are workaround summons, remove when summoning spells w/implicitTarget 73 implemented in Mangos + DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + + if (Heroic) + DoSpawnCreature(CREATURE_PURE_ENERGY, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); + + ++AlreadySpawnedAmount; + } + + if (ChainLightningTimer < diff) + { + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_CHAIN_LIGHTNING); + + ChainLightningTimer = 10000; + }else ChainLightningTimer -= diff; + + if (ArcaneShockTimer < diff) + { + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_ARCANE_SHOCK); + + ArcaneShockTimer = 8000; + }else ArcaneShockTimer -= diff; + } + else + { + if (OverloadTimer < diff) + { + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_OVERLOAD); + + OverloadTimer = 2200; + }else OverloadTimer -= diff; + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_vexallus(Creature *_Creature) +{ + return new boss_vexallusAI (_Creature); +}; + +struct TRINITY_DLL_DECL mob_pure_energyAI : public ScriptedAI +{ + mob_pure_energyAI(Creature *c) : ScriptedAI(c) {Reset();} + + void Reset() { } + + void JustDied(Unit* slayer) + { + if (Unit *temp = m_creature->GetOwner()) + { + if (temp && temp->isAlive()) + slayer->CastSpell(slayer, SPELL_ENERGY_FEEDBACK, true, 0, 0, temp->GetGUID()); + } + } + + void Aggro(Unit *who) { } + void MoveInLineOfSight(Unit *who) { } + void AttackStart(Unit *who) { } +}; + +CreatureAI* GetAI_mob_pure_energy(Creature *_Creature) +{ + return new mob_pure_energyAI (_Creature); +}; + +void AddSC_boss_vexallus() +{ + Script *newscript; + + newscript = new Script; + newscript->Name = "boss_vexallus"; + newscript->GetAI = &GetAI_boss_vexallus; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "mob_pure_energy"; + newscript->GetAI = &GetAI_mob_pure_energy; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp index bc99852481f..460a19aeb59 100644 --- a/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp +++ b/src/bindings/scripts/scripts/zone/shattrath/shattrath_city.cpp @@ -1,740 +1,740 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* ScriptData
-SDName: Shattrath_City
-SD%Complete: 100
-SDComment: Quest support: 10004, 10009, 10211, 10231. Flask vendors, Teleport to Caverns of Time
-SDCategory: Shattrath City
-EndScriptData */
-
-/* ContentData
-npc_raliq_the_drunk
-npc_salsalabim
-npc_shattrathflaskvendors
-npc_zephyr
-npc_kservant
-npc_dirty_larry
-npc_ishanah
-npc_khadgar
-EndContentData */
-
-#include "precompiled.h"
-#include "../../npc/npc_escortAI.h"
-
-/*######
-## npc_raliq_the_drunk
-######*/
-
-#define GOSSIP_RALIQ "You owe Sim'salabim money. Hand them over or die!"
-
-#define FACTION_HOSTILE_RD 45
-#define FACTION_FRIENDLY_RD 35
-
-#define SPELL_UPPERCUT 10966
-
-struct TRINITY_DLL_DECL npc_raliq_the_drunkAI : public ScriptedAI
-{
- npc_raliq_the_drunkAI(Creature* c) : ScriptedAI(c) { Reset(); }
-
- uint32 Uppercut_Timer;
-
- void Reset()
- {
- Uppercut_Timer = 5000;
- m_creature->setFaction(FACTION_FRIENDLY_RD);
- }
-
- void Aggro(Unit *who) {}
-
- void UpdateAI(const uint32 diff)
- {
- if(!UpdateVictim())
- return;
-
- if( Uppercut_Timer < diff )
- {
- DoCast(m_creature->getVictim(),SPELL_UPPERCUT);
- Uppercut_Timer = 15000;
- }else Uppercut_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
-};
-CreatureAI* GetAI_npc_raliq_the_drunk(Creature *_Creature)
-{
- return new npc_raliq_the_drunkAI (_Creature);
-}
-
-bool GossipHello_npc_raliq_the_drunk(Player *player, Creature *_Creature )
-{
- if( player->GetQuestStatus(10009) == QUEST_STATUS_INCOMPLETE )
- player->ADD_GOSSIP_ITEM(1, GOSSIP_RALIQ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(9440, _Creature->GetGUID());
- return true;
-}
-
-bool GossipSelect_npc_raliq_the_drunk(Player *player, Creature *_Creature, uint32 sender, uint32 action )
-{
- if( action == GOSSIP_ACTION_INFO_DEF+1 )
- {
- player->CLOSE_GOSSIP_MENU();
- _Creature->setFaction(FACTION_HOSTILE_RD);
- ((npc_raliq_the_drunkAI*)_Creature->AI())->AttackStart(player);
- }
- return true;
-}
-
-/*######
-# npc_salsalabim
-######*/
-
-#define FACTION_HOSTILE_SA 90
-#define FACTION_FRIENDLY_SA 35
-#define QUEST_10004 10004
-
-#define SPELL_MAGNETIC_PULL 31705
-
-struct TRINITY_DLL_DECL npc_salsalabimAI : public ScriptedAI
-{
- npc_salsalabimAI(Creature* c) : ScriptedAI(c) { Reset(); }
-
- uint32 MagneticPull_Timer;
-
- void Reset()
- {
- MagneticPull_Timer = 15000;
- m_creature->setFaction(FACTION_FRIENDLY_SA);
- }
-
- void Aggro(Unit *who) {}
-
- void DamageTaken(Unit *done_by, uint32 &damage)
- {
- if( done_by->GetTypeId() == TYPEID_PLAYER )
- if( (m_creature->GetHealth()-damage)*100 / m_creature->GetMaxHealth() < 20 )
- {
- ((Player*)done_by)->GroupEventHappens(QUEST_10004,m_creature);
- damage = 0;
- EnterEvadeMode();
- }
- }
-
- void UpdateAI(const uint32 diff)
- {
- if(!UpdateVictim())
- return;
-
- if( MagneticPull_Timer < diff )
- {
- DoCast(m_creature->getVictim(),SPELL_MAGNETIC_PULL);
- MagneticPull_Timer = 15000;
- }else MagneticPull_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
-};
-CreatureAI* GetAI_npc_salsalabim(Creature *_Creature)
-{
- return new npc_salsalabimAI (_Creature);
-}
-
-bool GossipHello_npc_salsalabim(Player *player, Creature *_Creature)
-{
- if( player->GetQuestStatus(QUEST_10004) == QUEST_STATUS_INCOMPLETE )
- {
- _Creature->setFaction(FACTION_HOSTILE_SA);
- ((npc_salsalabimAI*)_Creature->AI())->AttackStart(player);
- }
- else
- {
- if( _Creature->isQuestGiver() )
- player->PrepareQuestMenu( _Creature->GetGUID() );
- player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
- }
- return true;
-}
-
-/*
-##################################################
-Shattrath City Flask Vendors provides flasks to people exalted with 3 factions:
-Haldor the Compulsive
-Arcanist Xorith
-Both sell special flasks for use in Outlands 25man raids only,
-purchasable for one Mark of Illidari each
-Purchase requires exalted reputation with Scryers/Aldor, Cenarion Expedition and The Sha'tar
-##################################################
-*/
-
-bool GossipHello_npc_shattrathflaskvendors(Player *player, Creature *_Creature)
-{
- if(_Creature->GetEntry() == 23484)
- {
- // Aldor vendor
- if( _Creature->isVendor() && (player->GetReputationRank(932) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED) )
- {
- player->ADD_GOSSIP_ITEM(1, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
- player->SEND_GOSSIP_MENU(11085, _Creature->GetGUID());
- }
- else
- {
- player->SEND_GOSSIP_MENU(11083, _Creature->GetGUID());
- }
- }
-
- if(_Creature->GetEntry() == 23483)
- {
- // Scryers vendor
- if( _Creature->isVendor() && (player->GetReputationRank(934) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED) )
- {
- player->ADD_GOSSIP_ITEM(1, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
- player->SEND_GOSSIP_MENU(11085, _Creature->GetGUID());
- }
- else
- {
- player->SEND_GOSSIP_MENU(11084, _Creature->GetGUID());
- }
- }
-
- return true;
-}
-
-bool GossipSelect_npc_shattrathflaskvendors(Player *player, Creature *_Creature, uint32 sender, uint32 action)
-{
- if( action == GOSSIP_ACTION_TRADE )
- player->SEND_VENDORLIST( _Creature->GetGUID() );
-
- return true;
-}
-
-/*######
-# npc_zephyr
-######*/
-
-#define GOSSIP_HZ "Take me to the Caverns of Time."
-
-bool GossipHello_npc_zephyr(Player *player, Creature *_Creature)
-{
- if( player->GetReputationRank(989) >= REP_REVERED )
- player->ADD_GOSSIP_ITEM(0, GOSSIP_HZ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
-
- return true;
-}
-
-bool GossipSelect_npc_zephyr(Player *player, Creature *_Creature, uint32 sender, uint32 action)
-{
- if( action == GOSSIP_ACTION_INFO_DEF+1 )
- player->CastSpell(player,37778,false);
-
- return true;
-}
-
-/*######
-# npc_kservant
-######*/
-
-#define SAY1 -1000306
-#define WHISP1 -1000307
-#define WHISP2 -1000308
-#define WHISP3 -1000309
-#define WHISP4 -1000310
-#define WHISP5 -1000311
-#define WHISP6 -1000312
-#define WHISP7 -1000313
-#define WHISP8 -1000314
-#define WHISP9 -1000315
-#define WHISP10 -1000316
-#define WHISP11 -1000317
-#define WHISP12 -1000318
-#define WHISP13 -1000319
-#define WHISP14 -1000320
-#define WHISP15 -1000321
-#define WHISP16 -1000322
-#define WHISP17 -1000323
-#define WHISP18 -1000324
-#define WHISP19 -1000325
-#define WHISP20 -1000326
-#define WHISP21 -1000327
-
-struct TRINITY_DLL_DECL npc_kservantAI : public npc_escortAI
-{
-public:
- npc_kservantAI(Creature *c) : npc_escortAI(c) { Reset();}
-
-
- void WaypointReached(uint32 i)
- {
- Unit *pTemp = Unit::GetUnit(*m_creature,PlayerGUID);
-
- if( !pTemp )
- return;
-
- switch(i)
- {
- case 0: DoScriptText(SAY1, m_creature, pTemp); break;
- case 4: DoScriptText(WHISP1, m_creature, pTemp); break;
- case 6: DoScriptText(WHISP2, m_creature, pTemp); break;
- case 7: DoScriptText(WHISP3, m_creature, pTemp); break;
- case 8: DoScriptText(WHISP4, m_creature, pTemp); break;
- case 17: DoScriptText(WHISP5, m_creature, pTemp); break;
- case 18: DoScriptText(WHISP6, m_creature, pTemp); break;
- case 19: DoScriptText(WHISP7, m_creature, pTemp); break;
- case 33: DoScriptText(WHISP8, m_creature, pTemp); break;
- case 34: DoScriptText(WHISP9, m_creature, pTemp); break;
- case 35: DoScriptText(WHISP10, m_creature, pTemp); break;
- case 36: DoScriptText(WHISP11, m_creature, pTemp); break;
- case 43: DoScriptText(WHISP12, m_creature, pTemp); break;
- case 44: DoScriptText(WHISP13, m_creature, pTemp); break;
- case 49: DoScriptText(WHISP14, m_creature, pTemp); break;
- case 50: DoScriptText(WHISP15, m_creature, pTemp); break;
- case 51: DoScriptText(WHISP16, m_creature, pTemp); break;
- case 52: DoScriptText(WHISP17, m_creature, pTemp); break;
- case 53: DoScriptText(WHISP18, m_creature, pTemp); break;
- case 54: DoScriptText(WHISP19, m_creature, pTemp); break;
- case 55: DoScriptText(WHISP20, m_creature, pTemp); break;
- case 56: DoScriptText(WHISP21, m_creature, pTemp);
- if( PlayerGUID )
- {
- Unit* player = ((Creature*)Unit::GetUnit((*m_creature), PlayerGUID));
- if( player && player->GetTypeId() == TYPEID_PLAYER )
- ((Player*)player)->GroupEventHappens(10211,m_creature);
- }
- break;
- }
- }
-
- void Aggro(Unit* who) {}
-
- void MoveInLineOfSight(Unit *who)
- {
- if( IsBeingEscorted )
- return;
-
- if( who->GetTypeId() == TYPEID_PLAYER )
- {
- if( ((Player*)who)->GetQuestStatus(10211) == QUEST_STATUS_INCOMPLETE )
- {
- float Radius = 10.0;
- if( m_creature->IsWithinDistInMap(who, Radius) )
- {
- ((npc_escortAI*)(m_creature->AI()))->Start(false, false, false, who->GetGUID());
- }
- }
- }
- }
-
- void Reset() {}
-
- void UpdateAI(const uint32 diff)
- {
- npc_escortAI::UpdateAI(diff);
- }
-};
-CreatureAI* GetAI_npc_kservantAI(Creature *_Creature)
-{
- npc_kservantAI* kservantAI = new npc_kservantAI(_Creature);
-
- kservantAI->AddWaypoint(0, -1863.369019, 5419.517090, -10.463668, 4000);
- kservantAI->AddWaypoint(1, -1861.749023, 5416.465332, -10.508068);
- kservantAI->AddWaypoint(2, -1857.036133, 5410.966309, -12.428039);
- kservantAI->AddWaypoint(3, -1831.539185, 5365.472168, -12.428039);
- kservantAI->AddWaypoint(4, -1813.416504, 5333.776855, -12.428039);
- kservantAI->AddWaypoint(5, -1800.354370, 5313.290039, -12.428039);
- kservantAI->AddWaypoint(6, -1775.624878, 5268.786133, -38.809181);
- kservantAI->AddWaypoint(7, -1770.147339, 5259.268066, -38.829231);
- kservantAI->AddWaypoint(8, -1762.814209, 5261.098145, -38.848995);
- kservantAI->AddWaypoint(9, -1740.110474, 5268.858398, -40.208965);
- kservantAI->AddWaypoint(10, -1725.837402, 5270.936035, -40.208965);
- kservantAI->AddWaypoint(11, -1701.580322, 5290.323242, -40.209187);
- kservantAI->AddWaypoint(12, -1682.877808, 5291.406738, -34.429646);
- kservantAI->AddWaypoint(13, -1670.101685, 5291.201172, -32.786007);
- kservantAI->AddWaypoint(14, -1656.666870, 5294.333496, -37.862648);
- kservantAI->AddWaypoint(15, -1652.035767, 5295.413086, -40.245499);
- kservantAI->AddWaypoint(16, -1620.860596, 5300.133301, -40.208992);
- kservantAI->AddWaypoint(17, -1607.630981, 5293.983398, -38.577045, 5000);
- kservantAI->AddWaypoint(18, -1607.630981, 5293.983398, -38.577045, 5000);
- kservantAI->AddWaypoint(19, -1607.630981, 5293.983398, -38.577045, 5000);
- kservantAI->AddWaypoint(20, -1622.140869, 5301.955566, -40.208897);
- kservantAI->AddWaypoint(21, -1621.131836, 5333.112793, -40.208897);
- kservantAI->AddWaypoint(22, -1637.598999, 5342.134277, -40.208790);
- kservantAI->AddWaypoint(23, -1648.521606, 5352.309570, -47.496170);
- kservantAI->AddWaypoint(24, -1654.606934, 5357.419434, -45.870892);
- kservantAI->AddWaypoint(25, -1633.670044, 5422.067871, -42.835541);
- kservantAI->AddWaypoint(25, -1656.567505, 5426.236328, -40.405815);
- kservantAI->AddWaypoint(26, -1664.932373, 5425.686523, -38.846405);
- kservantAI->AddWaypoint(27, -1681.406006, 5425.871094, -38.810928);
- kservantAI->AddWaypoint(28, -1730.875977, 5427.413574, -12.427910);
- kservantAI->AddWaypoint(29, -1743.509521, 5369.599121, -12.427910);
- kservantAI->AddWaypoint(30, -1877.217041, 5303.710449, -12.427989);
- kservantAI->AddWaypoint(31, -1890.371216, 5289.273438, -12.428268);
- kservantAI->AddWaypoint(32, -1905.505737, 5266.534668, 2.630672);
- kservantAI->AddWaypoint(33, -1909.381348, 5273.008301, 1.663714, 10000);
- kservantAI->AddWaypoint(34, -1909.381348, 5273.008301, 1.663714, 12000);
- kservantAI->AddWaypoint(35, -1909.381348, 5273.008301, 1.663714, 8000);
- kservantAI->AddWaypoint(36, -1909.381348, 5273.008301, 1.663714, 15000);
- kservantAI->AddWaypoint(37, -1927.561401, 5275.324707, 1.984987);
- kservantAI->AddWaypoint(38, -1927.385498, 5300.879883, -12.427236);
- kservantAI->AddWaypoint(39, -1921.063965, 5314.318359, -12.427236);
- kservantAI->AddWaypoint(40, -1965.425415, 5379.298828, -12.427236);
- kservantAI->AddWaypoint(41, -1981.233154, 5450.743652, -12.427236);
- kservantAI->AddWaypoint(42, -1958.022461, 5455.904297, 0.487659);
- kservantAI->AddWaypoint(43, -1951.991455, 5463.580566, 0.874490, 10000);
- kservantAI->AddWaypoint(44, -1951.991455, 5463.580566, 0.874490, 12000);
- kservantAI->AddWaypoint(45, -1968.730225, 5481.752930, -12.427846);
- kservantAI->AddWaypoint(46, -1881.839844, 5554.040039, -12.427846);
- kservantAI->AddWaypoint(47, -1841.566650, 5545.965332, -12.427846);
- kservantAI->AddWaypoint(48, -1837.658325, 5523.780273, 0.558756);
- kservantAI->AddWaypoint(49, -1831.321777, 5534.821777, 1.221819, 6000);
- kservantAI->AddWaypoint(50, -1831.321777, 5534.821777, 1.221819, 8000);
- kservantAI->AddWaypoint(51, -1831.321777, 5534.821777, 1.221819, 5000);
- kservantAI->AddWaypoint(52, -1850.060669, 5472.610840, 0.857320, 6000);
- kservantAI->AddWaypoint(53, -1850.060669, 5472.610840, 0.857320, 8000);
- kservantAI->AddWaypoint(54, -1850.060669, 5472.610840, 0.857320, 9000);
- kservantAI->AddWaypoint(55, -1850.060669, 5472.610840, 0.857320, 9000);
- kservantAI->AddWaypoint(56, -1850.060669, 5472.610840, 0.857320, 4000);
-
- return (CreatureAI*)kservantAI;
-}
-
-/*######
-# npc_dirty_larry
-######*/
-
-#define GOSSIP_BOOK "Ezekiel said that you might have a certain book..."
-
-#define SAY_1 -1000328
-#define SAY_2 -1000329
-#define SAY_3 -1000330
-#define SAY_4 -1000331
-#define SAY_5 -1000332
-#define SAY_GIVEUP -1000333
-
-#define QUEST_WBI 10231
-#define NPC_CREEPJACK 19726
-#define NPC_MALONE 19725
-
-struct TRINITY_DLL_DECL npc_dirty_larryAI : public ScriptedAI
-{
- npc_dirty_larryAI(Creature* c) : ScriptedAI(c) {Reset();}
-
- bool Event;
- bool Attack;
- bool Done;
-
- uint64 PlayerGUID;
-
- uint32 SayTimer;
- uint32 Step;
-
- void Reset()
- {
- Event = false;
- Attack = false;
- Done = false;
-
- PlayerGUID = 0;
- SayTimer = 0;
- Step = 0;
-
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- m_creature->setFaction(1194);
- Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature);
- if(Creepjack)
- {
- ((Creature*)Creepjack)->AI()->EnterEvadeMode();
- Creepjack->setFaction(1194);
- Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature);
- if(Malone)
- {
- ((Creature*)Malone)->AI()->EnterEvadeMode();
- Malone->setFaction(1194);
- Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- }
-
- uint32 NextStep(uint32 Step)
- {
- Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
-
- switch(Step)
- {
- case 0:{ m_creature->SetInFront(player);
- Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature);
- if(Creepjack)
- Creepjack->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature);
- if(Malone)
- Malone->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }return 2000;
- case 1: DoScriptText(SAY_1, m_creature, player); return 3000;
- case 2: DoScriptText(SAY_2, m_creature, player); return 5000;
- case 3: DoScriptText(SAY_3, m_creature, player); return 2000;
- case 4: DoScriptText(SAY_4, m_creature, player); return 2000;
- case 5: DoScriptText(SAY_5, m_creature, player); return 2000;
- case 6: Attack = true; return 2000;
- default: return 0;
- }
- }
-
- void Aggro(Unit* who){}
-
- void UpdateAI(const uint32 diff)
- {
- if(SayTimer < diff)
- {
- if(Event)
- SayTimer = NextStep(++Step);
- }else SayTimer -= diff;
-
- if(Attack)
- {
- Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
- m_creature->setFaction(14);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if(player)
- {
- Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature);
- if(Creepjack)
- {
- Creepjack->Attack(player, true);
- Creepjack->setFaction(14);
- Creepjack->GetMotionMaster()->MoveChase(player);
- Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature);
- if(Malone)
- {
- Malone->Attack(player, true);
- Malone->setFaction(14);
- Malone->GetMotionMaster()->MoveChase(player);
- Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- DoStartMovement(player);
- AttackStart(player);
- }
- Attack = false;
- }
-
- if((m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1 && !Done)
- {
- Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature);
- if(Creepjack)
- {
- ((Creature*)Creepjack)->AI()->EnterEvadeMode();
- Creepjack->setFaction(1194);
- Creepjack->GetMotionMaster()->MoveTargetedHome();
- Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature);
- if(Malone)
- {
- ((Creature*)Malone)->AI()->EnterEvadeMode();
- Malone->setFaction(1194);
- Malone->GetMotionMaster()->MoveTargetedHome();
- Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- m_creature->setFaction(1194);
- Done = true;
- DoScriptText(SAY_GIVEUP, m_creature, NULL);
- m_creature->DeleteThreatList();
- m_creature->CombatStop();
- m_creature->GetMotionMaster()->MoveTargetedHome();
- Unit* player = Unit::GetUnit((*m_creature), PlayerGUID);
- if(player)
- ((Player*)player)->GroupEventHappens(QUEST_WBI, m_creature);
- }
- DoMeleeAttackIfReady();
- }
-};
-
-bool GossipHello_npc_dirty_larry(Player *player, Creature *creature)
-{
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if(player->GetQuestStatus(QUEST_WBI) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(0, GOSSIP_BOOK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(creature->GetNpcTextId(), creature->GetGUID());
- return true;
-}
-
-bool GossipSelect_npc_dirty_larry(Player *player, Creature *creature, uint32 sender, uint32 action )
-{
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- ((npc_dirty_larryAI*)creature->AI())->Event = true;
- ((npc_dirty_larryAI*)creature->AI())->PlayerGUID = player->GetGUID();
- player->CLOSE_GOSSIP_MENU();
- }
-
- return true;
-}
-
-CreatureAI* GetAI_npc_dirty_larryAI(Creature *_Creature)
-{
- return new npc_dirty_larryAI (_Creature);
-}
-
-/*######
-# npc_ishanah
-######*/
-
-#define ISANAH_GOSSIP_1 "Who are the Sha'tar?"
-#define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?"
-
-bool GossipHello_npc_ishanah(Player *player, Creature *_Creature)
-{
- if (_Creature->isQuestGiver())
- player->PrepareQuestMenu(_Creature->GetGUID());
-
- player->ADD_GOSSIP_ITEM(0, ISANAH_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->ADD_GOSSIP_ITEM(0, ISANAH_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
-
- player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID());
-
- return true;
-}
-
-bool GossipSelect_npc_ishanah(Player *player, Creature *_Creature, uint32 sender, uint32 action)
-{
- if(action == GOSSIP_ACTION_INFO_DEF+1)
- player->SEND_GOSSIP_MENU(9458, _Creature->GetGUID());
- else if(action == GOSSIP_ACTION_INFO_DEF+2)
- player->SEND_GOSSIP_MENU(9459, _Creature->GetGUID());
-
- return true;
-}
-
-/*######
-# npc_khadgar
-######*/
-
-#define KHADGAR_GOSSIP_1 "I've heard your name spoken only in whispers, mage. Who are you?"
-#define KHADGAR_GOSSIP_2 "Go on, please."
-#define KHADGAR_GOSSIP_3 "I see." //6th too this
-#define KHADGAR_GOSSIP_4 "What did you do then?"
-#define KHADGAR_GOSSIP_5 "What happened next?"
-#define KHADGAR_GOSSIP_7 "There was something else I wanted to ask you."
-
-bool GossipHello_npc_khadgar(Player *player, Creature *creature)
-{
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if(!player->hasQuest(10211))
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(9243, creature->GetGUID());
-
- return true;
-}
-
-bool GossipSelect_npc_khadgar(Player *player, Creature *creature, uint32 sender, uint32 action)
-{
- switch(action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->SEND_GOSSIP_MENU(9876, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
- player->SEND_GOSSIP_MENU(9877, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
- player->SEND_GOSSIP_MENU(9878, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
- player->SEND_GOSSIP_MENU(9879, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
- player->SEND_GOSSIP_MENU(9880, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
- player->SEND_GOSSIP_MENU(9881, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+7:
- player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(9243, creature->GetGUID());
- break;
- }
- return true;
-}
-
-void AddSC_shattrath_city()
-{
- Script *newscript;
-
- newscript = new Script;
- newscript->Name="npc_raliq_the_drunk";
- newscript->pGossipHello = &GossipHello_npc_raliq_the_drunk;
- newscript->pGossipSelect = &GossipSelect_npc_raliq_the_drunk;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_salsalabim";
- newscript->GetAI = &GetAI_npc_salsalabim;
- newscript->pGossipHello = &GossipHello_npc_salsalabim;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_shattrathflaskvendors";
- newscript->pGossipHello = &GossipHello_npc_shattrathflaskvendors;
- newscript->pGossipSelect = &GossipSelect_npc_shattrathflaskvendors;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_zephyr";
- newscript->pGossipHello = &GossipHello_npc_zephyr;
- newscript->pGossipSelect = &GossipSelect_npc_zephyr;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_kservant";
- newscript->GetAI = &GetAI_npc_kservantAI;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_dirty_larry";
- newscript->GetAI = &GetAI_npc_dirty_larryAI;
- newscript->pGossipHello = &GossipHello_npc_dirty_larry;
- newscript->pGossipSelect = &GossipSelect_npc_dirty_larry;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_ishanah";
- newscript->pGossipHello = &GossipHello_npc_ishanah;
- newscript->pGossipSelect = &GossipSelect_npc_ishanah;
- newscript->RegisterSelf();
-
- newscript = new Script;
- newscript->Name="npc_khadgar";
- newscript->pGossipHello = &GossipHello_npc_khadgar;
- newscript->pGossipSelect = &GossipSelect_npc_khadgar;
- newscript->RegisterSelf();
-}
-
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Shattrath_City +SD%Complete: 100 +SDComment: Quest support: 10004, 10009, 10211, 10231. Flask vendors, Teleport to Caverns of Time +SDCategory: Shattrath City +EndScriptData */ + +/* ContentData +npc_raliq_the_drunk +npc_salsalabim +npc_shattrathflaskvendors +npc_zephyr +npc_kservant +npc_dirty_larry +npc_ishanah +npc_khadgar +EndContentData */ + +#include "precompiled.h" +#include "../../npc/npc_escortAI.h" + +/*###### +## npc_raliq_the_drunk +######*/ + +#define GOSSIP_RALIQ "You owe Sim'salabim money. Hand them over or die!" + +#define FACTION_HOSTILE_RD 45 +#define FACTION_FRIENDLY_RD 35 + +#define SPELL_UPPERCUT 10966 + +struct TRINITY_DLL_DECL npc_raliq_the_drunkAI : public ScriptedAI +{ + npc_raliq_the_drunkAI(Creature* c) : ScriptedAI(c) { Reset(); } + + uint32 Uppercut_Timer; + + void Reset() + { + Uppercut_Timer = 5000; + m_creature->setFaction(FACTION_FRIENDLY_RD); + } + + void Aggro(Unit *who) {} + + void UpdateAI(const uint32 diff) + { + if(!UpdateVictim()) + return; + + if( Uppercut_Timer < diff ) + { + DoCast(m_creature->getVictim(),SPELL_UPPERCUT); + Uppercut_Timer = 15000; + }else Uppercut_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; +CreatureAI* GetAI_npc_raliq_the_drunk(Creature *_Creature) +{ + return new npc_raliq_the_drunkAI (_Creature); +} + +bool GossipHello_npc_raliq_the_drunk(Player *player, Creature *_Creature ) +{ + if( player->GetQuestStatus(10009) == QUEST_STATUS_INCOMPLETE ) + player->ADD_GOSSIP_ITEM(1, GOSSIP_RALIQ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(9440, _Creature->GetGUID()); + return true; +} + +bool GossipSelect_npc_raliq_the_drunk(Player *player, Creature *_Creature, uint32 sender, uint32 action ) +{ + if( action == GOSSIP_ACTION_INFO_DEF+1 ) + { + player->CLOSE_GOSSIP_MENU(); + _Creature->setFaction(FACTION_HOSTILE_RD); + ((npc_raliq_the_drunkAI*)_Creature->AI())->AttackStart(player); + } + return true; +} + +/*###### +# npc_salsalabim +######*/ + +#define FACTION_HOSTILE_SA 90 +#define FACTION_FRIENDLY_SA 35 +#define QUEST_10004 10004 + +#define SPELL_MAGNETIC_PULL 31705 + +struct TRINITY_DLL_DECL npc_salsalabimAI : public ScriptedAI +{ + npc_salsalabimAI(Creature* c) : ScriptedAI(c) { Reset(); } + + uint32 MagneticPull_Timer; + + void Reset() + { + MagneticPull_Timer = 15000; + m_creature->setFaction(FACTION_FRIENDLY_SA); + } + + void Aggro(Unit *who) {} + + void DamageTaken(Unit *done_by, uint32 &damage) + { + if( done_by->GetTypeId() == TYPEID_PLAYER ) + if( (m_creature->GetHealth()-damage)*100 / m_creature->GetMaxHealth() < 20 ) + { + ((Player*)done_by)->GroupEventHappens(QUEST_10004,m_creature); + damage = 0; + EnterEvadeMode(); + } + } + + void UpdateAI(const uint32 diff) + { + if(!UpdateVictim()) + return; + + if( MagneticPull_Timer < diff ) + { + DoCast(m_creature->getVictim(),SPELL_MAGNETIC_PULL); + MagneticPull_Timer = 15000; + }else MagneticPull_Timer -= diff; + + DoMeleeAttackIfReady(); + } +}; +CreatureAI* GetAI_npc_salsalabim(Creature *_Creature) +{ + return new npc_salsalabimAI (_Creature); +} + +bool GossipHello_npc_salsalabim(Player *player, Creature *_Creature) +{ + if( player->GetQuestStatus(QUEST_10004) == QUEST_STATUS_INCOMPLETE ) + { + _Creature->setFaction(FACTION_HOSTILE_SA); + ((npc_salsalabimAI*)_Creature->AI())->AttackStart(player); + } + else + { + if( _Creature->isQuestGiver() ) + player->PrepareQuestMenu( _Creature->GetGUID() ); + player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID()); + } + return true; +} + +/* +################################################## +Shattrath City Flask Vendors provides flasks to people exalted with 3 factions: +Haldor the Compulsive +Arcanist Xorith +Both sell special flasks for use in Outlands 25man raids only, +purchasable for one Mark of Illidari each +Purchase requires exalted reputation with Scryers/Aldor, Cenarion Expedition and The Sha'tar +################################################## +*/ + +bool GossipHello_npc_shattrathflaskvendors(Player *player, Creature *_Creature) +{ + if(_Creature->GetEntry() == 23484) + { + // Aldor vendor + if( _Creature->isVendor() && (player->GetReputationRank(932) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED) ) + { + player->ADD_GOSSIP_ITEM(1, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(11085, _Creature->GetGUID()); + } + else + { + player->SEND_GOSSIP_MENU(11083, _Creature->GetGUID()); + } + } + + if(_Creature->GetEntry() == 23483) + { + // Scryers vendor + if( _Creature->isVendor() && (player->GetReputationRank(934) == REP_EXALTED) && (player->GetReputationRank(935) == REP_EXALTED) && (player->GetReputationRank(942) == REP_EXALTED) ) + { + player->ADD_GOSSIP_ITEM(1, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE); + player->SEND_GOSSIP_MENU(11085, _Creature->GetGUID()); + } + else + { + player->SEND_GOSSIP_MENU(11084, _Creature->GetGUID()); + } + } + + return true; +} + +bool GossipSelect_npc_shattrathflaskvendors(Player *player, Creature *_Creature, uint32 sender, uint32 action) +{ + if( action == GOSSIP_ACTION_TRADE ) + player->SEND_VENDORLIST( _Creature->GetGUID() ); + + return true; +} + +/*###### +# npc_zephyr +######*/ + +#define GOSSIP_HZ "Take me to the Caverns of Time." + +bool GossipHello_npc_zephyr(Player *player, Creature *_Creature) +{ + if( player->GetReputationRank(989) >= REP_REVERED ) + player->ADD_GOSSIP_ITEM(0, GOSSIP_HZ, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_zephyr(Player *player, Creature *_Creature, uint32 sender, uint32 action) +{ + if( action == GOSSIP_ACTION_INFO_DEF+1 ) + player->CastSpell(player,37778,false); + + return true; +} + +/*###### +# npc_kservant +######*/ + +#define SAY1 -1000306 +#define WHISP1 -1000307 +#define WHISP2 -1000308 +#define WHISP3 -1000309 +#define WHISP4 -1000310 +#define WHISP5 -1000311 +#define WHISP6 -1000312 +#define WHISP7 -1000313 +#define WHISP8 -1000314 +#define WHISP9 -1000315 +#define WHISP10 -1000316 +#define WHISP11 -1000317 +#define WHISP12 -1000318 +#define WHISP13 -1000319 +#define WHISP14 -1000320 +#define WHISP15 -1000321 +#define WHISP16 -1000322 +#define WHISP17 -1000323 +#define WHISP18 -1000324 +#define WHISP19 -1000325 +#define WHISP20 -1000326 +#define WHISP21 -1000327 + +struct TRINITY_DLL_DECL npc_kservantAI : public npc_escortAI +{ +public: + npc_kservantAI(Creature *c) : npc_escortAI(c) { Reset();} + + + void WaypointReached(uint32 i) + { + Unit *pTemp = Unit::GetUnit(*m_creature,PlayerGUID); + + if( !pTemp ) + return; + + switch(i) + { + case 0: DoScriptText(SAY1, m_creature, pTemp); break; + case 4: DoScriptText(WHISP1, m_creature, pTemp); break; + case 6: DoScriptText(WHISP2, m_creature, pTemp); break; + case 7: DoScriptText(WHISP3, m_creature, pTemp); break; + case 8: DoScriptText(WHISP4, m_creature, pTemp); break; + case 17: DoScriptText(WHISP5, m_creature, pTemp); break; + case 18: DoScriptText(WHISP6, m_creature, pTemp); break; + case 19: DoScriptText(WHISP7, m_creature, pTemp); break; + case 33: DoScriptText(WHISP8, m_creature, pTemp); break; + case 34: DoScriptText(WHISP9, m_creature, pTemp); break; + case 35: DoScriptText(WHISP10, m_creature, pTemp); break; + case 36: DoScriptText(WHISP11, m_creature, pTemp); break; + case 43: DoScriptText(WHISP12, m_creature, pTemp); break; + case 44: DoScriptText(WHISP13, m_creature, pTemp); break; + case 49: DoScriptText(WHISP14, m_creature, pTemp); break; + case 50: DoScriptText(WHISP15, m_creature, pTemp); break; + case 51: DoScriptText(WHISP16, m_creature, pTemp); break; + case 52: DoScriptText(WHISP17, m_creature, pTemp); break; + case 53: DoScriptText(WHISP18, m_creature, pTemp); break; + case 54: DoScriptText(WHISP19, m_creature, pTemp); break; + case 55: DoScriptText(WHISP20, m_creature, pTemp); break; + case 56: DoScriptText(WHISP21, m_creature, pTemp); + if( PlayerGUID ) + { + Unit* player = ((Creature*)Unit::GetUnit((*m_creature), PlayerGUID)); + if( player && player->GetTypeId() == TYPEID_PLAYER ) + ((Player*)player)->GroupEventHappens(10211,m_creature); + } + break; + } + } + + void Aggro(Unit* who) {} + + void MoveInLineOfSight(Unit *who) + { + if( IsBeingEscorted ) + return; + + if( who->GetTypeId() == TYPEID_PLAYER ) + { + if( ((Player*)who)->GetQuestStatus(10211) == QUEST_STATUS_INCOMPLETE ) + { + float Radius = 10.0; + if( m_creature->IsWithinDistInMap(who, Radius) ) + { + ((npc_escortAI*)(m_creature->AI()))->Start(false, false, false, who->GetGUID()); + } + } + } + } + + void Reset() {} + + void UpdateAI(const uint32 diff) + { + npc_escortAI::UpdateAI(diff); + } +}; +CreatureAI* GetAI_npc_kservantAI(Creature *_Creature) +{ + npc_kservantAI* kservantAI = new npc_kservantAI(_Creature); + + kservantAI->AddWaypoint(0, -1863.369019, 5419.517090, -10.463668, 4000); + kservantAI->AddWaypoint(1, -1861.749023, 5416.465332, -10.508068); + kservantAI->AddWaypoint(2, -1857.036133, 5410.966309, -12.428039); + kservantAI->AddWaypoint(3, -1831.539185, 5365.472168, -12.428039); + kservantAI->AddWaypoint(4, -1813.416504, 5333.776855, -12.428039); + kservantAI->AddWaypoint(5, -1800.354370, 5313.290039, -12.428039); + kservantAI->AddWaypoint(6, -1775.624878, 5268.786133, -38.809181); + kservantAI->AddWaypoint(7, -1770.147339, 5259.268066, -38.829231); + kservantAI->AddWaypoint(8, -1762.814209, 5261.098145, -38.848995); + kservantAI->AddWaypoint(9, -1740.110474, 5268.858398, -40.208965); + kservantAI->AddWaypoint(10, -1725.837402, 5270.936035, -40.208965); + kservantAI->AddWaypoint(11, -1701.580322, 5290.323242, -40.209187); + kservantAI->AddWaypoint(12, -1682.877808, 5291.406738, -34.429646); + kservantAI->AddWaypoint(13, -1670.101685, 5291.201172, -32.786007); + kservantAI->AddWaypoint(14, -1656.666870, 5294.333496, -37.862648); + kservantAI->AddWaypoint(15, -1652.035767, 5295.413086, -40.245499); + kservantAI->AddWaypoint(16, -1620.860596, 5300.133301, -40.208992); + kservantAI->AddWaypoint(17, -1607.630981, 5293.983398, -38.577045, 5000); + kservantAI->AddWaypoint(18, -1607.630981, 5293.983398, -38.577045, 5000); + kservantAI->AddWaypoint(19, -1607.630981, 5293.983398, -38.577045, 5000); + kservantAI->AddWaypoint(20, -1622.140869, 5301.955566, -40.208897); + kservantAI->AddWaypoint(21, -1621.131836, 5333.112793, -40.208897); + kservantAI->AddWaypoint(22, -1637.598999, 5342.134277, -40.208790); + kservantAI->AddWaypoint(23, -1648.521606, 5352.309570, -47.496170); + kservantAI->AddWaypoint(24, -1654.606934, 5357.419434, -45.870892); + kservantAI->AddWaypoint(25, -1633.670044, 5422.067871, -42.835541); + kservantAI->AddWaypoint(25, -1656.567505, 5426.236328, -40.405815); + kservantAI->AddWaypoint(26, -1664.932373, 5425.686523, -38.846405); + kservantAI->AddWaypoint(27, -1681.406006, 5425.871094, -38.810928); + kservantAI->AddWaypoint(28, -1730.875977, 5427.413574, -12.427910); + kservantAI->AddWaypoint(29, -1743.509521, 5369.599121, -12.427910); + kservantAI->AddWaypoint(30, -1877.217041, 5303.710449, -12.427989); + kservantAI->AddWaypoint(31, -1890.371216, 5289.273438, -12.428268); + kservantAI->AddWaypoint(32, -1905.505737, 5266.534668, 2.630672); + kservantAI->AddWaypoint(33, -1909.381348, 5273.008301, 1.663714, 10000); + kservantAI->AddWaypoint(34, -1909.381348, 5273.008301, 1.663714, 12000); + kservantAI->AddWaypoint(35, -1909.381348, 5273.008301, 1.663714, 8000); + kservantAI->AddWaypoint(36, -1909.381348, 5273.008301, 1.663714, 15000); + kservantAI->AddWaypoint(37, -1927.561401, 5275.324707, 1.984987); + kservantAI->AddWaypoint(38, -1927.385498, 5300.879883, -12.427236); + kservantAI->AddWaypoint(39, -1921.063965, 5314.318359, -12.427236); + kservantAI->AddWaypoint(40, -1965.425415, 5379.298828, -12.427236); + kservantAI->AddWaypoint(41, -1981.233154, 5450.743652, -12.427236); + kservantAI->AddWaypoint(42, -1958.022461, 5455.904297, 0.487659); + kservantAI->AddWaypoint(43, -1951.991455, 5463.580566, 0.874490, 10000); + kservantAI->AddWaypoint(44, -1951.991455, 5463.580566, 0.874490, 12000); + kservantAI->AddWaypoint(45, -1968.730225, 5481.752930, -12.427846); + kservantAI->AddWaypoint(46, -1881.839844, 5554.040039, -12.427846); + kservantAI->AddWaypoint(47, -1841.566650, 5545.965332, -12.427846); + kservantAI->AddWaypoint(48, -1837.658325, 5523.780273, 0.558756); + kservantAI->AddWaypoint(49, -1831.321777, 5534.821777, 1.221819, 6000); + kservantAI->AddWaypoint(50, -1831.321777, 5534.821777, 1.221819, 8000); + kservantAI->AddWaypoint(51, -1831.321777, 5534.821777, 1.221819, 5000); + kservantAI->AddWaypoint(52, -1850.060669, 5472.610840, 0.857320, 6000); + kservantAI->AddWaypoint(53, -1850.060669, 5472.610840, 0.857320, 8000); + kservantAI->AddWaypoint(54, -1850.060669, 5472.610840, 0.857320, 9000); + kservantAI->AddWaypoint(55, -1850.060669, 5472.610840, 0.857320, 9000); + kservantAI->AddWaypoint(56, -1850.060669, 5472.610840, 0.857320, 4000); + + return (CreatureAI*)kservantAI; +} + +/*###### +# npc_dirty_larry +######*/ + +#define GOSSIP_BOOK "Ezekiel said that you might have a certain book..." + +#define SAY_1 -1000328 +#define SAY_2 -1000329 +#define SAY_3 -1000330 +#define SAY_4 -1000331 +#define SAY_5 -1000332 +#define SAY_GIVEUP -1000333 + +#define QUEST_WBI 10231 +#define NPC_CREEPJACK 19726 +#define NPC_MALONE 19725 + +struct TRINITY_DLL_DECL npc_dirty_larryAI : public ScriptedAI +{ + npc_dirty_larryAI(Creature* c) : ScriptedAI(c) {Reset();} + + bool Event; + bool Attack; + bool Done; + + uint64 PlayerGUID; + + uint32 SayTimer; + uint32 Step; + + void Reset() + { + Event = false; + Attack = false; + Done = false; + + PlayerGUID = 0; + SayTimer = 0; + Step = 0; + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->setFaction(1194); + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature); + if(Creepjack) + { + ((Creature*)Creepjack)->AI()->EnterEvadeMode(); + Creepjack->setFaction(1194); + Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature); + if(Malone) + { + ((Creature*)Malone)->AI()->EnterEvadeMode(); + Malone->setFaction(1194); + Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + } + + uint32 NextStep(uint32 Step) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + + switch(Step) + { + case 0:{ m_creature->SetInFront(player); + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature); + if(Creepjack) + Creepjack->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature); + if(Malone) + Malone->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }return 2000; + case 1: DoScriptText(SAY_1, m_creature, player); return 3000; + case 2: DoScriptText(SAY_2, m_creature, player); return 5000; + case 3: DoScriptText(SAY_3, m_creature, player); return 2000; + case 4: DoScriptText(SAY_4, m_creature, player); return 2000; + case 5: DoScriptText(SAY_5, m_creature, player); return 2000; + case 6: Attack = true; return 2000; + default: return 0; + } + } + + void Aggro(Unit* who){} + + void UpdateAI(const uint32 diff) + { + if(SayTimer < diff) + { + if(Event) + SayTimer = NextStep(++Step); + }else SayTimer -= diff; + + if(Attack) + { + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + m_creature->setFaction(14); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + if(player) + { + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature); + if(Creepjack) + { + Creepjack->Attack(player, true); + Creepjack->setFaction(14); + Creepjack->GetMotionMaster()->MoveChase(player); + Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature); + if(Malone) + { + Malone->Attack(player, true); + Malone->setFaction(14); + Malone->GetMotionMaster()->MoveChase(player); + Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + DoStartMovement(player); + AttackStart(player); + } + Attack = false; + } + + if((m_creature->GetHealth()*100)/m_creature->GetMaxHealth() < 1 && !Done) + { + Unit* Creepjack = FindCreature(NPC_CREEPJACK, 20, m_creature); + if(Creepjack) + { + ((Creature*)Creepjack)->AI()->EnterEvadeMode(); + Creepjack->setFaction(1194); + Creepjack->GetMotionMaster()->MoveTargetedHome(); + Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + Unit* Malone = FindCreature(NPC_MALONE, 20, m_creature); + if(Malone) + { + ((Creature*)Malone)->AI()->EnterEvadeMode(); + Malone->setFaction(1194); + Malone->GetMotionMaster()->MoveTargetedHome(); + Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->setFaction(1194); + Done = true; + DoScriptText(SAY_GIVEUP, m_creature, NULL); + m_creature->DeleteThreatList(); + m_creature->CombatStop(); + m_creature->GetMotionMaster()->MoveTargetedHome(); + Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); + if(player) + ((Player*)player)->GroupEventHappens(QUEST_WBI, m_creature); + } + DoMeleeAttackIfReady(); + } +}; + +bool GossipHello_npc_dirty_larry(Player *player, Creature *creature) +{ + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if(player->GetQuestStatus(QUEST_WBI) == QUEST_STATUS_INCOMPLETE) + player->ADD_GOSSIP_ITEM(0, GOSSIP_BOOK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(creature->GetNpcTextId(), creature->GetGUID()); + return true; +} + +bool GossipSelect_npc_dirty_larry(Player *player, Creature *creature, uint32 sender, uint32 action ) +{ + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + ((npc_dirty_larryAI*)creature->AI())->Event = true; + ((npc_dirty_larryAI*)creature->AI())->PlayerGUID = player->GetGUID(); + player->CLOSE_GOSSIP_MENU(); + } + + return true; +} + +CreatureAI* GetAI_npc_dirty_larryAI(Creature *_Creature) +{ + return new npc_dirty_larryAI (_Creature); +} + +/*###### +# npc_ishanah +######*/ + +#define ISANAH_GOSSIP_1 "Who are the Sha'tar?" +#define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?" + +bool GossipHello_npc_ishanah(Player *player, Creature *_Creature) +{ + if (_Creature->isQuestGiver()) + player->PrepareQuestMenu(_Creature->GetGUID()); + + player->ADD_GOSSIP_ITEM(0, ISANAH_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->ADD_GOSSIP_ITEM(0, ISANAH_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + + player->SEND_GOSSIP_MENU(_Creature->GetNpcTextId(), _Creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_ishanah(Player *player, Creature *_Creature, uint32 sender, uint32 action) +{ + if(action == GOSSIP_ACTION_INFO_DEF+1) + player->SEND_GOSSIP_MENU(9458, _Creature->GetGUID()); + else if(action == GOSSIP_ACTION_INFO_DEF+2) + player->SEND_GOSSIP_MENU(9459, _Creature->GetGUID()); + + return true; +} + +/*###### +# npc_khadgar +######*/ + +#define KHADGAR_GOSSIP_1 "I've heard your name spoken only in whispers, mage. Who are you?" +#define KHADGAR_GOSSIP_2 "Go on, please." +#define KHADGAR_GOSSIP_3 "I see." //6th too this +#define KHADGAR_GOSSIP_4 "What did you do then?" +#define KHADGAR_GOSSIP_5 "What happened next?" +#define KHADGAR_GOSSIP_7 "There was something else I wanted to ask you." + +bool GossipHello_npc_khadgar(Player *player, Creature *creature) +{ + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if(!player->hasQuest(10211)) + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + + player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); + + return true; +} + +bool GossipSelect_npc_khadgar(Player *player, Creature *creature, uint32 sender, uint32 action) +{ + switch(action) + { + case GOSSIP_ACTION_INFO_DEF+1: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2); + player->SEND_GOSSIP_MENU(9876, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+2: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3); + player->SEND_GOSSIP_MENU(9877, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+3: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4); + player->SEND_GOSSIP_MENU(9878, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+4: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5); + player->SEND_GOSSIP_MENU(9879, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+5: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6); + player->SEND_GOSSIP_MENU(9880, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+6: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7); + player->SEND_GOSSIP_MENU(9881, creature->GetGUID()); + break; + case GOSSIP_ACTION_INFO_DEF+7: + player->ADD_GOSSIP_ITEM(0, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(9243, creature->GetGUID()); + break; + } + return true; +} + +void AddSC_shattrath_city() +{ + Script *newscript; + + newscript = new Script; + newscript->Name="npc_raliq_the_drunk"; + newscript->pGossipHello = &GossipHello_npc_raliq_the_drunk; + newscript->pGossipSelect = &GossipSelect_npc_raliq_the_drunk; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_salsalabim"; + newscript->GetAI = &GetAI_npc_salsalabim; + newscript->pGossipHello = &GossipHello_npc_salsalabim; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_shattrathflaskvendors"; + newscript->pGossipHello = &GossipHello_npc_shattrathflaskvendors; + newscript->pGossipSelect = &GossipSelect_npc_shattrathflaskvendors; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_zephyr"; + newscript->pGossipHello = &GossipHello_npc_zephyr; + newscript->pGossipSelect = &GossipSelect_npc_zephyr; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_kservant"; + newscript->GetAI = &GetAI_npc_kservantAI; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_dirty_larry"; + newscript->GetAI = &GetAI_npc_dirty_larryAI; + newscript->pGossipHello = &GossipHello_npc_dirty_larry; + newscript->pGossipSelect = &GossipSelect_npc_dirty_larry; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_ishanah"; + newscript->pGossipHello = &GossipHello_npc_ishanah; + newscript->pGossipSelect = &GossipSelect_npc_ishanah; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="npc_khadgar"; + newscript->pGossipHello = &GossipHello_npc_khadgar; + newscript->pGossipSelect = &GossipSelect_npc_khadgar; + newscript->RegisterSelf(); +} + |