train coupling (physics pending)

This commit is contained in:
Boblet 2023-05-26 14:54:57 +02:00
parent 6898cdb09e
commit 85ce4008a1
8 changed files with 96 additions and 7 deletions

View File

@ -188,11 +188,11 @@ public class WeaponRecipes {
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_12gauge, 12), new Object[] { " I ", "GCL", " P ", 'I', ModItems.pellet_buckshot, 'G', ModItems.ballistite, 'C', ModItems.casing_buckshot, 'P', ModItems.primer_buckshot, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_12gauge.stackFromEnum(12, Ammo12Gauge.PERCUSSION), new Object[] { "G", "C", "P", 'G', ModItems.ballistite, 'C', ModItems.casing_buckshot, 'P', ModItems.primer_buckshot });
CraftingManager.addRecipeAuto(new ItemStack(ModItems.ammo_4gauge, 12), new Object[] { " I ", "GCL", " P ", 'I', ModItems.pellet_buckshot, 'G', ModItems.cordite, 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(12, Ammo4Gauge.SLUG), new Object[] { " I ", "GCL", " P ", 'I', PB.ingot(), 'G', ANY_SMOKELESS.dust(), 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(12, Ammo4Gauge.FLECHETTE), new Object[] { " I ", "GCL", " P ", 'I', ModItems.pellet_flechette, 'G', ANY_SMOKELESS.dust(), 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(4, Ammo4Gauge.EXPLOSIVE), new Object[] { " I ", "GCL", " P ", 'I', ModBlocks.tnt, 'G', ANY_SMOKELESS.dust(), 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(6, Ammo4Gauge.EXPLOSIVE), new Object[] { " I ", "GCL", " P ", 'I', ANY_PLASTICEXPLOSIVE.ingot(), 'G', ANY_SMOKELESS.dust(), 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(4, Ammo4Gauge.MINING), new Object[] { " I ", "GCL", " P ", 'I', ModBlocks.det_miner, 'G', ANY_SMOKELESS.dust(), 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(12, Ammo4Gauge.SLUG), new Object[] { " I ", "GCL", " P ", 'I', PB.ingot(), 'G', ModItems.cordite, 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(12, Ammo4Gauge.FLECHETTE), new Object[] { " I ", "GCL", " P ", 'I', ModItems.pellet_flechette, 'G', ModItems.cordite, 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(4, Ammo4Gauge.EXPLOSIVE), new Object[] { " I ", "GCL", " P ", 'I', ModBlocks.tnt, 'G', ModItems.cordite, 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(6, Ammo4Gauge.EXPLOSIVE), new Object[] { " I ", "GCL", " P ", 'I', ANY_PLASTICEXPLOSIVE.ingot(), 'G', ModItems.cordite, 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addRecipeAuto(ModItems.ammo_4gauge.stackFromEnum(4, Ammo4Gauge.MINING), new Object[] { " I ", "GCL", " P ", 'I', ModBlocks.det_miner, 'G', ModItems.cordite, 'C', ModItems.casing_50, 'P', ModItems.primer_50, 'L', ModItems.plate_polymer });
CraftingManager.addShapelessAuto(ModItems.ammo_4gauge.stackFromEnum(Ammo4Gauge.QUACK), new Object[] { ModItems.ammo_4gauge, ModItems.nugget_bismuth, ModItems.nugget_tantalium, ModItems.ball_dynamite });
CraftingManager.addRecipeAuto(ModItems.ammo_20gauge.stackFromEnum(12, Ammo20Gauge.STOCK), new Object[] { " I ", "GCL", " P ", 'I', ModItems.pellet_buckshot, 'G', ANY_SMOKELESS.dust(), 'C', ModItems.casing_buckshot, 'P', ModItems.primer_buckshot, 'L', CU.plate() });
CraftingManager.addRecipeAuto(ModItems.ammo_20gauge.stackFromEnum(12, Ammo20Gauge.SLUG), new Object[] { " I ", "GCL", " P ", 'I', PB.ingot(), 'G', ANY_SMOKELESS.dust(), 'C', ModItems.casing_buckshot, 'P', ModItems.primer_buckshot, 'L', CU.plate() });

View File

@ -1,8 +1,11 @@
package com.hbm.entity.train;
import java.util.List;
import com.hbm.blocks.rail.IRailNTM;
import com.hbm.blocks.rail.IRailNTM.RailContext;
import com.hbm.blocks.rail.IRailNTM.TrackGauge;
import com.hbm.items.ModItems;
import com.hbm.util.fauxpointtwelve.BlockPos;
import cpw.mods.fml.relauncher.Side;
@ -11,6 +14,7 @@ import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
@ -51,6 +55,51 @@ public abstract class EntityRailCarBase extends Entity {
@Override protected void entityInit() { }
@Override protected void readEntityFromNBT(NBTTagCompound nbt) { }
@Override protected void writeEntityToNBT(NBTTagCompound nbt) { }
@Override
public boolean interactFirst(EntityPlayer player) {
if(player.getHeldItem() != null && player.getHeldItem().getItem() == ModItems.coupling_tool) {
List<EntityRailCarBase> intersecting = worldObj.getEntitiesWithinAABB(EntityRailCarBase.class, this.boundingBox.expand(2D, 0D, 2D));
for(EntityRailCarBase neighbor : intersecting) {
if(neighbor == this) continue;
if(neighbor.getGauge() != this.getGauge()) continue;
TrainCoupling closestOwnCoupling = null;
TrainCoupling closestNeighborCoupling = null;
double closestDist = Double.POSITIVE_INFINITY;
for(TrainCoupling ownCoupling : TrainCoupling.values()) {
for(TrainCoupling neighborCoupling : TrainCoupling.values()) {
Vec3 ownPos = this.getCouplingPos(ownCoupling);
Vec3 neighborPos = neighbor.getCouplingPos(neighborCoupling);
if(ownPos != null && neighborPos != null) {
Vec3 delta = Vec3.createVectorHelper(ownPos.xCoord - neighborPos.xCoord, ownPos.yCoord - neighborPos.yCoord, ownPos.zCoord - neighborPos.zCoord);
double length = delta.lengthVector();
if(length < 1 && length < closestDist) {
closestDist = length;
closestOwnCoupling = ownCoupling;
closestNeighborCoupling = neighborCoupling;
}
}
}
}
if(closestOwnCoupling != null && closestNeighborCoupling != null) {
if(this.getCoupledTo(closestOwnCoupling) != null) continue;
if(neighbor.getCoupledTo(closestNeighborCoupling) != null) continue;
this.couple(closestOwnCoupling, neighbor);
neighbor.couple(closestNeighborCoupling, this);
return true;
}
}
}
return false;
}
@Override
public void onUpdate() {
@ -77,6 +126,13 @@ public abstract class EntityRailCarBase extends Entity {
this.setRotation(this.rotationYaw, this.rotationPitch);
}
/*
* TODO: move movement into the world tick event handler.
* step 1: detect linked trains, move linked units (LTUs) as one later
* step 2: move LTUs together using coupling rules (important to happen first, consistency has to be achieved before major movement)
* step 3: move LTUs based on their engine and gravity speed
* step 4: move LTUs based on collisions between LTUs (important to happen last, collision is most important)
*/
BlockPos anchor = this.getCurentAnchorPos();
Vec3 frontPos = getRelPosAlongRail(anchor, this.getLengthSpan());
Vec3 backPos = getRelPosAlongRail(anchor, -this.getLengthSpan());
@ -226,6 +282,10 @@ public abstract class EntityRailCarBase extends Entity {
public abstract TrackGauge getGauge();
/** Returns the length between the core and one of the bogies */
public abstract double getLengthSpan();
/* Returns a collision box, usually smaller than the entity's AABB for rendering, which is used for colliding trains */
public AxisAlignedBB getCollisionBox() {
return this.boundingBox;
}
/** Returns the "true" position of the train, i.e. the block it wants to snap to */
public BlockPos getCurentAnchorPos() {
@ -348,11 +408,29 @@ public abstract class EntityRailCarBase extends Entity {
BACK
}
public double getCouplingDist(TrainCoupling coupling) {
return 0D;
}
public Vec3 getCouplingPos(TrainCoupling coupling) {
return null;
double dist = this.getCouplingDist(coupling);
if(dist <= 0) return null;
Vec3 rot = Vec3.createVectorHelper(0, 0, dist);
rot.rotateAroundY((float) (-this.rotationYaw * Math.PI / 180D));
rot.xCoord += this.renderX;
rot.yCoord += this.renderY;
rot.zCoord += this.renderZ;
return rot;
}
public EntityRailCarBase getCoupledTo(TrainCoupling coupling) {
return coupling == TrainCoupling.FRONT ? this.coupledFront : coupling == TrainCoupling.BACK ? this.coupledBack : null;
}
public void couple(TrainCoupling coupling, EntityRailCarBase to) {
if(coupling == TrainCoupling.FRONT) this.coupledFront = to;
if(coupling == TrainCoupling.BACK) this.coupledBack = to;
}
}

View File

@ -77,6 +77,7 @@ public abstract class EntityRailCarRidable extends EntityRailCarCargo {
@Override
public boolean interactFirst(EntityPlayer player) {
if(super.interactFirst(player)) return true;
if(worldObj.isRemote) return true;
double nearestDist = Double.POSITIVE_INFINITY;

View File

@ -18,6 +18,7 @@ import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Vec3;
@ -54,6 +55,7 @@ public class TrainCargoTram extends EntityRailCarElectric implements IGUIProvide
@Override public boolean shouldRiderSit() { return false; }
@Override public int getSizeInventory() { return 29; }
@Override public String getInventoryName() { return this.hasCustomInventoryName() ? this.getEntityName() : "container.trainTram"; }
@Override public AxisAlignedBB getCollisionBox() { return AxisAlignedBB.getBoundingBox(renderX, renderY, renderZ, renderX, renderY + 1, renderZ).expand(4, 0, 4); }
@Override public int getMaxPower() { return this.getPowerConsumption() * 100; }
@Override public int getPowerConsumption() { return 10; }

View File

@ -1252,6 +1252,7 @@ public class ModItems {
public static Item rbmk_tool;
public static Item coltan_tool;
public static Item power_net_tool;
public static Item coupling_tool;
public static Item template_folder;
public static Item journal_pip;
@ -4580,6 +4581,7 @@ public class ModItems {
rbmk_tool = new ItemRBMKTool().setUnlocalizedName("rbmk_tool").setMaxStackSize(1).setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":rbmk_tool");
coltan_tool = new ItemColtanCompass().setUnlocalizedName("coltan_tool").setMaxStackSize(1).setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":coltass");
power_net_tool = new ItemPowerNetTool().setUnlocalizedName("power_net_tool").setMaxStackSize(1).setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":power_net_tool");
coupling_tool = new ItemCouplingTool().setUnlocalizedName("coupling_tool").setMaxStackSize(1).setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":coupling_tool");
key = new ItemKey().setUnlocalizedName("key").setMaxStackSize(1).setCreativeTab(MainRegistry.consumableTab).setTextureName(RefStrings.MODID + ":key");
key_red = new ItemCustomLore().setUnlocalizedName("key_red").setMaxStackSize(1).setCreativeTab(null).setTextureName(RefStrings.MODID + ":key_red");
@ -6722,6 +6724,7 @@ public class ModItems {
GameRegistry.registerItem(rbmk_tool, rbmk_tool.getUnlocalizedName());
GameRegistry.registerItem(coltan_tool, coltan_tool.getUnlocalizedName());
GameRegistry.registerItem(power_net_tool, power_net_tool.getUnlocalizedName());
GameRegistry.registerItem(coupling_tool, coupling_tool.getUnlocalizedName());
GameRegistry.registerItem(dosimeter, dosimeter.getUnlocalizedName());
GameRegistry.registerItem(geiger_counter, geiger_counter.getUnlocalizedName());
GameRegistry.registerItem(digamma_diagnostic, digamma_diagnostic.getUnlocalizedName());

View File

@ -0,0 +1,5 @@
package com.hbm.items.tool;
import net.minecraft.item.Item;
public class ItemCouplingTool extends Item { }

View File

@ -909,7 +909,7 @@ public class CraftingManager {
addRecipeAuto(new ItemStack(Items.lead, 4), new Object[] { "RSR", 'R', DictFrame.fromOne(ModItems.plant_item, EnumPlantType.ROPE), 'S', KEY_SLIME });
addRecipeAuto(new ItemStack(ModItems.rag, 4), new Object[] { "SW", "WS", 'S', Items.string, 'W', Blocks.wool });
addShapelessAuto(new ItemStack(ModItems.solid_fuel, 2), new Object[] { Fluids.HEATINGOIL.getDict(1000), KEY_TOOL_CHEMISTRYSET });
addShapelessAuto(new ItemStack(ModItems.solid_fuel, 3), new Object[] { Fluids.HEATINGOIL.getDict(16000), KEY_TOOL_CHEMISTRYSET });
addShapelessAuto(new ItemStack(ModItems.canister_full, 2, Fluids.LUBRICANT.getID()), new Object[] { Fluids.HEATINGOIL.getDict(1000), Fluids.UNSATURATEDS.getDict(1000), ModItems.canister_empty, ModItems.canister_empty, KEY_TOOL_CHEMISTRYSET });
addRecipeAuto(new ItemStack(ModBlocks.machine_condenser), new Object[] { "SIS", "ICI", "SIS", 'S', STEEL.ingot(), 'I', IRON.plate(), 'C', ModItems.board_copper });

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B