diff --git a/src/Commands/Data/Disasters/DisasterCreateCommand.cs b/src/Commands/Data/Disasters/DisasterCreateCommand.cs
new file mode 100644
index 00000000..2cfc7726
--- /dev/null
+++ b/src/Commands/Data/Disasters/DisasterCreateCommand.cs
@@ -0,0 +1,22 @@
+using ProtoBuf;
+
+namespace CSM.Commands.Data.Disasters
+{
+ ///
+ /// Sent when a natural disaster is started
+ ///
+ /// Sent by:
+ /// - DisasterHelper
+ [ProtoContract]
+ public class DisasterStartCommand : CommandBase
+ {
+ [ProtoMember(1)]
+ public ushort Id { get; set; }
+
+ ///
+ /// The client id of the disconnected user (to clear caches).
+ ///
+ [ProtoMember(2)]
+ public int ClientId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Commands/Data/Disasters/DisasterStartCommand.cs b/src/Commands/Data/Disasters/DisasterStartCommand.cs
new file mode 100644
index 00000000..500f19be
--- /dev/null
+++ b/src/Commands/Data/Disasters/DisasterStartCommand.cs
@@ -0,0 +1,44 @@
+using ProtoBuf;
+using ICities;
+
+namespace CSM.Commands.Data.Disasters
+{
+ ///
+ /// Sent when a natural disaster is created
+ ///
+ /// Sent by:
+ /// - DisasterExtension
+ [ProtoContract]
+ public class DisasterCreateCommand : CommandBase
+ {
+ [ProtoMember(1)]
+ public ushort Id { get; set; }
+
+ [ProtoMember(2)]
+ public DisasterType Type { get; set; }
+
+ [ProtoMember(3)]
+ public string Name { get; set; }
+
+ [ProtoMember(4)]
+ public float TargetX { get; set; }
+
+ [ProtoMember(5)]
+ public float TargetY { get; set; }
+
+ [ProtoMember(6)]
+ public float TargetZ { get; set; }
+
+ [ProtoMember(7)]
+ public float Angle { get; set; }
+
+ [ProtoMember(8)]
+ public byte Intensity { get; set; }
+
+ ///
+ /// The client id of the disconnected user (to clear caches).
+ ///
+ [ProtoMember(9)]
+ public int ClientId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Commands/Handler/Disasters/DisasterCreateHandler.cs b/src/Commands/Handler/Disasters/DisasterCreateHandler.cs
new file mode 100644
index 00000000..4531de70
--- /dev/null
+++ b/src/Commands/Handler/Disasters/DisasterCreateHandler.cs
@@ -0,0 +1,33 @@
+using CSM.Commands.Data.Disasters;
+using CSM.Helpers;
+using ICities;
+
+namespace CSM.Commands.Handler.Disasters
+{
+ public class DisasterCreateHandler : CommandHandler
+ {
+
+ public DisasterCreateHandler()
+ {
+ }
+
+ protected override void Handle(DisasterCreateCommand command)
+ {
+ IgnoreHelper.StartIgnore();
+ DisasterSettings settings = new DisasterSettings()
+ {
+ type = command.Type,
+ name = command.Name,
+ targetX = command.TargetX,
+ targetY = command.TargetY,
+ targetZ = command.TargetZ,
+ angle = command.Angle,
+ intensity = command.Intensity
+ };
+
+ ushort local = DisasterManager.instance.m_DisasterWrapper.CreateDisaster(settings);
+ DisasterHelper.receiveCreate(command.ClientId, command.Id, local);
+ IgnoreHelper.EndIgnore();
+ }
+ }
+}
diff --git a/src/Commands/Handler/Disasters/DisasterStartHandler.cs b/src/Commands/Handler/Disasters/DisasterStartHandler.cs
new file mode 100644
index 00000000..1d0cc789
--- /dev/null
+++ b/src/Commands/Handler/Disasters/DisasterStartHandler.cs
@@ -0,0 +1,22 @@
+using CSM.Commands.Data.Disasters;
+using CSM.Commands.Data.Game;
+using CSM.Helpers;
+
+namespace CSM.Commands.Handler.Disasters
+{
+ public class DisasterStartHandler : CommandHandler
+ {
+
+ public DisasterStartHandler()
+ {
+ }
+
+ protected override void Handle(DisasterStartCommand command)
+ {
+ IgnoreHelper.StartIgnore();
+ ushort local = DisasterHelper.getLocal(command.ClientId, command.Id);
+ DisasterManager.instance.m_DisasterWrapper.StartDisaster(local);
+ IgnoreHelper.EndIgnore();
+ }
+ }
+}
diff --git a/src/Extensions/DisastersExtension.cs b/src/Extensions/DisastersExtension.cs
new file mode 100644
index 00000000..a3d853a7
--- /dev/null
+++ b/src/Extensions/DisastersExtension.cs
@@ -0,0 +1,83 @@
+using CSM.Commands;
+using CSM.Injections;
+using CSM.Networking;
+using ICities;
+using System;
+using CSM.Helpers;
+using CSM.Commands.Data.Disasters;
+
+namespace CSM.Extensions
+{
+ public class DisastersExtension : IDisasterExtension
+ {
+ private IDisaster manager;
+
+ public void OnCreated(IDisaster disaster)
+ {
+ // Do nothing
+ this.manager = disaster;
+ }
+
+ public void OnReleased()
+ {
+ // Do nothing
+ }
+
+ public void OnDisasterCreated(ushort disasterID)
+ {
+ if (IgnoreHelper.IsIgnored())
+ return;
+
+ DisasterSettings settings = manager.GetDisasterSettings(disasterID);
+
+ Command.SendToAll(new DisasterCreateCommand
+ {
+ Id = disasterID,
+ Type = settings.type,
+ Name = settings.name,
+ TargetX = settings.targetX,
+ TargetY = settings.targetY,
+ TargetZ = settings.targetZ,
+ Angle = settings.angle,
+ Intensity = settings.intensity,
+ ClientId = MultiplayerManager.Instance.CurrentClient.ClientId
+ });
+ }
+
+ public void OnDisasterStarted(ushort disasterID)
+ {
+ if (IgnoreHelper.IsIgnored())
+ return;
+
+ Command.SendToAll(new DisasterStartCommand
+ {
+ Id = disasterID,
+ ClientId = MultiplayerManager.Instance.CurrentClient.ClientId
+ });
+ }
+
+ public void OnDisasterDetected(ushort disasterID)
+ {
+ if (IgnoreHelper.IsIgnored())
+ return;
+ }
+
+ public void OnDisasterActivated(ushort disasterID)
+ {
+ if (IgnoreHelper.IsIgnored())
+ return;
+ }
+
+ public void OnDisasterDeactivated(ushort disasterID)
+ {
+ if (IgnoreHelper.IsIgnored())
+ return;
+ }
+
+ public void OnDisasterFinished(ushort disasterID)
+ {
+ if (IgnoreHelper.IsIgnored())
+ return;
+ }
+ }
+}
diff --git a/src/Helpers/DisasterHelper.cs b/src/Helpers/DisasterHelper.cs
new file mode 100644
index 00000000..0eca3d9e
--- /dev/null
+++ b/src/Helpers/DisasterHelper.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+
+namespace CSM.Helpers
+{
+ public static class DisasterHelper
+ {
+
+ private static Dictionary disasterClientMap = new Dictionary();
+
+ public static void receiveCreate(int id, ushort server, ushort client)
+ {
+ if (!disasterClientMap.ContainsKey(id))
+ {
+ disasterClientMap.Add(id, new DisasterClient());
+ }
+
+ DisasterClient disaster = disasterClientMap[id];
+ disaster.add(server, client);
+ }
+
+ public static ushort getLocal(int client, ushort server)
+ {
+ DisasterClient disaster = disasterClientMap[client];
+ return disaster.convertServerToLocal(server);
+ }
+
+ public class DisasterClient
+ {
+ private IDictionary localToServerMap = new Dictionary();
+ private IDictionary serverToLocalMap = new Dictionary();
+
+ public ushort convertServerToLocal(ushort data)
+ {
+ return serverToLocalMap[data];
+ }
+
+ public ushort convertLocalToServer(ushort data)
+ {
+ return localToServerMap[data];
+ }
+
+ public void add(ushort server, ushort local)
+ {
+ localToServerMap.Add(local, server);
+ serverToLocalMap.Add(server, local);
+ }
+
+ public void removeLocal(ushort local)
+ {
+ ushort server = convertLocalToServer(local);
+ localToServerMap.Remove(local);
+ serverToLocalMap.Remove(server);
+ }
+
+ public void removeServer(ushort server)
+ {
+ ushort local = convertServerToLocal(server);
+ localToServerMap.Remove(local);
+ serverToLocalMap.Remove(server);
+ }
+ }
+ }
+}