Skip to content

Commit 1d54586

Browse files
authored
Merge branch 'main' into dependabot/github_actions/actions/download-artifact-7
2 parents c472772 + 486a86f commit 1d54586

12 files changed

Lines changed: 751 additions & 15 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"base_mobs": 2,
3+
"entity_tables": [
4+
{
5+
"attribute_modifiers": [
6+
{
7+
"amount": 0.5,
8+
"attribute": "minecraft:generic.max_health",
9+
"id": "mia:trial_spawner_health",
10+
"operation": "add_multiplied_total"
11+
}
12+
],
13+
"effects": [
14+
{
15+
"amplifier": 0,
16+
"duration": -1,
17+
"effect": "minecraft:fire_resistance"
18+
}
19+
],
20+
"entity": "minecraft:zombie",
21+
"equipment": {
22+
"chest": "minecraft:iron_chestplate",
23+
"head": "minecraft:iron_helmet",
24+
"mainhand": "minecraft:diamond_sword"
25+
},
26+
"weight": 10
27+
},
28+
{
29+
"attribute_modifiers": [
30+
{
31+
"amount": 2.0,
32+
"attribute": "minecraft:generic.attack_damage",
33+
"id": "mia:trial_spawner_damage",
34+
"operation": "add_value"
35+
}
36+
],
37+
"effects": [
38+
{
39+
"amplifier": 1,
40+
"duration": -1,
41+
"effect": "minecraft:speed"
42+
}
43+
],
44+
"entity": "minecraft:skeleton",
45+
"equipment": {
46+
"head": "minecraft:chainmail_helmet",
47+
"mainhand": "minecraft:bow"
48+
},
49+
"weight": 5
50+
}
51+
],
52+
"loot_tables": [
53+
{
54+
"loot_table": "minecraft:chests/trial_chambers/reward_rare",
55+
"weight": 10
56+
},
57+
{
58+
"loot_table": "minecraft:chests/trial_chambers/reward_unique",
59+
"weight": 3
60+
}
61+
],
62+
"mobs_per_player": 1,
63+
"spawn_per_tick": 1,
64+
"spawn_range": 5
65+
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package com.altnoir.mia.block.entity.renderer;
2+
3+
import com.altnoir.mia.block.entity.AbyssSpawnerBlockEntity;
4+
import com.altnoir.mia.client.render.MiaRenderTypes;
5+
import com.mojang.blaze3d.vertex.PoseStack;
6+
import com.mojang.blaze3d.vertex.VertexConsumer;
7+
import com.mojang.math.Axis;
8+
import net.minecraft.client.renderer.LightTexture;
9+
import net.minecraft.client.renderer.MultiBufferSource;
10+
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
11+
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
12+
import net.minecraft.util.FastColor;
13+
import net.minecraft.util.Mth;
14+
import net.minecraft.util.RandomSource;
15+
import org.joml.Matrix4f;
16+
import org.joml.Vector3f;
17+
18+
public class AbyssSpawnerRenderer implements BlockEntityRenderer<AbyssSpawnerBlockEntity> {
19+
private static final int SPHERE_SEGMENTS = 16;
20+
private static final int SPHERE_RINGS = 12;
21+
private static final float BASE_RADIUS = 0.25f;
22+
23+
private static final int CORE_COLOR = FastColor.ARGB32.color(230, 80, 20, 120);
24+
private static final int OUTER_COLOR = FastColor.ARGB32.color(180, 120, 60, 180);
25+
26+
public AbyssSpawnerRenderer(BlockEntityRendererProvider.Context context) {
27+
}
28+
29+
@Override
30+
public void render(AbyssSpawnerBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
31+
var level = blockEntity.getLevel();
32+
if (level == null) {
33+
return;
34+
}
35+
36+
if (!blockEntity.hasValidPattern()) {
37+
return;
38+
}
39+
40+
var spawner = blockEntity.getAbyssSpawner();
41+
float time = (level.getGameTime() + partialTick) * 0.05f;
42+
43+
poseStack.pushPose();
44+
poseStack.translate(0.5, 0.5, 0.5);
45+
46+
double spin = Mth.lerp(partialTick, spawner.getOSpin(), spawner.getSpin());
47+
poseStack.mulPose(Axis.YP.rotationDegrees((float) spin));
48+
49+
float bob = Mth.sin(time * 0.5f) * 0.05f;
50+
poseStack.translate(0, bob, 0);
51+
52+
float pulse = 1.0f + Mth.sin(time * 2.0f) * 0.1f;
53+
float radius = BASE_RADIUS * pulse;
54+
55+
renderDistortedSphere(poseStack, bufferSource, radius, time, packedLight);
56+
57+
poseStack.scale(1.3f, 1.3f, 1.3f);
58+
renderGlowingSphere(poseStack, bufferSource, radius * 0.8f, time);
59+
60+
poseStack.popPose();
61+
}
62+
63+
private void renderDistortedSphere(PoseStack poseStack, MultiBufferSource bufferSource, float radius, float time, int packedLight) {
64+
VertexConsumer buffer = bufferSource.getBuffer(MiaRenderTypes.ABYSS_ORB);
65+
Matrix4f matrix = poseStack.last().pose();
66+
67+
RandomSource random = RandomSource.create(42L);
68+
69+
for (int ring = 0; ring < SPHERE_RINGS; ring++) {
70+
float theta1 = (float) Math.PI * ring / SPHERE_RINGS;
71+
float theta2 = (float) Math.PI * (ring + 1) / SPHERE_RINGS;
72+
73+
for (int seg = 0; seg < SPHERE_SEGMENTS; seg++) {
74+
float phi1 = 2.0f * (float) Math.PI * seg / SPHERE_SEGMENTS;
75+
float phi2 = 2.0f * (float) Math.PI * (seg + 1) / SPHERE_SEGMENTS;
76+
77+
float distort1 = getDistortion(theta1, phi1, time, random);
78+
float distort2 = getDistortion(theta2, phi1, time, random);
79+
float distort3 = getDistortion(theta2, phi2, time, random);
80+
float distort4 = getDistortion(theta1, phi2, time, random);
81+
82+
Vector3f p1 = spherePoint(theta1, phi1, radius * distort1);
83+
Vector3f p2 = spherePoint(theta2, phi1, radius * distort2);
84+
Vector3f p3 = spherePoint(theta2, phi2, radius * distort3);
85+
Vector3f p4 = spherePoint(theta1, phi2, radius * distort4);
86+
87+
float v1 = (float) ring / SPHERE_RINGS;
88+
float v2 = (float) (ring + 1) / SPHERE_RINGS;
89+
90+
int color1 = lerpColor(CORE_COLOR, OUTER_COLOR, v1);
91+
int color2 = lerpColor(CORE_COLOR, OUTER_COLOR, v2);
92+
93+
addVertex(buffer, matrix, p1, color1, packedLight);
94+
addVertex(buffer, matrix, p2, color2, packedLight);
95+
addVertex(buffer, matrix, p3, color2, packedLight);
96+
97+
addVertex(buffer, matrix, p1, color1, packedLight);
98+
addVertex(buffer, matrix, p3, color2, packedLight);
99+
addVertex(buffer, matrix, p4, color1, packedLight);
100+
}
101+
}
102+
}
103+
104+
private void renderGlowingSphere(PoseStack poseStack, MultiBufferSource bufferSource, float radius, float time) {
105+
VertexConsumer buffer = bufferSource.getBuffer(MiaRenderTypes.ABYSS_ORB_GLOW);
106+
Matrix4f matrix = poseStack.last().pose();
107+
108+
float glowPulse = Mth.sin(time * 3.0f) * 0.5f + 0.5f;
109+
int glowAlpha = (int) (80 + glowPulse * 100);
110+
int glowColor = FastColor.ARGB32.color(glowAlpha, 180, 80, 220);
111+
112+
for (int ring = 0; ring < SPHERE_RINGS / 2; ring++) {
113+
float theta1 = (float) Math.PI * ring / (SPHERE_RINGS / 2);
114+
float theta2 = (float) Math.PI * (ring + 1) / (SPHERE_RINGS / 2);
115+
116+
for (int seg = 0; seg < SPHERE_SEGMENTS / 2; seg++) {
117+
float phi1 = 2.0f * (float) Math.PI * seg / (SPHERE_SEGMENTS / 2);
118+
float phi2 = 2.0f * (float) Math.PI * (seg + 1) / (SPHERE_SEGMENTS / 2);
119+
120+
Vector3f p1 = spherePoint(theta1, phi1, radius);
121+
Vector3f p2 = spherePoint(theta2, phi1, radius);
122+
Vector3f p3 = spherePoint(theta2, phi2, radius);
123+
Vector3f p4 = spherePoint(theta1, phi2, radius);
124+
125+
addVertex(buffer, matrix, p1, glowColor, LightTexture.FULL_BRIGHT);
126+
addVertex(buffer, matrix, p2, glowColor, LightTexture.FULL_BRIGHT);
127+
addVertex(buffer, matrix, p3, glowColor, LightTexture.FULL_BRIGHT);
128+
129+
addVertex(buffer, matrix, p1, glowColor, LightTexture.FULL_BRIGHT);
130+
addVertex(buffer, matrix, p3, glowColor, LightTexture.FULL_BRIGHT);
131+
addVertex(buffer, matrix, p4, glowColor, LightTexture.FULL_BRIGHT);
132+
}
133+
}
134+
}
135+
136+
private float getDistortion(float theta, float phi, float time, RandomSource random) {
137+
float noise = Mth.sin(theta * 5 + time) * Mth.cos(phi * 3 + time * 0.7f);
138+
float secondary = Mth.sin(theta * 8 - time * 1.3f) * Mth.sin(phi * 6 + time * 0.5f);
139+
return 1.0f + noise * 0.15f + secondary * 0.08f;
140+
}
141+
142+
private Vector3f spherePoint(float theta, float phi, float radius) {
143+
float x = radius * Mth.sin(theta) * Mth.cos(phi);
144+
float y = radius * Mth.cos(theta);
145+
float z = radius * Mth.sin(theta) * Mth.sin(phi);
146+
return new Vector3f(x, y, z);
147+
}
148+
149+
private void addVertex(VertexConsumer buffer, Matrix4f matrix, Vector3f pos, int color, int light) {
150+
buffer.addVertex(matrix, pos.x, pos.y, pos.z)
151+
.setColor(color)
152+
.setLight(light);
153+
}
154+
155+
private int lerpColor(int color1, int color2, float t) {
156+
int a1 = FastColor.ARGB32.alpha(color1);
157+
int r1 = FastColor.ARGB32.red(color1);
158+
int g1 = FastColor.ARGB32.green(color1);
159+
int b1 = FastColor.ARGB32.blue(color1);
160+
161+
int a2 = FastColor.ARGB32.alpha(color2);
162+
int r2 = FastColor.ARGB32.red(color2);
163+
int g2 = FastColor.ARGB32.green(color2);
164+
int b2 = FastColor.ARGB32.blue(color2);
165+
166+
int a = (int) Mth.lerp(t, a1, a2);
167+
int r = (int) Mth.lerp(t, r1, r2);
168+
int g = (int) Mth.lerp(t, g1, g2);
169+
int b = (int) Mth.lerp(t, b1, b2);
170+
171+
return FastColor.ARGB32.color(a, r, g, b);
172+
}
173+
174+
@Override
175+
public boolean shouldRenderOffScreen(AbyssSpawnerBlockEntity blockEntity) {
176+
return true;
177+
}
178+
179+
@Override
180+
public int getViewDistance() {
181+
return 64;
182+
}
183+
}

src/main/java/com/altnoir/mia/client/event/RegisterEntityRendererEvent.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.altnoir.mia.client.event;
22

3+
import com.altnoir.mia.block.entity.renderer.AbyssSpawnerRenderer;
34
import com.altnoir.mia.block.entity.renderer.EndlessCupBlockRenderer;
45
import com.altnoir.mia.block.entity.renderer.PedestalBlockRenderer;
56
import com.altnoir.mia.block.entity.renderer.SunStoneBlockRenderer;
@@ -14,5 +15,6 @@ public static void registerEntityRenderers(EntityRenderersEvent.RegisterRenderer
1415
event.registerBlockEntityRenderer(MiaBlockEntities.PEDESTAL_ENTITY.get(), PedestalBlockRenderer::new);
1516
event.registerBlockEntityRenderer(MiaBlockEntities.ENDLESS_CUP_BLOCK_ENTITY.get(), EndlessCupBlockRenderer::new);
1617
event.registerBlockEntityRenderer(MiaBlockEntities.SUN_STONE_BLOCK_ENTITY.get(), SunStoneBlockRenderer::new);
18+
event.registerBlockEntityRenderer(MiaBlockEntities.ABYSS_SPAWNER_ENTITY.get(), AbyssSpawnerRenderer::new);
1719
}
1820
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.altnoir.mia.client.render;
2+
3+
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
4+
import com.mojang.blaze3d.vertex.VertexFormat;
5+
import net.minecraft.client.renderer.RenderType;
6+
7+
public class MiaRenderTypes extends RenderType {
8+
9+
public MiaRenderTypes(String name, VertexFormat format, VertexFormat.Mode mode, int bufferSize, boolean affectsCrumbling, boolean sortOnUpload, Runnable setupState, Runnable clearState) {
10+
super(name, format, mode, bufferSize, affectsCrumbling, sortOnUpload, setupState, clearState);
11+
}
12+
13+
public static final RenderType ABYSS_ORB = create(
14+
"mia_abyss_orb",
15+
DefaultVertexFormat.POSITION_COLOR_LIGHTMAP,
16+
VertexFormat.Mode.TRIANGLES,
17+
1536,
18+
false,
19+
true,
20+
CompositeState.builder()
21+
.setShaderState(POSITION_COLOR_LIGHTMAP_SHADER)
22+
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
23+
.setWriteMaskState(COLOR_DEPTH_WRITE)
24+
.setCullState(NO_CULL)
25+
.setDepthTestState(LEQUAL_DEPTH_TEST)
26+
.createCompositeState(false)
27+
);
28+
29+
public static final RenderType ABYSS_ORB_GLOW = create(
30+
"mia_abyss_orb_glow",
31+
DefaultVertexFormat.POSITION_COLOR_LIGHTMAP,
32+
VertexFormat.Mode.TRIANGLES,
33+
1536,
34+
false,
35+
true,
36+
CompositeState.builder()
37+
.setShaderState(POSITION_COLOR_LIGHTMAP_SHADER)
38+
.setTransparencyState(ADDITIVE_TRANSPARENCY)
39+
.setWriteMaskState(COLOR_WRITE)
40+
.setCullState(NO_CULL)
41+
.setDepthTestState(LEQUAL_DEPTH_TEST)
42+
.createCompositeState(false)
43+
);
44+
}

src/main/java/com/altnoir/mia/core/spawner/AbyssTrialSpawner.java

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ private boolean trySpawnMob(ServerLevel level, BlockPos pos, AbyssTrialSpawnerPa
243243
return false;
244244
}
245245

246-
var entityType = selectedEntity.get().getEntityType();
246+
var entityInstance = selectedEntity.get();
247+
var entityType = entityInstance.getEntityType();
247248

248249
int range = pattern.spawnRange();
249250
for (int attempts = 0; attempts < 20; attempts++) {
@@ -258,6 +259,8 @@ private boolean trySpawnMob(ServerLevel level, BlockPos pos, AbyssTrialSpawnerPa
258259
if (entity != null) {
259260
if (entity instanceof Mob mob) {
260261
mob.finalizeSpawn(level, level.getCurrentDifficultyAt(spawnPos), MobSpawnType.TRIAL_SPAWNER, null);
262+
263+
applyEntityConfiguration(mob, entityInstance);
261264
}
262265

263266
level.addFreshEntity(entity);
@@ -280,6 +283,32 @@ private boolean trySpawnMob(ServerLevel level, BlockPos pos, AbyssTrialSpawnerPa
280283
return false;
281284
}
282285

286+
private void applyEntityConfiguration(Mob mob, EntityTableInstance entityInstance) {
287+
if (entityInstance.hasEquipment()) {
288+
for (var entry : entityInstance.getEquipment().entrySet()) {
289+
mob.setItemSlot(entry.getKey(), entry.getValue().copy());
290+
mob.setDropChance(entry.getKey(), 0.0F);
291+
}
292+
}
293+
294+
if (entityInstance.hasEffects()) {
295+
for (var effect : entityInstance.getEffects()) {
296+
mob.addEffect(new net.minecraft.world.effect.MobEffectInstance(effect));
297+
}
298+
}
299+
300+
if (entityInstance.hasAttributeModifiers()) {
301+
for (var entry : entityInstance.getAttributeModifiers().entrySet()) {
302+
var attributeInstance = mob.getAttribute(entry.getKey());
303+
if (attributeInstance != null) {
304+
attributeInstance.addPermanentModifier(entry.getValue());
305+
}
306+
}
307+
// Ensure mob's health matches new max health after modifiers
308+
mob.setHealth(mob.getMaxHealth());
309+
}
310+
}
311+
283312
private void collectRewardsForPlayer(ServerLevel level, BlockPos pos, Player player, AbyssTrialSpawnerPattern pattern) {
284313
var selectedLoot = WeightedRandom.getRandomItem(this.random, pattern.lootTables().unwrap());
285314
if (selectedLoot.isEmpty()) {
@@ -426,18 +455,6 @@ public double getOSpin() {
426455
return this.oSpin;
427456
}
428457

429-
@Nullable
430-
public Entity getOrCreateDisplayEntity(Level level, BlockPos pos) {
431-
if (this.displayEntity == null && hasValidPattern() && level instanceof ServerLevel serverLevel) {
432-
var pattern = getPattern();
433-
var selected = WeightedRandom.getRandomItem(this.random, pattern.entityTables().unwrap());
434-
if (selected.isPresent()) {
435-
this.displayEntity = selected.get().getEntityType().create(serverLevel, null, pos, MobSpawnType.TRIAL_SPAWNER, false, false);
436-
}
437-
}
438-
return this.displayEntity;
439-
}
440-
441458
public interface StateAccessor {
442459
TrialSpawnerState getState();
443460
void setState(Level level, TrialSpawnerState state);

0 commit comments

Comments
 (0)