mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-28 11:39:07 +00:00
Object Command & Entity Spawn Changes (#492)
- Redid object paste command
- Added rotate flag to paste with rotation
- Added scale flag to paste with scale. Optional interpolation method can be used
- Changes are now logged and can be reverted with the undo command
- Fixed edit flag
- Made the edit flag now update your wand even if it isn't in your hand
- Added object undo command
- Added object check command
- Added a surface target to spawn on for entities. This will fix mobs spawning in water
- LAND for mobs that spawn on any land surface
- ANIMAL for mobs that should only spawn on grass and dirt
- WATER for mobs that should spawn in water
- OVERWORLD for mobs that can spawn on both land and water (turtles, for example)
- LAVA for mobs that can spawn on lava (striders, for example)
- Attempted to fix PAPI complaining about registering on the wrong thread
- Fixed console spam for entities (was due to the mount event being called async)
- Fixed grass paths and a few other update breaking blocks
- Made it so if a block state changes on an update, it will now use as many as the other states as it can rather than not use anything
- Patch to stop people naming the world 'Iris'
This commit is contained in:
@@ -27,6 +27,11 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Leaves;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class B {
|
||||
private static final Material AIR_MATERIAL = Material.AIR;
|
||||
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
|
||||
@@ -157,26 +162,67 @@ public class B {
|
||||
|
||||
blockDataCache.put(ix, bx);
|
||||
return bx;
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
} catch (Exception e) {
|
||||
//Iris.reportError(e);
|
||||
Iris.debug("Failed to load block \"" + ix + "\"");
|
||||
|
||||
String block = ix.contains(":") ? ix.split(":")[1].toLowerCase() : ix.toLowerCase();
|
||||
String state = block.contains("[") ? block.split("\\[")[1].split("\\]")[0] : "";
|
||||
Map<String, String> stateMap = new HashMap<>();
|
||||
if (!state.equals("")) {
|
||||
Arrays.stream(state.split(",")).forEach(s -> {
|
||||
stateMap.put(s.split("=")[0], s.split("=")[1]);
|
||||
});
|
||||
}
|
||||
block = block.split("\\[")[0];
|
||||
|
||||
switch (block) {
|
||||
case "cauldron" -> block = "water_cauldron"; //Would fail to load if it has a level parameter
|
||||
case "grass_path" -> block = "dirt_path";
|
||||
case "concrete" -> block = "white_concrete";
|
||||
case "wool" -> block = "white_wool";
|
||||
case "beetroots" -> {
|
||||
if (stateMap.containsKey("age")) {
|
||||
String updated = stateMap.get("age");
|
||||
switch (updated) {
|
||||
case "7" -> updated = "3";
|
||||
case "3", "4", "5" -> updated = "2";
|
||||
case "1", "2" -> updated = "1";
|
||||
}
|
||||
stateMap.put("age", updated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> newStates = new HashMap<>();
|
||||
for (String key : stateMap.keySet()) { //Iterate through every state and check if its valid
|
||||
try {
|
||||
String newState = block + "[" + key + "=" + stateMap.get(key) + "]";
|
||||
Bukkit.createBlockData(newState);
|
||||
|
||||
//If we get to here, the state is okay so we can use it
|
||||
newStates.put(key, stateMap.get(key));
|
||||
|
||||
} catch (IllegalArgumentException ignored) { }
|
||||
}
|
||||
|
||||
//Combine all the "good" states again
|
||||
state = newStates.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).collect(Collectors.joining(","));
|
||||
if (!state.equals("")) state = "[" + state + "]";
|
||||
String newBlock = block + state;
|
||||
Iris.debug("Converting " + ix + " to " + newBlock);
|
||||
|
||||
try {
|
||||
BlockData bd = Bukkit.createBlockData(newBlock);
|
||||
blockDataCache.put(ix, bd);
|
||||
return bd;
|
||||
} catch (Throwable e1) {
|
||||
Iris.reportError(e1);
|
||||
}
|
||||
|
||||
nullBlockDataCache.add(ix);
|
||||
return null;
|
||||
}
|
||||
|
||||
String i = ix.toUpperCase().trim();
|
||||
i = i.equals("GRASS_PATH") ? "DIRT_PATH" : i;
|
||||
i = i.equals("WOOL") ? "WHITE_WOOL" : i;
|
||||
i = i.equals("CONCRETE") ? "WHITE_CONCRETE" : i;
|
||||
|
||||
try {
|
||||
BlockData bd = Material.valueOf(i).createBlockData();
|
||||
blockDataCache.put(ix, bd);
|
||||
} catch (Throwable e) {
|
||||
Iris.reportError(e);
|
||||
|
||||
}
|
||||
|
||||
nullBlockDataCache.add(ix);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static BlockData parseBlockData(String ix) {
|
||||
|
||||
@@ -136,6 +136,12 @@ public class IrisEntity extends IrisRegistrant {
|
||||
@Desc("The this entity is ageable, set it's baby status")
|
||||
private boolean baby = false;
|
||||
|
||||
@Desc("If the entity should never be culled. Useful for Jigsaws")
|
||||
private boolean keepEntity = false;
|
||||
|
||||
@Desc("The surface type to spawn this mob on")
|
||||
private IrisSurface surface = IrisSurface.LAND;
|
||||
|
||||
public Entity spawn(Engine gen, Location at) {
|
||||
return spawn(gen, at, new RNG(at.hashCode()));
|
||||
}
|
||||
@@ -154,10 +160,14 @@ public class IrisEntity extends IrisRegistrant {
|
||||
e.setGravity(isGravity());
|
||||
e.setInvulnerable(isInvulnerable());
|
||||
e.setSilent(isSilent());
|
||||
e.setPersistent(isKeepEntity());
|
||||
|
||||
int gg = 0;
|
||||
for (IrisEntity i : passengers) {
|
||||
e.addPassenger(i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++)));
|
||||
Entity passenger = i.spawn(gen, at, rng.nextParallelRNG(234858 + gg++));
|
||||
if (!Bukkit.isPrimaryThread()) {
|
||||
J.s(() -> e.addPassenger(passenger));
|
||||
}
|
||||
}
|
||||
|
||||
if (e instanceof Attributable) {
|
||||
|
||||
@@ -38,7 +38,9 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.HeightMap;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
@Accessors(chain = true)
|
||||
@@ -105,8 +107,8 @@ public class IrisEntitySpawn implements IRare {
|
||||
};
|
||||
|
||||
if (l != null) {
|
||||
spawn100(gen, l);
|
||||
s++;
|
||||
if (spawn100(gen, l) != null)
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,8 +134,11 @@ public class IrisEntitySpawn implements IRare {
|
||||
|
||||
private Entity spawn100(Engine g, Location at) {
|
||||
try {
|
||||
Location l = at.clone().add(0.5, 1, 0.5);
|
||||
Entity e = getRealEntity(g).spawn(g, l, rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)));
|
||||
IrisEntity irisEntity = getRealEntity(g);
|
||||
|
||||
if (!irisEntity.getSurface().matches(at.clone().subtract(0, 1, 0).getBlock().getState())) return null; //Make sure it can spawn on the block
|
||||
|
||||
Entity e = irisEntity.spawn(g, at.add(0.5, 0, 0.5), rng.aquire(() -> new RNG(g.getTarget().getWorld().seed() + 4)));
|
||||
if (e != null) {
|
||||
Iris.debug("Spawned " + C.DARK_AQUA + "Entity<" + getEntity() + "> " + C.GREEN + e.getType() + C.LIGHT_PURPLE + " @ " + C.GRAY + e.getLocation().getX() + ", " + e.getLocation().getY() + ", " + e.getLocation().getZ());
|
||||
}
|
||||
|
||||
@@ -787,6 +787,8 @@ public class IrisObject extends IrisRegistrant {
|
||||
|
||||
IrisPosition l1 = getAABB().max();
|
||||
IrisPosition l2 = getAABB().min();
|
||||
@SuppressWarnings({"unchecked", "rawtypes"}) HashMap<BlockVector, BlockData> placeBlock = new HashMap();
|
||||
|
||||
Vector center = getCenter();
|
||||
if (getH() == 2) {
|
||||
center = center.setY(center.getBlockY() + 0.5);
|
||||
@@ -797,14 +799,13 @@ public class IrisObject extends IrisRegistrant {
|
||||
if (getD() == 2) {
|
||||
center = center.setZ(center.getBlockZ() + 0.5);
|
||||
}
|
||||
@SuppressWarnings({"unchecked", "rawtypes"}) HashMap<BlockVector, BlockData> placeBlock = new HashMap();
|
||||
|
||||
IrisObject oo = new IrisObject((int) Math.ceil((w * scale) + (scale * 2)), (int) Math.ceil((h * scale) + (scale * 2)), (int) Math.ceil((d * scale) + (scale * 2)));
|
||||
|
||||
for (Map.Entry<BlockVector, BlockData> entry : blocks.entrySet()) {
|
||||
BlockData bd = entry.getValue();
|
||||
placeBlock.put(entry.getKey().clone().add(HALF).subtract(center)
|
||||
.multiply(scale).toBlockVector(), bd);
|
||||
.multiply(scale).add(sm1).toBlockVector(), bd);
|
||||
}
|
||||
|
||||
for (Map.Entry<BlockVector, BlockData> entry : placeBlock.entrySet()) {
|
||||
|
||||
50
src/main/java/com/volmit/iris/engine/object/IrisSurface.java
Normal file
50
src/main/java/com/volmit/iris/engine/object/IrisSurface.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.volmit.iris.engine.object;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.engine.object.annotations.Desc;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.Waterlogged;
|
||||
|
||||
@Desc("The type of surface entities should spawn on")
|
||||
public enum IrisSurface {
|
||||
|
||||
@Desc("Land surfaces")
|
||||
LAND,
|
||||
|
||||
@Desc("Any surfaces animals can spawn on, such as dirt, grass and podzol")
|
||||
ANIMAL,
|
||||
|
||||
@Desc("Within the water")
|
||||
WATER,
|
||||
|
||||
@Desc("On land or on water")
|
||||
OVERWORLD,
|
||||
|
||||
@Desc("Within lava")
|
||||
LAVA;
|
||||
|
||||
/**
|
||||
* Check if this Iris surface matches the blockstate provided
|
||||
* @param state The blockstate
|
||||
* @return True if it matches
|
||||
*/
|
||||
public boolean matches(BlockState state) {
|
||||
Material type = state.getType();
|
||||
if (type.isSolid()) {
|
||||
return this == LAND || this == OVERWORLD || (this == ANIMAL
|
||||
&& (type == Material.GRASS_BLOCK || type == Material.DIRT
|
||||
|| type == Material.DIRT_PATH || type == Material.COARSE_DIRT
|
||||
|| type == Material.ROOTED_DIRT || type == Material.PODZOL
|
||||
|| type == Material.MYCELIUM || type == Material.SNOW_BLOCK));
|
||||
}
|
||||
if (type == Material.LAVA) return this == LAVA;
|
||||
if (type == Material.WATER || type == Material.SEAGRASS
|
||||
|| type == Material.TALL_SEAGRASS || type == Material.KELP_PLANT
|
||||
|| type == Material.KELP ||
|
||||
(state instanceof Waterlogged && ((Waterlogged) state).isWaterlogged()))
|
||||
return this == WATER || this == OVERWORLD;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user