@@ -54,12 +54,86 @@ const BAR_WIDTH = 20; // bar thickness
5454const BAR_ROUNDING = 10 ; // px corner radius
5555const RATIO_EASE = 0.05 ; // lerp factor
5656
57+ let lastHP = { } ; // key: unit.id, value: hp
58+ let bloodStains = [ ] ;
59+
5760const types = {
5861 CORE : 0 ,
5962 UNIT : 1 ,
6063 RESOURCE : 2
6164}
6265
66+ // ─── Blood settings (area-based) ───────────────────────────────────────────
67+ const BLOOD_MAX_AREA = 25000000 ;
68+
69+ function updateBloodStains ( ) {
70+ // compute the same offsets you use in drawBlood/draw_grid
71+ const xOff = - cols * boxSize / 2 ;
72+ const yOff = - rows * boxSize / 2 ;
73+ const f = ( cols * boxSize ) / config . width ;
74+
75+ for ( let unit of game . units || [ ] ) {
76+ if ( ! ( unit . id in lastHP ) ) lastHP [ unit . id ] = unit . hp ;
77+ const prev = lastHP [ unit . id ] ;
78+ const lost = prev - unit . hp ;
79+
80+ if ( lost > 0 ) {
81+ // instead of top-left, we now add +boxSize/2 to center it
82+ const x = unit . pos . x * f + xOff + boxSize / 2 ;
83+ const y = unit . pos . y * f + yOff + boxSize / 2 ;
84+
85+ let merged = false ;
86+ for ( let stain of bloodStains ) {
87+ const r = Math . sqrt ( stain . area / Math . PI ) ;
88+ if ( dist ( x , y , stain . x , stain . y ) < r ) {
89+ stain . area += lost ;
90+ if ( stain . area > BLOOD_MAX_AREA ) {
91+ stain . area = BLOOD_MAX_AREA ;
92+ }
93+ merged = true ;
94+ break ;
95+ }
96+ }
97+ if ( ! merged ) {
98+ bloodStains . push ( {
99+ x : x ,
100+ y : y ,
101+ area : Math . min ( lost , BLOOD_MAX_AREA )
102+ } ) ;
103+ }
104+ }
105+ lastHP [ unit . id ] = unit . hp ;
106+ }
107+ }
108+
109+ function drawBlood ( ) {
110+ noStroke ( ) ;
111+ fill ( 150 , 0 , 0 , 200 ) ;
112+
113+ for ( let i = 0 ; i < bloodStains . length ; i ++ ) {
114+ const a = bloodStains [ i ] ;
115+ // compute radius from stored area
116+ const rA = Math . sqrt ( a . area / Math . PI ) ;
117+ ellipse ( a . x , a . y , rA * 2 , rA * 2 ) ;
118+
119+ // connect overlaps with a nice bridge
120+ for ( let j = i + 1 ; j < bloodStains . length ; j ++ ) {
121+ const b = bloodStains [ j ] ;
122+ const rB = Math . sqrt ( b . area / Math . PI ) ;
123+ if ( dist ( a . x , a . y , b . x , b . y ) < ( rA + rB ) * 0.5 ) {
124+ const midX = ( a . x + b . x ) / 2 ;
125+ const midY = ( a . y + b . y ) / 2 ;
126+ const h = min ( rA , rB ) * 0.3 ;
127+ beginShape ( ) ;
128+ vertex ( a . x , a . y ) ;
129+ quadraticVertex ( midX , midY - h , b . x , b . y ) ;
130+ quadraticVertex ( midX , midY + h , a . x , a . y ) ;
131+ endShape ( CLOSE ) ;
132+ }
133+ }
134+ }
135+ }
136+
63137function updateWinRatio ( ) {
64138 if ( ! game . units || game . units . length === 0 ) return ;
65139 if ( ! game . teams || game . teams . length < 2 ) return ;
@@ -329,6 +403,7 @@ function preload() {
329403}
330404
331405function setupWebSocket ( ) {
406+ bloodStains = [ ] ;
332407 socket = new WebSocket ( 'ws://{{.socket}}/ws' ) ;
333408
334409 // WebSocket event listeners
@@ -421,6 +496,7 @@ function isUnitMoving(unit)
421496}
422497
423498function setup ( ) {
499+ bloodStains = [ ] ;
424500 setupWebSocket ( ) ;
425501
426502 cols = config . width / 1000 ;
@@ -449,6 +525,7 @@ function setup() {
449525}
450526
451527function reconnect ( ) {
528+ bloodStains = [ ] ;
452529 configPresent = false ;
453530 isGameOver = false ;
454531 setTimeout ( setupWebSocket , 1000 ) ;
@@ -881,12 +958,16 @@ function draw_game_over() {
881958 stroke ( 0 ) ;
882959 strokeWeight ( 2 ) ;
883960 text
884- if ( game . cores [ 0 ] . team_id == 1 ) {
885- fill ( 'lightgray' ) ;
886- text ( "Skeleton Team " + config . teams [ 0 ] . name + " wins!" , 0 , 0 ) ;
961+ if ( game . cores . length > 1 ) {
962+ text ( "Someone exited, Pauls gotta look at the log uwu" , 0 , 0 ) ;
887963 } else {
888- fill ( 'greenyellow' ) ;
889- text ( "Goblin Team " + config . teams [ 1 ] . name + " wins!" , 0 , 0 ) ;
964+ if ( game . cores [ 0 ] . team_id == 1 ) {
965+ fill ( 'lightgray' ) ;
966+ text ( "Skeleton Team " + config . teams [ 0 ] . name + " wins!" , 0 , 0 ) ;
967+ } else {
968+ fill ( 'greenyellow' ) ;
969+ text ( "Goblin Team " + config . teams [ 1 ] . name + " wins!" , 0 , 0 ) ;
970+ }
890971 }
891972 pop ( ) ;
892973 isGameOver = true ;
@@ -901,6 +982,8 @@ function draw() {
901982
902983 // draw playing field and its elements
903984 draw_grid ( ) ;
985+ updateBloodStains ( ) ;
986+ drawBlood ( ) ;
904987 draw_target_lines ( ) ;
905988 draw_cores ( ) ;
906989 draw_resources ( ) ;
0 commit comments