diff --git a/desktop_version/src/CustomLevels.cpp b/desktop_version/src/CustomLevels.cpp
index 2a7494cf..3c5fdab2 100644
--- a/desktop_version/src/CustomLevels.cpp
+++ b/desktop_version/src/CustomLevels.cpp
@@ -1214,6 +1214,15 @@ bool customlevelclass::load(std::string _path)
                 edEntityEl->QueryIntAttribute("p5", &entity.p5);
                 edEntityEl->QueryIntAttribute("p6", &entity.p6);
 
+                const char* activitytext = "";
+                const char* activitycolour = "";
+
+                edEntityEl->QueryStringAttribute("activitytext", &activitytext);
+                edEntityEl->QueryStringAttribute("activitycolour", &activitycolour);
+
+                entity.activitytext = activitytext;
+                entity.activitycolour = activitycolour;
+
                 customentities.push_back(entity);
             }
         }
@@ -1568,7 +1577,16 @@ bool customlevelclass::save(const std::string& _path)
         edentityElement->SetAttribute(  "p3", customentities[i].p3);
         edentityElement->SetAttribute( "p4", customentities[i].p4);
         edentityElement->SetAttribute( "p5", customentities[i].p5);
-        edentityElement->SetAttribute(  "p6", customentities[i].p6);
+        edentityElement->SetAttribute( "p6", customentities[i].p6);
+        if (!customentities[i].activitytext.empty())
+        {
+            edentityElement->SetAttribute("activitytext", customentities[i].activitytext.c_str());
+        }
+        if (!customentities[i].activitycolour.empty())
+        {
+            edentityElement->SetAttribute("activitycolour", customentities[i].activitycolour.c_str());
+        }
+
         edentityElement->LinkEndChild( doc.NewText( customentities[i].scriptname.c_str() )) ;
         msg->LinkEndChild( edentityElement );
     }
diff --git a/desktop_version/src/CustomLevels.h b/desktop_version/src/CustomLevels.h
index 97e3448d..79000821 100644
--- a/desktop_version/src/CustomLevels.h
+++ b/desktop_version/src/CustomLevels.h
@@ -13,6 +13,8 @@ public:
     //parameters
     int p1, p2, p3, p4, p5, p6;
     std::string scriptname;
+    std::string activitycolour;
+    std::string activitytext;
 };
 
 
diff --git a/desktop_version/src/Editor.cpp b/desktop_version/src/Editor.cpp
index a9d8cdc1..db8858d1 100644
--- a/desktop_version/src/Editor.cpp
+++ b/desktop_version/src/Editor.cpp
@@ -1112,6 +1112,67 @@ static void draw_entities(void)
                     font::print(PR_FONT_LEVEL | PR_BOR | PR_CJK_HIGH, x, y - 8, entity->scriptname, 210, 210, 255);
                 }
                 break;
+            case 20: // Activity Zones
+                graphics.draw_rect(x, y, entity->p1 * 8, entity->p2 * 8, graphics.getRGB(164, 255, 255));
+                graphics.draw_rect(x, y, 8, 8, graphics.getRGB(255, 255, 255));
+                if (i == edent_under_cursor)
+                {
+                    font::print(PR_FONT_LEVEL | PR_BOR | PR_CJK_HIGH, x, y - 8, entity->scriptname, 210, 210, 255);
+                }
+                break;
+            case 21: // Collision Boxes
+                graphics.draw_rect(x, y, entity->p1 * 8, entity->p2 * 8, graphics.getRGB(164, 255, 164));
+                graphics.draw_rect(x, y, 8, 8, graphics.getRGB(255, 255, 255));
+                break;
+            case 22: // Damage Boxes
+                graphics.draw_rect(x, y, entity->p1 * 8, entity->p2 * 8, graphics.getRGB(255, 164, 164));
+                graphics.draw_rect(x, y, 8, 8, graphics.getRGB(255, 255, 255));
+                break;
+            case 23: // Directional Boxes
+            {
+                // Move x and y to the center of the box
+                int arrow_x = x + (entity->p1 - 1) * 4;
+                int arrow_y = y + (entity->p2 - 1) * 4;
+
+                if (customentities[i].p3 == 0)
+                {
+                    // UP ARROW
+                    font::print(PR_FONT_LEVEL | PR_BOR | PR_CJK_HIGH, arrow_x, arrow_y, "\xE2\x86\x91", 255, 255, 255);
+                }
+                else if (customentities[i].p3 == 1)
+                {
+                    // DOWN ARROW
+                    font::print(PR_FONT_LEVEL | PR_BOR | PR_CJK_HIGH, arrow_x, arrow_y, "\xE2\x86\x93", 255, 255, 255);
+                }
+                else if (customentities[i].p3 == 2)
+                {
+                    // LEFT ARROW
+                    font::print(PR_FONT_LEVEL | PR_BOR | PR_CJK_HIGH, arrow_x, arrow_y, "\xE2\x86\x90", 255, 255, 255);
+                }
+                else if (customentities[i].p3 == 3)
+                {
+                    // RIGHT ARROW
+                    font::print(PR_FONT_LEVEL | PR_BOR | PR_CJK_HIGH, arrow_x, arrow_y, "\xE2\x86\x92", 255, 255, 255);
+                }
+                graphics.draw_rect(x, y, entity->p1 * 8, entity->p2 * 8, graphics.getRGB(255, 255, 164));
+                break;
+            }
+            case 24: // Safe Boxes
+                graphics.draw_rect(x, y, entity->p1 * 8, entity->p2 * 8, graphics.getRGB(164, 164, 255));
+                graphics.draw_rect(x, y, 8, 8, graphics.getRGB(255, 255, 255));
+                break;
+            case 25: // Gamestate Triggers
+            {
+                graphics.draw_rect(x, y, entity->p1 * 8, entity->p2 * 8, graphics.getRGB(255, 164, 255));
+                graphics.draw_rect(x, y, 8, 8, graphics.getRGB(255, 255, 255));
+
+                int arrow_x = x + (entity->p1 - 1) * 4;
+                int arrow_y = y + (entity->p2 - 1) * 4;
+
+                font::print(PR_FONT_LEVEL | PR_BOR | PR_CJK_HIGH, arrow_x, arrow_y, help.String(entity->p3), 255, 255, 255);
+
+                break;
+            }
             case 50: // Warp Lines
                 if (entity->p1 >= 2) // Horizontal
                 {
diff --git a/desktop_version/src/Entity.cpp b/desktop_version/src/Entity.cpp
index 210145a8..f6bcca1e 100644
--- a/desktop_version/src/Entity.cpp
+++ b/desktop_version/src/Entity.cpp
@@ -851,6 +851,7 @@ void entityclass::createblock( int t, int xp, int yp, int w, int h, int trig /*=
         block.type = ACTIVITY;
         block.wp = w;
         block.hp = h;
+        block.script = script;
         block.rectset(xp, yp, w, h);
 
         //Ok, each and every activity zone in the game is initilised here. "Trig" in this case is a variable that
diff --git a/desktop_version/src/Map.cpp b/desktop_version/src/Map.cpp
index 747ebc38..98760941 100644
--- a/desktop_version/src/Map.cpp
+++ b/desktop_version/src/Map.cpp
@@ -1937,6 +1937,27 @@ void mapclass::loadlevel(int rx, int ry)
                 obj.createblock(TRIGGER, ex, ey, ent.p1 * 8, ent.p2 * 8, 300 + tempscriptbox, "custom_" + ent.scriptname);
                 tempscriptbox++;
                 break;
+            case 20: // Activity Zone
+                obj.customactivitytext = ent.activitytext;
+                obj.customactivitycolour = ent.activitycolour;
+                obj.customscript = ent.scriptname;
+                obj.createblock(ACTIVITY, ex, ey, ent.p1 * 8, ent.p2 * 8, 35, "custom_" + ent.scriptname, true);
+                break;
+            case 21: // Collision Box
+                obj.createblock(BLOCK, ex, ey, ent.p1 * 8, ent.p2 * 8);
+                break;
+            case 22: // Damage Box
+                obj.createblock(DAMAGE, ex, ey, ent.p1 * 8, ent.p2 * 8);
+                break;
+            case 23: // Directional Box
+                obj.createblock(DIRECTIONAL, ex, ey, ent.p1 * 8, ent.p2 * 8, ent.p3);
+                break;
+            case 24: // Safe Box
+                obj.createblock(SAFE, ex, ey, ent.p1 * 8, ent.p2 * 8);
+                break;
+            case 25: // Trigger
+                obj.createblock(TRIGGER, ex, ey, ent.p1 * 8, ent.p2 * 8, ent.p3);
+                break;
             case 50: // Warp Lines
                 obj.customwarpmode=true;
                 switch (ent.p1)
diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp
index a58b1735..455da0b6 100644
--- a/desktop_version/src/Script.cpp
+++ b/desktop_version/src/Script.cpp
@@ -899,6 +899,40 @@ void scriptclass::run(void)
                 words[8] = word8;
                 words[9] = word9;
             }
+            else if (words[0] == "createblock")
+            {
+                int i = BLOCK;
+                if (words[1] == "block")
+                {
+                    i = BLOCK;
+                }
+                else if (words[1] == "trigger" || words[1] == "script")
+                {
+                    i = TRIGGER;
+                }
+                else if (words[1] == "damage")
+                {
+                    i = DAMAGE;
+                }
+                else if (words[1] == "directional")
+                {
+                    i = DIRECTIONAL;
+                }
+                else if (words[1] == "safe")
+                {
+                    i = SAFE;
+                }
+                else if (words[1] == "activity")
+                {
+                    i = ACTIVITY;
+                }
+                else
+                {
+                    i = ss_toi(words[1]);
+                }
+
+                obj.createblock(i, ss_toi(words[2]), ss_toi(words[3]), ss_toi(words[4]), ss_toi(words[5]), ss_toi(words[6]), words[7], true);
+            }
             else if (words[0] == "createcrewman")
             {
                 // Note: Do not change the "r" variable, it's used in custom levels