mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/LCE-Revelations.git
synced 2026-05-22 13:14:50 +00:00
Display hardcore heart textures when a world is in hardcore mode, matching Java Edition behavior. Hearts switch between normal/hardcore across all states (poison, wither, flash) and all HUD resolutions. C++ changes: - IUIScene_HUD: check isHardcore() and call SetHardcoreMode() each tick - UIScene_HUD: send hardcore boolean to Flash via Iggy, invalidate SetHealth dirty check on state change to force heart redraw - CreateWorldMenu/LoadMenu: lock game mode to Survival when hardcore - MinecraftServer: gate server.properties hardcore override behind MINECRAFT_SERVER_BUILD so offline worlds preserve their saved flag SWF changes (via new Java tools): - AddHardcoreBitmaps: adds 10 hardcore heart bitmaps to graphics SWFs - AddHardcoreHearts: adds 10 new frames (15-24) to health sprite - PatchHudABC: patches HUD ActionScript bytecode with SetHardcore method and frame offset logic (+14 normal/poison, +6 wither) Also updates README changelog styling with consistent ### headings.
116 lines
3.9 KiB
Java
116 lines
3.9 KiB
Java
import com.jpexs.decompiler.flash.SWF;
|
|
import com.jpexs.decompiler.flash.tags.*;
|
|
import com.jpexs.decompiler.flash.tags.base.*;
|
|
import javax.imageio.ImageIO;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.*;
|
|
import java.util.*;
|
|
|
|
/**
|
|
* Adds hardcore heart bitmap assets to a skinGraphicsHud SWF.
|
|
* These bitmaps are referenced by class name from PlaceObject3 tags in
|
|
* the health sprite frames defined in the parent skinHud/skinHDHud SWF.
|
|
*
|
|
* Usage: AddHardcoreBitmaps <skinGraphicsHud.swf> <textures-dir> <output.swf>
|
|
*/
|
|
public class AddHardcoreBitmaps {
|
|
static final String[] TEXTURE_NAMES = {
|
|
"Health_Background_Hardcore",
|
|
"Health_Background_Hardcore_Flash",
|
|
"Health_Full_Hardcore",
|
|
"Health_Half_Hardcore",
|
|
"Health_Full_Flash_Hardcore",
|
|
"Health_Half_Flash_Hardcore",
|
|
"Health_Full_Poison_Hardcore",
|
|
"Health_Half_Poison_Hardcore",
|
|
"Health_Full_Poison_Flash_Hardcore",
|
|
"Health_Half_Poison_Flash_Hardcore"
|
|
};
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
if (args.length < 3) {
|
|
System.out.println("Usage: AddHardcoreBitmaps <skinGraphicsHud.swf> <textures-dir> <output.swf>");
|
|
System.exit(1);
|
|
}
|
|
|
|
String swfPath = args[0];
|
|
String texturesDir = args[1];
|
|
String outputPath = args[2];
|
|
|
|
System.out.println("Loading SWF: " + swfPath);
|
|
SWF swf = new SWF(new FileInputStream(swfPath), false);
|
|
|
|
// Find max character ID
|
|
int maxCharId = 0;
|
|
for (Tag tag : swf.getTags()) {
|
|
if (tag instanceof CharacterTag) {
|
|
int id = ((CharacterTag) tag).getCharacterId();
|
|
if (id > maxCharId) maxCharId = id;
|
|
}
|
|
}
|
|
System.out.println("Max existing character ID: " + maxCharId);
|
|
|
|
// Find SymbolClass tag
|
|
SymbolClassTag symbolClass = null;
|
|
int symbolClassIdx = -1;
|
|
for (int i = 0; i < swf.getTags().size(); i++) {
|
|
if (swf.getTags().get(i) instanceof SymbolClassTag) {
|
|
symbolClass = (SymbolClassTag) swf.getTags().get(i);
|
|
symbolClassIdx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (symbolClass == null) {
|
|
System.err.println("ERROR: No SymbolClass tag found");
|
|
System.exit(1);
|
|
}
|
|
|
|
int nextCharId = maxCharId + 1;
|
|
int added = 0;
|
|
|
|
for (String texName : TEXTURE_NAMES) {
|
|
String pngFile = texturesDir + "/" + texName + ".png";
|
|
File f = new File(pngFile);
|
|
if (!f.exists()) {
|
|
System.err.println("ERROR: Missing texture: " + pngFile);
|
|
System.exit(1);
|
|
}
|
|
|
|
BufferedImage img = ImageIO.read(f);
|
|
System.out.println(" Adding " + texName + " (id=" + nextCharId + ", " + img.getWidth() + "x" + img.getHeight() + ")");
|
|
|
|
// Create DefineBitsLossless2 tag
|
|
DefineBitsLossless2Tag bmp = new DefineBitsLossless2Tag(swf);
|
|
bmp.characterID = nextCharId;
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
ImageIO.write(img, "PNG", baos);
|
|
bmp.setImage(baos.toByteArray());
|
|
|
|
// Insert before SymbolClass
|
|
swf.addTag(symbolClassIdx, bmp);
|
|
symbolClassIdx++; // SymbolClass shifted by 1
|
|
|
|
// Add to SymbolClass
|
|
symbolClass.tags.add(nextCharId);
|
|
symbolClass.names.add(texName);
|
|
|
|
nextCharId++;
|
|
added++;
|
|
}
|
|
|
|
System.out.println("Added " + added + " hardcore heart bitmaps");
|
|
|
|
// Mark SymbolClass as modified so new entries get serialized
|
|
symbolClass.setModified(true);
|
|
|
|
// Save
|
|
System.out.println("Saving to: " + outputPath);
|
|
try (FileOutputStream fos = new FileOutputStream(outputPath)) {
|
|
swf.saveTo(fos);
|
|
}
|
|
System.out.println("Done!");
|
|
}
|
|
}
|