diff --git a/includes/components/SmartAI/SmartAI.class.php b/includes/components/SmartAI/SmartAI.class.php index a9307160..07f25a11 100644 --- a/includes/components/SmartAI/SmartAI.class.php +++ b/includes/components/SmartAI/SmartAI.class.php @@ -37,6 +37,12 @@ trait SmartHelper private function castFlags(int $flags) : string { + if ($x = ($flags & ~SmartAI::CAST_FLAG_VALIDATE)) + { + trigger_error('SmartAI::castFlags - unknown SmartCastFlags '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags &= SmartAI::CAST_FLAG_VALIDATE; + } + $cf = []; for ($i = 1; $i <= SmartAI::CAST_FLAG_COMBAT_MOVE; $i <<= 1) if (($flags & $i) && ($x = Lang::smartAI('castFlags', $i))) @@ -47,6 +53,12 @@ trait SmartHelper private function npcFlags(int $flags) : string { + if ($x = ($flags & ~NPC_FLAG_VALIDATE)) + { + trigger_error('SmartAI::npcFlags - unknown NpcFlags '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags &= NPC_FLAG_VALIDATE; + } + $nf = []; for ($i = 1; $i <= NPC_FLAG_MAILBOX; $i <<= 1) if (($flags & $i) && ($x = Lang::npc('npcFlags', $i))) @@ -57,6 +69,12 @@ trait SmartHelper private function dynFlags(int $flags) : string { + if ($x = ($flags & ~UNIT_DYNFLAG_VALIDATE)) + { + trigger_error('SmartAI::dynFlags - unknown unit dynFlags '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags &= UNIT_DYNFLAG_VALIDATE; + } + $df = []; for ($i = 1; $i <= UNIT_DYNFLAG_TAPPED_BY_ALL_THREAT_LIST; $i <<= 1) if (($flags & $i) && ($x = Lang::unit('dynFlags', $i))) @@ -67,6 +85,12 @@ trait SmartHelper private function goFlags(int $flags) : string { + if ($x = ($flags & ~GO_FLAG_VALIDATE)) + { + trigger_error('SmartAI::goFlags - unknown GameobjectFlags '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags &= GO_FLAG_VALIDATE; + } + $gf = []; for ($i = 1; $i <= GO_FLAG_DESTROYED; $i <<= 1) if (($flags & $i) && ($x = Lang::gameObject('goFlags', $i))) @@ -77,6 +101,12 @@ trait SmartHelper private function spawnFlags(int $flags) : string { + if ($x = ($flags & ~SmartAI::SPAWN_FLAG_VALIDATE)) + { + trigger_error('SmartAI::spawnFlags - unknown SmartSpawnFlags '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags &= SmartAI::SPAWN_FLAG_VALIDATE; + } + $sf = []; for ($i = 1; $i <= SmartAI::SPAWN_FLAG_NOSAVE_RESPAWN; $i <<= 1) if (($flags & $i) && ($x = Lang::smartAI('spawnFlags', $i))) @@ -87,6 +117,18 @@ trait SmartHelper private function unitFlags(int $flags, int $flags2) : string { + if ($x = ($flags & ~UNIT_FLAG_VALIDATE)) + { + trigger_error('SmartAI::unitFlags - unknown UnitFlags '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags &= UNIT_FLAG_VALIDATE; + } + + if ($x = ($flags2 & ~UNIT_FLAG2_VALIDATE)) + { + trigger_error('SmartAI::unitFlags - unknown UnitFlags2 '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags2 &= UNIT_FLAG2_VALIDATE; + } + $field = $flags2 ? 'flags2' : 'flags'; $max = $flags2 ? UNIT_FLAG2_ALLOW_CHEAT_SPELLS : UNIT_FLAG_UNK_31; $uf = []; @@ -181,6 +223,7 @@ class SmartAI // public const CAST_FORCE_TARGET_SELF = 0x10; // the target to cast this spell on itself public const CAST_FLAG_AURA_MISSING = 0x20; // Only casts the spell if the target does not have an aura from the spell public const CAST_FLAG_COMBAT_MOVE = 0x40; // Prevents combat movement if cast successful. Allows movement on range, OOM, LOS + public const CAST_FLAG_VALIDATE = self::CAST_FLAG_INTERRUPT_PREV | self::CAST_FLAG_TRIGGERED | self::CAST_FLAG_AURA_MISSING | self::CAST_FLAG_COMBAT_MOVE; public const REACT_PASSIVE = 0; public const REACT_DEFENSIVE = 1; @@ -207,6 +250,7 @@ class SmartAI public const SPAWN_FLAG_IGNORE_RESPAWN = 0x01; // onSpawnIn - ignore & reset respawn timer public const SPAWN_FLAG_FORCE_SPAWN = 0x02; // onSpawnIn - force additional spawn if already in world public const SPAWN_FLAG_NOSAVE_RESPAWN = 0x04; // onDespawn - remove respawn time + public const SPAWN_FLAG_VALIDATE = self::SPAWN_FLAG_IGNORE_RESPAWN | self::SPAWN_FLAG_FORCE_SPAWN | self::SPAWN_FLAG_NOSAVE_RESPAWN; private array $jsGlobals = []; private array $rawData = []; diff --git a/includes/components/SmartAI/SmartAction.class.php b/includes/components/SmartAI/SmartAction.class.php index c80c8b7f..924c8358 100644 --- a/includes/components/SmartAI/SmartAction.class.php +++ b/includes/components/SmartAI/SmartAction.class.php @@ -467,8 +467,8 @@ class SmartAction WHERE tp.`id` = ?d', Lang::getLocale()->value, Lang::getLocale()->value, Lang::getLocale()->value, Lang::getLocale()->value, $this->param[0] ); - $this->param[10] = Util::jsEscape(Util::localizedString($nodes, 'start')); - $this->param[11] = Util::jsEscape(Util::localizedString($nodes, 'end')); + $this->param[10] = Util::localizedString($nodes, 'start'); + $this->param[11] = Util::localizedString($nodes, 'end'); break; case self::ACTION_SET_INGAME_PHASE_MASK: // 44 -> any target if ($this->param[0]) diff --git a/includes/components/SmartAI/SmartEvent.class.php b/includes/components/SmartAI/SmartEvent.class.php index a9f1f3f8..726ac3a6 100644 --- a/includes/components/SmartAI/SmartEvent.class.php +++ b/includes/components/SmartAI/SmartEvent.class.php @@ -112,6 +112,7 @@ class SmartEvent public const FLAG_NO_RESET = 0x0100; public const FLAG_WHILE_CHARMED = 0x0200; public const FLAG_ALL_DIFFICULTIES = self::FLAG_DIFFICULTY_0 | self::FLAG_DIFFICULTY_1 | self::FLAG_DIFFICULTY_2 | self::FLAG_DIFFICULTY_3; + public const FLAG_VALIDATE = self::FLAG_NO_REPEAT | self::FLAG_DEBUG_ONLY | self::FLAG_NO_RESET | self::FLAG_WHILE_CHARMED | self::FLAG_ALL_DIFFICULTIES; private const EVENT_CELL_TPL = '[tooltip name=e-#rowIdx#]%1$s[/tooltip][span tooltip=e-#rowIdx#]%2$s[/span]'; @@ -304,7 +305,7 @@ class SmartEvent ); if ($gmo) - $this->param[10] = Util::jsEscape(Util::localizedString($gmo, 'text')); + $this->param[10] = Util::localizedString($gmo, 'text'); else trigger_error('SmartAI::event - could not find gossip menu option for event #'.$this->type); break; @@ -374,6 +375,12 @@ class SmartEvent { $flags = $this->flags; + if ($x = ($flags & ~self::FLAG_VALIDATE)) + { + trigger_error('SmartEvent::formatFlags - unused SmartEventFlags '.Util::asBin($x).' set on id #'.$this->id, E_USER_NOTICE); + $flags &= self::FLAG_VALIDATE; + } + if (($flags & self::FLAG_ALL_DIFFICULTIES) == self::FLAG_ALL_DIFFICULTIES) $flags &= ~self::FLAG_ALL_DIFFICULTIES; diff --git a/includes/defines.php b/includes/defines.php index 03cf0fce..b6eda11c 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -681,6 +681,7 @@ define('NPC_FLAG_STABLE_MASTER', 0x00400000); define('NPC_FLAG_GUILD_BANK', 0x00800000); define('NPC_FLAG_SPELLCLICK', 0x01000000); define('NPC_FLAG_MAILBOX', 0x04000000); +define('NPC_FLAG_VALIDATE', 0x05FFFFF3); define('CREATURE_FLAG_EXTRA_INSTANCE_BIND', 0x00000001); // creature kill binds instance to killer and killer's group define('CREATURE_FLAG_EXTRA_CIVILIAN', 0x00000002); // creature does not aggro (ignore faction/reputation hostility) @@ -740,6 +741,7 @@ define('UNIT_FLAG_UNK_28', 0x10000000); // (PreventKneelingW define('UNIT_FLAG_UNK_29', 0x20000000); // Used in Feign Death spell or NPC will play dead. (PreventEmotes) define('UNIT_FLAG_SHEATHE', 0x40000000); // define('UNIT_FLAG_UNK_31', 0x80000000); // +define('UNIT_FLAG_VALIDATE', 0x7FFFFFFF); // define('UNIT_FLAG2_FEIGN_DEATH', 0x00000001); // define('UNIT_FLAG2_UNK1', 0x00000002); // Hide unit model (show only player equip) @@ -759,6 +761,7 @@ define('UNIT_FLAG2_DISABLE_TURN', 0x00008000); // define('UNIT_FLAG2_UNK2', 0x00010000); // define('UNIT_FLAG2_PLAY_DEATH_ANIM', 0x00020000); // Plays special death animation upon death define('UNIT_FLAG2_ALLOW_CHEAT_SPELLS', 0x00040000); // allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL +define('UNIT_FLAG2_VALIDATE', 0x0006FDFF); // // UNIT_FIELD_BYTES_1 - idx 0 (UnitStandStateType) define('UNIT_STAND_STATE_STAND', 0); @@ -794,6 +797,7 @@ define('UNIT_DYNFLAG_SPECIALINFO', 0x10); // define('UNIT_DYNFLAG_DEAD', 0x20); // Makes the creature appear dead (this DOES NOT make the creature's name grey or not attack players). define('UNIT_DYNFLAG_REFER_A_FRIEND', 0x40); // define('UNIT_DYNFLAG_TAPPED_BY_ALL_THREAT_LIST', 0x80); // Lua_UnitIsTappedByAllThreatList +define('UNIT_DYNFLAG_VALIDATE', 0xFF); // define('PET_TALENT_TYPE_FEROCITY', 0); define('PET_TALENT_TYPE_TENACITY', 1); @@ -863,9 +867,11 @@ define('GO_FLAG_INTERACT_COND', 0x0004); // Untargetable, can define('GO_FLAG_TRANSPORT', 0x0008); // Gameobject can transport (boat, elevator, car) define('GO_FLAG_NOT_SELECTABLE', 0x0010); // Not selectable (Not even in GM-mode) define('GO_FLAG_NODESPAWN', 0x0020); // Never despawns. Typical for gameobjects with on/off state (doors for example) -define('GO_FLAG_TRIGGERED', 0x0040); // typically, summoned objects. Triggered by spell or other events +define('GO_FLAG_AI_OBSTACLE', 0x0040); // makes the client register the object in something called AIObstacleMgr, unknown what it does +define('GO_FLAG_FREEZE_ANIMATION',0x0080); // define('GO_FLAG_DAMAGED', 0x0200); // Gameobject has been siege damaged define('GO_FLAG_DESTROYED', 0x0400); // Gameobject has been destroyed +define('GO_FLAG_VALIDATE', 0x06FF); // define('GO_STATE_ACTIVE', 0); // show in world as used and not reset (closed door open) define('GO_STATE_READY', 1); // show in world as ready (closed door close) diff --git a/localization/locale_dede.php b/localization/locale_dede.php index 2cc5dcb6..d55c252a 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -1139,14 +1139,15 @@ $lang = array( 'foundIn' => "Dieses Objekt befindet sich in", 'restock' => "Wird alle %s wieder aufgefüllt.", 'goFlags' => array( - GO_FLAG_IN_USE => 'In Benutzung', - GO_FLAG_LOCKED => 'Verschlossen', - GO_FLAG_INTERACT_COND => 'Nicht interagierbar', - GO_FLAG_TRANSPORT => 'Transporter', - GO_FLAG_NOT_SELECTABLE => 'Nicht anwählbar', - GO_FLAG_TRIGGERED => 'Ausgelöst', - GO_FLAG_DAMAGED => 'Belagerung beschädigt', - GO_FLAG_DESTROYED => 'Belagerung zerstört' + GO_FLAG_IN_USE => 'In Benutzung', + GO_FLAG_LOCKED => 'Verschlossen', + GO_FLAG_INTERACT_COND => 'Nicht interagierbar', + GO_FLAG_TRANSPORT => 'Transporter', + GO_FLAG_NOT_SELECTABLE => 'Nicht anwählbar', + GO_FLAG_AI_OBSTACLE => 'Ausgelöst', + GO_FLAG_FREEZE_ANIMATION => 'Pausiert Animation', + GO_FLAG_DAMAGED => 'Belagerung beschädigt', + GO_FLAG_DESTROYED => 'Belagerung zerstört' ), 'actions' => array( "None", "Animate Custom 0", "Animate Custom 1", "Animate Custom 2", "Animate Custom 3", diff --git a/localization/locale_enus.php b/localization/locale_enus.php index e15fae40..d306d84a 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -1139,14 +1139,15 @@ $lang = array( 'foundIn' => "This object can be found in", 'restock' => "Restocks every %s.", 'goFlags' => array( - GO_FLAG_IN_USE => 'In use', - GO_FLAG_LOCKED => 'Locked', - GO_FLAG_INTERACT_COND => 'Cannot interact', - GO_FLAG_TRANSPORT => 'Transport', - GO_FLAG_NOT_SELECTABLE => 'Not selectable', - GO_FLAG_TRIGGERED => 'Triggered', - GO_FLAG_DAMAGED => 'Siege damaged', - GO_FLAG_DESTROYED => 'Siege destroyed' + GO_FLAG_IN_USE => 'In use', + GO_FLAG_LOCKED => 'Locked', + GO_FLAG_INTERACT_COND => 'Cannot interact', + GO_FLAG_TRANSPORT => 'Transport', + GO_FLAG_NOT_SELECTABLE => 'Not selectable', + GO_FLAG_AI_OBSTACLE => 'Triggered', + GO_FLAG_FREEZE_ANIMATION => 'Freeze Animation', + GO_FLAG_DAMAGED => 'Siege damaged', + GO_FLAG_DESTROYED => 'Siege destroyed' ), 'actions' => array( "None", "Animate Custom 0", "Animate Custom 1", "Animate Custom 2", "Animate Custom 3", diff --git a/localization/locale_eses.php b/localization/locale_eses.php index a8b20675..e78c918e 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -1139,14 +1139,15 @@ $lang = array( 'foundIn' => "Esta entidad se puede encontrar en", 'restock' => "Se renueva cada %s.", 'goFlags' => array( - GO_FLAG_IN_USE => 'En uso', - GO_FLAG_LOCKED => 'Bloqueado', - GO_FLAG_INTERACT_COND => 'No se puede interactuar', - GO_FLAG_TRANSPORT => 'Transporte', - GO_FLAG_NOT_SELECTABLE => 'No seleccionable', - GO_FLAG_TRIGGERED => 'Activado', - GO_FLAG_DAMAGED => 'Dañado por asedio', - GO_FLAG_DESTROYED => 'Destruido por asedio' + GO_FLAG_IN_USE => 'En uso', + GO_FLAG_LOCKED => 'Bloqueado', + GO_FLAG_INTERACT_COND => 'No se puede interactuar', + GO_FLAG_TRANSPORT => 'Transporte', + GO_FLAG_NOT_SELECTABLE => 'No seleccionable', + GO_FLAG_AI_OBSTACLE => 'Activado', + GO_FLAG_FREEZE_ANIMATION => 'Congelar animación', + GO_FLAG_DAMAGED => 'Dañado por asedio', + GO_FLAG_DESTROYED => 'Destruido por asedio' ), 'actions' => array( "Ninguno", "Animar personalizado 0", "Animar personalizado 1", "Animar personalizado 2", "Animar personalizado 3", diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index 26b363f9..52b16a3b 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -1139,14 +1139,15 @@ $lang = array( 'foundIn' => "Cette entité se trouve dans", 'restock' => "Se remplit toutes les %s.", 'goFlags' => array( - GO_FLAG_IN_USE => 'In use', - GO_FLAG_LOCKED => 'Locked', - GO_FLAG_INTERACT_COND => 'Cannot interact', - GO_FLAG_TRANSPORT => 'Transport', - GO_FLAG_NOT_SELECTABLE => 'Not selectable', - GO_FLAG_TRIGGERED => 'Triggered', - GO_FLAG_DAMAGED => 'Siege damaged', - GO_FLAG_DESTROYED => 'Siege destroyed' + GO_FLAG_IN_USE => 'In use', + GO_FLAG_LOCKED => 'Locked', + GO_FLAG_INTERACT_COND => 'Cannot interact', + GO_FLAG_TRANSPORT => 'Transport', + GO_FLAG_NOT_SELECTABLE => 'Not selectable', + GO_FLAG_AI_OBSTACLE => 'Triggered', + GO_FLAG_FREEZE_ANIMATION => 'Freeze Animation', + GO_FLAG_DAMAGED => 'Siege damaged', + GO_FLAG_DESTROYED => 'Siege destroyed' ), 'actions' => array( "None", "Animate Custom 0", "Animate Custom 1", "Animate Custom 2", "Animate Custom 3", diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index c9bf049f..51b53869 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -1139,14 +1139,15 @@ $lang = array( 'foundIn' => "Этот НИП может быть найден в следующих зонах:", 'restock' => "[Restocks every %s.]", 'goFlags' => array( - GO_FLAG_IN_USE => 'In use', - GO_FLAG_LOCKED => 'Locked', - GO_FLAG_INTERACT_COND => 'Cannot interact', - GO_FLAG_TRANSPORT => 'Transport', - GO_FLAG_NOT_SELECTABLE => 'Not selectable', - GO_FLAG_TRIGGERED => 'Triggered', - GO_FLAG_DAMAGED => 'Siege damaged', - GO_FLAG_DESTROYED => 'Siege destroyed' + GO_FLAG_IN_USE => 'In use', + GO_FLAG_LOCKED => 'Locked', + GO_FLAG_INTERACT_COND => 'Cannot interact', + GO_FLAG_TRANSPORT => 'Transport', + GO_FLAG_NOT_SELECTABLE => 'Not selectable', + GO_FLAG_AI_OBSTACLE => 'Triggered', + GO_FLAG_FREEZE_ANIMATION => 'Freeze Animation', + GO_FLAG_DAMAGED => 'Siege damaged', + GO_FLAG_DESTROYED => 'Siege destroyed' ), 'actions' => array( "None", "Animate Custom 0", "Animate Custom 1", "Animate Custom 2", "Animate Custom 3", diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php index 43b73336..e3eb62f3 100644 --- a/localization/locale_zhcn.php +++ b/localization/locale_zhcn.php @@ -1139,14 +1139,15 @@ $lang = array( 'foundIn' => "这个游戏对象可以在以下地区找到:", 'restock' => "每%s重新补给一次。", 'goFlags' => array( - GO_FLAG_IN_USE => '正在使用', - GO_FLAG_LOCKED => '已锁定', - GO_FLAG_INTERACT_COND => '无法交互', - GO_FLAG_TRANSPORT => '传送', - GO_FLAG_NOT_SELECTABLE => '不可选择', - GO_FLAG_TRIGGERED => '已触发', - GO_FLAG_DAMAGED => 'Siege damaged', - GO_FLAG_DESTROYED => 'Siege destroyed' + GO_FLAG_IN_USE => '正在使用', + GO_FLAG_LOCKED => '已锁定', + GO_FLAG_INTERACT_COND => '无法交互', + GO_FLAG_TRANSPORT => '传送', + GO_FLAG_NOT_SELECTABLE => '不可选择', + GO_FLAG_AI_OBSTACLE => '已触发', + GO_FLAG_FREEZE_ANIMATION => 'Freeze Animation', + GO_FLAG_DAMAGED => 'Siege damaged', + GO_FLAG_DESTROYED => 'Siege destroyed' ), 'actions' => array( "None", "Animate Custom 0", "Animate Custom 1", "Animate Custom 2", "Animate Custom 3",