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
3034editorclass::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+
30923275void 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 );
0 commit comments