22
33import com .mojang .blaze3d .vertex .PoseStack ;
44import com .mojang .blaze3d .vertex .VertexConsumer ;
5- import com .mojang .math .Axis ;
65import com .robertx22 .library_of_exile .util .UNICODE ;
7- import com .robertx22 .library_of_exile .utils .CLOC ;
86import com .robertx22 .mine_and_slash .config .forge .ServerContainer ;
97import com .robertx22 .mine_and_slash .database .data .mob_affixes .MobAffix ;
108import com .robertx22 .mine_and_slash .database .registry .ExileDB ;
119import com .robertx22 .mine_and_slash .mmorpg .MMORPG ;
1210import com .robertx22 .mine_and_slash .uncommon .datasaving .Load ;
11+ import com .robertx22 .mine_and_slash .uncommon .localization .Formatter ;
1312import com .robertx22 .mine_and_slash .uncommon .utilityclasses .HealthUtils ;
1413import net .minecraft .ChatFormatting ;
1514import net .minecraft .client .Minecraft ;
1615import net .minecraft .client .gui .Font ;
1716import net .minecraft .client .renderer .MultiBufferSource ;
18- import net .minecraft .client .renderer .texture .OverlayTexture ;
19- import net .minecraft .client .resources .language .I18n ;
17+ import net .minecraft .client .renderer .RenderType ;
2018import net .minecraft .core .registries .Registries ;
19+ import net .minecraft .network .chat .CommonComponents ;
20+ import net .minecraft .network .chat .Component ;
21+ import net .minecraft .network .chat .MutableComponent ;
2122import net .minecraft .resources .ResourceLocation ;
2223import net .minecraft .tags .TagKey ;
2324import net .minecraft .util .Mth ;
2728import net .minecraft .world .entity .MobType ;
2829import net .minecraft .world .entity .monster .Monster ;
2930import net .minecraft .world .entity .player .Player ;
30- import net .minecraft .world .item .ItemDisplayContext ;
3131import net .minecraft .world .item .ItemStack ;
3232import net .minecraft .world .item .Items ;
3333import net .minecraft .world .level .ClipContext ;
34- import net .minecraft .world .level .Level ;
3534import net .minecraft .world .phys .AABB ;
3635import net .minecraft .world .phys .HitResult ;
3736import net .minecraft .world .phys .Vec3 ;
3837import net .minecraft .world .scores .Team ;
3938import net .minecraftforge .registries .ForgeRegistries ;
39+ import org .apache .commons .lang3 .ArrayUtils ;
40+ import org .apache .commons .lang3 .tuple .Pair ;
41+ import org .jetbrains .annotations .NotNull ;
4042import org .joml .Quaternionf ;
4143
4244import java .text .DecimalFormat ;
43- import java .util .Arrays ;
45+ import java .util .ArrayList ;
46+ import java .util .Collections ;
4447import java .util .List ;
4548import java .util .Optional ;
4649import java .util .stream .Collectors ;
4750
4851public class HealthBarRenderer {
4952
5053 private static final DecimalFormat HEALTH_FORMAT = new DecimalFormat ("#.##" );
54+ private static final TagKey <EntityType <?>> FORGE_BOSS_TAG =
55+ TagKey .create (Registries .ENTITY_TYPE , new ResourceLocation ("forge" , "bosses" ));
56+ private static final TagKey <EntityType <?>> FABRIC_BOSS_TAG =
57+ TagKey .create (Registries .ENTITY_TYPE , new ResourceLocation ("c" , "bosses" ));
5158
5259 private static Entity getEntityLookedAt (Entity e ) {
5360 Entity foundEntity = null ;
@@ -138,12 +145,6 @@ private static int getColor(LivingEntity entity, boolean colorByType, boolean bo
138145 }
139146 }
140147
141- private static final TagKey <EntityType <?>> FORGE_BOSS_TAG =
142- TagKey .create (Registries .ENTITY_TYPE , new ResourceLocation ("forge" , "bosses" ));
143-
144- private static final TagKey <EntityType <?>> FABRIC_BOSS_TAG =
145- TagKey .create (Registries .ENTITY_TYPE , new ResourceLocation ("c" , "bosses" ));
146-
147148 private static boolean isBoss (Entity entity ) {
148149 return entity .getType ().is (FORGE_BOSS_TAG ) || entity .getType ().is (FABRIC_BOSS_TAG );
149150 }
@@ -201,13 +202,18 @@ private static boolean shouldShowPlate(LivingEntity living, Entity cameraEntity)
201202 return visible ;
202203 }
203204
204- static List <ItemStack > getIcons (Entity e ) {
205+ static List <EffectIcon > getIcons (Entity e ) {
205206
206207 if (e instanceof LivingEntity en ) {
207208 return Load .Unit (en ).getStatusEffectsData ().exileMap .entrySet ().stream ()
208- .map (x -> new ItemStack (ExileDB .ExileEffects ().get (x .getKey ()).getEffectDisplayItem (), x .getValue ().stacks )).collect (Collectors .toList ());
209+ .map (x -> Pair .of (EffectIcon .of (ExileDB .ExileEffects ().get (x .getKey ()).getTexture (), x .getValue ().stacks ), x .getValue ().ticks_left ))
210+ .sorted ((x , y ) -> -Integer .compare (x .getValue (), y .getValue ()))
211+ .map (Pair ::getLeft )
212+ .filter (x -> x .location () == null )
213+ .peek (x -> System .out .println ("found one!" ))
214+ .collect (Collectors .toCollection (ArrayList ::new ));
209215 }
210- return Arrays . asList () ;
216+ return Collections . EMPTY_LIST ;
211217
212218 }
213219
@@ -231,68 +237,33 @@ public static void hookRender(Entity entity, PoseStack poseStack, MultiBufferSou
231237 final int barHeight = NeatConfig .instance .barHeight ();
232238 final boolean boss = isBoss (living );
233239
234- List <ItemStack > icons = getIcons (entity );
235-
236- int lvl = Load .Unit (living ).getLevel ();
237- int playerlvl = Load .Unit (mc .player ).getLevel ();
238- int diffabove = lvl - playerlvl ;
239-
240- String lvltext = "Lvl " + lvl ;
241-
242- if (entity instanceof Player == false && diffabove > ServerContainer .get ().LEVEL_DISTANCE_SKULL_SHOW .get ()) {
243- if (ServerContainer .get ().SKULL_HIDES_LEVEL .get ()) {
244- lvltext = "Lvl " + ChatFormatting .RED + UNICODE .SKULL ;
245- } else {
246- lvltext = "Lvl " + lvl + " " + ChatFormatting .RED + UNICODE .SKULL ;
247- }
248- }
249-
250- String prefix = "" ;
251- String suffix = "" ;
240+ List <EffectIcon > icons = getIcons (entity );
252241
253- for (MobAffix affix : Load .Unit (entity ).getAffixData ().getAffixes ()) {
254-
255- if (affix .type .isPrefix ()) {
242+ MutableComponent name = getNameString (entity , living , mc );
256243
257- prefix += CLOC .translate (affix .locName ());
258- } else {
259-
260- suffix += CLOC .translate (affix .locName ());
261-
262- }
263- }
264-
265- String rar = I18n .get (Load .Unit (living ).getMobRarity ().locName ().getString ());
266-
267- ChatFormatting color = Load .Unit (living ).getMobRarity ().textFormatting ();
268-
269- if (living instanceof Player ) {
270- rar = "" ;
271- color = ChatFormatting .RED ;
272- }
273-
274- String name = ChatFormatting .YELLOW + lvltext + " " + color + rar + " " + prefix + " " + living .getDisplayName ().getString () + " " + suffix ;
275-
276- final float nameLen = (mc .font .width (name ) + (icons .size () * 5 )) * textScale ;
244+ final float nameLen = (mc .font .width (name .getString ()) + (icons .size () * 5 )) * textScale ;
277245 final float halfSize = Math .max (NeatConfig .instance .plateSize (), nameLen / 2.0F + 10.0F );
278246
279247 poseStack .pushPose ();
248+ //System.out.println(living.getBbHeight());
249+ //System.out.println(NeatConfig.instance.heightAbove());
280250 poseStack .translate (0 , living .getBbHeight () + NeatConfig .instance .heightAbove (), 0 );
281251 poseStack .mulPose (cameraOrientation );
282252
283253 // Plate background, bars, and text operate with globalScale, but icons don't
284254 poseStack .pushPose ();
285255 poseStack .scale (-globalScale , -globalScale , globalScale );
286-
256+ RenderType renderType = NeatRenderType .getHealthBarType ();
257+ float padding = NeatConfig .instance .backgroundPadding ();
258+ int bgHeight = NeatConfig .instance .backgroundHeight ();
287259 // Background
288260 if (NeatConfig .instance .drawBackground ()) {
289- float padding = NeatConfig .instance .backgroundPadding ();
290- int bgHeight = NeatConfig .instance .backgroundHeight ();
291- VertexConsumer builder = buffers .getBuffer (NeatRenderType .BAR_TEXTURE_TYPE );
292- builder .vertex (poseStack .last ().pose (), -halfSize - padding , -bgHeight , 0.01F ).color (0 , 0 , 0 , 64 ).uv (0.0F , 0.0F ).uv2 (light ).endVertex ();
293- builder .vertex (poseStack .last ().pose (), -halfSize - padding , barHeight + padding , 0.01F ).color (0 , 0 , 0 , 64 ).uv (0.0F , 0.5F ).uv2 (light ).endVertex ();
294- builder .vertex (poseStack .last ().pose (), halfSize + padding , barHeight + padding , 0.01F ).color (0 , 0 , 0 , 64 ).uv (1.0F , 0.5F ).uv2 (light ).endVertex ();
295- builder .vertex (poseStack .last ().pose (), halfSize + padding , -bgHeight , 0.01F ).color (0 , 0 , 0 , 64 ).uv (1.0F , 0.0F ).uv2 (light ).endVertex ();
261+
262+ VertexConsumer builder = buffers .getBuffer (renderType );
263+ builder .vertex (poseStack .last ().pose (), -halfSize - padding , -bgHeight , 0.01F ).color (0 , 0 , 0 , 64 ).uv (0.0F , 0.0F ).endVertex ();
264+ builder .vertex (poseStack .last ().pose (), -halfSize - padding , barHeight + padding , 0.01F ).color (0 , 0 , 0 , 64 ).uv (0.0F , 0.5F ).endVertex ();
265+ builder .vertex (poseStack .last ().pose (), halfSize + padding , barHeight + padding , 0.01F ).color (0 , 0 , 0 , 64 ).uv (1.0F , 0.5F ).endVertex ();
266+ builder .vertex (poseStack .last ().pose (), halfSize + padding , -bgHeight , 0.01F ).color (0 , 0 , 0 , 64 ).uv (1.0F , 0.0F ).endVertex ();
296267 }
297268
298269 // Health Bar
@@ -306,18 +277,18 @@ public static void hookRender(Entity entity, PoseStack poseStack, MultiBufferSou
306277 float maxHealth = Math .max (living .getHealth (), living .getMaxHealth ());
307278 float healthHalfSize = halfSize * (living .getHealth () / maxHealth );
308279
309- VertexConsumer builder = buffers .getBuffer (NeatRenderType . BAR_TEXTURE_TYPE );
310- builder .vertex (poseStack .last ().pose (), -halfSize , 0 , 0.001F ).color (r , g , b , 127 ).uv (0.0F , 0.75F ).uv2 ( light ). endVertex ();
311- builder .vertex (poseStack .last ().pose (), -halfSize , barHeight , 0.001F ).color (r , g , b , 127 ).uv (0.0F , 1.0F ).uv2 ( light ). endVertex ();
312- builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , barHeight , 0.001F ).color (r , g , b , 127 ).uv (1.0F , 1.0F ).uv2 ( light ). endVertex ();
313- builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , 0 , 0.001F ).color (r , g , b , 127 ).uv (1.0F , 0.75F ).uv2 ( light ). endVertex ();
280+ VertexConsumer builder = buffers .getBuffer (renderType );
281+ builder .vertex (poseStack .last ().pose (), -halfSize , 0 , 0.001F ).color (r , g , b , 127 ).uv (0.0F , 0.75F ).endVertex ();
282+ builder .vertex (poseStack .last ().pose (), -halfSize , barHeight , 0.001F ).color (r , g , b , 127 ).uv (0.0F , 1.0F ).endVertex ();
283+ builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , barHeight , 0.001F ).color (r , g , b , 127 ).uv (1.0F , 1.0F ).endVertex ();
284+ builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , 0 , 0.001F ).color (r , g , b , 127 ).uv (1.0F , 0.75F ).endVertex ();
314285
315286 // Blank part of the bar
316287 if (healthHalfSize < halfSize ) {
317- builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , 0 , 0.001F ).color (0 , 0 , 0 , 127 ).uv (0.0F , 0.5F ).uv2 ( light ). endVertex ();
318- builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , barHeight , 0.001F ).color (0 , 0 , 0 , 127 ).uv (0.0F , 0.75F ).uv2 ( light ). endVertex ();
319- builder .vertex (poseStack .last ().pose (), halfSize , barHeight , 0.001F ).color (0 , 0 , 0 , 127 ).uv (1.0F , 0.75F ).uv2 ( light ). endVertex ();
320- builder .vertex (poseStack .last ().pose (), halfSize , 0 , 0.001F ).color (0 , 0 , 0 , 127 ).uv (1.0F , 0.5F ).uv2 ( light ). endVertex ();
288+ builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , 0 , 0.001F ).color (0 , 0 , 0 , 127 ).uv (0.0F , 0.5F ).endVertex ();
289+ builder .vertex (poseStack .last ().pose (), -halfSize + 2 * healthHalfSize , barHeight , 0.001F ).color (0 , 0 , 0 , 127 ).uv (0.0F , 0.75F ).endVertex ();
290+ builder .vertex (poseStack .last ().pose (), halfSize , barHeight , 0.001F ).color (0 , 0 , 0 , 127 ).uv (1.0F , 0.75F ).endVertex ();
291+ builder .vertex (poseStack .last ().pose (), halfSize , 0 , 0.001F ).color (0 , 0 , 0 , 127 ).uv (1.0F , 0.5F ).endVertex ();
321292 }
322293 }
323294
@@ -368,17 +339,19 @@ public static void hookRender(Entity entity, PoseStack poseStack, MultiBufferSou
368339
369340 // Icons
370341 {
371- final float zBump = -0.1F ;
342+ final int size = 8 ;
343+ final float iconInterval = size * 0.2f ;
372344 poseStack .pushPose ();
345+ poseStack .scale (-globalScale , -globalScale , 1 );
346+ poseStack .translate (halfSize + padding , bgHeight , 0 );
347+ float horizontalOffset = icons .size () * size + (icons .size () - 1 ) * iconInterval ;
348+ //todo: haven't handle the case like entity has insane amount of effects.
349+ // it will make the icon exceed the left of health bar.
350+ poseStack .translate (-horizontalOffset , 0 , 0 );
351+ for (int i = 0 ; i < icons .size (); i ++) {
352+ if (i != 0 ) poseStack .translate (size + iconInterval , 0 , 0 );
353+ icons .get (i ).renderOnHealthBar (poseStack , buffers , size );
373354
374- float iconOffset = 2.85F ;
375- float zShift = 0F ;
376-
377- // todo
378- for (ItemStack icon : icons ) {
379- renderIcon (living .level (), icon , poseStack , buffers , globalScale , halfSize , iconOffset , zShift );
380- iconOffset += 5F ;
381- zShift += zBump ;
382355 }
383356
384357
@@ -388,26 +361,53 @@ public static void hookRender(Entity entity, PoseStack poseStack, MultiBufferSou
388361 poseStack .popPose ();
389362 }
390363
391- private static void renderIcon (Level level , ItemStack icon , PoseStack poseStack ,
392- MultiBufferSource buffers , float globalScale , float halfSize , float leftShift , float zShift ) {
393- if (!icon .isEmpty ()) {
394- final float iconScale = 0.12F ;
395- poseStack .pushPose ();
396- // halfSize and co. are units operating under the assumption of globalScale,
397- // but in the icon rendering section we don't use globalScale, so we need
398- // to manually multiply it in to ensure the units line up.
399- float dx = (halfSize - leftShift ) * globalScale ;
400- float dy = 3F * globalScale ;
401- float dz = zShift * globalScale ;
402- // Need to negate X due to our rotation below
403- poseStack .translate (-dx , dy , dz );
404- poseStack .scale (iconScale , iconScale , iconScale );
405- poseStack .mulPose (Axis .YP .rotationDegrees (180F ));
406-
407-
408- Minecraft .getInstance ().getItemRenderer ()
409- .renderStatic (icon , ItemDisplayContext .NONE , 0xF000F0 , OverlayTexture .NO_OVERLAY , poseStack , buffers , level , 0 );
410- poseStack .popPose ();
364+ private static @ NotNull MutableComponent getNameString (Entity entity , LivingEntity living , Minecraft mc ) {
365+ int lvl = Load .Unit (living ).getLevel ();
366+ int playerlvl = Load .Unit (mc .player ).getLevel ();
367+ int diffabove = lvl - playerlvl ;
368+ MutableComponent level = Component .literal (lvl + "" );
369+
370+ if (entity instanceof Player == false && diffabove > ServerContainer .get ().LEVEL_DISTANCE_SKULL_SHOW .get ()) {
371+ if (ServerContainer .get ().SKULL_HIDES_LEVEL .get ()) {
372+ level = Component .literal (UNICODE .SKULL ).withStyle (ChatFormatting .RED );
373+ } else {
374+ level = Component .literal (lvl + " " + UNICODE .SKULL ).withStyle (ChatFormatting .RED );
375+ }
411376 }
377+ level = level .withStyle (ChatFormatting .YELLOW );
378+
379+ Component prefix = CommonComponents .EMPTY ;
380+ Component name = living .getDisplayName ();
381+ Component suffix = CommonComponents .EMPTY ;
382+
383+
384+ for (MobAffix affix : Load .Unit (entity ).getAffixData ().getAffixes ()) {
385+
386+ if (affix .type .isPrefix ()) {
387+ prefix = affix .locName ();
388+ } else {
389+ suffix = affix .locName ();
390+
391+ }
392+ }
393+ ChatFormatting rarityColor ;
394+ Component rarity ;
395+ rarity = Load .Unit (living ).getMobRarity ().locName ();
396+
397+ rarityColor = Load .Unit (living ).getMobRarity ().textFormatting ();
398+
399+ if (living instanceof Player ) {
400+ rarity = CommonComponents .EMPTY ;
401+ rarityColor = ChatFormatting .RED ;
402+ }
403+ List <Component > rarity1 = List .of (rarity , prefix , name , suffix );
404+ for (Component component : rarity1 ) {
405+ if (component instanceof MutableComponent ){
406+ ((MutableComponent ) component ).withStyle (rarityColor );
407+ }
408+ }
409+ Component [] array = rarity1 .toArray (Component []::new );
410+ return Formatter .MOB_NAME_TEMPLATE .locName ((Object []) ArrayUtils .addFirst (array , level )).withStyle (ChatFormatting .YELLOW );
412411 }
412+
413413}
0 commit comments