diff --git a/Phobos.vcxproj b/Phobos.vcxproj
index f4a9c2c97e..37e8f261b2 100644
--- a/Phobos.vcxproj
+++ b/Phobos.vcxproj
@@ -39,8 +39,10 @@
+
+
@@ -139,6 +141,7 @@
+
diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md
index 1cc3c017f7..b61032ccdb 100644
--- a/docs/Fixed-or-Improved-Logics.md
+++ b/docs/Fixed-or-Improved-Logics.md
@@ -400,6 +400,10 @@ In `rulesmd.ini`:
MinimapColor= ; integer - Red,Green,Blue
```
+## Trigger
+
+- In a multiplayer map, set trigger owner as '4475'-'4482' is player@A-player@G, if nonexist, trigger will be desotroyed.
+
## Vehicles
### IsSimpleDeployer vehicle deploy animation / direction customization
diff --git a/src/Misc/Hooks.Trigger.cpp b/src/Misc/Hooks.Trigger.cpp
new file mode 100644
index 0000000000..cafa9f8dd0
--- /dev/null
+++ b/src/Misc/Hooks.Trigger.cpp
@@ -0,0 +1,84 @@
+#include
+#include
+#include
+
+#include
+
+#include
+
+DEFINE_HOOK(0x7272AE, TriggerTypeClass_LoadFromINI_House, 0x8)
+{
+ GET(TriggerTypeClass*, pThis, EBP);
+ GET(const char*, pID, ESI);
+
+ int idx = atoi(pID);
+
+ if (HouseClass::PlayerAtA <= idx && idx <= HouseClass::PlayerAtH)
+ {
+ TriggerMPOwner::TriggerType_Owner[pThis->GetArrayIndex()] = idx;
+
+ R->EDX(HouseTypeClass::Find("special"));
+
+ return 0x7272C1;
+ }
+
+ R->EAX(HouseTypeClass::FindIndex(pID));
+
+ return 0x7272B5;
+}
+
+DEFINE_HOOK(0x72612C, TriggerClass_CTOR_DestoryIfMultiplayerNonexist, 0x8)
+{
+ GET(TriggerClass*, pThis, ESI);
+
+ if (pThis->Type == nullptr)
+ return 0;
+
+ int idx = pThis->Type->GetArrayIndex();
+ const auto& houseIdxMapper = TriggerMPOwner::TriggerType_Owner;
+
+ if (houseIdxMapper.count(idx))
+ {
+ HouseClass* pHouse = HouseClass::FindByIndex(houseIdxMapper.at(idx));
+
+ if (pHouse == nullptr)
+ pThis->Destroyed = true;
+ }
+
+ return 0;
+}
+
+
+DEFINE_HOOK(0x726538, TriggerClass_RaiseEvent_ReplaceHouse, 0x5)
+{
+ GET(TriggerClass*, pThis, ESI);
+
+ int idx = pThis->Type->GetArrayIndex();
+ const auto& houseIdxMapper = TriggerMPOwner::TriggerType_Owner;
+
+ if (houseIdxMapper.count(idx))
+ {
+ HouseClass* pHouse = HouseClass::FindByIndex(houseIdxMapper.at(idx));
+ R->EAX(pHouse == nullptr ? HouseClass::FindSpecial() : pHouse);
+ }
+
+ return 0;
+}
+
+DEFINE_HOOK(0x7265F7, TriggerClass_FireActions_ReplaceHouse, 0x6)
+{
+ GET(TriggerClass*, pThis, EDI);
+
+ int idx = pThis->Type->GetArrayIndex();
+ const auto& houseIdxMapper = TriggerMPOwner::TriggerType_Owner;
+
+ if (houseIdxMapper.count(idx))
+ {
+ HouseClass* pHouse = HouseClass::FindByIndex(houseIdxMapper.at(idx));
+ R->EAX(pHouse == nullptr ? HouseClass::FindSpecial() : pHouse);
+
+ return 0x726602;
+ }
+
+ return 0;
+}
diff --git a/src/Misc/TriggerMPOwner.cpp b/src/Misc/TriggerMPOwner.cpp
new file mode 100644
index 0000000000..2f49b1c4c2
--- /dev/null
+++ b/src/Misc/TriggerMPOwner.cpp
@@ -0,0 +1,19 @@
+#include "TriggerMPOwner.h"
+
+#include
+
+std::map TriggerMPOwner::TriggerType_Owner;
+
+bool TriggerMPOwner::LoadGlobals(PhobosStreamReader& stm)
+{
+ return stm
+ .Process(TriggerType_Owner)
+ .Success();
+}
+
+bool TriggerMPOwner::SaveGlobals(PhobosStreamWriter& stm)
+{
+ return stm
+ .Process(TriggerType_Owner)
+ .Success();
+}
diff --git a/src/Misc/TriggerMPOwner.h b/src/Misc/TriggerMPOwner.h
new file mode 100644
index 0000000000..387d1b7c97
--- /dev/null
+++ b/src/Misc/TriggerMPOwner.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include