26
26
#include " Vlogging.h"
27
27
28
28
#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
29
33
30
34
editorclass::editorclass (void )
31
35
{
@@ -48,6 +52,7 @@ editorclass::editorclass(void)
48
52
register_tool (EditorTool_WARP_LINES, " Warp Lines" , " I" , SDLK_i, false );
49
53
register_tool (EditorTool_CREWMATES, " Crewmates" , " O" , SDLK_o, false );
50
54
register_tool (EditorTool_START_POINT, " Start Point" , " P" , SDLK_p, false );
55
+ register_tool (EditorTool_TELEPORTERS, " Teleporters" , " ^2" , SDLK_2, true );
51
56
52
57
static const short basic[] = {
53
58
121 , 121 , 121 , 121 , 121 , 121 , 121 , 160 , 121 , 121 , 121 , 121 , 121 , 121 , 121 ,
@@ -365,11 +370,18 @@ void editorclass::reset(void)
365
370
levy = 0 ;
366
371
keydelay = 0 ;
367
372
lclickdelay = 0 ;
373
+ rclickdelay = 0 ;
368
374
savekey = false ;
369
375
loadkey = false ;
370
376
updatetiles = true ;
371
377
changeroom = true ;
372
378
379
+ dragging = false ;
380
+ dragging_entity = -1 ;
381
+ dragging_point = 1 ;
382
+ drag_offset_x = 0 ;
383
+ drag_offset_y = 0 ;
384
+
373
385
entframe = 0 ;
374
386
entframedelay = 0 ;
375
387
@@ -990,6 +1002,73 @@ static void draw_entities(void)
990
1002
font::print (PR_BOR | PR_CJK_HIGH, x, y - 8 , text, 210 , 210 , 255 );
991
1003
break ;
992
1004
}
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
+ }
993
1072
case 15 : // Crewmates
994
1073
graphics.draw_sprite (x - 4 , y, 144 , graphics.crewcolourreal (entity->p1 ));
995
1074
graphics.draw_rect (x, y, 16 , 24 , graphics.getRGB (164 , 164 , 164 ));
@@ -1329,6 +1408,10 @@ static void draw_cursor(void)
1329
1408
// 2x3
1330
1409
graphics.draw_rect (x, y, 16 , 24 , blue);
1331
1410
break ;
1411
+ case EditorTool_TELEPORTERS:
1412
+ // 12x12
1413
+ graphics.draw_rect (x, y, 96 , 96 , blue);
1414
+ break ;
1332
1415
default :
1333
1416
break ;
1334
1417
}
@@ -1703,6 +1786,15 @@ void editorclass::draw_tool(EditorTools tool, int x, int y)
1703
1786
case EditorTool_START_POINT:
1704
1787
graphics.draw_sprite (x, y, 184 , graphics.col_crewcyan );
1705
1788
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
+ }
1706
1798
default :
1707
1799
break ;
1708
1800
}
@@ -2591,6 +2683,18 @@ void editorclass::tool_place()
2591
2683
add_entity (levx, levy, tilex, tiley, 16 , 0 );
2592
2684
lclickdelay = 1 ;
2593
2685
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
+ }
2594
2698
default :
2595
2699
break ;
2596
2700
}
@@ -2843,15 +2947,16 @@ static void start_at_checkpoint(void)
2843
2947
{
2844
2948
extern editorclass ed;
2845
2949
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
2847
2951
int testeditor = -1 ;
2848
2952
bool startpoint = false ;
2849
2953
2850
2954
for (size_t i = 0 ; i < customentities.size (); i++)
2851
2955
{
2852
2956
startpoint = customentities[i].t == 16 ;
2853
2957
const bool is_startpoint_or_checkpoint = startpoint ||
2854
- customentities[i].t == 10 ;
2958
+ customentities[i].t == 10 ||
2959
+ customentities[i].t == 14 ;
2855
2960
if (!is_startpoint_or_checkpoint)
2856
2961
{
2857
2962
continue ;
@@ -2890,25 +2995,31 @@ static void start_at_checkpoint(void)
2890
2995
game.edsaverx = 100 + customentities[testeditor].rx ;
2891
2996
game.edsavery = 100 + customentities[testeditor].ry ;
2892
2997
2998
+ game.edsavedir = 0 ;
2999
+ game.edsavegc = 0 ;
3000
+
2893
3001
if (!startpoint)
2894
3002
{
2895
3003
// 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!
2897
3011
{
2898
3012
game.edsavegc = 1 ;
2899
3013
game.edsavey -= 2 ;
2900
3014
}
2901
3015
else
2902
3016
{
2903
- game.edsavegc = 0 ;
2904
3017
game.edsavey -= 7 ;
2905
3018
}
2906
- game.edsavedir = 0 ;
2907
3019
}
2908
3020
else
2909
3021
{
2910
3022
// Start point spawn
2911
- game.edsavegc = 0 ;
2912
3023
game.edsavey ++;
2913
3024
game.edsavedir = 1 - customentities[testeditor].p1 ;
2914
3025
}
@@ -3089,6 +3200,78 @@ static void handle_draw_input()
3089
3200
}
3090
3201
}
3091
3202
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
+
3092
3275
void editorclass::get_input_line (const enum TextMode mode, const std::string& prompt, std::string* ptr)
3093
3276
{
3094
3277
state = EditorState_DRAW;
@@ -3280,7 +3463,30 @@ void editorinput(void)
3280
3463
}
3281
3464
3282
3465
// 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 )
3284
3490
{
3285
3491
ed.tool_place ();
3286
3492
}
@@ -3289,11 +3495,16 @@ void editorinput(void)
3289
3495
ed.lclickdelay = 0 ;
3290
3496
}
3291
3497
3292
- if (key.rightbutton )
3498
+ if (key.rightbutton && !ed. dragging )
3293
3499
{
3294
3500
ed.tool_remove ();
3295
3501
}
3296
3502
3503
+ if (!key.rightbutton )
3504
+ {
3505
+ ed.rclickdelay = 0 ;
3506
+ }
3507
+
3297
3508
if (key.middlebutton )
3298
3509
{
3299
3510
ed.direct_mode_tile = cl.gettile (ed.levx , ed.levy , ed.tilex , ed.tiley );
0 commit comments