Skip to content

Commit fb7d28b

Browse files
committed
Teleporter edentities with custom curves
1 parent 456a81d commit fb7d28b

File tree

10 files changed

+398
-17
lines changed

10 files changed

+398
-17
lines changed

desktop_version/lang/en/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,7 @@
613613
<string english="O: Crewmate" translation="" explanation="***OUTDATED***"/>
614614
<string english="O: Crewmates" translation="" explanation="editor tool. Crewmate that can be rescued" max="32"/>
615615
<string english="P: Start Point" translation="" explanation="editor tool" max="32"/>
616+
<string english="^2: Teleporters" translation="" explanation="editor tool. Large round teleporter which can teleport the player to other teleporters" max="32"/>
616617
<string english="START" translation="" explanation="start point in level editor" max="10"/>
617618
<string english="SPACE ^ SHIFT ^" translation="" explanation="editor, indicates both SPACE key and SHIFT key open up menus. ^ is rendered as up arrow" max="32"/>
618619
<string english="F1: Change Tileset" translation="" explanation="editor shortcut, switch to different tileset" max="25"/>

desktop_version/src/Editor.cpp

Lines changed: 219 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#include "Vlogging.h"
2727

2828
#define SCRIPT_LINE_PADDING 6
29+
#define LERP(a, b, t) ((a) + (t) * ((b) - (a)))
30+
#define POINT_OFFSET 12
31+
#define POINT_SIZE 6
32+
#define TELEPORTER_ARC_SMOOTHNESS 255
2933

3034
editorclass::editorclass(void)
3135
{
@@ -48,6 +52,7 @@ editorclass::editorclass(void)
4852
register_tool(EditorTool_WARP_LINES, "Warp Lines", "I", SDLK_i, false);
4953
register_tool(EditorTool_CREWMATES, "Crewmates", "O", SDLK_o, false);
5054
register_tool(EditorTool_START_POINT, "Start Point", "P", SDLK_p, false);
55+
register_tool(EditorTool_TELEPORTERS, "Teleporters", "^2", SDLK_2, true);
5156

5257
static const short basic[] = {
5358
121, 121, 121, 121, 121, 121, 121, 160, 121, 121, 121, 121, 121, 121, 121,
@@ -365,11 +370,18 @@ void editorclass::reset(void)
365370
levy = 0;
366371
keydelay = 0;
367372
lclickdelay = 0;
373+
rclickdelay = 0;
368374
savekey = false;
369375
loadkey = false;
370376
updatetiles = true;
371377
changeroom = true;
372378

379+
dragging = false;
380+
dragging_entity = -1;
381+
dragging_point = 1;
382+
drag_offset_x = 0;
383+
drag_offset_y = 0;
384+
373385
entframe = 0;
374386
entframedelay = 0;
375387

@@ -990,6 +1002,73 @@ static void draw_entities(void)
9901002
font::print(PR_BOR | PR_CJK_HIGH, x, y - 8, text, 210, 210, 255);
9911003
break;
9921004
}
1005+
case 14: // Teleporters
1006+
{
1007+
graphics.drawtele(x, y, 1, graphics.getcol(100));
1008+
graphics.draw_rect(x, y, 8 * 12, 8 * 12, graphics.getRGB(164, 164, 255));
1009+
1010+
int sprite = 0;
1011+
if (customentities[i].p5 % 2 == 0)
1012+
{
1013+
sprite += 3;
1014+
}
1015+
1016+
if (customentities[i].p5 >= 2)
1017+
{
1018+
sprite += 6;
1019+
}
1020+
1021+
graphics.draw_sprite(customentities[i].p3, customentities[i].p4, sprite, graphics.crewcolourreal(0));
1022+
1023+
SDL_Point triangle[4] = {
1024+
{ x + 37 + POINT_OFFSET, y + 37 + POINT_OFFSET },
1025+
{ customentities[i].p1 + POINT_OFFSET, customentities[i].p2 + POINT_OFFSET },
1026+
{ customentities[i].p3 + POINT_OFFSET, customentities[i].p4 + POINT_OFFSET },
1027+
{ x + 37 + POINT_OFFSET, y + 37 + POINT_OFFSET}
1028+
};
1029+
1030+
SDL_SetRenderDrawColor(gameScreen.m_renderer, 164, 255, 255, 255);
1031+
SDL_RenderDrawLines(gameScreen.m_renderer, triangle, SDL_arraysize(triangle));
1032+
1033+
SDL_Point points[TELEPORTER_ARC_SMOOTHNESS + 1];
1034+
1035+
for (int j = 0; j <= TELEPORTER_ARC_SMOOTHNESS; j++)
1036+
{
1037+
float progress = (float)j / TELEPORTER_ARC_SMOOTHNESS;
1038+
float left_line_x = LERP(x + 37 + POINT_OFFSET, customentities[i].p1 + POINT_OFFSET, progress);
1039+
float left_line_y = LERP(y + 37 + POINT_OFFSET, customentities[i].p2 + POINT_OFFSET, progress);
1040+
float right_line_x = LERP(customentities[i].p1 + POINT_OFFSET, customentities[i].p3 + POINT_OFFSET, progress);
1041+
float right_line_y = LERP(customentities[i].p2 + POINT_OFFSET, customentities[i].p4 + POINT_OFFSET, progress);
1042+
1043+
SDL_Point coords;
1044+
coords.x = LERP(left_line_x, right_line_x, progress);
1045+
coords.y = LERP(left_line_y, right_line_y, progress);
1046+
1047+
points[j] = coords;
1048+
}
1049+
1050+
SDL_SetRenderDrawColor(gameScreen.m_renderer, 164, 255, 164, 255);
1051+
SDL_RenderDrawLines(gameScreen.m_renderer, points, SDL_arraysize(points));
1052+
1053+
int offset = POINT_OFFSET - (POINT_SIZE / 2);
1054+
1055+
SDL_Color point1 = graphics.getRGB(255, 255, 255);
1056+
SDL_Color point2 = graphics.getRGB(255, 255, 255);
1057+
1058+
if (ed.dragging_entity == i && ed.dragging_point == 1)
1059+
{
1060+
point1 = graphics.getRGB(164, 164, 255);
1061+
}
1062+
else if (ed.dragging_entity == i && ed.dragging_point == 2)
1063+
{
1064+
point2 = graphics.getRGB(164, 164, 255);
1065+
}
1066+
1067+
graphics.draw_rect(customentities[i].p1 + offset, customentities[i].p2 + offset, POINT_SIZE, POINT_SIZE, point1);
1068+
graphics.draw_rect(customentities[i].p3 + offset, customentities[i].p4 + offset, POINT_SIZE, POINT_SIZE, point2);
1069+
1070+
break;
1071+
}
9931072
case 15: // Crewmates
9941073
graphics.draw_sprite(x - 4, y, 144, graphics.crewcolourreal(entity->p1));
9951074
graphics.draw_rect(x, y, 16, 24, graphics.getRGB(164, 164, 164));
@@ -1329,6 +1408,10 @@ static void draw_cursor(void)
13291408
// 2x3
13301409
graphics.draw_rect(x, y, 16, 24, blue);
13311410
break;
1411+
case EditorTool_TELEPORTERS:
1412+
// 12x12
1413+
graphics.draw_rect(x, y, 96, 96, blue);
1414+
break;
13321415
default:
13331416
break;
13341417
}
@@ -1703,6 +1786,15 @@ void editorclass::draw_tool(EditorTools tool, int x, int y)
17031786
case EditorTool_START_POINT:
17041787
graphics.draw_sprite(x, y, 184, graphics.col_crewcyan);
17051788
break;
1789+
case EditorTool_TELEPORTERS:
1790+
{
1791+
graphics.fill_rect(x, y, 16, 16, graphics.getRGB(16, 16, 16));
1792+
SDL_Color color = graphics.getcol(100);
1793+
graphics.set_texture_color_mod(graphics.grphx.im_teleporter, color.r, color.g, color.b);
1794+
graphics.draw_texture_part(graphics.grphx.im_teleporter, x, y, 136, 40, 16, 16, 1, 1);
1795+
graphics.set_texture_color_mod(graphics.grphx.im_teleporter, 255, 255, 255);
1796+
break;
1797+
}
17061798
default:
17071799
break;
17081800
}
@@ -2591,6 +2683,18 @@ void editorclass::tool_place()
25912683
add_entity(levx, levy, tilex, tiley, 16, 0);
25922684
lclickdelay = 1;
25932685
break;
2686+
case EditorTool_TELEPORTERS:
2687+
{
2688+
lclickdelay = 1;
2689+
2690+
int point1x = SDL_clamp((tilex + 9) * 8, -POINT_OFFSET, SCREEN_WIDTH_PIXELS - POINT_OFFSET);
2691+
int point1y = SDL_clamp((tiley - 4) * 8 + 37, -POINT_OFFSET, SCREEN_HEIGHT_PIXELS - POINT_OFFSET);
2692+
int point2x = SDL_clamp((tilex + 16) * 8 + 38, -POINT_OFFSET, SCREEN_WIDTH_PIXELS - POINT_OFFSET);
2693+
int point2y = SDL_clamp((tiley + 8) * 8, -POINT_OFFSET, SCREEN_HEIGHT_PIXELS - POINT_OFFSET);
2694+
2695+
add_entity(levx, levy, tilex, tiley, 14, point1x, point1y, point2x, point2y, 1, 7);
2696+
break;
2697+
}
25942698
default:
25952699
break;
25962700
}
@@ -2843,15 +2947,16 @@ static void start_at_checkpoint(void)
28432947
{
28442948
extern editorclass ed;
28452949

2846-
// Scan the room for a start point or a checkpoint, the start point taking priority
2950+
// Scan the room for a start point or a checkpoint/teleporter, the start point taking priority
28472951
int testeditor = -1;
28482952
bool startpoint = false;
28492953

28502954
for (size_t i = 0; i < customentities.size(); i++)
28512955
{
28522956
startpoint = customentities[i].t == 16;
28532957
const bool is_startpoint_or_checkpoint = startpoint ||
2854-
customentities[i].t == 10;
2958+
customentities[i].t == 10 ||
2959+
customentities[i].t == 14;
28552960
if (!is_startpoint_or_checkpoint)
28562961
{
28572962
continue;
@@ -2890,25 +2995,31 @@ static void start_at_checkpoint(void)
28902995
game.edsaverx = 100 + customentities[testeditor].rx;
28912996
game.edsavery = 100 + customentities[testeditor].ry;
28922997

2998+
game.edsavedir = 0;
2999+
game.edsavegc = 0;
3000+
28933001
if (!startpoint)
28943002
{
28953003
// Checkpoint spawn
2896-
if (customentities[testeditor].p1 == 0) // NOT a bool check!
3004+
if (customentities[testeditor].t == 14) {
3005+
// Actually, teleporter!
3006+
game.edsavex += 48;
3007+
game.edsavey += 44;
3008+
game.edsavedir = 1;
3009+
}
3010+
else if (customentities[testeditor].p1 == 0) // NOT a bool check!
28973011
{
28983012
game.edsavegc = 1;
28993013
game.edsavey -= 2;
29003014
}
29013015
else
29023016
{
2903-
game.edsavegc = 0;
29043017
game.edsavey -= 7;
29053018
}
2906-
game.edsavedir = 0;
29073019
}
29083020
else
29093021
{
29103022
// Start point spawn
2911-
game.edsavegc = 0;
29123023
game.edsavey++;
29133024
game.edsavedir = 1 - customentities[testeditor].p1;
29143025
}
@@ -3089,6 +3200,78 @@ static void handle_draw_input()
30893200
}
30903201
}
30913202

3203+
void check_if_dragging(void)
3204+
{
3205+
extern editorclass ed;
3206+
3207+
ed.dragging_entity = -1;
3208+
3209+
// Is the mouse currently over a teleporter point? Loop through entities.
3210+
for (size_t i = 0; i < customentities.size(); i++)
3211+
{
3212+
// If it's not in the current room, continue.
3213+
if (customentities[i].x < ed.levx * 40 || customentities[i].x >= (ed.levx + 1) * 40 ||
3214+
customentities[i].y < ed.levy * 30 || customentities[i].y >= (ed.levy + 1) * 30)
3215+
{
3216+
continue;
3217+
}
3218+
3219+
// If it's not a teleporter, continue.
3220+
if (customentities[i].t != 14)
3221+
{
3222+
continue;
3223+
}
3224+
3225+
// Okay, it's a teleporter. First, is our mouse on a point?
3226+
SDL_Rect point = {
3227+
customentities[i].p3 + POINT_OFFSET - (POINT_SIZE / 2),
3228+
customentities[i].p4 + POINT_OFFSET - (POINT_SIZE / 2),
3229+
POINT_SIZE,
3230+
POINT_SIZE
3231+
};
3232+
3233+
SDL_Point mouse = { key.mousex, key.mousey };
3234+
3235+
if (SDL_PointInRect(&mouse, &point))
3236+
{
3237+
// We're on the second point!
3238+
ed.dragging_entity = i;
3239+
ed.dragging_point = 2;
3240+
ed.drag_offset_x = key.mousex - customentities[i].p3;
3241+
ed.drag_offset_y = key.mousey - customentities[i].p4;
3242+
3243+
if (key.leftbutton)
3244+
{
3245+
ed.dragging = true;
3246+
}
3247+
else if (key.rightbutton && (ed.rclickdelay == 0))
3248+
{
3249+
customentities[i].p5 = (customentities[i].p5 + 1) % 4;
3250+
ed.rclickdelay = 1;
3251+
}
3252+
break;
3253+
}
3254+
3255+
// Nope, let's check the other point...
3256+
point.x = customentities[i].p1 + POINT_OFFSET - (POINT_SIZE / 2);
3257+
point.y = customentities[i].p2 + POINT_OFFSET - (POINT_SIZE / 2);
3258+
3259+
if (SDL_PointInRect(&mouse, &point))
3260+
{
3261+
// We're on the first point!
3262+
ed.dragging_entity = i;
3263+
ed.dragging_point = 1;
3264+
ed.drag_offset_x = key.mousex - customentities[i].p1;
3265+
ed.drag_offset_y = key.mousey - customentities[i].p2;
3266+
if (key.leftbutton)
3267+
{
3268+
ed.dragging = true;
3269+
}
3270+
break;
3271+
}
3272+
}
3273+
}
3274+
30923275
void editorclass::get_input_line(const enum TextMode mode, const std::string& prompt, std::string* ptr)
30933276
{
30943277
state = EditorState_DRAW;
@@ -3280,7 +3463,30 @@ void editorinput(void)
32803463
}
32813464

32823465
// Mouse input
3283-
if (key.leftbutton && ed.lclickdelay == 0)
3466+
if (ed.dragging)
3467+
{
3468+
if (key.leftbutton && INBOUNDS_VEC(ed.dragging_entity, customentities))
3469+
{
3470+
if (ed.dragging_point == 1)
3471+
{
3472+
customentities[ed.dragging_entity].p1 = key.mousex - ed.drag_offset_x;
3473+
customentities[ed.dragging_entity].p2 = key.mousey - ed.drag_offset_y;
3474+
}
3475+
else
3476+
{
3477+
customentities[ed.dragging_entity].p3 = key.mousex - ed.drag_offset_x;
3478+
customentities[ed.dragging_entity].p4 = key.mousey - ed.drag_offset_y;
3479+
}
3480+
}
3481+
else
3482+
{
3483+
ed.dragging = false;
3484+
}
3485+
}
3486+
3487+
check_if_dragging();
3488+
3489+
if ( key.leftbutton && ed.lclickdelay == 0 && !ed.dragging)
32843490
{
32853491
ed.tool_place();
32863492
}
@@ -3289,11 +3495,16 @@ void editorinput(void)
32893495
ed.lclickdelay = 0;
32903496
}
32913497

3292-
if (key.rightbutton)
3498+
if (key.rightbutton && !ed.dragging)
32933499
{
32943500
ed.tool_remove();
32953501
}
32963502

3503+
if (!key.rightbutton)
3504+
{
3505+
ed.rclickdelay = 0;
3506+
}
3507+
32973508
if (key.middlebutton)
32983509
{
32993510
ed.direct_mode_tile = cl.gettile(ed.levx, ed.levy, ed.tilex, ed.tiley);

desktop_version/src/Editor.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum EditorTools
4848
EditorTool_WARP_LINES,
4949
EditorTool_CREWMATES,
5050
EditorTool_START_POINT,
51+
EditorTool_TELEPORTERS,
5152

5253
NUM_EditorTools
5354
};
@@ -223,7 +224,7 @@ class editorclass
223224

224225
int old_tilex, old_tiley;
225226
int tilex, tiley;
226-
int keydelay, lclickdelay;
227+
int keydelay, lclickdelay, rclickdelay;
227228
bool savekey, loadkey;
228229
int levx, levy;
229230
int entframe, entframedelay;
@@ -241,6 +242,13 @@ class editorclass
241242
};
242243
bool x_modifier, z_modifier, c_modifier, v_modifier, b_modifier, h_modifier, f_modifier, toolbox_open;
243244

245+
bool dragging;
246+
247+
int dragging_entity;
248+
int dragging_point;
249+
int drag_offset_x;
250+
int drag_offset_y;
251+
244252
int roomnamehide;
245253
bool saveandquit;
246254
bool help_open, shiftkey;

desktop_version/src/Ent.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ class entclass
3939
float newxp, newyp;
4040
bool isplatform;
4141
int x1,y1,x2,y2;
42+
int p1x, p1y, p2x, p2y, p3x, p3y;
43+
int pathtime, pathmaxtime;
4244
//Collision Rules
4345
int onentity;
4446
bool harmful;

0 commit comments

Comments
 (0)