I found some crazy links last time ...
One Aegis was linked to 10 to 13 Aegis around, because all other shields touch it's shield, but the other ones are not linked to another :-/
|.|
|.|
|.|_
_/ . \
. |
. _/
/
/
/
/
Here is my idea how to do that:
At first, the code should try to create a triangle by this way:
( Aegis #0 is in the center of 4 others #3, #2, #4 and #1
| clockwise order, starts on the north
| #4 not linked, because it's new
)
The code should recognize that #4 is in range of #2, #1 and #0
If a shield between #2, #1 and #0 is attached and #4 is inside ( collide )
- remove the shield
- link #4 to #2, #1 and #0
- create 3 shields in the new triangles
If #4 build outside
- the 2 closest Aegis are #2 and #1
- link to all 3 Aegis
- create a shield with 2# and #1 only
To handle a destroyed Aegis - #1 for example:
- destroy each linked shield
- recognize that #1 is linked to #4, #3 and #0 ( clockwise )
- #1 and #4 only share #0 as link partner
- #1 and #3 only share #0 as link partner
- #1 and #0 share #4 and #3 as link partner
- - 2 matches at #0 detected
- - ask the matches for link state
- - false means they can not create a shield
- tell each linked Aegis that #0 is dead and they have to refresh the shield cache
To handle a destroyed Aegis - #4 for example( build inside shield #2, #1 and #0 )
- destroy each linked shield
- recognize that #4 is linked to #1, #0 and #2
- #4 and #1 share #2 and #0 as link partner
- - 2 matches at #1 detected
- - ask the matches for link state
- - true means #1 can create a shield with the 2 link partner
- - - tell #1, #0 and #2 that they should create a new shield between them
- #0 just got a new shield by #4
- #2 just got a new shield by #4
- tell each linked Aegis that #0 is dead and they have to refresh the shield cache
To draw the
joining shields:
( It should need less triangles to draw this as there are needed for full bubbles ( 360° ) inclusive bottom half )
Constants
- split 90° ( PI/2, from horizontal to vertical ) into 3 parts
- - 30° ( PI/6 )
- get vertical, horizontal distances and horizontal distances * cos( 30° )
- - // 3: top level top, 2: middle level top, 1 bottom level top, 0: ground
- - V0: H3: D3: 0
- - V1: H2: shieldHeight * sin( 30° )
- - V2: H1: shieldHeight * sin( 60° )
- - V3: H0: shieldHeight * 1
- - D0: H0 * cos( 15 ) * cos( 45 ): H0 * 0.6315
- - D1: H1 * cos( 15 ) * cos( 45 ): H0 * 0.6315
- - D2: H2 * cos( 15 ) * cos( 45 ): H0 * 0.6315
Only 1 Triangle between 3 Aegis - allways the same hight
- draw all triangles around 1 Aegis if not drawed by a previous one
- get Aegis linked where are no shields at one or both sides of the link
- - l[1] ( no shield )
- - l[2] ( empty side: conter-clockwise )
- - l[3] ( empty side: clockwise )
- get angles from link directions
- - a[1..3] from l[1..3]
- get vectors for sides with no shield
- - v[1]a: a[1] - 90° ( conter-clockwise )
- - v[1]b: a[1] + 90° ( clockwise )
- - v[2]a: a[2] - 90° ( conter-clockwise )
- - v[3]b: a[3] + 90° ( clockwise )
- get positions from self and links
- - p[0..3]x, p[0..3]z
- get shields and shield bubble parts to draw on the sides:
- - s[1]a: v[1]a ( = s[0]b in l[1] )
- - s[1]b: v[1]b ( = s[0]a in l[1] )
- - sb[0][...]...
( - for each emty angle ( vector[#start..#end] )
| - - // sum( angles of triangle ) = 180
| - - // #start - #end < 60 should mean can not be emty anyway?
| - - #parts: ceil( ( #end - #start - 60° ) / 30° )
| - - sb[#a]size: #a / #parts
| - - for 0..#parts #p
| - - - sb[#a][#p]: #b + #p* sb[#a]size
)
- - (...)
- draw routine
- - // 0° means x:1 and z:0, 270° means x:0 and z:-1, ...
- - for each shield call drawShield
- - for each shield bubble part call drawShieldBubblePart
- drawShield
- - 3 levels with 6 triangles - 2 triangles to draw a rect for each level:
- - // 90° rects attached to an 30° bubble part
- - #d: distance between linked Aegis's
- - #shieldAngle: link angle +90° or -90°
- - #x: cos( #angle )
- - #z: sin( #angle )
- - // x: horizontal distance to current Aegis
- - // y: vertical distance relative to ground
- - // z: horizontal distance to link
- - positions:
- - - h3p1: ( x: #x * ( 0 +D3 ), y: V3, z: #z * ( 0 +D3 ) )
- - - h3p2: ( x: #x * ( #d -D3 ), y: V3, z: #z * ( #d -D3 ) )
- - - h2p1: ( x: #x * ( 0 +D2 ), y: V2, z: #z * ( 0 +D2 ) )
- - - h2p2: ( x: #x * ( #d -D2 ), y: V2, z: #z * ( #d -D2 ) )
- - - h1p1: ( x: #x * ( 0 +D1 ), y: v1, z: #z * ( 0 +D1 ) )
- - - h1p2: ( x: #x * ( #d -D1 ), y: v1, z: #z * ( #d -D1 ) )
- - - h0p1: ( x: #x * ( 0 +D0 ), y: V0, z: #z * ( 0 +D0 ) )
- - - h0p2: ( x: #x * ( #d -D0 ), y: V0, z: #z * ( #d -D0 ) )
- - top rect:
- - - 1st: ( h3p1, h3p2, h2p1 )
- - - 2nd: ( h2p1, h3p2, h2p2 )
- - middle rect:
- - - 1st: ( h2p1, h2p2, h1p1 )
- - - 2nd: ( h1p1, h2p2, h1p2 )
- - bottom rect:
- - - 1st: ( h1p1, h1p2, h0p1 )
- - - 2nd: ( h0p1, h1p2, h0p2 )
- - // now we need to add the offsets to get real positions
- draw shieldBubblePart
- - 3 levels with 6 triangles - 2 triangles to draw a rect for each level:
- - // but there are 6 triangles for each part and different vectors
- - #aStart: start angle of bubble part
- - #aEnd: end angle of bubble part
- - #aCenter: #aStart + ( #aEnd - #aStart ) *0.5
- - #x: cos( #aCenter - #aStart ) * cos( #aCenter )
- - #z: sin( #aCenter - #aStart ) * sin( #aCenter )
- - // x: horizontal distance to angle
- - // y: vertical distance relative to ground
- - // z: horizontal distance to Aegis
- - positions:
- - - h3p1: ( x: -#x * H3, y: V3, z: -#z * H3 )
- - - h3p2: ( x: +#x * H3, y: V3, z: +#z * H3 )
- - - h2p1: ( x: -#x * H2, y: V2, z: -#z * H2 )
- - - h2p2: ( x: +#x * H2, y: V2, z: +#z * H2 )
- - - h1p1: ( x: -#x * H1, y: v1, z: -#z * H1 )
- - - h1p2: ( x: +#x * H1, y: v1, z: +#z * H1 )
- - - h0p1: ( x: -#x * H0, y: V0, z: -#z * H0 )
- - - h0p2: ( x: +#x * H0, y: V0, z: +#z * H0 )
- - top rect:
- - - 1st: ( h3p1, h3p2, h2p1 )
- - - 2nd: ( h2p1, h3p2, h2p2 )
- - middle rect:
- - - 1st: ( h2p1, h2p2, h1p1 )
- - - 2nd: ( h1p1, h2p2, h1p2 )
- - bottom rect:
- - - 1st: ( h1p1, h1p2, h0p1 )
- - - 2nd: ( h0p1, h1p2, h0p2 )
- - // now we need to add the offsets to get real positions
^^ cache results for triangles to increase performance while no link or shield attached got changed
I hope there are no errors, because I'm not practiced enough, to test my code in Spring.
But I've think about it many times ...