「 FLOWER MAN 」

This commit is contained in:
Boblet 2026-07-03 14:24:21 +02:00
parent 78d8766671
commit 07fbc99133
7 changed files with 126 additions and 69 deletions

View File

@ -1,3 +1,17 @@
## Added
* Pneumatic Storage System
* Mass storage logistics system that can perform various automation tasks
* Items can be stored in clutter storages (steel crate equivalent) or mono type storages (ironically supports three types set using filters holding several thousand items)
* In order to be accessible, all storages need a supply of compressed air with the compression level dictating range
* Access points allow items to be retrieved and inserted manually
* Access points have a search function as well as several sorting options
* Importers allow hopper IO to add items to the network
* Exporters allow items to be retrieved and then taken using hopper IO, things like filters and request rules can be defined in several ways
* Allows continuous request and request on demand (redstone or RoR command)
* Filters can be set using items or RoR commands
* Requests can be configured to take as much as possible, to only take full stacks, or to only take full requests
* In combination with assembler recipe switching, using RoR logic, this means that on-demand recipe automation is now possible
## Changed
* Updated chinese localization
* Watz powerplant now has OC and RoR integration
@ -45,6 +59,17 @@
* Polling for receiving only fresh RoR signals
* A command for writing the world time to the buffer, allowing for more precise timers
* All RoR values/commands are now case-insensitive
* Changed mask man spawning rules
* Instead of random checks and chances, if a player meets the requirements, a timer starts (timer exists per player)
* Once this timer runs out, mask man spawns
* Should the timer run out but the spawn be unsuccessful (spawn restrictions) then a different message appears
* If the requirements are no longer met, the timer immediately resets, making it easier to avoid him deliberately
* The default spawn timer is now 20 minutes, making it easier to spawn him deliberately
* One minute before the timer ends, a warning message appears
* Changed normal mode control unit recipes
* Standard control units now use rubber instead of speed I upgrades
* Advanced control units now use hardplastics instead of speed III upgrades
* Quantum computers now use speed III upgrades instead of overdrive I
## Fixed
* Fixed AUTOCAL's number comparison functions not working with variable substitution as advertised

View File

@ -5,8 +5,7 @@ import net.minecraftforge.common.config.Configuration;
public class MobConfig {
public static boolean enableMaskman = true;
public static int maskmanDelay = 60 * 60 * 60;
public static int maskmanChance = 3;
public static int maskmanDelay = 20 * 60; // 20 minutes
public static int maskmanMinRad = 50;
public static boolean maskmanUnderground = true;
@ -78,8 +77,7 @@ public class MobConfig {
final String CATEGORY = CommonConfig.CATEGORY_MOBS;
enableMaskman = CommonConfig.createConfigBool(config, CATEGORY, "12.M00_enableMaskman", "Whether mask man should spawn", true);
maskmanDelay = CommonConfig.createConfigInt(config, CATEGORY, "12.M01_maskmanDelay", "How many world ticks need to pass for a check to be performed", 60 * 60 * 60);
maskmanChance = CommonConfig.createConfigInt(config, CATEGORY, "12.M02_maskmanChance", "1:x chance to spawn mask man, must be at least 1", 3);
maskmanDelay = CommonConfig.createConfigInt(config, CATEGORY, "12.M01_maskmanTimer", "How many world seconds need to pass for mask man to spawn, if the requirements are met", 20 * 60);
maskmanMinRad = CommonConfig.createConfigInt(config, CATEGORY, "12.M03_maskmanMinRad", "The amount of radiation needed for mask man to spawn", 50);
maskmanUnderground = CommonConfig.createConfigBool(config, CATEGORY, "12.M04_maskmanUnderound", "Whether players need to be underground for mask man to spawn", true);

View File

@ -9,43 +9,45 @@ import net.minecraft.entity.ai.EntityAIBase;
import net.minecraft.util.Vec3;
public class EntityAIMaskmanMinigun extends EntityAIBase {
private EntityCreature owner;
private EntityLivingBase target;
int delay;
int timer;
private EntityLivingBase target;
int delay;
int timer;
public EntityAIMaskmanMinigun(EntityCreature owner, boolean checkSight, boolean nearbyOnly, int delay) {
this.owner = owner;
this.delay = delay;
timer = delay;
this.timer = delay;
}
@Override
public boolean shouldExecute() {
EntityLivingBase entity = this.owner.getAttackTarget();
if(entity == null) {
return false;
} else {
this.target = entity;
double dist = Vec3.createVectorHelper(target.posX - owner.posX, target.posY - owner.posY, target.posZ - owner.posZ).lengthVector();
return dist > 5 && dist < 10;
}
EntityLivingBase entity = this.owner.getAttackTarget();
if(entity == null || !entity.isEntityAlive()) {
return false;
} else {
this.target = entity;
double dist = Vec3.createVectorHelper(target.posX - owner.posX, target.posY - owner.posY, target.posZ - owner.posZ).lengthVector();
return dist > 5 && dist < 10;
}
}
@Override
public boolean continueExecuting() {
return this.shouldExecute() || !this.owner.getNavigator().noPath();
}
@Override
public void updateTask() {
public boolean continueExecuting() {
return this.shouldExecute() || !this.owner.getNavigator().noPath();
}
@Override
public void updateTask() {
timer--;
// TEST
if(target != null) this.owner.getLookHelper().setLookPositionWithEntity(this.target, 15F, 15F);
if(timer <= 0) {
timer = delay;
@ -53,7 +55,7 @@ public class EntityAIMaskmanMinigun extends EntityAIBase {
owner.worldObj.spawnEntityInWorld(bullet);
owner.playSound("hbm:weapon.calShoot", 1.0F, 1.0F);
}
this.owner.rotationYaw = this.owner.rotationYawHead;
}
}
}

View File

@ -25,35 +25,43 @@ public class HbmPlayerProps implements IExtendedEntityProperties {
public static final String key = "NTM_EXT_PLAYER";
public EntityPlayer player;
public boolean hasReceivedBook = false;
/* Toggles for keybind */
public boolean enableHUD = true;
public boolean enableBackpack = true;
public boolean enableMagnet = true;
/** Keybind tracking */
private boolean[] keysPressed = new boolean[EnumKeybind.values().length];
/* Dashes for bismuth armor/cloud in a bottle */
public boolean dashActivated = true;
public static final int dashCooldownLength = 5;
public int dashCooldown = 0;
public int totalDashCount = 0;
public int stamina = 0;
public static final int dashCooldownLength = 5;
public static final int plinkCooldownLength = 10;
/** Cooldown for armor plinking noise when canceling damage */
public int plinkCooldown = 0;
public static final int plinkCooldownLength = 10;
/** Shield infusion */
public float shield = 0;
public float maxShield = 0;
public int lastDamage = 0;
public static final float shieldCap = 100;
/** Latnern repair/destroy count */
public int reputation;
/** Hack for allowing ladders on multiblocks */
public boolean isOnLadder = false;
/** Pulling the pin on a grenade - it's a player prop instead of an NBT trait */
public int grenadeDeployment;
/** Maskman timer */
public int maskManTimer = 0;
public HbmPlayerProps(EntityPlayer player) {
this.player = player;
@ -187,7 +195,6 @@ public class HbmPlayerProps implements IExtendedEntityProperties {
public void init(Entity entity, World world) { }
public void serialize(ByteBuf buf) {
buf.writeBoolean(this.hasReceivedBook);
buf.writeFloat(this.shield);
buf.writeFloat(this.maxShield);
buf.writeBoolean(this.enableBackpack);
@ -199,7 +206,6 @@ public class HbmPlayerProps implements IExtendedEntityProperties {
public void deserialize(ByteBuf buf) {
if(buf.readableBytes() > 0) {
this.hasReceivedBook = buf.readBoolean();
this.shield = buf.readFloat();
this.maxShield = buf.readFloat();
this.enableBackpack = buf.readBoolean();
@ -216,7 +222,6 @@ public class HbmPlayerProps implements IExtendedEntityProperties {
NBTTagCompound props = new NBTTagCompound();
props.setBoolean("hasReceivedBook", hasReceivedBook);
props.setFloat("shield", shield);
props.setFloat("maxShield", maxShield);
props.setBoolean("enableBackpack", enableBackpack);
@ -224,6 +229,7 @@ public class HbmPlayerProps implements IExtendedEntityProperties {
props.setBoolean("enableHUD", enableHUD);
props.setInteger("reputation", reputation);
props.setBoolean("isOnLadder", isOnLadder);
props.setInteger("maskManTimer", maskManTimer);
nbt.setTag("HbmPlayerProps", props);
}
@ -235,7 +241,6 @@ public class HbmPlayerProps implements IExtendedEntityProperties {
NBTTagCompound props = (NBTTagCompound) nbt.getTag("HbmPlayerProps");
if(props != null) {
this.hasReceivedBook = props.getBoolean("hasReceivedBook");
this.shield = props.getFloat("shield");
this.maxShield = props.getFloat("maxShield");
this.enableBackpack = props.getBoolean("enableBackpack");
@ -243,6 +248,7 @@ public class HbmPlayerProps implements IExtendedEntityProperties {
this.enableHUD = props.getBoolean("enableHUD");
this.reputation = props.getInteger("reputation");
this.isOnLadder = props.getBoolean("isOnLadder");
this.maskManTimer = props.getInteger("maskManTimer");
}
}
}

View File

@ -13,6 +13,7 @@ import com.hbm.entity.mob.EntityMaskMan;
import com.hbm.entity.mob.EntityRADBeast;
import com.hbm.entity.projectile.EntityMeteor;
import com.hbm.extprop.HbmLivingProps;
import com.hbm.extprop.HbmPlayerProps;
import com.hbm.items.ModItems;
import com.hbm.main.MainRegistry;
import com.hbm.util.ContaminationUtil;
@ -29,6 +30,7 @@ import net.minecraft.util.ChatComponentText;
import net.minecraft.util.ChatStyle;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.Vec3;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import net.minecraftforge.event.ForgeEventFactory;
@ -45,33 +47,44 @@ public class BossSpawnHandler {
* - the player has at least 50 RAD
* - the player has either crafted or placed an ore acidizer before
*/
if(MobConfig.enableMaskman) {
if(world.getTotalWorldTime() % MobConfig.maskmanDelay == 0) {
if(world.rand.nextInt(MobConfig.maskmanChance) == 0 && !world.playerEntities.isEmpty() && world.provider.isSurfaceWorld()) { //33% chance only if there is a player online
EntityPlayer player = (EntityPlayer) world.playerEntities.get(world.rand.nextInt(world.playerEntities.size())); //choose a random player
int id = Item.getIdFromItem(Item.getItemFromBlock(ModBlocks.machine_crystallizer));
StatBase statCraft = StatList.objectCraftStats[id];
StatBase statPlace = StatList.objectUseStats[id];
if(!(player instanceof EntityPlayerMP)) return;
EntityPlayerMP playerMP = (EntityPlayerMP) player;
boolean acidizerStat = !GeneralConfig.enableStatReRegistering || (statCraft != null && playerMP.func_147099_x().writeStat(statCraft) > 0)|| (statPlace != null && playerMP.func_147099_x().writeStat(statPlace) > 0);
if(acidizerStat && ContaminationUtil.getRads(player) >= MobConfig.maskmanMinRad && (world.getHeightValue((int)player.posX, (int)player.posZ) > player.posY + 3 || !MobConfig.maskmanUnderground)) { //if the player has more than 50 RAD and is underground
player.addChatComponentMessage(new ChatComponentText("The mask man is about to claim another victim.").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)));
if(MobConfig.enableMaskman && world.getTotalWorldTime() % 20 == 0 && world.provider.isSurfaceWorld() && world.difficultySetting != EnumDifficulty.PEACEFUL) {
for(Object o : world.playerEntities) {
if(!(o instanceof EntityPlayerMP)) return;
EntityPlayerMP player = (EntityPlayerMP) o;
int id = Item.getIdFromItem(Item.getItemFromBlock(ModBlocks.machine_crystallizer));
StatBase statCraft = StatList.objectCraftStats[id];
StatBase statPlace = StatList.objectUseStats[id];
boolean acidizerStat = !GeneralConfig.enableStatReRegistering || (statCraft != null && player.func_147099_x().writeStat(statCraft) > 0)|| (statPlace != null && player.func_147099_x().writeStat(statPlace) > 0);
boolean hasRads = ContaminationUtil.getRads(player) >= MobConfig.maskmanMinRad;
boolean underground = world.getHeightValue((int) Math.floor(player.posX), (int) Math.floor(player.posZ)) > player.posY + 3 || !MobConfig.maskmanUnderground;
if(acidizerStat && hasRads && underground) {
HbmPlayerProps data = HbmPlayerProps.getData(player);
data.maskManTimer++;
if(data.maskManTimer == MobConfig.maskmanDelay - 20 * 60) {
player.addChatComponentMessage(new ChatComponentText("The mask man draws near.").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)));
}
if(data.maskManTimer >= MobConfig.maskmanDelay) {
data.maskManTimer = 0;
double spawnX = player.posX + world.rand.nextGaussian() * 20;
double spawnZ = player.posZ + world.rand.nextGaussian() * 20;
double spawnY = world.getHeightValue((int)spawnX, (int)spawnZ);
trySpawn(world, (float)spawnX, (float)spawnY, (float)spawnZ, new EntityMaskMan(world));
double spawnY = world.getHeightValue((int) Math.floor(spawnX), (int) Math.floor(spawnZ));
if(trySpawn(world, (float) spawnX, (float) spawnY, (float) spawnZ, new EntityMaskMan(world))) {
player.addChatComponentMessage(new ChatComponentText("The mask man is about to claim another victim.").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)));
} else {
player.addChatComponentMessage(new ChatComponentText("Seems like mask man couldn't come today.").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.BLUE)));
}
}
} else {
HbmPlayerProps.getData(player).maskManTimer = 0;
}
}
}
@ -169,8 +182,7 @@ public class BossSpawnHandler {
}
}
private static void trySpawn(World world, float x, float y, float z, EntityLiving e) {
private static boolean trySpawn(World world, float x, float y, float z, EntityLiving e) {
e.setLocationAndAngles(x, y, z, world.rand.nextFloat() * 360.0F, 0.0F);
Result canSpawn = ForgeEventFactory.canEntitySpawn(e, world, x, y, z);
@ -179,7 +191,10 @@ public class BossSpawnHandler {
world.spawnEntityInWorld(e);
ForgeEventFactory.doSpecialSpawn(e, world, x, y, z);
e.onSpawnWithEgg(null);
return true;
}
return false;
}
public static void markFBI(EntityPlayer player) {

View File

@ -118,7 +118,7 @@ public class SolderingRecipes extends SerializableRecipe {
new ComparableStack(ModItems.circuit, lbsm ? 8 : 16, EnumCircuitType.CAPACITOR_TANTALIUM)},
new AStack[] {
new ComparableStack(ModItems.circuit, 1, EnumCircuitType.CONTROLLER_CHASSIS),
new ComparableStack(ModItems.upgrade_speed_1)},
new OreDictStack(RUBBER.ingot(), 4)},
new AStack[] {
new OreDictStack(PB.wireFine(), 16)}
));
@ -130,7 +130,7 @@ public class SolderingRecipes extends SerializableRecipe {
new ComparableStack(ModItems.circuit, 1, EnumCircuitType.ATOMIC_CLOCK)},
new AStack[] {
new ComparableStack(ModItems.circuit, 1, EnumCircuitType.CONTROLLER_CHASSIS),
new ComparableStack(ModItems.upgrade_speed_3)},
new OreDictStack(ANY_HARDPLASTIC.ingot(), 4)},
new AStack[] {
new OreDictStack(PB.wireFine(), 24)}
));
@ -142,7 +142,7 @@ public class SolderingRecipes extends SerializableRecipe {
new ComparableStack(ModItems.circuit, lbsm ? 1 : 8, EnumCircuitType.ATOMIC_CLOCK)},
new AStack[] {
new ComparableStack(ModItems.circuit, 2, EnumCircuitType.CONTROLLER_ADVANCED),
new ComparableStack(ModItems.upgrade_overdrive_1)},
new ComparableStack(ModItems.upgrade_speed_3)},
new AStack[] {
new OreDictStack(PB.wireFine(), 32)}
));

View File

@ -18,7 +18,10 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
public class TileEntityPneumoStorageExporter extends TileEntityPneumaticMachineBase implements IRORInteractive, IControlReceiver {
public class TileEntityPneumoStorageExporter extends TileEntityPneumaticMachineBase implements IRORInteractive, IControlReceiver { // TODO: NBT serialization
// TODO: also maybe test all of this first
// TODO: more energy drincc
// TODO: the lion does not concern himself with chest pains, it's just the feeling of the heart screaming for more redbull
/** If requests should be pulled repeatedly every tick */
public boolean continuousRequest = false;
@ -38,6 +41,8 @@ public class TileEntityPneumoStorageExporter extends TileEntityPneumaticMachineB
public static final int MODE_FULL_STACK = 1;
/** All request slots try to pull the desired quantities simultaneously */
public static final int MODE_FULL_REQUEST = 2;
public boolean lastRedstone = false;
public TileEntityPneumoStorageExporter() {
super(18);
@ -57,11 +62,17 @@ public class TileEntityPneumoStorageExporter extends TileEntityPneumaticMachineB
for(int i = 0; i < 9; i++) {
if(slotDelay[i] > 0) slotDelay[i]--;
}
boolean redstone = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
if(continuousRequest) {
this.doRequest(false);
} else {
if(redstone && !lastRedstone) this.doRequest(true);
}
this.lastRedstone = redstone;
this.networkPackNT(15);
}
}