LasertagCreditsScreen()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
package de.pewpewproject.lasertag.client.screen;
2
3
import com.google.common.collect.Lists;
4
import com.google.gson.JsonArray;
5
import com.google.gson.JsonElement;
6
import com.google.gson.JsonObject;
7
import com.mojang.blaze3d.platform.GlStateManager;
8
import com.mojang.blaze3d.systems.RenderSystem;
9
import de.pewpewproject.lasertag.LasertagMod;
10
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
11
import it.unimi.dsi.fastutil.ints.IntSet;
12
import net.fabricmc.api.EnvType;
13
import net.fabricmc.api.Environment;
14
import net.minecraft.client.gui.DrawableHelper;
15
import net.minecraft.client.gui.screen.Screen;
16
import net.minecraft.client.render.*;
17
import net.minecraft.client.util.NarratorManager;
18
import net.minecraft.client.util.math.MatrixStack;
19
import net.minecraft.text.OrderedText;
20
import net.minecraft.text.Text;
21
import net.minecraft.util.Formatting;
22
import net.minecraft.util.Identifier;
23
import net.minecraft.util.JsonHelper;
24
import net.minecraft.util.math.random.Random;
25
import org.lwjgl.glfw.GLFW;
26
27
import java.io.BufferedReader;
28
import java.io.IOException;
29
import java.io.Reader;
30
import java.util.List;
31
32
/**
33
 * The lasertag credits screen - Heavily inspired by the standard Minecraft credits screen
34
 *
35
 * @author Étienne Muser
36
 */
37
public class LasertagCreditsScreen extends Screen {
38
    private static final Identifier LASERTAG_TITLE_TEXTURE = new Identifier(LasertagMod.ID, "textures/gui/title/lasertag_mod_banner.png");
39
    private static final Identifier VIGNETTE_TEXTURE = new Identifier("textures/misc/vignette.png");
40
    private static final Text SEPARATOR_LINE = Text.literal("============").formatted(Formatting.WHITE);
41
    private static final String CENTERED_LINE_PREFIX = "           ";
42
    private static final String OBFUSCATION_PLACEHOLDER = "" + Formatting.WHITE + Formatting.OBFUSCATED + Formatting.GREEN + Formatting.AQUA;
43
    private float time;
44
    private List<OrderedText> credits;
45
    private IntSet centeredLines;
46
    private int creditsHeight;
47
    private boolean spaceKeyPressed;
48
    private final IntSet pressedCtrlKeys = new IntOpenHashSet();
49
    private float speed;
50
    private final float baseSpeed;
51
52
    public LasertagCreditsScreen() {
53
        super(NarratorManager.EMPTY);
54
        this.baseSpeed = 0.5f;
55
        this.speed = this.baseSpeed;
56
    }
57
58
    private float getSpeed() {
59
        if (this.spaceKeyPressed) {
60
            return this.baseSpeed * (5.0f + (float)this.pressedCtrlKeys.size() * 15.0f);
61
        }
62
        return this.baseSpeed;
63
    }
64
65
    @Override
66
    public void tick() {
67
        this.client.getMusicTracker().tick();
68
        this.client.getSoundManager().tick(false);
69
        float f = this.creditsHeight + this.height + this.height + 24;
70
        if (this.time > f) {
71
            this.closeScreen();
72
        }
73
    }
74
75
    @Override
76
    public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
77
        if (keyCode == GLFW.GLFW_KEY_LEFT_CONTROL || keyCode == GLFW.GLFW_KEY_RIGHT_CONTROL) {
78
            this.pressedCtrlKeys.add(keyCode);
79
        } else if (keyCode == GLFW.GLFW_KEY_SPACE) {
80
            this.spaceKeyPressed = true;
81
        }
82
        this.speed = this.getSpeed();
83
        return super.keyPressed(keyCode, scanCode, modifiers);
84
    }
85
86
    @Override
87
    public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
88
        if (keyCode == GLFW.GLFW_KEY_SPACE) {
89
            this.spaceKeyPressed = false;
90
        } else if (keyCode == GLFW.GLFW_KEY_LEFT_CONTROL || keyCode == GLFW.GLFW_KEY_RIGHT_CONTROL) {
91
            this.pressedCtrlKeys.remove(keyCode);
92
        }
93
        this.speed = this.getSpeed();
94
        return super.keyReleased(keyCode, scanCode, modifiers);
95
    }
96
97
    @Override
98
    public void close() {
99
        this.closeScreen();
100
    }
101
102
    private void closeScreen() {
103
        this.client.setScreen(null);
104
    }
105
106
    @Override
107
    protected void init() {
108
        if (this.credits != null) {
109
            return;
110
        }
111
        this.credits = Lists.newArrayList();
112
        this.centeredLines = new IntOpenHashSet();
113
        this.load("texts/credits.json", this::readCredits);
114
        this.load("texts/postcredits.txt", this::readPoem);
115
        this.creditsHeight = this.credits.size() * 12;
116
    }
117
118
    private void load(String id, LasertagCreditsScreen.CreditsReader reader) {
119
        try (BufferedReader reader2 = this.client.getResourceManager().openAsReader(new Identifier(LasertagMod.ID, id))){
120
            reader.read(reader2);
121
        }
122
        catch (Exception exception) {
123
            LasertagMod.LOGGER.error("Couldn't load lasertag credits", exception);
124
        }
125
    }
126
127
    private void readPoem(Reader reader) throws IOException {
128
        int i;
129
        String line;
130
        BufferedReader bufferedReader = new BufferedReader(reader);
131
        Random random = Random.create(8124371L);
132
        while ((line = bufferedReader.readLine()) != null) {
133
            line = line.replaceAll("PLAYERNAME", this.client.getSession().getUsername());
134
            while ((i = line.indexOf(OBFUSCATION_PLACEHOLDER)) != -1) {
135
                String string2 = line.substring(0, i);
136
                String string3 = line.substring(i + OBFUSCATION_PLACEHOLDER.length());
137
                line = string2 + Formatting.WHITE + Formatting.OBFUSCATED + "XXXXXXXX".substring(0, random.nextInt(4) + 3) + string3;
138
            }
139
            this.addText(line);
140
            this.addEmptyLine();
141
        }
142
        for (i = 0; i < 8; ++i) {
143
            this.addEmptyLine();
144
        }
145
    }
146
147
    private void readCredits(Reader reader) {
148
        JsonArray jsonArray = JsonHelper.deserializeArray(reader);
149
        for (JsonElement jsonElement : jsonArray) {
150
            JsonObject jsonObject = jsonElement.getAsJsonObject();
151
            String string = jsonObject.get("section").getAsString();
152
            this.addText(SEPARATOR_LINE, true);
153
            this.addText(Text.literal(string).formatted(Formatting.YELLOW), true);
154
            this.addText(SEPARATOR_LINE, true);
155
            this.addEmptyLine();
156
            this.addEmptyLine();
157
            JsonArray jsonArray2 = jsonObject.getAsJsonArray("titles");
158
            for (JsonElement jsonElement2 : jsonArray2) {
159
                JsonObject jsonObject2 = jsonElement2.getAsJsonObject();
160
                String string2 = jsonObject2.get("title").getAsString();
161
                JsonArray jsonArray3 = jsonObject2.getAsJsonArray("names");
162
                this.addText(Text.literal(string2).formatted(Formatting.GRAY), false);
163
                for (JsonElement jsonElement3 : jsonArray3) {
164
                    String string3 = jsonElement3.getAsString();
165
                    this.addText(Text.literal(CENTERED_LINE_PREFIX).append(string3).formatted(Formatting.WHITE), false);
166
                }
167
                this.addEmptyLine();
168
                this.addEmptyLine();
169
            }
170
        }
171
    }
172
173
    private void addEmptyLine() {
174
        this.credits.add(OrderedText.EMPTY);
175
    }
176
177
    private void addText(String text) {
178
        this.credits.addAll(this.client.textRenderer.wrapLines(Text.literal(text), 274));
179
    }
180
181
    private void addText(Text text, boolean centered) {
182
        if (centered) {
183
            this.centeredLines.add(this.credits.size());
184
        }
185
        this.credits.add(text.asOrderedText());
186
    }
187
188
    private void renderBackground() {
189
        RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
190
        RenderSystem.setShaderTexture(0, DrawableHelper.OPTIONS_BACKGROUND_TEXTURE);
191
        int i = this.width;
192
        float f = -this.time * 0.5f;
193
        float g = (float)this.height - 0.5f * this.time;
194
        float j = this.time / this.baseSpeed;
195
        float k = j * 0.02f;
196
        float l = (float)(this.creditsHeight + this.height + this.height + 24) / this.baseSpeed;
197
        float m = (l - 20.0f - j) * 0.005f;
198
        if (m < k) {
199
            k = m;
200
        }
201
        if (k > 1.0f) {
202
            k = 1.0f;
203
        }
204
        k *= k;
205
        k = k * 96.0f / 255.0f;
206
        Tessellator tessellator = Tessellator.getInstance();
207
        BufferBuilder bufferBuilder = tessellator.getBuffer();
208
        bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
209
        bufferBuilder.vertex(0.0,    this.height, this.getZOffset()).texture(0.0f,                 f * 0.015625f).color(k, k, k, 1.0f).next();
210
        bufferBuilder.vertex(i,         this.height, this.getZOffset()).texture((float)i * 0.015625f, f * 0.015625f).color(k, k, k, 1.0f).next();
211
        bufferBuilder.vertex(i,      0.0,         this.getZOffset()).texture((float)i * 0.015625f, g * 0.015625f).color(k, k, k, 1.0f).next();
212
        bufferBuilder.vertex(0.0, 0.0,         this.getZOffset()).texture(0.0f,                 g * 0.015625f).color(k, k, k, 1.0f).next();
213
        tessellator.draw();
214
    }
215
216
    @Override
217
    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
218
        int l;
219
        this.time += delta * this.speed;
220
        this.renderBackground();
221
        int xPos = this.width / 2 - 137;
222
        int yPos = this.height + 50;
223
        float f = -this.time;
224
        matrices.push();
225
        matrices.translate(0.0, f, 0.0);
226
        RenderSystem.setShaderTexture(0, LASERTAG_TITLE_TEXTURE);
227
        RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f);
228
        RenderSystem.enableBlend();
229
        DrawableHelper.drawTexture(matrices, xPos, yPos, 0, 0, 310, 100, 310, 100);
230
        RenderSystem.disableBlend();
231
        int k = yPos + 100;
232
        for (l = 0; l < this.credits.size(); ++l) {
233
            float g;
234
            if (l == this.credits.size() - 1 && (g = (float)k + f - (float)(this.height / 2 - 6)) < 0.0f) {
235
                matrices.translate(0.0, -g, 0.0);
236
            }
237
            if ((float)k + f + 12.0f + 8.0f > 0.0f && (float)k + f < (float)this.height) {
238
                OrderedText orderedText = this.credits.get(l);
239
                if (this.centeredLines.contains(l)) {
240
                    this.textRenderer.drawWithShadow(matrices, orderedText, (float)(xPos + (274 - this.textRenderer.getWidth(orderedText)) / 2), (float)k, 0xFFFFFF);
241
                } else {
242
                    this.textRenderer.drawWithShadow(matrices, orderedText, (float)xPos, (float)k, 0xFFFFFF);
243
                }
244
            }
245
            k += 12;
246
        }
247
        matrices.pop();
248
        RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
249
        RenderSystem.setShaderTexture(0, VIGNETTE_TEXTURE);
250
        RenderSystem.enableBlend();
251
        RenderSystem.blendFunc(GlStateManager.SrcFactor.ZERO, GlStateManager.DstFactor.ONE_MINUS_SRC_COLOR);
252
        l = this.width;
253
        int m = this.height;
254
        Tessellator tessellator = Tessellator.getInstance();
255
        BufferBuilder bufferBuilder = tessellator.getBuffer();
256
        bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
257
        bufferBuilder.vertex(0.0, m, this.getZOffset()).texture(0.0f, 1.0f).color(1.0f, 1.0f, 1.0f, 1.0f).next();
258
        bufferBuilder.vertex(l, m, this.getZOffset()).texture(1.0f, 1.0f).color(1.0f, 1.0f, 1.0f, 1.0f).next();
259
        bufferBuilder.vertex(l, 0.0, this.getZOffset()).texture(1.0f, 0.0f).color(1.0f, 1.0f, 1.0f, 1.0f).next();
260
        bufferBuilder.vertex(0.0, 0.0, this.getZOffset()).texture(0.0f, 0.0f).color(1.0f, 1.0f, 1.0f, 1.0f).next();
261
        tessellator.draw();
262
        RenderSystem.disableBlend();
263
        super.render(matrices, mouseX, mouseY, delta);
264
    }
265
266
    @FunctionalInterface
267
    @Environment(value= EnvType.CLIENT)
268
    interface CreditsReader {
269
        void read(Reader var1) throws IOException;
270
    }
271
}
272