From bb0bd5360464d84f1f42b7c5a2e74fd8b69f0c20 Mon Sep 17 00:00:00 2001 From: AllyTally Date: Mon, 21 Nov 2022 13:55:32 -0400 Subject: [PATCH] Add edentity blocks & createblock() This adds editor entity blocks (boxes which do different things on collision) like activity zones, hurt boxes, etc. This also adds a command to go along with it, to both match `createentity` and so block spawning can be behind conditions. --- desktop_version/src/CustomLevels.cpp | 20 ++++++++- desktop_version/src/CustomLevels.h | 2 + desktop_version/src/Editor.cpp | 61 ++++++++++++++++++++++++++++ desktop_version/src/Entity.cpp | 1 + desktop_version/src/Map.cpp | 21 ++++++++++ desktop_version/src/Script.cpp | 34 ++++++++++++++++ 6 files changed, 138 insertions(+), 1 deletion(-) 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