2
0
Fork 0

Carriage system created, but unpolished

main
KeyLime17 6 months ago
parent f81103fbc6
commit 24f6c207f2

@ -9,6 +9,8 @@ import com.zivilon.cinder_loe.client.render.*;
import com.zivilon.cinder_loe.client.render.corrupt.*;
import com.zivilon.cinder_loe.client.render.projectile.*;
import com.zivilon.cinder_loe.command.CommandCinderCharacter;
import com.zivilon.cinder_loe.command.CommandOpenCarriageMenu;
import com.zivilon.cinder_loe.command.CommandSetDestination;
import com.zivilon.cinder_loe.command.CommandWarband;
import com.zivilon.cinder_loe.entity.*;
import com.zivilon.cinder_loe.entity.animals.Monkey;
@ -366,6 +368,8 @@ public class CinderLoE {
CharacterRoleAPI.loadRolesFromFile();
event.registerServerCommand(new CommandCinderCharacter());
event.registerServerCommand(new CommandWarband());
event.registerServerCommand(new CommandOpenCarriageMenu());
event.registerServerCommand(new CommandSetDestination());
// event.registerServerCommand(new CommandMobileSound());
}

@ -0,0 +1,14 @@
package com.zivilon.cinder_loe.carriage;
public class CarriageDestination {
public final String name;
public final int x, y, z;
public final int dimension;
public CarriageDestination(String name, int x, int y, int z, int dimension) {
this.name = name;
this.x = x;
this.y = y;
this.z = z;
this.dimension = dimension;
}
}

@ -0,0 +1,148 @@
package com.zivilon.cinder_loe.carriage;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData;
import net.minecraft.world.WorldServer;
import net.minecraft.world.storage.MapStorage;
import java.util.*;
public class CarriageDestinationsData extends WorldSavedData {
public static final String DATA_NAME = "carriage_destinations";
private final Map<String, CarriageDestination> destinations = new HashMap<>();
public CarriageDestinationsData() {
super(DATA_NAME);
}
public CarriageDestinationsData(String name) {
super(name);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
destinations.clear();
NBTTagList list = nbt.getTagList("Destinations", 10);
for (int i = 0; i < list.tagCount(); i++) {
NBTTagCompound tag = list.getCompoundTagAt(i);
String name = tag.getString("Name");
int x = tag.getInteger("X");
int y = tag.getInteger("Y");
int z = tag.getInteger("Z");
int dim = tag.getInteger("Dim");
int defaultCost = 50; // or whatever default you want
destinations.put(name, new CarriageDestination(name, x, y, z, dim));
}
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
NBTTagList list = new NBTTagList();
for (CarriageDestination dest : destinations.values()) {
NBTTagCompound tag = new NBTTagCompound();
tag.setString("Name", dest.name);
tag.setInteger("X", dest.x);
tag.setInteger("Y", dest.y);
tag.setInteger("Z", dest.z);
tag.setInteger("Dim", dest.dimension);
list.appendTag(tag);
}
nbt.setTag("Destinations", list);
}
public void addDestination(CarriageDestination dest) {
destinations.put(dest.name, dest);
markDirty();
}
public Map<String, CarriageDestination> getDestinations() {
return destinations;
}
public static CarriageDestinationsData get(World world) {
if (!world.isRemote && world instanceof WorldServer) {
MapStorage storage = ((WorldServer) world).mapStorage;
CarriageDestinationsData data = (CarriageDestinationsData) storage.loadData(CarriageDestinationsData.class, DATA_NAME);
if (data == null) {
data = new CarriageDestinationsData();
storage.setData(DATA_NAME, data);
}
return data;
}
return null;
}
public List<CarriageDestination> getNearestFour(double px, double pz) {
CarriageDestination north = null, south = null, east = null, west = null;
double nDist = Double.MAX_VALUE, sDist = Double.MAX_VALUE, eDist = Double.MAX_VALUE, wDist = Double.MAX_VALUE;
Set<CarriageDestination> alreadyPicked = new HashSet<>();
for (CarriageDestination dest : destinations.values()) {
double dx = dest.x - px;
double dz = dest.z - pz;
double distance = Math.sqrt(dx * dx + dz * dz);
if (distance < 10) {
continue; // skip nearby
}
// north
if (dz < 0 && Math.abs(dz) < nDist && !alreadyPicked.contains(dest)) {
nDist = Math.abs(dz);
north = dest;
}
// south
if (dz > 0 && dz < sDist && !alreadyPicked.contains(dest)) {
sDist = dz;
south = dest;
}
// east
if (dx > 0 && dx < eDist && !alreadyPicked.contains(dest)) {
eDist = dx;
east = dest;
}
// west
if (dx < 0 && Math.abs(dx) < wDist && !alreadyPicked.contains(dest)) {
wDist = Math.abs(dx);
west = dest;
}
}
// track already selected
if (north != null) alreadyPicked.add(north);
if (south != null) alreadyPicked.add(south);
if (east != null) alreadyPicked.add(east);
if (west != null) alreadyPicked.add(west);
// second pass: fill missing slots with next nearest
for (CarriageDestination dest : destinations.values()) {
if (alreadyPicked.contains(dest)) continue;
double dx = dest.x - px;
double dz = dest.z - pz;
double distance = Math.sqrt(dx * dx + dz * dz);
if (distance < 10) continue;
if (north == null && dz < 0) { north = dest; alreadyPicked.add(dest); continue; }
if (south == null && dz > 0) { south = dest; alreadyPicked.add(dest); continue; }
if (east == null && dx > 0) { east = dest; alreadyPicked.add(dest); continue; }
if (west == null && dx < 0) { west = dest; alreadyPicked.add(dest); continue; }
}
List<CarriageDestination> result = new ArrayList<>();
if (north != null) result.add(north);
if (south != null) result.add(south);
if (east != null) result.add(east);
if (west != null) result.add(west);
return result;
}
}

@ -0,0 +1,88 @@
package com.zivilon.cinder_loe.carriage;
import lotr.common.LOTRMod;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
public class CarriageUtils {
public static boolean hasEnoughCoins(EntityPlayer player, int cost) {
int total = 0;
for (ItemStack stack : player.inventory.mainInventory) {
if (stack != null && stack.getItem() == LOTRMod.silverCoin) {
int value = getCoinValue(stack);
total += value * stack.stackSize;
if (total >= cost) {
return true;
}
}
}
return total >= cost;
}
public static boolean removeCoins(EntityPlayer player, int cost) {
int total = 0;
int[] counts = new int[3]; // 0 = $1, 1 = $10, 2 = $100
// Step 1: Count total money and track counts
for (ItemStack stack : player.inventory.mainInventory) {
if (stack != null && stack.getItem() == LOTRMod.silverCoin) {
int value = getCoinValue(stack);
total += value * stack.stackSize;
counts[stack.getItemDamage()] += stack.stackSize;
}
}
if (total < cost) {
return false; // Not enough money
}
// Step 2: Remove only coin stacks
for (int i = 0; i < player.inventory.mainInventory.length; i++) {
ItemStack stack = player.inventory.mainInventory[i];
if (stack != null && stack.getItem() == LOTRMod.silverCoin) {
player.inventory.setInventorySlotContents(i, null);
}
}
// Step 3: Calculate remaining change
int change = total - cost;
// Step 4: Give back change as biggest coins first
int[] coinValues = {100, 10, 1};
for (int i = 0; i < coinValues.length; i++) {
int value = coinValues[i];
int count = change / value;
change %= value;
while (count > 0) {
int stackSize = Math.min(count, LOTRMod.silverCoin.getItemStackLimit());
ItemStack changeStack = new ItemStack(LOTRMod.silverCoin, stackSize, i);
player.inventory.addItemStackToInventory(changeStack);
count -= stackSize;
}
}
player.inventory.markDirty();
return true;
}
private static int getCoinValue(ItemStack stack) {
int damage = stack.getItemDamage();
switch (damage) {
case 0: return 1; // 1$
case 1: return 10; // 10$
case 2: return 100; // 100$
default: return 0;
}
}
public static int calculateCost(double playerX, double playerZ, CarriageDestination dest) {
double dist = Math.sqrt(Math.pow(dest.x - playerX, 2) + Math.pow(dest.z - playerZ, 2));
int cost = Math.max(1, (int)(dist / 50)); // replace 10 with another hardcoded value
return cost;
}
}

@ -0,0 +1,41 @@
package com.zivilon.cinder_loe.carriage.gui;
import net.minecraft.client.gui.GuiScreen;
public class GuiCarriageFade extends GuiScreen {
private int ticksPassed = 0;
private final int totalTicks = 60;
public GuiCarriageFade() {
// no destination name needed anymore
}
@Override
public void updateScreen() {
ticksPassed++;
if (ticksPassed == 10 || ticksPassed == 30) {
mc.thePlayer.playSound("mob.horse.gallop", 1.0F, 1.0F);
}
if (ticksPassed == 50) {
mc.thePlayer.playSound("mob.horse.angry", 1.0F, 1.0F);
}
if (ticksPassed >= totalTicks) {
mc.displayGuiScreen(null);
}
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
int alpha = (ticksPassed < totalTicks / 2)
? (int)(255 * (ticksPassed / (float)(totalTicks / 2)))
: (int)(255 * ((totalTicks - ticksPassed) / (float)(totalTicks / 2)));
alpha = Math.min(255, Math.max(0, alpha));
drawRect(0, 0, width, height, (alpha << 24));
}
@Override
public boolean doesGuiPauseGame() {
return false;
}
}

@ -0,0 +1,80 @@
package com.zivilon.cinder_loe.carriage.gui;
import com.zivilon.cinder_loe.carriage.CarriageDestination;
import com.zivilon.cinder_loe.carriage.CarriageUtils;
import com.zivilon.cinder_loe.network.PacketCarriageSelect;
import lotr.client.gui.LOTRGuiScreenBase;
import lotr.common.LOTRMod;
import lotr.common.network.LOTRPacketHandler;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import java.util.List;
public class GuiCarriageMenu extends LOTRGuiScreenBase {
private final List<CarriageDestination> destinations;
private final List<Integer> costs;
private final RenderItem itemRenderer = new RenderItem();
public GuiCarriageMenu(List<CarriageDestination> dests, List<Integer> costs) {
this.destinations = dests;
this.costs = costs;
}
@Override
public void initGui() {
buttonList.clear();
int centerX = width / 2;
int centerY = height / 2;
int yStart = centerY - (destinations.size() * 12);
int id = 0;
for (int i = 0; i < destinations.size(); i++) {
CarriageDestination dest = destinations.get(i);
int cost = costs.get(i);
// Strip quotes from name
String displayName = dest.name.replace("\"", "");
boolean hasEnough = CarriageUtils.hasEnoughCoins(mc.thePlayer, cost);
String text = displayName + " " + cost; // show cost as number only, icon drawn separately
if (!hasEnough) {
text = EnumChatFormatting.DARK_GRAY + text;
}
GuiButton button = new GuiButton(id++, centerX - 100, yStart + id * 25, 200, 20, text);
button.enabled = hasEnough;
buttonList.add(button);
}
}
@Override
protected void actionPerformed(GuiButton button) {
CarriageDestination selected = destinations.get(button.id);
LOTRPacketHandler.networkWrapper.sendToServer(new PacketCarriageSelect(selected.name));
mc.thePlayer.closeScreen();
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
drawDefaultBackground();
drawCenteredString("Choose your destination", width / 2, height / 2 - (destinations.size() * 12) - 20, 0xFFFFFF);
super.drawScreen(mouseX, mouseY, partialTicks);
// Draw coin icons next to cost text
for (int i = 0; i < buttonList.size(); i++) {
GuiButton button = (GuiButton) buttonList.get(i);
int iconX = button.xPosition + button.width - 18;
int iconY = button.yPosition + 2;
RenderHelper.enableGUIStandardItemLighting();
itemRenderer.renderItemIntoGUI(fontRendererObj, mc.getTextureManager(), new ItemStack(LOTRMod.silverCoin), iconX, iconY);
RenderHelper.disableStandardItemLighting();
}
}
}

@ -0,0 +1,52 @@
package com.zivilon.cinder_loe.command;
import com.zivilon.cinder_loe.carriage.CarriageDestination;
import com.zivilon.cinder_loe.carriage.CarriageDestinationsData;
import com.zivilon.cinder_loe.network.PacketOpenCarriageGui;
import lotr.common.network.LOTRPacketHandler;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public class CommandOpenCarriageMenu extends CommandBase {
@Override
public String getCommandName() {
return "open_carriage_menu";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/open_carriage_menu";
}
@Override
public void processCommand(ICommandSender sender, String[] args) {
if (!(sender instanceof EntityPlayerMP)) {
throw new CommandException("Must be run by a player.");
}
EntityPlayerMP player = (EntityPlayerMP) sender;
World world = player.worldObj;
CarriageDestinationsData data = CarriageDestinationsData.get(world);
List<CarriageDestination> nearest = data.getNearestFour(player.posX, player.posZ);
List<String> names = new ArrayList<>();
List<Integer> costs = new ArrayList<>();
for (CarriageDestination dest : nearest) {
double dist = Math.sqrt(Math.pow(dest.x - player.posX, 2) + Math.pow(dest.z - player.posZ, 2));
int cost = Math.max(1, (int)(dist / 10));
names.add(dest.name);
costs.add(cost);
}
LOTRPacketHandler.networkWrapper.sendTo(new PacketOpenCarriageGui(names, costs), player);
}
}

@ -0,0 +1,53 @@
package com.zivilon.cinder_loe.command;
import com.zivilon.cinder_loe.carriage.CarriageDestination;
import com.zivilon.cinder_loe.carriage.CarriageDestinationsData;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import org.apache.commons.lang3.StringUtils;
public class CommandSetDestination extends CommandBase {
@Override
public String getCommandName() {
return "set_destination";
}
@Override
public String getCommandUsage(ICommandSender sender) {
return "/set_destination \"Destination Name\"";
}
@Override
public void processCommand(ICommandSender sender, String[] args) {
if (args.length < 1) {
throw new WrongUsageException("Usage: /set_destination \"Destination Name\"");
}
String name = StringUtils.join(args, " ");
World world = sender.getEntityWorld();
if (!(sender instanceof EntityPlayerMP)) {
throw new CommandException("Must be run by a player.");
}
EntityPlayerMP player = (EntityPlayerMP) sender;
int x = (int) player.posX;
int y = (int) player.posY;
int z = (int) player.posZ;
int dim = player.dimension;
CarriageDestinationsData data = CarriageDestinationsData.get(world);
if (data != null) {
data.addDestination(new CarriageDestination(name, x, y, z, dim));
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Destination '" + name + "' saved."));
} else {
throw new CommandException("Failed to access destination storage.");
}
}
}

@ -0,0 +1,38 @@
package com.zivilon.cinder_loe.network;
import com.zivilon.cinder_loe.carriage.gui.GuiCarriageFade;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
public class PacketCarriageFTB implements IMessage {
private String destinationName;
public PacketCarriageFTB() {}
public PacketCarriageFTB(String destinationName) {
this.destinationName = destinationName;
}
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, destinationName);
}
@Override
public void fromBytes(ByteBuf buf) {
destinationName = ByteBufUtils.readUTF8String(buf);
}
public static class Handler implements IMessageHandler<PacketCarriageFTB, IMessage> {
@Override
public IMessage onMessage(PacketCarriageFTB msg, MessageContext ctx) {
Minecraft.getMinecraft().func_152344_a(() ->
Minecraft.getMinecraft().displayGuiScreen(new GuiCarriageFade())
);
return null;
}
}
}

@ -0,0 +1,68 @@
package com.zivilon.cinder_loe.network;
import com.zivilon.cinder_loe.carriage.CarriageDestination;
import com.zivilon.cinder_loe.carriage.CarriageDestinationsData;
import com.zivilon.cinder_loe.carriage.CarriageUtils;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import lotr.common.network.LOTRPacketHandler;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.WorldServer;
public class PacketCarriageSelect implements IMessage {
private String destinationName;
public PacketCarriageSelect() {}
public PacketCarriageSelect(String destinationName) {
this.destinationName = destinationName;
}
@Override
public void toBytes(ByteBuf buf) {
ByteBufUtils.writeUTF8String(buf, destinationName);
}
@Override
public void fromBytes(ByteBuf buf) {
destinationName = ByteBufUtils.readUTF8String(buf);
}
public static class Handler implements IMessageHandler<PacketCarriageSelect, IMessage> {
@Override
public IMessage onMessage(PacketCarriageSelect msg, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
WorldServer world = player.getServerForPlayer();
CarriageDestinationsData data = CarriageDestinationsData.get(world);
CarriageDestination dest = data.getDestinations().get(msg.destinationName);
if (dest != null) {
int cost = CarriageUtils.calculateCost(player.posX, player.posZ, dest);
if (CarriageUtils.removeCoins(player, cost)) {
if (player.dimension != dest.dimension) {
MinecraftServer.getServer().getConfigurationManager().transferPlayerToDimension(player, dest.dimension);
}
player.setPositionAndUpdate(dest.x + 0.5, dest.y, dest.z + 0.5);
world.playSoundEffect(dest.x, dest.y, dest.z, "lotr:event.trade", 1.0F, 1.0F);
// Send fade packet to client
//LOTRPacketHandler.networkWrapper.sendTo(new PacketCarriageFTB(), player);
String displayName = dest.name.replace("\"", "");
player.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "You have arrived at " + displayName + "..."));
} else {
player.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Not enough coins!"));
}
}
return null;
}
}
}

@ -0,0 +1,61 @@
package com.zivilon.cinder_loe.network;
import com.zivilon.cinder_loe.carriage.CarriageDestination;
import com.zivilon.cinder_loe.carriage.gui.GuiCarriageMenu;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import java.util.ArrayList;
import java.util.List;
public class PacketOpenCarriageGui implements IMessage {
private List<String> names = new ArrayList<>();
private List<Integer> costs = new ArrayList<>();
public PacketOpenCarriageGui() {}
public PacketOpenCarriageGui(List<String> names, List<Integer> costs) {
this.names = names;
this.costs = costs;
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(names.size());
for (int i = 0; i < names.size(); i++) {
ByteBufUtils.writeUTF8String(buf, names.get(i));
buf.writeInt(costs.get(i));
}
}
@Override
public void fromBytes(ByteBuf buf) {
int count = buf.readInt();
for (int i = 0; i < count; i++) {
names.add(ByteBufUtils.readUTF8String(buf));
costs.add(buf.readInt());
}
}
public static class Handler implements IMessageHandler<PacketOpenCarriageGui, IMessage> {
@Override
public IMessage onMessage(PacketOpenCarriageGui msg, MessageContext ctx) {
Minecraft.getMinecraft().func_152344_a(new Runnable() {
@Override
public void run() {
List<CarriageDestination> dests = new ArrayList<>();
for (int i = 0; i < msg.names.size(); i++) {
dests.add(new CarriageDestination(msg.names.get(i), 0, 0, 0, 0)); // dummy pos
}
Minecraft.getMinecraft().displayGuiScreen(new GuiCarriageMenu(dests, msg.costs));
}
});
return null;
}
}
}

@ -1,6 +1,6 @@
package com.zivilon.cinder_loe.network;
import com.zivilon.cinder_loe.network.PacketWarbandLocations.Handler;
import cpw.mods.fml.common.FMLCommonHandler;
import lotr.common.network.LOTRPacketHandler;
import cpw.mods.fml.relauncher.Side;
@ -8,5 +8,12 @@ public class PacketRegistration {
public static void register() {
int id = 200;
LOTRPacketHandler.networkWrapper.registerMessage(PacketWarbandLocations.Handler.class, PacketWarbandLocations.class, id++, Side.CLIENT);
LOTRPacketHandler.networkWrapper.registerMessage(PacketOpenCarriageGui.Handler.class, PacketOpenCarriageGui.class, id++, Side.CLIENT);
LOTRPacketHandler.networkWrapper.registerMessage(PacketCarriageSelect.Handler.class, PacketCarriageSelect.class, id++, Side.SERVER);
//if (FMLCommonHandler.instance().getSide().isClient()) {
// LOTRPacketHandler.networkWrapper.registerMessage(
// PacketCarriageFTB.Handler.class, PacketCarriageFTB.class, id++, Side.CLIENT
// );
//}
}
}

Loading…
Cancel
Save