Skip to content

Commit bc21f64

Browse files
committed
war timer hellcode (also war terminal block)
1 parent b703623 commit bc21f64

File tree

17 files changed

+382
-78
lines changed

17 files changed

+382
-78
lines changed

src/main/java/breadmod/mixin/client/ClientLevelMixin.java

-28
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package breadmod.mixin.client;
2+
3+
import breadmod.ClientForgeEventBus;
4+
import breadmod.util.render.RenderGeneralKt;
5+
import net.minecraft.client.multiplayer.ClientLevel;
6+
import net.minecraft.client.renderer.LevelRenderer;
7+
import net.minecraft.util.Mth;
8+
import net.minecraft.world.phys.Vec3;
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.injection.At;
11+
import org.spongepowered.asm.mixin.injection.Redirect;
12+
13+
@Mixin(LevelRenderer.class)
14+
abstract class LevelRendererMixin {
15+
@Redirect(method = "renderSky",
16+
at = @At(
17+
value = "INVOKE",
18+
target = "Lnet/minecraft/client/multiplayer/ClientLevel;getSkyColor(Lnet/minecraft/world/phys/Vec3;F)Lnet/minecraft/world/phys/Vec3;"
19+
)
20+
)
21+
private Vec3 changeSkyColor(ClientLevel instance, Vec3 f7, float f10) {
22+
final Vec3 skyColor = instance.getSkyColor(f7, f10);
23+
final float redness = ClientForgeEventBus.INSTANCE.getRedness();
24+
final float rednessClamped = Mth.clamp(redness, 0f, 1f);
25+
if (RenderGeneralKt.getSkyColorMixinActive()) {
26+
return new Vec3(
27+
skyColor.x + rednessClamped,
28+
skyColor.y - rednessClamped,
29+
skyColor.z - rednessClamped
30+
);
31+
} else return instance.getSkyColor(f7, f10);
32+
}
33+
}

src/main/kotlin/breadmod/ClientForgeEventBus.kt

+73
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,24 @@ import breadmod.util.gui.IHoldScreen
1111
import breadmod.util.render.modifierMatches
1212
import breadmod.util.render.renderBuffer
1313
import breadmod.util.render.rgMinecraft
14+
import breadmod.util.render.skyColorMixinActive
1415
import com.mojang.blaze3d.platform.InputConstants
16+
import com.mojang.blaze3d.systems.RenderSystem
17+
import com.mojang.blaze3d.vertex.BufferUploader
18+
import com.mojang.blaze3d.vertex.DefaultVertexFormat
19+
import com.mojang.blaze3d.vertex.Tesselator
20+
import com.mojang.blaze3d.vertex.VertexFormat
21+
import com.mojang.math.Axis
22+
import net.minecraft.Util
1523
import net.minecraft.client.KeyMapping
1624
import net.minecraft.client.Minecraft
1725
import net.minecraft.client.gui.screens.Screen
1826
import net.minecraft.client.player.LocalPlayer
27+
import net.minecraft.client.renderer.FogRenderer
28+
import net.minecraft.client.renderer.GameRenderer
1929
import net.minecraft.commands.Commands
2030
import net.minecraft.sounds.SoundEvents
31+
import net.minecraft.util.Mth.clamp
2132
import net.minecraft.world.item.ItemStack
2233
import net.minecraftforge.api.distmarker.Dist
2334
import net.minecraftforge.client.event.InputEvent
@@ -31,6 +42,9 @@ import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent
3142
import net.minecraftforge.eventbus.api.SubscribeEvent
3243
import net.minecraftforge.fml.common.Mod
3344
import org.apache.commons.lang3.ArrayUtils
45+
import kotlin.math.cos
46+
import kotlin.math.max
47+
import kotlin.math.sin
3448

3549
@Suppress("unused")
3650
@Mod.EventBusSubscriber(modid = ModMain.ID, bus = Mod.EventBusSubscriber.Bus.FORGE, value = [Dist.CLIENT])
@@ -77,6 +91,65 @@ object ClientForgeEventBus {
7791
)
7892
}
7993

94+
var redness = 0f
95+
96+
@SubscribeEvent
97+
fun renderStageEvent(event: RenderLevelStageEvent) {
98+
if (event.stage == RenderLevelStageEvent.Stage.AFTER_SKY && WarTickerClient.timerActive) {
99+
val poseStack = event.poseStack
100+
val bufferBuilder = Tesselator.getInstance().builder
101+
val millis = Util.getMillis()
102+
103+
RenderSystem.setShader { GameRenderer.getPositionColorShader() }
104+
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
105+
RenderSystem.enableBlend()
106+
poseStack.pushPose()
107+
poseStack.mulPose(Axis.XP.rotationDegrees(-17f))
108+
val matrix = poseStack.last().pose()
109+
bufferBuilder.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION_COLOR)
110+
bufferBuilder.vertex(matrix, 0f, 100f, 0f).color(0.9f, 0f, 0.1f, clamp(redness - 0.2f, 0f, 1f)).endVertex()
111+
112+
for (j: Int in 0..16) {
113+
val f1 = j * (Math.PI.toFloat() * 2f) / 16f
114+
val f2: Float = sin(f1)
115+
val f3: Float = cos(f1)
116+
bufferBuilder.vertex(matrix, f2, -1f, -f3).color(0.9f, 0f, 0.1f, clamp(redness - 0.2f, 0f, 1f)).endVertex()
117+
}
118+
119+
val shaderFogColor = RenderSystem.getShaderFogColor()
120+
RenderSystem.setShaderFogColor(
121+
shaderFogColor[0] + redness,
122+
shaderFogColor[1] - redness,
123+
shaderFogColor[2] - redness,
124+
1f
125+
)
126+
FogRenderer.setupFog(
127+
event.camera,
128+
FogRenderer.FogMode.FOG_SKY,
129+
256f,
130+
true,
131+
event.partialTick
132+
)
133+
FogRenderer.setupFog(
134+
event.camera,
135+
FogRenderer.FogMode.FOG_TERRAIN,
136+
max(256f, 32f),
137+
true,
138+
event.partialTick
139+
)
140+
141+
redness = clamp((sin(millis.toFloat() / 1800) + 1) / 2, 0f, 1f)
142+
skyColorMixinActive = true
143+
144+
BufferUploader.drawWithShader(bufferBuilder.end())
145+
RenderSystem.disableBlend()
146+
poseStack.popPose()
147+
} else if (!WarTickerClient.timerActive) {
148+
redness = 0.0f
149+
skyColorMixinActive = false
150+
}
151+
}
152+
80153
private fun handleToolgunInput(
81154
player: LocalPlayer,
82155
itemHeld: ToolGunItem, stackHeld: ItemStack,

src/main/kotlin/breadmod/CommonForgeEventBus.kt

+38-12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import breadmod.commands.server.WarTimerCommand
44
import breadmod.datagen.tool_gun.ModToolGunModeDataLoader
55
import breadmod.network.PacketHandler
66
import breadmod.network.clientbound.war_timer.WarTimerSynchronizationPacket
7+
import breadmod.network.clientbound.war_timer.WarTimerTogglePacket
8+
import breadmod.util.ModDamageTypes
79
import net.minecraft.commands.Commands
810
import net.minecraft.server.level.ServerPlayer
911
import net.minecraftforge.event.AddReloadListenerEvent
@@ -24,15 +26,17 @@ object CommonForgeEventBus {
2426
/**
2527
* A map holding a war timer for every player on the server
2628
* * First int holds the time left.
27-
* * Second int holds the delay (or ticker) before the time left decrements by one.
28-
* * Third int holds the increasing timer (how long the timer will increase for).
29-
* * First boolean is for the timer being active or not.
30-
* * Second boolean is if the timer is currently increasing in time.
29+
* * Second int holds the grace period left before the timer completely expires
30+
* * Third int holds the delay (or ticker) before the time left decrements by one.
31+
* * Fourth int holds the increasing timer (how long the timer will increase for).
32+
* * First boolean is for if the timer grace period is active or not
33+
* * Second boolean is for the timer being active or not.
34+
* * Third boolean is if the timer is currently increasing in time.
3135
* * Players need to manually be added to the timer map using the warTimer command
3236
* * Server automatically pauses the player's timer if they leave and unpauses when they rejoin
3337
* * Timer is automatically removed if their time left is 0 or their timer is force ended by an admin
3438
*/
35-
val warTimerMap: MutableMap<ServerPlayer, Pair<Triple<Int, Int, Int>, Pair<Boolean, Boolean>>> = mutableMapOf()
39+
val warTimerMap: MutableMap<ServerPlayer, Pair<Triple<Triple<Int, Int, Boolean>, Int, Int>, Pair<Boolean, Boolean>>> = mutableMapOf()
3640

3741
@SubscribeEvent
3842
fun serverTick(event: TickEvent.ServerTickEvent) {
@@ -41,32 +45,54 @@ object CommonForgeEventBus {
4145

4246
private fun warTimerTick() {
4347
warTimerMap.forEach { (key, value) ->
44-
val timeLeft = value.first.first
48+
val timeLeft = value.first.first.first
4549
val ticker = value.first.second
4650
val increaseTime = value.first.third
4751
val active = value.second.first
4852
val isIncreasing = value.second.second
4953

54+
val gracePeriodActive = value.first.first.third
55+
val gracePeriod = value.first.first.second
56+
5057
warTimerMap[key]?.let {
5158
if (active && !isIncreasing) {
52-
if (ticker == 0 && timeLeft > 0) {
59+
if (ticker == 0 && timeLeft > 0 && !gracePeriodActive) {
5360
val timeDecrement = timeLeft - 1
54-
warTimerMap[key] = Triple(timeDecrement, 41, increaseTime) to it.second
61+
warTimerMap[key] = Triple(Triple(timeDecrement, gracePeriod, false), 40, increaseTime) to it.second
5562
PacketHandler.NETWORK.send(
5663
PacketDistributor.PLAYER.with { key },
5764
WarTimerSynchronizationPacket(timeDecrement)
5865
)
59-
} else if (timeLeft > 0) {
66+
} else if (!gracePeriodActive && ticker != 0) {
6067
val tickerDecrement = ticker - 1
61-
warTimerMap[key] = Triple(timeLeft, tickerDecrement, increaseTime) to it.second
68+
warTimerMap[key] = Triple(Triple(timeLeft, gracePeriod, false), tickerDecrement, increaseTime) to it.second
69+
} else if (timeLeft == 0 && !gracePeriodActive) {
70+
warTimerMap[key] = Triple(Triple(timeLeft, gracePeriod, true), 40, increaseTime) to it.second
71+
PacketHandler.NETWORK.send(
72+
PacketDistributor.PLAYER.with { key },
73+
WarTimerSynchronizationPacket(timeLeft)
74+
)
75+
} else if (gracePeriodActive && gracePeriod != 0) {
76+
println(gracePeriod)
77+
val gracePeriodDecrement = gracePeriod - 1
78+
warTimerMap[key] = Triple(Triple(timeLeft, gracePeriodDecrement, true), 40, increaseTime) to it.second
79+
} else if (timeLeft == 0) {
80+
if (!key.isCreative) {
81+
key.hurt(ModDamageTypes.TIMER_RAN_OUT.source(key.level()), 1000f)
82+
}
83+
warTimerMap.remove(key)
84+
PacketHandler.NETWORK.send(
85+
PacketDistributor.PLAYER.with { key },
86+
WarTimerTogglePacket(false)
87+
)
6288
}
6389
}
6490
if (increaseTime > 0 && isIncreasing) {
6591
val increasingDecrement = increaseTime - 1
6692
val increasingTime = timeLeft + 1
67-
warTimerMap[key] = Triple(increasingTime, ticker, increasingDecrement) to it.second
93+
warTimerMap[key] = Triple(Triple(increasingTime, gracePeriod, false), ticker, increasingDecrement) to it.second
6894
} else if (isIncreasing && increaseTime == 0) {
69-
warTimerMap[key] = Triple(timeLeft, ticker, increaseTime) to (it.second.first to false)
95+
warTimerMap[key] = Triple(Triple(timeLeft, gracePeriod, false), ticker, increaseTime) to (it.second.first to false)
7096
}
7197
}
7298
}

src/main/kotlin/breadmod/block/WarTerminalBlock.kt

+59-1
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,55 @@ import breadmod.CommonForgeEventBus.warTimerMap
44
import breadmod.network.PacketHandler
55
import breadmod.network.clientbound.war_timer.WarTimerIncrementPacket
66
import net.minecraft.core.BlockPos
7+
import net.minecraft.core.Direction
78
import net.minecraft.world.entity.player.Player
9+
import net.minecraft.world.item.context.BlockPlaceContext
10+
import net.minecraft.world.level.BlockGetter
811
import net.minecraft.world.level.Level
912
import net.minecraft.world.level.block.Block
1013
import net.minecraft.world.level.block.state.BlockState
14+
import net.minecraft.world.level.block.state.StateDefinition
15+
import net.minecraft.world.level.block.state.properties.BlockStateProperties
1116
import net.minecraft.world.level.material.FluidState
17+
import net.minecraft.world.phys.shapes.BooleanOp
18+
import net.minecraft.world.phys.shapes.CollisionContext
19+
import net.minecraft.world.phys.shapes.Shapes
20+
import net.minecraft.world.phys.shapes.VoxelShape
1221
import net.minecraftforge.network.PacketDistributor
22+
import java.util.stream.Stream
1323

14-
// todo 3d model, texturing, sounds
1524
class WarTerminalBlock: Block(Properties.of()) {
25+
val northAABB = Stream.of(
26+
box(0.0, 6.0, 0.0, 16.0, 7.0, 1.0),
27+
box(0.0, 0.0, 1.0, 16.0, 7.0, 5.0),
28+
box(0.0, 0.0, 5.0, 16.0, 16.0, 16.0)
29+
).reduce{ v1, v2 -> Shapes.join(v1, v2, BooleanOp.OR) }.get()
30+
val southAABB = Stream.of(
31+
box(0.0, 6.0, 15.0, 16.0, 7.0, 16.0),
32+
box(0.0, 0.0, 11.0, 16.0, 7.0, 15.0),
33+
box(0.0, 0.0, 0.0, 16.0, 16.0, 11.0)
34+
).reduce{ v1, v2 -> Shapes.join(v1, v2, BooleanOp.OR) }.get()
35+
val eastAABB = Stream.of(
36+
box(15.0, 6.0, 0.0, 16.0, 7.0, 16.0),
37+
box(11.0, 0.0, 0.0, 15.0, 7.0, 16.0),
38+
box(0.0, 0.0, 0.0, 11.0, 16.0, 16.0)
39+
).reduce{ v1, v2 -> Shapes.join(v1, v2, BooleanOp.OR) }.get()
40+
val westAABB = Stream.of(
41+
box(0.0, 6.0, 0.0, 1.0, 7.0, 16.0),
42+
box(1.0, 0.0, 0.0, 5.0, 7.0, 16.0),
43+
box(5.0, 0.0, 0.0, 16.0, 16.0, 16.0)
44+
).reduce{ v1, v2 -> Shapes.join(v1, v2, BooleanOp.OR) }.get()
45+
46+
init {
47+
registerDefaultState(defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, Direction.NORTH))
48+
}
49+
50+
override fun getStateForPlacement(pContext: BlockPlaceContext): BlockState =
51+
defaultBlockState().setValue(BlockStateProperties.HORIZONTAL_FACING, pContext.horizontalDirection.opposite)
52+
53+
override fun createBlockStateDefinition(pBuilder: StateDefinition.Builder<Block, BlockState>) {
54+
pBuilder.add(BlockStateProperties.HORIZONTAL_FACING)
55+
}
1656

1757
override fun onDestroyedByPlayer(
1858
state: BlockState,
@@ -35,4 +75,22 @@ class WarTerminalBlock: Block(Properties.of()) {
3575
}
3676
return super.onDestroyedByPlayer(state, level, pos, player, willHarvest, fluid)
3777
}
78+
79+
@Deprecated(
80+
"Deprecated in Java", ReplaceWith(
81+
"super.getShape(pState, pLevel, pPos, pContext)",
82+
"net.minecraft.world.level.block.Block"
83+
)
84+
)
85+
override fun getShape(
86+
pState: BlockState,
87+
pLevel: BlockGetter,
88+
pPos: BlockPos,
89+
pContext: CollisionContext
90+
): VoxelShape = when (pState.getValue(BlockStateProperties.HORIZONTAL_FACING)) {
91+
Direction.SOUTH -> southAABB
92+
Direction.EAST -> eastAABB
93+
Direction.WEST -> westAABB
94+
else -> northAABB
95+
}
3896
}

src/main/kotlin/breadmod/client/gui/WarOverlay.kt

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package breadmod.client.gui
22

33
import breadmod.ModMain.modLocation
4-
import breadmod.client.gui.WarTickerClient.lastTimerPosition
5-
import breadmod.client.gui.WarTickerClient.timerPosition
4+
import breadmod.client.gui.WarTickerClient.timerActive
65
import breadmod.util.ModFonts
76
import breadmod.util.render.rgMinecraft
87
import breadmod.util.render.scaleFlat
98
import com.mojang.blaze3d.vertex.PoseStack
9+
import net.minecraft.Util
1010
import net.minecraft.client.gui.GuiGraphics
1111
import net.minecraft.client.player.LocalPlayer
1212
import net.minecraft.client.renderer.MultiBufferSource
@@ -17,6 +17,8 @@ import java.awt.Color
1717

1818
class WarOverlay : AbstractModGuiOverlay() {
1919
private val overlayTexture = modLocation("textures", "gui", "hud", "war_overlay_timer.png")
20+
var timerPosition = -110f
21+
var lastTimerPosition = -110f
2022

2123
override fun renderOverlay(
2224
pGui: ForgeGui,
@@ -35,11 +37,18 @@ class WarOverlay : AbstractModGuiOverlay() {
3537
val colorPair: Triple<Float, Float, Float> =
3638
if (WarTickerClient.isTimerIncreasing) Triple(0.376f, 0.91f, 0.471f)
3739
else Triple(0.973f, 0f, 0f)
40+
val millis = Util.getMillis()
41+
42+
if (timerPosition > -110.0 && !timerActive) {
43+
timerPosition -= Mth.clamp(millis / 2700f, 0f, 1f)
44+
} else if (timerPosition < -1.0 && timerActive) {
45+
timerPosition += Mth.clamp(millis / 2700f, 0f, 1f)
46+
}
3847

3948
if (timerPosition > -110f) {
4049
pPoseStack.pushPose()
4150
pPoseStack.scaleFlat(0.5f)
42-
pPoseStack.translate(0.0, Mth.lerp(rgMinecraft.partialTick, lastTimerPosition, timerPosition).toDouble(), 0.0)
51+
pPoseStack.translate(0.0, timerPosition.toDouble(), 0.0)
4352
pPoseStack.translate(pScreenWidth - (pScreenWidth / 2).toDouble(), 0.0, 0.0)
4453
pGuiGraphics.blit(overlayTexture, 0, 0, 0, 0, 163, 89)
4554
pGuiGraphics.blit(overlayTexture, 163, 0, 0, 90, 166, 111)

0 commit comments

Comments
 (0)