split entity ai to server #2+
This commit is contained in:
parent
02c0bfcbf6
commit
ad828ec6b4
27 changed files with 1160 additions and 1622 deletions
|
@ -162,7 +162,6 @@ import common.util.Util;
|
||||||
import common.util.HitPosition.ObjectType;
|
import common.util.HitPosition.ObjectType;
|
||||||
import common.world.Chunk;
|
import common.world.Chunk;
|
||||||
import common.world.LightType;
|
import common.world.LightType;
|
||||||
import common.world.Region;
|
|
||||||
import common.world.State;
|
import common.world.State;
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
import common.world.WorldClient;
|
import common.world.WorldClient;
|
||||||
|
@ -280,7 +279,7 @@ public class Client implements IThreadListener, IClient {
|
||||||
private final List<Message> chat = Lists.newArrayList();
|
private final List<Message> chat = Lists.newArrayList();
|
||||||
private final List<Message> feed = Lists.newArrayList();
|
private final List<Message> feed = Lists.newArrayList();
|
||||||
private final List<Message> hotbar = Lists.newArrayList();
|
private final List<Message> hotbar = Lists.newArrayList();
|
||||||
private final File config = new File(System.getProperty("config.file", "game.cfg"));
|
private final File config = new File(System.getProperty("config.file", "client.cfg"));
|
||||||
|
|
||||||
private boolean primary;
|
private boolean primary;
|
||||||
private boolean secondary;
|
private boolean secondary;
|
||||||
|
@ -1775,8 +1774,8 @@ public class Client implements IThreadListener, IClient {
|
||||||
String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX,
|
String.format("XYZ: %.3f / %.3f / %.3f", this.viewEntity.posX,
|
||||||
this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" +
|
this.viewEntity.getEntityBoundingBox().minY, this.viewEntity.posZ) + "\n" +
|
||||||
String.format("Block: %d %d %d, R: '%s/%s'", blockpos.getX(), blockpos.getY(), blockpos.getZ(),
|
String.format("Block: %d %d %d, R: '%s/%s'", blockpos.getX(), blockpos.getY(), blockpos.getZ(),
|
||||||
Region.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4),
|
Util.getRegionFolder(blockpos.getX() >> 4, blockpos.getZ() >> 4),
|
||||||
Region.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" +
|
Util.getRegionName(blockpos.getX() >> 4, blockpos.getZ() >> 4)) + "\n" +
|
||||||
String.format("Chunk: %d %d %d + %d %d %d, FOV: %.1f °%s", blockpos.getX() >> 4, blockpos.getY() >> 4, blockpos.getZ() >> 4,
|
String.format("Chunk: %d %d %d + %d %d %d, FOV: %.1f °%s", blockpos.getX() >> 4, blockpos.getY() >> 4, blockpos.getZ() >> 4,
|
||||||
blockpos.getX() & 15, blockpos.getY() & 15, blockpos.getZ() & 15, this.zooming ?
|
blockpos.getX() & 15, blockpos.getY() & 15, blockpos.getZ() & 15, this.zooming ?
|
||||||
(this.fov / this.zoomLevel) : this.fov, this.zooming ?
|
(this.fov / this.zoomLevel) : this.fov, this.zooming ?
|
||||||
|
@ -2217,7 +2216,6 @@ public class Client implements IThreadListener, IClient {
|
||||||
Log.SYSTEM.info("Beende ...");
|
Log.SYSTEM.info("Beende ...");
|
||||||
unload(false);
|
unload(false);
|
||||||
this.getSoundManager().unload();
|
this.getSoundManager().unload();
|
||||||
Region.killIO();
|
|
||||||
this.renderGlobal.stopChunkBuilders();
|
this.renderGlobal.stopChunkBuilders();
|
||||||
if(audio.end())
|
if(audio.end())
|
||||||
Log.SOUND.info("Audiogerät geschlossen");
|
Log.SOUND.info("Audiogerät geschlossen");
|
||||||
|
|
|
@ -1,214 +0,0 @@
|
||||||
package client.gui;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileFilter;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import client.Client.FileMode;
|
|
||||||
import client.gui.element.ActButton;
|
|
||||||
import client.gui.element.ActButton.Mode;
|
|
||||||
import client.gui.element.GuiList;
|
|
||||||
import client.gui.element.ListEntry;
|
|
||||||
import client.gui.element.NavButton;
|
|
||||||
import client.renderer.Drawing;
|
|
||||||
import client.world.Converter;
|
|
||||||
import common.color.TextColor;
|
|
||||||
import common.dimension.Space;
|
|
||||||
import common.log.Log;
|
|
||||||
import common.world.Region;
|
|
||||||
import common.world.World;
|
|
||||||
import common.world.Region.FolderInfo;
|
|
||||||
import common.world.Region.SaveVersion;
|
|
||||||
|
|
||||||
public class GuiConvert extends GuiList<GuiConvert.SaveInfo> implements ActButton.Callback
|
|
||||||
{
|
|
||||||
protected class SaveInfo implements Comparable<SaveInfo>, ListEntry {
|
|
||||||
private final String file;
|
|
||||||
private final int dimensions;
|
|
||||||
private final int players;
|
|
||||||
private final long seed;
|
|
||||||
private final FolderInfo info;
|
|
||||||
|
|
||||||
public SaveInfo(String file, int dimensions, int players, long seed, FolderInfo info) {
|
|
||||||
this.file = file;
|
|
||||||
this.dimensions = dimensions;
|
|
||||||
this.players = players;
|
|
||||||
this.seed = seed;
|
|
||||||
this.info = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFile() {
|
|
||||||
return this.file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDimensions() {
|
|
||||||
return this.dimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPlayers() {
|
|
||||||
return this.players;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean mustConvert() {
|
|
||||||
return this.info.legacy != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return this.info.legacy == null ? (this.info.version == null ? "<Unbekannt>" : this.info.version) : this.info.legacy.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isIncompatible() {
|
|
||||||
return this.info.legacy == SaveVersion.RELEASE_1_13;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLastPlayed() {
|
|
||||||
return this.info.lastPlayed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSeed() {
|
|
||||||
return this.seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(SaveInfo comp) {
|
|
||||||
return this.info.lastPlayed < comp.info.lastPlayed ? 1 : (this.info.lastPlayed > comp.info.lastPlayed ? -1 : this.file.compareTo(comp.file));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void select(boolean isDoubleClick, int mouseX, int mouseY)
|
|
||||||
{
|
|
||||||
boolean use = !this.isIncompatible() && this.mustConvert();
|
|
||||||
GuiConvert.this.selectButton.enabled = use;
|
|
||||||
|
|
||||||
if (isDoubleClick && use)
|
|
||||||
{
|
|
||||||
GuiConvert.this.use(GuiConvert.this.selectButton, Mode.PRIMARY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(int x, int y, int mouseXIn, int mouseYIn, boolean hover)
|
|
||||||
{
|
|
||||||
Drawing.drawText((this.isIncompatible() ? TextColor.DRED : "") + this.getFile() + (this.mustConvert() ? "" :
|
|
||||||
(TextColor.GRAY + " - " + TextColor.RESET + (this.getPlayers() > 0 ? this.getPlayers() + " Spieler" : "Keine Spieler"))),
|
|
||||||
x + 2, y, 0xffffffff);
|
|
||||||
Drawing.drawText((this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON : "") + this.getVersion() : (this.getDimensions() <= 0 ? "Keine Dimensionen" : this.getDimensions() + " Dimension" + (this.getDimensions() != 1 ? "en" : "") + " erschaffen"))
|
|
||||||
, x + 2, y + 18, 0xff808080);
|
|
||||||
Drawing.drawText(this.mustConvert() ? (this.isIncompatible() ? TextColor.CRIMSON + "Kann nicht konvertiert werden!" :
|
|
||||||
"Muss konvertiert werden!") : ( // "Kreativmodus: " + (info.isNoCreative() ? "Aus" : "An") +
|
|
||||||
"Zuletzt gespielt: " + DATE_FORMAT.format(new Date(this.getLastPlayed()))) + " " + TextColor.LGRAY + this.getVersion(), x + 2, y + 18 + 16, 0xff808080);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final GuiConvert INSTANCE = new GuiConvert();
|
|
||||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
|
|
||||||
|
|
||||||
private ActButton selectButton;
|
|
||||||
private File dir = null;
|
|
||||||
|
|
||||||
private GuiConvert()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load() {
|
|
||||||
this.elements.clear();
|
|
||||||
if(this.dir == null || !this.dir.exists() || !this.dir.isDirectory())
|
|
||||||
return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File[] files = dir.listFiles();
|
|
||||||
if(files == null)
|
|
||||||
throw new RuntimeException("Kann den Speicherordner für Welten nicht lesen oder öffnen!");
|
|
||||||
for(File file : files) {
|
|
||||||
if(!file.isDirectory())
|
|
||||||
continue;
|
|
||||||
FolderInfo info = Region.loadWorldInfo(file);
|
|
||||||
if(info == null)
|
|
||||||
info = Converter.convertMapFormat(file, false);
|
|
||||||
if(info == null) {
|
|
||||||
this.elements.add(new SaveInfo(file.getName(), -1, -1,
|
|
||||||
0L, new FolderInfo(World.START_TIME, file.lastModified(), null, null)));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int dims = -1;
|
|
||||||
int players = -1;
|
|
||||||
if(info.legacy == null) {
|
|
||||||
dims = 0;
|
|
||||||
File[] folders = new File(new File(dir, file.getName()), "chunk").listFiles(new FileFilter() {
|
|
||||||
public boolean accept(File pathname) {
|
|
||||||
return pathname.isDirectory() && !pathname.getName().equals(Space.INSTANCE.getDimensionName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(folders != null) {
|
|
||||||
for(File sub : folders) {
|
|
||||||
File[] dim = sub.listFiles();
|
|
||||||
if(dim != null && dim.length > 0)
|
|
||||||
dims++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File[] plrs = new File(new File(dir, file.getName()), "players").listFiles(new FileFilter() {
|
|
||||||
public boolean accept(File pathname) {
|
|
||||||
return pathname.getName().endsWith(".nbt");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
players = plrs == null ? 0 : plrs.length;
|
|
||||||
}
|
|
||||||
this.elements.add(new SaveInfo(file.getName(), dims, players,
|
|
||||||
0L, info));
|
|
||||||
}
|
|
||||||
Collections.sort(this.elements);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log.IO.error("Konnte Weltliste nicht laden", e);
|
|
||||||
this.elements.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(int width, int height)
|
|
||||||
{
|
|
||||||
super.init(width, height);
|
|
||||||
this.setDimensions(width, height, 32, height - 32);
|
|
||||||
|
|
||||||
this.load();
|
|
||||||
|
|
||||||
this.add(this.selectButton = new ActButton(width / 2 - 383, height - 28, 150, 24, this, "Konvertieren"));
|
|
||||||
this.add(new NavButton(width / 2 + 233, height - 28, 150, 24, GuiMenu.INSTANCE, "Abbrechen"));
|
|
||||||
|
|
||||||
this.add(new ActButton(4, 4, 200, 24, new ActButton.Callback() {
|
|
||||||
public void use(ActButton elem, ActButton.Mode action) {
|
|
||||||
if(GuiConvert.this.gm.world != null)
|
|
||||||
return;
|
|
||||||
GuiConvert.this.gm.showFileDialog(FileMode.DIRECTORY_LOAD, "Ordner wählen", GuiConvert.this.dir, new FileCallback() {
|
|
||||||
public void selected(File file) {
|
|
||||||
GuiConvert.this.dir = file;
|
|
||||||
GuiConvert.this.gm.displayGuiScreen(GuiConvert.this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, "Ordner wählen ..."));
|
|
||||||
|
|
||||||
this.selectButton.enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return "Welt auswählen";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getListWidth()
|
|
||||||
{
|
|
||||||
return 660;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSlotHeight()
|
|
||||||
{
|
|
||||||
return 56;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void use(ActButton button, Mode mode)
|
|
||||||
{
|
|
||||||
String dir = this.getSelected().getFile();
|
|
||||||
File folder = new File(this.dir, dir);
|
|
||||||
if(folder.isDirectory())
|
|
||||||
Converter.convertMapFormat(folder, true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -94,12 +94,11 @@ public class GuiMenu extends Gui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.add(new NavButton(0, 102, 196, 24, GuiConvert.INSTANCE, "Welt konvertieren"));
|
this.add(new ActButton(0, 102, 400, 24, new ActButton.Callback() {
|
||||||
this.add(new ActButton(204, 102, 196, 24, new ActButton.Callback() {
|
|
||||||
public void use(ActButton elem, ActButton.Mode action) {
|
public void use(ActButton elem, ActButton.Mode action) {
|
||||||
GuiMenu.this.gm.interrupted = true;
|
GuiMenu.this.gm.interrupted = true;
|
||||||
}
|
}
|
||||||
}, "Spiel beenden"));
|
}, "Client schließen"));
|
||||||
this.shift();
|
this.shift();
|
||||||
this.add(new Label(4, /* this.gm.fb_y - 2 */ 0, 200, 20, TextColor.VIOLET + Config.VERSION, true));
|
this.add(new Label(4, /* this.gm.fb_y - 2 */ 0, 200, 20, TextColor.VIOLET + Config.VERSION, true));
|
||||||
this.splashLabel = this.add(new Label(0, 160, width, 24, ""));
|
this.splashLabel = this.add(new Label(0, 160, width, 24, ""));
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class AIFireballAttack extends EntityAIBase
|
||||||
|
|
||||||
public boolean shouldExecute()
|
public boolean shouldExecute()
|
||||||
{
|
{
|
||||||
return this.parentEntity.getAttackTarget() != null;
|
return this.parentEntity.getNode().getAttackTarget() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startExecuting()
|
public void startExecuting()
|
||||||
|
@ -45,7 +45,7 @@ public class AIFireballAttack extends EntityAIBase
|
||||||
|
|
||||||
public void updateTask()
|
public void updateTask()
|
||||||
{
|
{
|
||||||
EntityLiving target = this.parentEntity.getAttackTarget();
|
EntityLiving target = this.parentEntity.getNode().getAttackTarget();
|
||||||
// double d0 = 64.0D;
|
// double d0 = 64.0D;
|
||||||
|
|
||||||
if (target.getDistanceSqToEntity(this.parentEntity) < this.distance * this.distance && this.parentEntity.canEntityBeSeen(target))
|
if (target.getDistanceSqToEntity(this.parentEntity) < this.distance * this.distance && this.parentEntity.canEntityBeSeen(target))
|
||||||
|
@ -84,7 +84,7 @@ public class AIFireballAttack extends EntityAIBase
|
||||||
world.spawnEntityInWorld(fireball);
|
world.spawnEntityInWorld(fireball);
|
||||||
this.attackTimer = -this.delay * this.parentEntity.getRNG().range(1, 4);
|
this.attackTimer = -this.delay * this.parentEntity.getRNG().range(1, 4);
|
||||||
}
|
}
|
||||||
this.parentEntity.getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f);
|
this.parentEntity.getNode().getLookHelper().setLookPositionWithEntity(target, 30.0f, 30.0f);
|
||||||
}
|
}
|
||||||
else if (this.attackTimer > 0)
|
else if (this.attackTimer > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -166,7 +166,7 @@ public class EntityAIControlledByPlayer extends EntityAIBase
|
||||||
|
|
||||||
if (flag && 0 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j, i1, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, i, j + 1, k, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j + 1, i1, j1, k1, l1, false, false, true))
|
if (flag && 0 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j, i1, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, i, j + 1, k, j1, k1, l1, false, false, true) && 1 == WalkNodeProcessor.getColliding(this.thisEntity.worldObj, this.thisEntity, l, j + 1, i1, j1, k1, l1, false, false, true))
|
||||||
{
|
{
|
||||||
entitycreature.getJumpHelper().setJumping();
|
entitycreature.getNode().getJumpHelper().setJumping();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
common/src/common/ai/IEntityLivingNode.java
Normal file
21
common/src/common/ai/IEntityLivingNode.java
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package common.ai;
|
||||||
|
|
||||||
|
import common.entity.DamageSource;
|
||||||
|
import common.entity.types.EntityLiving;
|
||||||
|
import common.nbt.NBTTagCompound;
|
||||||
|
|
||||||
|
public interface IEntityLivingNode extends IEntityNode {
|
||||||
|
void update();
|
||||||
|
void updateRenderAngles();
|
||||||
|
void updateLeashedState();
|
||||||
|
void setLeashTag(NBTTagCompound tag);
|
||||||
|
EntityLiving getAttacking();
|
||||||
|
EntityLiving getAttackTarget();
|
||||||
|
void resetCombat();
|
||||||
|
void trackDamage(DamageSource source, int amount);
|
||||||
|
void sendDeathMessage();
|
||||||
|
EntityJumpHelper getJumpHelper();
|
||||||
|
EntityLookHelper getLookHelper();
|
||||||
|
void updateAttacking();
|
||||||
|
void dropExperience();
|
||||||
|
}
|
14
common/src/common/ai/IEntityMobNPCNode.java
Normal file
14
common/src/common/ai/IEntityMobNPCNode.java
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package common.ai;
|
||||||
|
|
||||||
|
import common.entity.Entity;
|
||||||
|
import common.entity.types.EntityLiving;
|
||||||
|
|
||||||
|
public interface IEntityMobNPCNode extends IEntityNPCNode {
|
||||||
|
|
||||||
|
void becomeAngryAt(Entity entity);
|
||||||
|
|
||||||
|
boolean isAngry();
|
||||||
|
|
||||||
|
void setAngerTarget(EntityLiving entity);
|
||||||
|
|
||||||
|
}
|
9
common/src/common/ai/IEntityNPCNode.java
Normal file
9
common/src/common/ai/IEntityNPCNode.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package common.ai;
|
||||||
|
|
||||||
|
import common.entity.types.EntityLiving;
|
||||||
|
|
||||||
|
public interface IEntityNPCNode extends IEntityLivingNode {
|
||||||
|
void setCombatTask();
|
||||||
|
boolean canCounter(EntityLiving entity);
|
||||||
|
boolean canAttack(EntityLiving entity);
|
||||||
|
}
|
|
@ -1,17 +1,10 @@
|
||||||
package common.ai;
|
package common.ai;
|
||||||
|
|
||||||
import common.entity.DamageSource;
|
|
||||||
import common.entity.types.EntityLiving;
|
|
||||||
import common.nbt.NBTTagCompound;
|
import common.nbt.NBTTagCompound;
|
||||||
|
import common.world.World;
|
||||||
|
|
||||||
public interface IEntityNode {
|
public interface IEntityNode {
|
||||||
void update();
|
void readNbt(NBTTagCompound tag);
|
||||||
void updateRenderAngles();
|
void writeNbt(NBTTagCompound tag);
|
||||||
void updateLeashedState();
|
void setWorld(World world);
|
||||||
void setLeashTag(NBTTagCompound tag);
|
|
||||||
EntityLiving getAttacking();
|
|
||||||
EntityLiving getAttackTarget();
|
|
||||||
void resetCombat();
|
|
||||||
void trackDamage(DamageSource source, int amount);
|
|
||||||
void sendDeathMessage();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package common.entity;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import common.ai.IEntityLivingNode;
|
||||||
|
import common.ai.IEntityNode;
|
||||||
import common.block.Block;
|
import common.block.Block;
|
||||||
import common.block.BlockFence;
|
import common.block.BlockFence;
|
||||||
import common.block.BlockFenceGate;
|
import common.block.BlockFenceGate;
|
||||||
|
@ -45,13 +47,14 @@ import common.world.State;
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
import common.world.WorldServer;
|
import common.world.WorldServer;
|
||||||
|
|
||||||
public abstract class Entity
|
public abstract class Entity<T extends IEntityNode>
|
||||||
{
|
{
|
||||||
private static final BoundingBox ZERO_AABB = new BoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
|
private static final BoundingBox ZERO_AABB = new BoundingBox(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D);
|
||||||
private static int nextID;
|
private static int nextID;
|
||||||
|
|
||||||
protected final DataWatcher dataWatcher;
|
protected final DataWatcher dataWatcher;
|
||||||
protected final Random rand;
|
protected final Random rand;
|
||||||
|
protected T node;
|
||||||
|
|
||||||
private int eid;
|
private int eid;
|
||||||
public World worldObj;
|
public World worldObj;
|
||||||
|
@ -118,6 +121,14 @@ public abstract class Entity
|
||||||
protected PortalType inPortal;
|
protected PortalType inPortal;
|
||||||
// private boolean invulnerable;
|
// private boolean invulnerable;
|
||||||
|
|
||||||
|
public T getNode() {
|
||||||
|
return this.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNode(T node) {
|
||||||
|
this.node = node;
|
||||||
|
}
|
||||||
|
|
||||||
public int getId()
|
public int getId()
|
||||||
{
|
{
|
||||||
return this.eid;
|
return this.eid;
|
||||||
|
@ -1130,6 +1141,8 @@ public abstract class Entity
|
||||||
public void setWorld(World worldIn)
|
public void setWorld(World worldIn)
|
||||||
{
|
{
|
||||||
this.worldObj = worldIn;
|
this.worldObj = worldIn;
|
||||||
|
if(this.node != null)
|
||||||
|
this.node.setWorld(worldIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1523,6 +1536,8 @@ public abstract class Entity
|
||||||
tagCompund.setBoolean("IgnoreFall", this.ignoreFall);
|
tagCompund.setBoolean("IgnoreFall", this.ignoreFall);
|
||||||
|
|
||||||
this.writeEntityToNBT(tagCompund);
|
this.writeEntityToNBT(tagCompund);
|
||||||
|
if(this.node != null)
|
||||||
|
this.node.writeNbt(tagCompund);
|
||||||
|
|
||||||
if (this.vehicle != null && !(this.isPlayer()))
|
if (this.vehicle != null && !(this.isPlayer()))
|
||||||
{
|
{
|
||||||
|
@ -1592,6 +1607,8 @@ public abstract class Entity
|
||||||
// this.setSilent(tagCompund.getBoolean("Silent"));
|
// this.setSilent(tagCompund.getBoolean("Silent"));
|
||||||
this.ignoreFall = tagCompund.getBoolean("IgnoreFall");
|
this.ignoreFall = tagCompund.getBoolean("IgnoreFall");
|
||||||
this.readEntityFromNBT(tagCompund);
|
this.readEntityFromNBT(tagCompund);
|
||||||
|
if(this.node != null)
|
||||||
|
this.node.readNbt(tagCompund);
|
||||||
|
|
||||||
if (this.shouldSetPosAfterLoading())
|
if (this.shouldSetPosAfterLoading())
|
||||||
{
|
{
|
||||||
|
|
22
common/src/common/entity/npc/AIHurtByAggressor.java
Normal file
22
common/src/common/entity/npc/AIHurtByAggressor.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package common.entity.npc;
|
||||||
|
|
||||||
|
import common.ai.EntityAIHurtByTarget;
|
||||||
|
import common.entity.types.EntityLiving;
|
||||||
|
|
||||||
|
public class AIHurtByAggressor extends EntityAIHurtByTarget
|
||||||
|
{
|
||||||
|
public AIHurtByAggressor(EntityMobNPC p_i45828_1_)
|
||||||
|
{
|
||||||
|
super(p_i45828_1_, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn)
|
||||||
|
{
|
||||||
|
super.setEntityAttackTarget(creatureIn, entityLivingBaseIn);
|
||||||
|
|
||||||
|
if (creatureIn.getClass() == this.taskOwner.getClass())
|
||||||
|
{
|
||||||
|
((EntityMobNPC)creatureIn).getNode().becomeAngryAt(entityLivingBaseIn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -108,7 +108,7 @@ public class EntityChaosMarine extends EntityNPC {
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getAttackSpeed() {
|
public int getAttackSpeed() {
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -141,10 +141,6 @@ public class EntityGargoyle extends EntityFlyingNPC
|
||||||
// this.launchBoxToEntity(target);
|
// this.launchBoxToEntity(target);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public boolean isRangedWeapon(ItemStack stack) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||||
{
|
{
|
||||||
// if (this.isEntityInvulnerable(source))
|
// if (this.isEntityInvulnerable(source))
|
||||||
|
|
|
@ -1,317 +1,45 @@
|
||||||
package common.entity.npc;
|
package common.entity.npc;
|
||||||
|
|
||||||
import common.ai.EntityAIHurtByTarget;
|
import common.ai.IEntityMobNPCNode;
|
||||||
import common.entity.DamageSource;
|
import common.entity.DamageSource;
|
||||||
import common.entity.Entity;
|
import common.entity.Entity;
|
||||||
import common.entity.attributes.AttributeInstance;
|
|
||||||
import common.entity.attributes.Attributes;
|
|
||||||
import common.entity.types.EntityLiving;
|
import common.entity.types.EntityLiving;
|
||||||
import common.nbt.NBTTagCompound;
|
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
|
|
||||||
public abstract class EntityMobNPC extends EntityNPC
|
public abstract class EntityMobNPC<T extends IEntityMobNPCNode> extends EntityNPC<T>
|
||||||
{
|
{
|
||||||
private int angerLevel;
|
public T getNode() {
|
||||||
// private int randomSoundDelay;
|
return this.node;
|
||||||
private int angerTarget;
|
}
|
||||||
// private Class<? extends EntityNPC> angerClass;
|
|
||||||
|
|
||||||
public EntityMobNPC(World worldIn)
|
public EntityMobNPC(World worldIn)
|
||||||
{
|
{
|
||||||
super(worldIn);
|
super(worldIn);
|
||||||
this.targets.addTask(1, new AIHurtByAggressor(this));
|
|
||||||
// this.targets.addTask(2, new AITargetAggressor(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public boolean isImmuneToFire()
|
|
||||||
// {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void setAttackedBy(EntityLiving livingBase)
|
public void setAttackedBy(EntityLiving livingBase)
|
||||||
{
|
{
|
||||||
super.setAttackedBy(livingBase);
|
super.setAttackedBy(livingBase);
|
||||||
|
|
||||||
if (livingBase != null)
|
if (livingBase != null)
|
||||||
{
|
{
|
||||||
this.angerTarget = livingBase.getId();
|
this.node.setAngerTarget(livingBase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// protected void applyEntityAI()
|
|
||||||
// {
|
|
||||||
// this.targets.addTask(1, new EntityMobNPC.AIHurtByAggressor(this));
|
|
||||||
// this.targets.addTask(2, new EntityMobNPC.AITargetAggressor(this));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// protected void applyEntityAttributes()
|
|
||||||
// {
|
|
||||||
// super.applyEntityAttributes();
|
|
||||||
// this.getEntityAttribute(Attributes.REINFORCEMENT_CHANCE).setBaseValue(0.0D);
|
|
||||||
// this.getEntityAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.23000000417232513D);
|
|
||||||
// this.getEntityAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(5.0D);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Called to update the entity's position/logic.
|
|
||||||
// */
|
|
||||||
// public void onUpdate()
|
|
||||||
// {
|
|
||||||
// super.onUpdate();
|
|
||||||
// }
|
|
||||||
|
|
||||||
protected void updateAITasks()
|
|
||||||
{
|
|
||||||
AttributeInstance iattributeinstance = this.getEntityAttribute(Attributes.MOVEMENT_SPEED);
|
|
||||||
|
|
||||||
if (this.isAngry())
|
|
||||||
{
|
|
||||||
if (/* !this.isChild() && */ !iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD))
|
|
||||||
{
|
|
||||||
iattributeinstance.applyModifier(Attributes.RUSHING_SPEED_MOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
--this.angerLevel;
|
|
||||||
}
|
|
||||||
else if (iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD))
|
|
||||||
{
|
|
||||||
iattributeinstance.removeModifier(Attributes.RUSHING_SPEED_MOD);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (this.randomSoundDelay > 0 && --this.randomSoundDelay == 0)
|
|
||||||
// {
|
|
||||||
// this.playSound("mob.zombiepig.zpigangry", this.getSoundVolume() * 2.0F, ((this.rand.floatv() - this.rand.floatv()) * 0.2F + 1.0F) * 1.8F);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (this.angerLevel > 0 && this.angerTarget != 0 && this.getAttackedBy() == null)
|
|
||||||
{
|
|
||||||
Entity entity = this.worldObj.getEntityByID(this.angerTarget);
|
|
||||||
if(entity instanceof EntityLiving)
|
|
||||||
this.setAttackedBy((EntityLiving)entity);
|
|
||||||
if(entity != null && entity.isPlayer())
|
|
||||||
this.playerAttacker = (EntityNPC)entity;
|
|
||||||
this.recentlyHit = this.getAttackedTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
super.updateAITasks();
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Checks if the entity's current position is a valid location to spawn this entity.
|
|
||||||
// */
|
|
||||||
// public boolean getCanSpawnHere()
|
|
||||||
// {
|
|
||||||
// return this.worldObj.getDifficulty() != Difficulty.PEACEFUL;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (abstract) Protected helper method to write subclass entity data to NBT.
|
|
||||||
*/
|
|
||||||
public void writeEntityToNBT(NBTTagCompound tagCompound)
|
|
||||||
{
|
|
||||||
super.writeEntityToNBT(tagCompound);
|
|
||||||
tagCompound.setShort("Anger", (short)this.angerLevel);
|
|
||||||
|
|
||||||
// if (this.angerTarget != null)
|
|
||||||
// {
|
|
||||||
// tagCompound.setString("HurtBy", this.angerTarget);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// tagCompound.setString("HurtBy", "");
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
|
||||||
*/
|
|
||||||
public void readEntityFromNBT(NBTTagCompound tagCompund)
|
|
||||||
{
|
|
||||||
super.readEntityFromNBT(tagCompund);
|
|
||||||
this.angerLevel = tagCompund.getShort("Anger");
|
|
||||||
// String s = tagCompund.getString("HurtBy");
|
|
||||||
//
|
|
||||||
// if (s.length() > 0)
|
|
||||||
// {
|
|
||||||
// this.angerTarget = s;
|
|
||||||
// EntityNPC entityplayer = this.worldObj.getPlayer(this.angerTarget);
|
|
||||||
// this.setAttackedBy(entityplayer);
|
|
||||||
//
|
|
||||||
// if (entityplayer != null)
|
|
||||||
// {
|
|
||||||
// this.playerAttacker = entityplayer;
|
|
||||||
// this.recentlyHit = this.getAttackedTime();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the entity is attacked.
|
|
||||||
*/
|
|
||||||
public boolean attackEntityFrom(DamageSource source, int amount)
|
public boolean attackEntityFrom(DamageSource source, int amount)
|
||||||
{
|
{
|
||||||
// if (this.isEntityInvulnerable(source))
|
|
||||||
// {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
Entity entity = source.getEntity();
|
Entity entity = source.getEntity();
|
||||||
|
|
||||||
if (entity != null && entity instanceof EntityNPC)
|
if (entity != null && entity instanceof EntityNPC)
|
||||||
{
|
{
|
||||||
this.becomeAngryAt(entity);
|
this.node.becomeAngryAt(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.attackEntityFrom(source, amount);
|
return super.attackEntityFrom(source, amount);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes this PigZombie to become angry at the supplied Entity (which will be a player).
|
|
||||||
*/
|
|
||||||
private void becomeAngryAt(Entity p_70835_1_)
|
|
||||||
{
|
|
||||||
this.angerLevel = this.rand.excl(400, 800);
|
|
||||||
// this.randomSoundDelay = this.rand.zrange(40);
|
|
||||||
|
|
||||||
if (p_70835_1_ instanceof EntityLiving)
|
|
||||||
{
|
|
||||||
this.setAttackedBy((EntityLiving)p_70835_1_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAngry()
|
|
||||||
{
|
|
||||||
return this.angerLevel > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Returns the sound this mob makes while it's alive.
|
|
||||||
// */
|
|
||||||
// protected String getLivingSound()
|
|
||||||
// {
|
|
||||||
// return "mob.zombiepig.zpig";
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Returns the sound this mob makes when it is hurt.
|
|
||||||
// */
|
|
||||||
// protected String getHurtSound()
|
|
||||||
// {
|
|
||||||
// return "mob.zombiepig.zpighurt";
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Returns the sound this mob makes on death.
|
|
||||||
// */
|
|
||||||
// protected String getDeathSound()
|
|
||||||
// {
|
|
||||||
// return "mob.zombiepig.zpigdeath";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Drop 0-2 items of this living's type
|
|
||||||
// *
|
|
||||||
// * @param wasRecentlyHit true if this this entity was recently hit by appropriate entity (generally only if player
|
|
||||||
// * or tameable)
|
|
||||||
// * @param lootingModifier level of enchanment to be applied to this drop
|
|
||||||
// */
|
|
||||||
// protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier)
|
|
||||||
// {
|
|
||||||
// int i = this.rand.zrange(2 + lootingModifier);
|
|
||||||
//
|
|
||||||
// for (int j = 0; j < i; ++j)
|
|
||||||
// {
|
|
||||||
// this.dropItem(Items.rotten_flesh, 1);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// i = this.rand.zrange(2 + lootingModifier);
|
|
||||||
//
|
|
||||||
// for (int k = 0; k < i; ++k)
|
|
||||||
// {
|
|
||||||
// this.dropItem(Items.gold_nugget, 1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
|
|
||||||
// */
|
|
||||||
// public boolean interact(EntityNPC player)
|
|
||||||
// {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Causes this Entity to drop a random item.
|
|
||||||
// */
|
|
||||||
// protected void addRandomDrop()
|
|
||||||
// {
|
|
||||||
// this.dropItem(Items.gold_ingot, 1);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Gives armor or weapon for entity based on given DifficultyInstance
|
|
||||||
// */
|
|
||||||
// protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty)
|
|
||||||
// {
|
|
||||||
// this.setItem(0, new ItemStack(Items.golden_sword));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Called only once on an entity when first time spawned, via egg, mob spawner, natural spawning etc, but not called
|
|
||||||
// * when entity is reloaded from nbt. Mainly used for initializing attributes and inventory
|
|
||||||
// */
|
|
||||||
// public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata)
|
|
||||||
// {
|
|
||||||
// super.onInitialSpawn(difficulty, livingdata);
|
|
||||||
//// this.setVillager(false);
|
|
||||||
// return livingdata;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public int getColor() {
|
|
||||||
// return 0xff9494;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public void onStruckByLightning(EntityLightning lightningBolt) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
public boolean isAggressive(Class<? extends EntityNPC> clazz) {
|
||||||
return this.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz);
|
return this.node.isAngry() && clazz != this.getClass() && !this.isPeaceful(clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class AIHurtByAggressor extends EntityAIHurtByTarget
|
|
||||||
{
|
|
||||||
public AIHurtByAggressor(EntityMobNPC p_i45828_1_)
|
|
||||||
{
|
|
||||||
super(p_i45828_1_, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setEntityAttackTarget(EntityLiving creatureIn, EntityLiving entityLivingBaseIn)
|
|
||||||
{
|
|
||||||
super.setEntityAttackTarget(creatureIn, entityLivingBaseIn);
|
|
||||||
|
|
||||||
if (creatureIn.getClass() == this.taskOwner.getClass())
|
|
||||||
{
|
|
||||||
((EntityMobNPC)creatureIn).becomeAngryAt(entityLivingBaseIn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static class AITargetAggressor extends EntityAINearestAttackableTarget<EntityLiving>
|
|
||||||
// {
|
|
||||||
// public AITargetAggressor(EntityMobNPC p_i45829_1_)
|
|
||||||
// {
|
|
||||||
// super(p_i45829_1_, EntityLiving.class, 10, true, false, new Predicate<EntityLiving>() {
|
|
||||||
// public boolean test(EntityLiving entity) {
|
|
||||||
// return entity.isPlayer(); // || entity instanceof EntityNPC;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public boolean shouldExecute()
|
|
||||||
// {
|
|
||||||
// return ((EntityMobNPC)this.taskOwner).isAngry() && super.shouldExecute();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,24 +2,8 @@ package common.entity.npc;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
import common.IClient;
|
import common.IClient;
|
||||||
import common.ai.AIRangedAttack;
|
import common.ai.IEntityNPCNode;
|
||||||
import common.ai.EntityAIAttackOnCollide;
|
|
||||||
import common.ai.EntityAIAvoidEntity;
|
|
||||||
import common.ai.EntityAIHurtByTarget;
|
|
||||||
import common.ai.EntityAILookAtTalkingPlayer;
|
|
||||||
import common.ai.EntityAINagPlayer;
|
|
||||||
import common.ai.EntityAINearestAttackableTarget;
|
|
||||||
import common.ai.EntityAINpcInteract;
|
|
||||||
import common.ai.EntityAINpcMate;
|
|
||||||
import common.ai.EntityAIOpenDoor;
|
|
||||||
import common.ai.EntityAIPlay;
|
|
||||||
import common.ai.EntityAISwimming;
|
|
||||||
import common.ai.EntityAIWander;
|
|
||||||
import common.ai.EntityAIWatchClosest;
|
|
||||||
import common.ai.EntityAIWatchClosest2;
|
|
||||||
import common.block.Block;
|
import common.block.Block;
|
||||||
import common.block.BlockBed;
|
import common.block.BlockBed;
|
||||||
import common.dimension.Space;
|
import common.dimension.Space;
|
||||||
|
@ -78,7 +62,6 @@ import common.packet.CPacketInput;
|
||||||
import common.packet.CPacketPlayer;
|
import common.packet.CPacketPlayer;
|
||||||
import common.packet.SPacketEntityEquipment;
|
import common.packet.SPacketEntityEquipment;
|
||||||
import common.packet.SPacketEntityVelocity;
|
import common.packet.SPacketEntityVelocity;
|
||||||
import common.pathfinding.PathNavigateGround;
|
|
||||||
import common.potion.Potion;
|
import common.potion.Potion;
|
||||||
import common.potion.PotionEffect;
|
import common.potion.PotionEffect;
|
||||||
import common.rng.Random;
|
import common.rng.Random;
|
||||||
|
@ -98,7 +81,7 @@ import common.world.World;
|
||||||
import common.world.WorldClient;
|
import common.world.WorldClient;
|
||||||
import common.world.WorldServer;
|
import common.world.WorldServer;
|
||||||
|
|
||||||
public abstract class EntityNPC extends EntityLiving
|
public abstract class EntityNPC<T extends IEntityNPCNode> extends EntityLiving<T>
|
||||||
{
|
{
|
||||||
public static class CharacterTypeData
|
public static class CharacterTypeData
|
||||||
{
|
{
|
||||||
|
@ -211,6 +194,10 @@ public abstract class EntityNPC extends EntityLiving
|
||||||
// public float nausea;
|
// public float nausea;
|
||||||
// public float prevNausea;
|
// public float prevNausea;
|
||||||
|
|
||||||
|
public T getNode() {
|
||||||
|
return this.node;
|
||||||
|
}
|
||||||
|
|
||||||
public EntityNPC(World worldIn)
|
public EntityNPC(World worldIn)
|
||||||
{
|
{
|
||||||
super(worldIn);
|
super(worldIn);
|
||||||
|
@ -260,53 +247,20 @@ public abstract class EntityNPC extends EntityLiving
|
||||||
return this.connection != null || this.gm != null;
|
return this.connection != null || this.gm != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public final boolean canInfight(Alignment align) {
|
|
||||||
return this.alignment.chaotic || (!this.alignment.lawful &&
|
|
||||||
((this.alignment.good && align.evil) || (this.alignment.evil && align.good)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final boolean canMurder(Alignment align) {
|
|
||||||
return this.alignment.chaotic && ((this.alignment.good && align.evil) || (this.alignment.evil && align.good));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canCounter(EntityLiving entity) {
|
|
||||||
return !(entity instanceof EntityNPC) ||
|
|
||||||
(this.getClass() == entity.getClass() ? this.canInfight(((EntityNPC)entity).alignment) :
|
|
||||||
!this.isPeaceful(((EntityNPC)entity).getClass()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canAttack(EntityLiving entity) {
|
|
||||||
return entity instanceof EntityNPC && (this.getClass() == entity.getClass() ? this.canMurder(((EntityNPC)entity).alignment) :
|
|
||||||
this.isAggressive(((EntityNPC)entity).getClass()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canAmbush(EntityLiving entity) {
|
public boolean canAmbush(EntityLiving entity) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldFlee(EntityLiving entity) {
|
|
||||||
return (this.getHealth() <= (this.getMaxHealth() / 4) || !this.canCounter(entity)) &&
|
|
||||||
((entity instanceof EntityNPC && (((EntityNPC)entity).canAttack(this)) ||
|
|
||||||
(entity == this.getAttackedBy() && ((EntityNPC)entity).canCounter(this))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void setCombatTask()
|
// public void setCombatTask()
|
||||||
// {
|
// {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public boolean isRangedWeapon(ItemStack stack) {
|
|
||||||
return stack != null && (stack.getItem() == Items.bow || stack.getItem() instanceof ItemGunBase ||
|
|
||||||
stack.getItem() == Items.snowball || stack.getItem() == Items.potion);
|
|
||||||
}
|
|
||||||
|
|
||||||
// public boolean isSneaking()
|
// public boolean isSneaking()
|
||||||
// {
|
// {
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
protected int getAttackSpeed() {
|
public int getAttackSpeed() {
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,6 +678,11 @@ public abstract class EntityNPC extends EntityLiving
|
||||||
return Alignment.values()[this.dataWatcher.getWatchableObjectByte(18) % Alignment.values().length];
|
return Alignment.values()[this.dataWatcher.getWatchableObjectByte(18) % Alignment.values().length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Alignment getAlignmentCached()
|
||||||
|
{
|
||||||
|
return this.alignment;
|
||||||
|
}
|
||||||
|
|
||||||
public void setHeight(float height)
|
public void setHeight(float height)
|
||||||
{
|
{
|
||||||
this.dataWatcher.updateObject(29, ExtMath.clampf(height, 0.2f, 10.0f));
|
this.dataWatcher.updateObject(29, ExtMath.clampf(height, 0.2f, 10.0f));
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class EntitySpaceMarine extends EntityNPC {
|
||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getAttackSpeed() {
|
public int getAttackSpeed() {
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import common.ai.IEntityNode;
|
import common.ai.IEntityLivingNode;
|
||||||
import common.block.Block;
|
import common.block.Block;
|
||||||
import common.block.SoundType;
|
import common.block.SoundType;
|
||||||
import common.collect.Maps;
|
import common.collect.Maps;
|
||||||
|
@ -57,11 +57,10 @@ import common.world.State;
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
import common.world.WorldServer;
|
import common.world.WorldServer;
|
||||||
|
|
||||||
public abstract class EntityLiving extends Entity
|
public abstract class EntityLiving<T extends IEntityLivingNode> extends Entity<T>
|
||||||
{
|
{
|
||||||
private static final ItemStack[] EMPTY_INV = new ItemStack[5];
|
private static final ItemStack[] EMPTY_INV = new ItemStack[5];
|
||||||
|
|
||||||
protected IEntityNode node;
|
|
||||||
private AttributeMap attributes;
|
private AttributeMap attributes;
|
||||||
private final Map<Potion, PotionEffect> effects = Maps.<Potion, PotionEffect>newEnumMap(Potion.class);
|
private final Map<Potion, PotionEffect> effects = Maps.<Potion, PotionEffect>newEnumMap(Potion.class);
|
||||||
public int soundTimer;
|
public int soundTimer;
|
||||||
|
@ -105,13 +104,6 @@ public abstract class EntityLiving extends Entity
|
||||||
public int maxHurtTime;
|
public int maxHurtTime;
|
||||||
public int deathTime;
|
public int deathTime;
|
||||||
public int hurtCooldown = 20;
|
public int hurtCooldown = 20;
|
||||||
protected int lastDamage;
|
|
||||||
protected EntityNPC playerAttacker;
|
|
||||||
protected int recentlyHit;
|
|
||||||
private EntityLiving attackedBy;
|
|
||||||
private int lastAttacked;
|
|
||||||
private EntityLiving attacker;
|
|
||||||
private int lastAttackTime;
|
|
||||||
|
|
||||||
// protected int entityAge;
|
// protected int entityAge;
|
||||||
private int absorptionAmount;
|
private int absorptionAmount;
|
||||||
|
@ -129,6 +121,10 @@ public abstract class EntityLiving extends Entity
|
||||||
private float ageWidth = -1.0F;
|
private float ageWidth = -1.0F;
|
||||||
private float ageHeight;
|
private float ageHeight;
|
||||||
|
|
||||||
|
public T getNode() {
|
||||||
|
return this.node;
|
||||||
|
}
|
||||||
|
|
||||||
public EntityLiving(World worldIn)
|
public EntityLiving(World worldIn)
|
||||||
{
|
{
|
||||||
super(worldIn);
|
super(worldIn);
|
||||||
|
@ -297,37 +293,9 @@ public abstract class EntityLiving extends Entity
|
||||||
this.onDeathUpdate();
|
this.onDeathUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.recentlyHit > 0)
|
|
||||||
{
|
|
||||||
--this.recentlyHit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.playerAttacker = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.attacker != null && !this.attacker.isEntityAlive())
|
|
||||||
{
|
|
||||||
this.attacker = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if(this.attackedBy.isPlayer() && ((EntityNPC)this.attackedBy).capabilities.isCreativeMode) {
|
|
||||||
// this.attackedBy = null; // FIX Creative
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (this.attackedBy != null)
|
|
||||||
{
|
|
||||||
if (!this.attackedBy.isEntityAlive())
|
|
||||||
{
|
|
||||||
this.setAttackedBy(null);
|
|
||||||
}
|
|
||||||
else if (this.ticksExisted - this.lastAttacked > 100)
|
|
||||||
{
|
|
||||||
this.setAttackedBy(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.worldObj.client) {
|
if(!this.worldObj.client) {
|
||||||
|
this.node.updateAttacking();
|
||||||
|
|
||||||
if(!this.firstEffectUpdate && Config.radiation) { // &&
|
if(!this.firstEffectUpdate && Config.radiation) { // &&
|
||||||
// (!(this.isPlayer()) || !((EntityNPCMP)this).creative)) {
|
// (!(this.isPlayer()) || !((EntityNPCMP)this).creative)) {
|
||||||
float radiation = this.radiation + (float)this.attributes.getAttributeInstance(Attributes.RADIATION).getAttributeValue();
|
float radiation = this.radiation + (float)this.attributes.getAttributeInstance(Attributes.RADIATION).getAttributeValue();
|
||||||
|
@ -389,16 +357,9 @@ public abstract class EntityLiving extends Entity
|
||||||
|
|
||||||
if (this.deathTime == 20)
|
if (this.deathTime == 20)
|
||||||
{
|
{
|
||||||
if (!this.worldObj.client && (this.recentlyHit > 0 || this.isPlayer()) && this.canDropLoot() && Config.mobXP)
|
if (!this.worldObj.client)
|
||||||
{
|
{
|
||||||
int i = this.getExperiencePoints(this.playerAttacker);
|
this.node.dropExperience();
|
||||||
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
int j = EntityXp.getXPSplit(i);
|
|
||||||
i -= j;
|
|
||||||
this.worldObj.spawnEntityInWorld(new EntityXp(this.worldObj, this.posX, this.posY, this.posZ, j));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
this.setDead();
|
||||||
|
@ -452,46 +413,6 @@ public abstract class EntityLiving extends Entity
|
||||||
return this.rand;
|
return this.rand;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityLiving getAttackedBy()
|
|
||||||
{
|
|
||||||
return this.attackedBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAttackedTime()
|
|
||||||
{
|
|
||||||
return this.lastAttacked;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttackedBy(EntityLiving livingBase)
|
|
||||||
{
|
|
||||||
this.attackedBy = livingBase;
|
|
||||||
this.lastAttacked = this.ticksExisted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityLiving getLastAttack()
|
|
||||||
{
|
|
||||||
return this.attacker;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLastAttackTime()
|
|
||||||
{
|
|
||||||
return this.lastAttackTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastAttack(Entity entity)
|
|
||||||
{
|
|
||||||
if (entity instanceof EntityLiving)
|
|
||||||
{
|
|
||||||
this.attacker = (EntityLiving)entity;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.attacker = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lastAttackTime = this.ticksExisted;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public int getAge()
|
// public int getAge()
|
||||||
// {
|
// {
|
||||||
// return this.entityAge;
|
// return this.entityAge;
|
||||||
|
@ -1336,11 +1257,6 @@ public abstract class EntityLiving extends Entity
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityLiving getAttackingEntity()
|
|
||||||
{
|
|
||||||
return (EntityLiving)(this.node.getAttacking() != null ? this.node.getAttacking() : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int getMaxHealth()
|
public final int getMaxHealth()
|
||||||
{
|
{
|
||||||
return (int)this.getEntityAttribute(Attributes.MAX_HEALTH).getAttributeValue();
|
return (int)this.getEntityAttribute(Attributes.MAX_HEALTH).getAttributeValue();
|
||||||
|
|
|
@ -389,4 +389,12 @@ int utf_len(const char *str) {
|
||||||
public static double ftime() {
|
public static double ftime() {
|
||||||
return ((double)rtime()) / 1000000.0;
|
return ((double)rtime()) / 1000000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getRegionFolder(int x, int z) {
|
||||||
|
return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRegionName(int x, int z) {
|
||||||
|
return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,7 @@ import common.collect.Lists;
|
||||||
import common.collect.Maps;
|
import common.collect.Maps;
|
||||||
import common.entity.Entity;
|
import common.entity.Entity;
|
||||||
import common.init.BlockRegistry;
|
import common.init.BlockRegistry;
|
||||||
import common.init.Config;
|
|
||||||
import common.init.EntityRegistry;
|
import common.init.EntityRegistry;
|
||||||
import common.init.UniverseRegistry;
|
|
||||||
import common.log.Log;
|
import common.log.Log;
|
||||||
import common.nbt.NBTLoader;
|
import common.nbt.NBTLoader;
|
||||||
import common.nbt.NBTTagCompound;
|
import common.nbt.NBTTagCompound;
|
||||||
|
@ -33,39 +31,9 @@ import common.tileentity.TileEntity;
|
||||||
import common.util.BlockPos;
|
import common.util.BlockPos;
|
||||||
import common.util.NextTickListEntry;
|
import common.util.NextTickListEntry;
|
||||||
import common.util.NibbleArray;
|
import common.util.NibbleArray;
|
||||||
|
import common.util.Util;
|
||||||
|
|
||||||
public class Region {
|
public class Region {
|
||||||
public static enum SaveVersion {
|
|
||||||
ALPHA_1_0("Alpha 1.0 - Beta 1.2"),
|
|
||||||
BETA_1_3("Beta 1.3 - Release 1.8.9"),
|
|
||||||
RELEASE_1_9("Release 1.9 - Release 1.12.2"),
|
|
||||||
RELEASE_1_13("Release 1.13 +");
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
private SaveVersion(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FolderInfo {
|
|
||||||
public final long time;
|
|
||||||
public final long lastPlayed;
|
|
||||||
public final SaveVersion legacy;
|
|
||||||
public final String version;
|
|
||||||
|
|
||||||
public FolderInfo(long time, long lastPlayed, SaveVersion legacy, String version) {
|
|
||||||
this.time = time;
|
|
||||||
this.lastPlayed = lastPlayed;
|
|
||||||
this.legacy = legacy;
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ChunkBuffer extends ByteArrayOutputStream {
|
private static class ChunkBuffer extends ByteArrayOutputStream {
|
||||||
public ChunkBuffer() {
|
public ChunkBuffer() {
|
||||||
super(8096);
|
super(8096);
|
||||||
|
@ -91,9 +59,6 @@ public class Region {
|
||||||
private static final Map<String, Region> CACHE = Maps.<String, Region>newHashMap();
|
private static final Map<String, Region> CACHE = Maps.<String, Region>newHashMap();
|
||||||
private static final List<WorldServer> QUEUE = Collections.<WorldServer>synchronizedList(Lists.<WorldServer>newArrayList());
|
private static final List<WorldServer> QUEUE = Collections.<WorldServer>synchronizedList(Lists.<WorldServer>newArrayList());
|
||||||
|
|
||||||
// public static long lastPlayed;
|
|
||||||
// public static int version;
|
|
||||||
// public static String owner;
|
|
||||||
private static volatile long queued;
|
private static volatile long queued;
|
||||||
private static volatile long saved;
|
private static volatile long saved;
|
||||||
private static volatile boolean waiting;
|
private static volatile boolean waiting;
|
||||||
|
@ -113,10 +78,10 @@ public class Region {
|
||||||
private boolean modified;
|
private boolean modified;
|
||||||
|
|
||||||
public Region(File dir, int x, int z) {
|
public Region(File dir, int x, int z) {
|
||||||
File sdir = new File(dir, getRegionFolder(x << 3, z << 3));
|
File sdir = new File(dir, Util.getRegionFolder(x << 3, z << 3));
|
||||||
if(!sdir.exists())
|
if(!sdir.exists())
|
||||||
sdir.mkdirs();
|
sdir.mkdirs();
|
||||||
this.regFile = new File(sdir, getRegionName(x << 3, z << 3));
|
this.regFile = new File(sdir, Util.getRegionName(x << 3, z << 3));
|
||||||
this.folder = dir;
|
this.folder = dir;
|
||||||
this.xPos = x;
|
this.xPos = x;
|
||||||
this.zPos = z;
|
this.zPos = z;
|
||||||
|
@ -313,13 +278,6 @@ public class Region {
|
||||||
this.write(x, z, buf.getData(), buf.size());
|
this.write(x, z, buf.getData(), buf.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// public NBTTagCompound readTag(int x, int z) throws IOException {
|
|
||||||
// byte[] data = this.read(x, z);
|
|
||||||
// if(data == null)
|
|
||||||
// return null;
|
|
||||||
// return CompressedStreamTools.read(new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(data)))));
|
|
||||||
// }
|
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
return this.regFile;
|
return this.regFile;
|
||||||
}
|
}
|
||||||
|
@ -336,7 +294,7 @@ public class Region {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File getExpansionFile(File dir, int x, int z) {
|
private static File getExpansionFile(File dir, int x, int z) {
|
||||||
File sdir = new File(dir, getRegionFolder(x, z));
|
File sdir = new File(dir, Util.getRegionFolder(x, z));
|
||||||
if(!sdir.exists())
|
if(!sdir.exists())
|
||||||
sdir.mkdirs();
|
sdir.mkdirs();
|
||||||
return new File(sdir, String.format("c.%c%X%c%X.chk", x < 0 ? 'n' : 'p', (x < 0) ? -x : x, z < 0 ? 'n' : 'p', (z < 0) ? -z : z));
|
return new File(sdir, String.format("c.%c%X%c%X.chk", x < 0 ? 'n' : 'p', (x < 0) ? -x : x, z < 0 ? 'n' : 'p', (z < 0) ? -z : z));
|
||||||
|
@ -399,14 +357,6 @@ public class Region {
|
||||||
// getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag);
|
// getRegionFile(dir, x >> 3, z >> 3).writeTag(x & 7, z & 7, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getRegionFolder(int x, int z) {
|
|
||||||
return String.format("%c%03X%c%03X", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 9, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getRegionName(int x, int z) {
|
|
||||||
return String.format("r.%c%X%c%X.rgn", x < 0 ? 'n' : 'p', ((x < 0) ? -x : x) >> 3, z < 0 ? 'n' : 'p', ((z < 0) ? -z : z) >> 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) {
|
public static Chunk readNbt(WorldServer world, int x, int z, NBTTagCompound tag) {
|
||||||
// if(!tag.hasKey("Level", 10)) {
|
// if(!tag.hasKey("Level", 10)) {
|
||||||
// Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe");
|
// Log.error("Chunk-Datei bei " + x + "," + z + " hat keine Level-Daten, überspringe");
|
||||||
|
@ -680,93 +630,4 @@ public class Region {
|
||||||
public static void killIO() {
|
public static void killIO() {
|
||||||
killed = true;
|
killed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void saveWorldInfo(File worldDir, long time) {
|
|
||||||
NBTTagCompound data = new NBTTagCompound();
|
|
||||||
data.setLong("Time", time);
|
|
||||||
data.setLong("LastAccess", System.currentTimeMillis());
|
|
||||||
data.setString("Version", Config.VERSION);
|
|
||||||
NBTTagCompound cfg = new NBTTagCompound();
|
|
||||||
for(String cvar : Config.VARS.keySet()) {
|
|
||||||
cfg.setString(cvar, Config.VARS.get(cvar).getValue());
|
|
||||||
// Config.Value value = Config.VARS.get(cvar);
|
|
||||||
// switch(value.getType()) {
|
|
||||||
// case BOOLEAN:
|
|
||||||
// cfg.setString(cvar, "" + value.getBoolean());
|
|
||||||
// break;
|
|
||||||
// case INTEGER:
|
|
||||||
// cfg.setString(cvar, "" + value.getInt());
|
|
||||||
// break;
|
|
||||||
// case FLOAT:
|
|
||||||
// cfg.setString(cvar, "" + value.getFloat());
|
|
||||||
// break;
|
|
||||||
// case STRING:
|
|
||||||
// cfg.setString(cvar, value.getString());
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
data.setTag("Config", cfg);
|
|
||||||
data.setTag("Universe", UniverseRegistry.saveNbt());
|
|
||||||
if(worldDir != null)
|
|
||||||
worldDir.mkdirs();
|
|
||||||
File nfile = new File(worldDir, "level.nbt.tmp");
|
|
||||||
File lfile = new File(worldDir, "level.nbt");
|
|
||||||
try {
|
|
||||||
// File ofile = new File(worldDir, "level.nbt_old");
|
|
||||||
NBTLoader.writeGZip(data, nfile);
|
|
||||||
// if(ofile.exists())
|
|
||||||
// ofile.delete();
|
|
||||||
// lfile.renameTo(ofile);
|
|
||||||
if(lfile.exists())
|
|
||||||
lfile.delete();
|
|
||||||
nfile.renameTo(lfile);
|
|
||||||
// if(nfile.exists())
|
|
||||||
// nfile.delete();
|
|
||||||
}
|
|
||||||
catch(Exception e) {
|
|
||||||
Log.JNI.error(e, "Fehler beim Schreiben von " + nfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FolderInfo loadWorldInfo(File worldDir) {
|
|
||||||
Config.clear();
|
|
||||||
UniverseRegistry.clear();
|
|
||||||
File file = new File(worldDir, "level.nbt");
|
|
||||||
if(!file.exists())
|
|
||||||
file = new File(worldDir, "level.nbt.tmp");
|
|
||||||
if(file.exists()) {
|
|
||||||
try {
|
|
||||||
NBTTagCompound tag = NBTLoader.readGZip(file);
|
|
||||||
NBTTagCompound cfg = tag.getCompoundTag("Config");
|
|
||||||
for(String key : cfg.getKeySet()) {
|
|
||||||
Config.set(key, cfg.getString(key), null);
|
|
||||||
}
|
|
||||||
UniverseRegistry.loadNbt(tag.getCompoundTag("Universe"));
|
|
||||||
// tag.getInteger("Version");
|
|
||||||
long lastPlayed = tag.getLong("LastAccess");
|
|
||||||
String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null;
|
|
||||||
version = version != null && version.isEmpty() ? null : version;
|
|
||||||
long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME;
|
|
||||||
return new FolderInfo(time, lastPlayed, null, version);
|
|
||||||
}
|
|
||||||
catch(Exception e) {
|
|
||||||
Log.JNI.error(e, "Fehler beim Lesen von " + file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public static void reloadWorldInfo(File worldDir) {
|
|
||||||
// File file = new File(worldDir, "level.nbt");
|
|
||||||
// if(file.exists()) {
|
|
||||||
// Config.clear();
|
|
||||||
// try {
|
|
||||||
// Config.readFromNbt(NBTLoader.readGZip(file).getCompoundTag("Config"), true);
|
|
||||||
// }
|
|
||||||
// catch(Exception e) {
|
|
||||||
// Log.error("Fehler beim Lesen von " + file, e);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -962,6 +962,7 @@ public final class WorldServer extends World {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onEntityAdded(Entity entityIn) {
|
protected void onEntityAdded(Entity entityIn) {
|
||||||
|
// TODO: add node
|
||||||
this.trackEntity(entityIn);
|
this.trackEntity(entityIn);
|
||||||
this.entityIds.addKey(entityIn.getId(), entityIn);
|
this.entityIds.addKey(entityIn.getId(), entityIn);
|
||||||
Entity[] aentity = entityIn.getParts();
|
Entity[] aentity = entityIn.getParts();
|
||||||
|
|
|
@ -6,9 +6,11 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -74,7 +76,6 @@ import common.util.WorldPos;
|
||||||
import common.world.Region;
|
import common.world.Region;
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
import common.world.WorldServer;
|
import common.world.WorldServer;
|
||||||
import common.world.Region.FolderInfo;
|
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
|
@ -90,8 +91,10 @@ import io.netty.util.concurrent.Future;
|
||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
import server.command.CommandEnvironment;
|
import server.command.CommandEnvironment;
|
||||||
import server.command.FixedExecutor;
|
import server.command.FixedExecutor;
|
||||||
|
import server.init.NodeRegistry;
|
||||||
import server.network.HandshakeHandler;
|
import server.network.HandshakeHandler;
|
||||||
import server.network.Player;
|
import server.network.Player;
|
||||||
|
import server.world.Converter;
|
||||||
|
|
||||||
public final class Server implements IThreadListener, IServer {
|
public final class Server implements IThreadListener, IServer {
|
||||||
private static final LazyLoadBase<NioEventLoopGroup> SERVER_NIO_EVENTLOOP = new LazyLoadBase<NioEventLoopGroup>() {
|
private static final LazyLoadBase<NioEventLoopGroup> SERVER_NIO_EVENTLOOP = new LazyLoadBase<NioEventLoopGroup>() {
|
||||||
|
@ -141,6 +144,7 @@ public final class Server implements IThreadListener, IServer {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Util.checkOs();
|
Util.checkOs();
|
||||||
Registry.setup("Server thread");
|
Registry.setup("Server thread");
|
||||||
|
NodeRegistry.register();
|
||||||
boolean debug = System.getProperty("server.debug", null) != null;
|
boolean debug = System.getProperty("server.debug", null) != null;
|
||||||
boolean ipc = debug || System.getProperty("server.pipe", null) != null;
|
boolean ipc = debug || System.getProperty("server.pipe", null) != null;
|
||||||
int port = Integer.parseInt(System.getProperty("server.port", "" + Config.PORT));
|
int port = Integer.parseInt(System.getProperty("server.port", "" + Config.PORT));
|
||||||
|
@ -155,6 +159,63 @@ public final class Server implements IThreadListener, IServer {
|
||||||
Log.flushLog();
|
Log.flushLog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void saveServerConfig(long time) {
|
||||||
|
NBTTagCompound data = new NBTTagCompound();
|
||||||
|
data.setLong("Time", time);
|
||||||
|
data.setLong("LastAccess", System.currentTimeMillis());
|
||||||
|
data.setString("Version", Config.VERSION);
|
||||||
|
NBTTagCompound cfg = new NBTTagCompound();
|
||||||
|
for(String cvar : Config.VARS.keySet()) {
|
||||||
|
cfg.setString(cvar, Config.VARS.get(cvar).getValue());
|
||||||
|
}
|
||||||
|
data.setTag("Config", cfg);
|
||||||
|
data.setTag("Universe", UniverseRegistry.saveNbt());
|
||||||
|
File nfile = new File("server.nbt.tmp");
|
||||||
|
File lfile = new File("server.nbt");
|
||||||
|
try {
|
||||||
|
NBTLoader.writeGZip(data, nfile);
|
||||||
|
if(lfile.exists())
|
||||||
|
lfile.delete();
|
||||||
|
nfile.renameTo(lfile);
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
Log.IO.error(e, "Fehler beim Schreiben von " + nfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long loadServerConfig() {
|
||||||
|
Config.clear();
|
||||||
|
UniverseRegistry.clear();
|
||||||
|
File file = new File("server.nbt");
|
||||||
|
if(!file.exists())
|
||||||
|
file = new File("server.nbt.tmp");
|
||||||
|
if(file.exists()) {
|
||||||
|
try {
|
||||||
|
NBTTagCompound tag = NBTLoader.readGZip(file);
|
||||||
|
NBTTagCompound cfg = tag.getCompoundTag("Config");
|
||||||
|
for(String key : cfg.getKeySet()) {
|
||||||
|
Config.set(key, cfg.getString(key), null);
|
||||||
|
}
|
||||||
|
UniverseRegistry.loadNbt(tag.getCompoundTag("Universe"));
|
||||||
|
long lastPlayed = tag.getLong("LastAccess");
|
||||||
|
String version = tag.hasKey("Version", 8) ? tag.getString("Version") : null;
|
||||||
|
version = version != null && version.isEmpty() ? "<unbekannt>" : version;
|
||||||
|
long time = tag.hasKey("Time", 4) ? tag.getLong("Time") : World.START_TIME;
|
||||||
|
Log.IO.info("Version: %s", version);
|
||||||
|
Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", time, time / 20L);
|
||||||
|
Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed)));
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
Log.IO.error(e, "Fehler beim Lesen von " + file);
|
||||||
|
Config.clear();
|
||||||
|
UniverseRegistry.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.IO.info("Erstelle neue Welt und Konfiguration");
|
||||||
|
return World.START_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
private Server(boolean debug, boolean ipc) {
|
private Server(boolean debug, boolean ipc) {
|
||||||
this.debug = debug;
|
this.debug = debug;
|
||||||
this.ipcpipe = ipc;
|
this.ipcpipe = ipc;
|
||||||
|
@ -182,7 +243,7 @@ public final class Server implements IThreadListener, IServer {
|
||||||
|
|
||||||
public void saveWorldInfo() {
|
public void saveWorldInfo() {
|
||||||
if(!this.debug) {
|
if(!this.debug) {
|
||||||
Region.saveWorldInfo(null, this.space.getDayTime());
|
saveServerConfig(this.space.getDayTime());
|
||||||
WorldServer.saveWarps(this.warps);
|
WorldServer.saveWarps(this.warps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,13 +318,14 @@ public final class Server implements IThreadListener, IServer {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
Log.JNI.info("Starte Server Version " + Config.VERSION);
|
Log.JNI.info("Starte Server Version " + Config.VERSION);
|
||||||
if(!this.debug) {
|
if(!this.debug) {
|
||||||
|
Converter.convert();
|
||||||
this.setMessage("Welt wird erstellt und geladen");
|
this.setMessage("Welt wird erstellt und geladen");
|
||||||
FolderInfo info = Region.loadWorldInfo(null);
|
long wtime = loadServerConfig();
|
||||||
// if(dtime == -1L) // {
|
// if(dtime == -1L) // {
|
||||||
// dtime = World.START_TIME;
|
// dtime = World.START_TIME;
|
||||||
//// Config.set("spawnDim", "1", null);
|
//// Config.set("spawnDim", "1", null);
|
||||||
//// }
|
//// }
|
||||||
this.worlds.add(this.space = new WorldServer(this, info == null ? World.START_TIME : info.time,
|
this.worlds.add(this.space = new WorldServer(this, wtime,
|
||||||
Space.INSTANCE, false));
|
Space.INSTANCE, false));
|
||||||
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
this.dimensions.put(this.space.dimension.getDimensionId(), this.space);
|
||||||
new File("players").mkdirs();
|
new File("players").mkdirs();
|
||||||
|
|
537
server/src/server/ai/EntityLivingNode.java
Normal file
537
server/src/server/ai/EntityLivingNode.java
Normal file
|
@ -0,0 +1,537 @@
|
||||||
|
package server.ai;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import common.ai.EntityAIBase;
|
||||||
|
import common.ai.EntityAIMoveTowardsRestriction;
|
||||||
|
import common.ai.EntityAITasks;
|
||||||
|
import common.ai.EntityJumpHelper;
|
||||||
|
import common.ai.EntityLookHelper;
|
||||||
|
import common.ai.EntityMoveHelper;
|
||||||
|
import common.ai.EntitySenses;
|
||||||
|
import common.ai.IEntityLivingNode;
|
||||||
|
import common.block.Block;
|
||||||
|
import common.collect.Lists;
|
||||||
|
import common.color.TextColor;
|
||||||
|
import common.entity.DamageSource;
|
||||||
|
import common.entity.Entity;
|
||||||
|
import common.entity.EntityDamageSource;
|
||||||
|
import common.entity.item.EntityLeashKnot;
|
||||||
|
import common.entity.item.EntityXp;
|
||||||
|
import common.entity.npc.EntityNPC;
|
||||||
|
import common.entity.types.CombatEntry;
|
||||||
|
import common.entity.types.EntityBodyHelper;
|
||||||
|
import common.entity.types.EntityLiving;
|
||||||
|
import common.entity.types.EntityTameable;
|
||||||
|
import common.init.Blocks;
|
||||||
|
import common.init.Config;
|
||||||
|
import common.item.ItemStack;
|
||||||
|
import common.nbt.NBTTagCompound;
|
||||||
|
import common.network.IPlayer;
|
||||||
|
import common.pathfinding.PathNavigate;
|
||||||
|
import common.pathfinding.PathNavigateGround;
|
||||||
|
import common.rng.Random;
|
||||||
|
import common.util.BlockPos;
|
||||||
|
import common.world.WorldServer;
|
||||||
|
|
||||||
|
public abstract class EntityLivingNode<T extends EntityLiving> extends EntityNode<T> implements IEntityLivingNode {
|
||||||
|
protected final Random rand;
|
||||||
|
private final List<CombatEntry> combat = Lists.<CombatEntry>newArrayList();
|
||||||
|
private EntityLookHelper lookHelper;
|
||||||
|
protected EntityMoveHelper moveHelper;
|
||||||
|
protected EntityJumpHelper jumpHelper;
|
||||||
|
private EntityBodyHelper bodyHelper;
|
||||||
|
protected PathNavigate navigator;
|
||||||
|
protected final EntityAITasks tasks;
|
||||||
|
protected final EntityAITasks targets;
|
||||||
|
private EntityLiving target;
|
||||||
|
private EntitySenses senses;
|
||||||
|
private NBTTagCompound leashTag;
|
||||||
|
private boolean isMovementAITaskSet;
|
||||||
|
private EntityAIBase aiBase;
|
||||||
|
private boolean attacked;
|
||||||
|
private boolean damaged;
|
||||||
|
private String blockType;
|
||||||
|
private int lastDamaged;
|
||||||
|
protected EntityNPC playerAttacker;
|
||||||
|
private EntityLiving attackedBy;
|
||||||
|
protected int lastDamage;
|
||||||
|
protected int recentlyHit;
|
||||||
|
private int lastAttacked;
|
||||||
|
private EntityLiving attacker;
|
||||||
|
private int lastAttackTime;
|
||||||
|
|
||||||
|
public EntityLivingNode(T entity) {
|
||||||
|
super(entity);
|
||||||
|
this.rand = entity.getRNG();
|
||||||
|
this.tasks = new EntityAITasks();
|
||||||
|
this.targets = new EntityAITasks();
|
||||||
|
this.lookHelper = new EntityLookHelper(entity);
|
||||||
|
this.moveHelper = new EntityMoveHelper(entity);
|
||||||
|
this.jumpHelper = new EntityJumpHelper(entity);
|
||||||
|
this.bodyHelper = new EntityBodyHelper(entity);
|
||||||
|
this.navigator = this.getNewNavigator();
|
||||||
|
this.senses = new EntitySenses(entity);
|
||||||
|
this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D);
|
||||||
|
this.registerTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getEntity() {
|
||||||
|
return this.entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityLiving getAttackingEntity() {
|
||||||
|
EntityLiving attacking = this.getAttacking();
|
||||||
|
return attacking != null ? attacking : (this.playerAttacker != null ? this.playerAttacker : (this.attackedBy != null ? this.attackedBy : null));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PathNavigate getNewNavigator() {
|
||||||
|
return new PathNavigateGround(this.entity, this.entity.worldObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected PathNavigate getNewNavigator() { EntityArachnoid
|
||||||
|
// return new PathNavigateClimber(this.entity, this.entity.worldObj);
|
||||||
|
// }
|
||||||
|
|
||||||
|
protected abstract void registerTasks();
|
||||||
|
|
||||||
|
public EntityLookHelper getLookHelper() {
|
||||||
|
return this.lookHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityMoveHelper getMoveHelper() {
|
||||||
|
return this.moveHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityJumpHelper getJumpHelper() {
|
||||||
|
return this.jumpHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathNavigate getNavigator() {
|
||||||
|
return this.navigator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntitySenses getEntitySenses() {
|
||||||
|
return this.senses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityLiving getAttackTarget() {
|
||||||
|
return this.target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttackTarget(EntityLiving entitylivingbaseIn) {
|
||||||
|
this.target = entitylivingbaseIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPath()
|
||||||
|
{
|
||||||
|
return !this.navigator.noPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRenderAngles() {
|
||||||
|
this.bodyHelper.updateRenderAngles();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateAITasks() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
this.senses.clearSensingCache();
|
||||||
|
this.targets.onUpdateTasks();
|
||||||
|
this.tasks.onUpdateTasks();
|
||||||
|
this.navigator.onUpdateNavigation();
|
||||||
|
this.updateAITasks();
|
||||||
|
this.moveHelper.onUpdateMoveHelper();
|
||||||
|
this.lookHelper.onUpdateLook();
|
||||||
|
this.jumpHelper.doJump();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeashTag(NBTTagCompound tag) {
|
||||||
|
this.leashTag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recreateLeash() {
|
||||||
|
if(this.entity.getLeashed() && this.leashTag != null) {
|
||||||
|
// if(this.leashTag.hasKey("PlayerName", 8)) {
|
||||||
|
// String id = this.leashTag.getString("PlayerName");
|
||||||
|
// if(!id.isEmpty()) {
|
||||||
|
// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class,
|
||||||
|
// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) {
|
||||||
|
// if(entitylivingbase.getUser().equals(id)) {
|
||||||
|
// this.leashedTo = entitylivingbase;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) {
|
||||||
|
BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"),
|
||||||
|
this.leashTag.getInteger("Z"));
|
||||||
|
EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos);
|
||||||
|
|
||||||
|
if(entityleashknot == null) {
|
||||||
|
entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.entity.setLeashedTo(entityleashknot, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.entity.clearLeashed(false, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.leashTag = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onUpdateLeashed(float distance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected void onUpdateLeashed(float distance) EntityHorse
|
||||||
|
// {
|
||||||
|
// if (distance > 6.0F && this.entity.isEatingHaystack())
|
||||||
|
// {
|
||||||
|
// this.entity.setEatingHaystack(false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void updateLeashedState() {
|
||||||
|
if(this.leashTag != null) {
|
||||||
|
this.recreateLeash();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.entity.getLeashed()) {
|
||||||
|
if(!this.entity.isEntityAlive()) {
|
||||||
|
this.entity.clearLeashed(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) {
|
||||||
|
this.entity.clearLeashed(true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj)
|
||||||
|
{
|
||||||
|
Entity entity = this.entity.getLeashedTo();
|
||||||
|
this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5);
|
||||||
|
float f = this.entity.getDistanceToEntity(entity);
|
||||||
|
|
||||||
|
if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting())
|
||||||
|
{
|
||||||
|
if (f > 10.0F)
|
||||||
|
{
|
||||||
|
this.entity.clearLeashed(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isMovementAITaskSet)
|
||||||
|
{
|
||||||
|
this.tasks.addTask(2, this.aiBase);
|
||||||
|
|
||||||
|
if (this.getNavigator() instanceof PathNavigateGround)
|
||||||
|
{
|
||||||
|
((PathNavigateGround)this.getNavigator()).setAvoidsWater(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isMovementAITaskSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onUpdateLeashed(f);
|
||||||
|
|
||||||
|
if (f > 4.0F)
|
||||||
|
{
|
||||||
|
this.getNavigator().tryMoveToEntityLiving(entity, 1.0D);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f > 6.0F)
|
||||||
|
{
|
||||||
|
double d0 = (entity.posX - this.entity.posX) / (double)f;
|
||||||
|
double d1 = (entity.posY - this.entity.posY) / (double)f;
|
||||||
|
double d2 = (entity.posZ - this.entity.posZ) / (double)f;
|
||||||
|
this.entity.motionX += d0 * Math.abs(d0) * 0.4D;
|
||||||
|
this.entity.motionY += d1 * Math.abs(d1) * 0.4D;
|
||||||
|
this.entity.motionZ += d2 * Math.abs(d2) * 0.4D;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f > 10.0F)
|
||||||
|
{
|
||||||
|
this.entity.clearLeashed(true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!this.entity.getLeashed() && this.isMovementAITaskSet)
|
||||||
|
{
|
||||||
|
this.isMovementAITaskSet = false;
|
||||||
|
this.tasks.removeTask(this.aiBase);
|
||||||
|
|
||||||
|
if (this.getNavigator() instanceof PathNavigateGround)
|
||||||
|
{
|
||||||
|
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.entity.detachHome();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void trackDamage(DamageSource source, int amount) {
|
||||||
|
this.resetCombat();
|
||||||
|
this.blockType = null;
|
||||||
|
if(this.entity.isOnLadder()) {
|
||||||
|
Block block = this.entity.worldObj
|
||||||
|
.getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock();
|
||||||
|
if(block == Blocks.ladder)
|
||||||
|
this.blockType = "von einer Leiter";
|
||||||
|
else if(block == Blocks.vine)
|
||||||
|
this.blockType = "von Ranken";
|
||||||
|
}
|
||||||
|
else if(this.entity.isInLiquid()) {
|
||||||
|
this.blockType = "aus dem Wasser";
|
||||||
|
}
|
||||||
|
CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance);
|
||||||
|
this.combat.add(entry);
|
||||||
|
this.lastDamaged = this.entity.ticksExisted;
|
||||||
|
this.damaged = true;
|
||||||
|
if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive())
|
||||||
|
this.attacked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendDeathMessage() {
|
||||||
|
this.sendDeathMessage(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendDeathMessage(boolean natural, boolean forAll) {
|
||||||
|
// if(this.entity.worldObj.client)
|
||||||
|
// return;
|
||||||
|
String msg;
|
||||||
|
String kill;
|
||||||
|
IPlayer receiver = null;
|
||||||
|
if(this.combat.size() == 0) {
|
||||||
|
msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CombatEntry strong = null;
|
||||||
|
CombatEntry block = null;
|
||||||
|
int min = 0;
|
||||||
|
float max = 0.0F;
|
||||||
|
|
||||||
|
for(int z = 0; z < this.combat.size(); ++z) {
|
||||||
|
CombatEntry entry = (CombatEntry)this.combat.get(z);
|
||||||
|
CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null;
|
||||||
|
|
||||||
|
if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) &&
|
||||||
|
entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) {
|
||||||
|
if(z > 0) {
|
||||||
|
strong = last;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strong = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
max = entry.getFallDistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) {
|
||||||
|
block = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null);
|
||||||
|
CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1);
|
||||||
|
Entity lastEnt = last.getSource().getEntity();
|
||||||
|
|
||||||
|
if(fall != null && last.getSource() == DamageSource.fall) {
|
||||||
|
if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) {
|
||||||
|
Entity fallEnt = fall.getSource().getEntity();
|
||||||
|
if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) {
|
||||||
|
ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null;
|
||||||
|
receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null;
|
||||||
|
if(fallItem != null) { // && fallItem.hasDisplayName()) {
|
||||||
|
msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN),
|
||||||
|
fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN));
|
||||||
|
kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt",
|
||||||
|
this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN),
|
||||||
|
fallEnt.getColoredName(TextColor.CYAN));
|
||||||
|
kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt",
|
||||||
|
this.entity.getColoredName(TextColor.CYAN));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(lastEnt != null) {
|
||||||
|
ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null;
|
||||||
|
receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null;
|
||||||
|
if(lastItem != null) { // && lastItem.hasDisplayName()) {
|
||||||
|
msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt",
|
||||||
|
this.entity.getColoredName(TextColor.BLUE),
|
||||||
|
lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE));
|
||||||
|
kill = String.format(TextColor.BLUE + "* %s mit %s erledigt",
|
||||||
|
this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE),
|
||||||
|
lastEnt.getColoredName(TextColor.BLUE));
|
||||||
|
kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()),
|
||||||
|
this.entity.getColoredName(TextColor.NEON)) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null;
|
||||||
|
msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null;
|
||||||
|
kill = msg == null ? null : last.getSource().getKillMessage(this.entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(msg == null)
|
||||||
|
return;
|
||||||
|
if(receiver != null)
|
||||||
|
receiver.addFeed(kill);
|
||||||
|
if(forAll)
|
||||||
|
for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) {
|
||||||
|
if(player != receiver)
|
||||||
|
player.addFeed(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityLiving getAttacking() {
|
||||||
|
EntityLiving entity = null;
|
||||||
|
EntityNPC player = null;
|
||||||
|
int edmg = 0;
|
||||||
|
int pdmg = 0;
|
||||||
|
for(CombatEntry entry : this.combat) {
|
||||||
|
if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) {
|
||||||
|
pdmg = entry.getDamage();
|
||||||
|
player = (EntityNPC)entry.getSource().getEntity();
|
||||||
|
}
|
||||||
|
if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) {
|
||||||
|
edmg = entry.getDamage();
|
||||||
|
entity = (EntityLiving)entry.getSource().getEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return player != null && pdmg >= edmg / 3 ? player : entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetCombat() {
|
||||||
|
int timeout = this.attacked ? 300 : 100;
|
||||||
|
if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) {
|
||||||
|
this.damaged = false;
|
||||||
|
this.attacked = false;
|
||||||
|
this.combat.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxFallHeight() {
|
||||||
|
if(this.target == null) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F);
|
||||||
|
// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4;
|
||||||
|
|
||||||
|
if(i < 0) {
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public int getMaxFallHeight() EntityHaunter
|
||||||
|
// {
|
||||||
|
// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void updateAttacking() {
|
||||||
|
if (this.recentlyHit > 0)
|
||||||
|
{
|
||||||
|
--this.recentlyHit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.playerAttacker = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.attacker != null && !this.attacker.isEntityAlive())
|
||||||
|
{
|
||||||
|
this.attacker = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(this.attackedBy.isPlayer() && ((EntityNPC)this.attackedBy).capabilities.isCreativeMode) {
|
||||||
|
// this.attackedBy = null; // FIX Creative
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (this.attackedBy != null)
|
||||||
|
{
|
||||||
|
if (!this.attackedBy.isEntityAlive())
|
||||||
|
{
|
||||||
|
this.setAttackedBy(null);
|
||||||
|
}
|
||||||
|
else if (this.entity.ticksExisted - this.lastAttacked > 100)
|
||||||
|
{
|
||||||
|
this.setAttackedBy(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dropExperience() {
|
||||||
|
if ((this.recentlyHit > 0 || this.player) && this.entity.canDropLoot() && Config.mobXP)
|
||||||
|
{
|
||||||
|
int i = this.entity.getExperiencePoints(this.playerAttacker);
|
||||||
|
|
||||||
|
while (i > 0)
|
||||||
|
{
|
||||||
|
int j = EntityXp.getXPSplit(i);
|
||||||
|
i -= j;
|
||||||
|
this.world.spawnEntityInWorld(new EntityXp(this.world, this.entity.posX, this.entity.posY, this.entity.posZ, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityLiving getAttackedBy()
|
||||||
|
{
|
||||||
|
return this.attackedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAttackedTime()
|
||||||
|
{
|
||||||
|
return this.lastAttacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttackedBy(EntityLiving livingBase)
|
||||||
|
{
|
||||||
|
this.attackedBy = livingBase;
|
||||||
|
this.lastAttacked = this.entity.ticksExisted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityLiving getLastAttack()
|
||||||
|
{
|
||||||
|
return this.attacker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastAttackTime()
|
||||||
|
{
|
||||||
|
return this.lastAttackTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastAttack(Entity entity)
|
||||||
|
{
|
||||||
|
if (entity instanceof EntityLiving)
|
||||||
|
{
|
||||||
|
this.attacker = (EntityLiving)entity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.attacker = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastAttackTime = this.entity.ticksExisted;
|
||||||
|
}
|
||||||
|
}
|
84
server/src/server/ai/EntityMobNPCNode.java
Normal file
84
server/src/server/ai/EntityMobNPCNode.java
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package server.ai;
|
||||||
|
|
||||||
|
import common.ai.IEntityMobNPCNode;
|
||||||
|
import common.entity.Entity;
|
||||||
|
import common.entity.attributes.AttributeInstance;
|
||||||
|
import common.entity.attributes.Attributes;
|
||||||
|
import common.entity.npc.AIHurtByAggressor;
|
||||||
|
import common.entity.npc.EntityMobNPC;
|
||||||
|
import common.entity.npc.EntityNPC;
|
||||||
|
import common.entity.types.EntityLiving;
|
||||||
|
import common.nbt.NBTTagCompound;
|
||||||
|
|
||||||
|
public class EntityMobNPCNode<T extends EntityMobNPC> extends EntityNPCNode<T> implements IEntityMobNPCNode {
|
||||||
|
private int angerLevel;
|
||||||
|
private int angerTarget;
|
||||||
|
|
||||||
|
public EntityMobNPCNode(T entity) {
|
||||||
|
super(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void registerTasks() {
|
||||||
|
super.registerTasks();
|
||||||
|
this.targets.addTask(1, new AIHurtByAggressor(this.entity));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateAITasks()
|
||||||
|
{
|
||||||
|
AttributeInstance iattributeinstance = this.entity.getEntityAttribute(Attributes.MOVEMENT_SPEED);
|
||||||
|
|
||||||
|
if (this.isAngry())
|
||||||
|
{
|
||||||
|
if (!iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD))
|
||||||
|
{
|
||||||
|
iattributeinstance.applyModifier(Attributes.RUSHING_SPEED_MOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
--this.angerLevel;
|
||||||
|
}
|
||||||
|
else if (iattributeinstance.hasModifier(Attributes.RUSHING_SPEED_MOD))
|
||||||
|
{
|
||||||
|
iattributeinstance.removeModifier(Attributes.RUSHING_SPEED_MOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.angerLevel > 0 && this.angerTarget != 0 && this.entity.getAttackedBy() == null)
|
||||||
|
{
|
||||||
|
Entity entity = this.world.getEntityByID(this.angerTarget);
|
||||||
|
if(entity instanceof EntityLiving)
|
||||||
|
this.entity.setAttackedBy((EntityLiving)entity);
|
||||||
|
if(entity != null && entity.isPlayer())
|
||||||
|
this.entity.playerAttacker = (EntityNPC)entity;
|
||||||
|
this.entity.recentlyHit = this.entity.getAttackedTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
super.updateAITasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeNbt(NBTTagCompound tagCompound)
|
||||||
|
{
|
||||||
|
super.writeNbt(tagCompound);
|
||||||
|
tagCompound.setShort("Anger", (short)this.angerLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readNbt(NBTTagCompound tagCompund)
|
||||||
|
{
|
||||||
|
super.readNbt(tagCompund);
|
||||||
|
this.angerLevel = tagCompund.getShort("Anger");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void becomeAngryAt(Entity entity)
|
||||||
|
{
|
||||||
|
this.angerLevel = this.rand.excl(400, 800);
|
||||||
|
if(entity instanceof EntityLiving)
|
||||||
|
this.entity.setAttackedBy((EntityLiving)entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAngry()
|
||||||
|
{
|
||||||
|
return this.angerLevel > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAngerTarget(EntityLiving entity) {
|
||||||
|
this.angerTarget = entity.getId();
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,17 +17,21 @@ import common.ai.EntityAISwimming;
|
||||||
import common.ai.EntityAIWander;
|
import common.ai.EntityAIWander;
|
||||||
import common.ai.EntityAIWatchClosest;
|
import common.ai.EntityAIWatchClosest;
|
||||||
import common.ai.EntityAIWatchClosest2;
|
import common.ai.EntityAIWatchClosest2;
|
||||||
|
import common.ai.IEntityNPCNode;
|
||||||
|
import common.entity.npc.Alignment;
|
||||||
import common.entity.npc.EntityNPC;
|
import common.entity.npc.EntityNPC;
|
||||||
import common.entity.types.EntityLiving;
|
import common.entity.types.EntityLiving;
|
||||||
|
import common.init.Items;
|
||||||
|
import common.item.ItemGunBase;
|
||||||
import common.item.ItemStack;
|
import common.item.ItemStack;
|
||||||
import common.pathfinding.PathNavigateGround;
|
import common.pathfinding.PathNavigateGround;
|
||||||
|
|
||||||
public class EntityNPCNode extends EntityNode {
|
public class EntityNPCNode<T extends EntityNPC> extends EntityLivingNode<T> implements IEntityNPCNode {
|
||||||
protected final EntityAIAttackOnCollide aiMelee;
|
protected final EntityAIAttackOnCollide aiMelee;
|
||||||
protected final AIRangedAttack aiRanged;
|
protected final AIRangedAttack aiRanged;
|
||||||
private boolean fleeing;
|
private boolean fleeing;
|
||||||
|
|
||||||
public EntityNPCNode(EntityNPC entity) {
|
public EntityNPCNode(T entity) {
|
||||||
super(entity);
|
super(entity);
|
||||||
this.aiMelee = new EntityAIAttackOnCollide(entity, EntityLiving.class, 1.0D, true, true) {
|
this.aiMelee = new EntityAIAttackOnCollide(entity, EntityLiving.class, 1.0D, true, true) {
|
||||||
public boolean shouldExecute()
|
public boolean shouldExecute()
|
||||||
|
@ -65,22 +69,18 @@ public class EntityNPCNode extends EntityNode {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityNPC getEntity() {
|
|
||||||
return (EntityNPC)this.entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void registerTasks() {
|
protected void registerTasks() {
|
||||||
if(this.getNavigator() instanceof PathNavigateGround) {
|
if(this.getNavigator() instanceof PathNavigateGround) {
|
||||||
((PathNavigateGround)this.getNavigator()).setBreakDoors(true);
|
((PathNavigateGround)this.getNavigator()).setBreakDoors(true);
|
||||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
||||||
}
|
}
|
||||||
this.tasks.addTask(0, new EntityAISwimming(this.getEntity()));
|
this.tasks.addTask(0, new EntityAISwimming(this.entity));
|
||||||
// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true));
|
// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityNPC.class, 0.6D, true, true));
|
||||||
// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true));
|
// this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 0.6D, true, true));
|
||||||
this.tasks.addTask(1, new EntityAINpcMate(this.getEntity()));
|
this.tasks.addTask(1, new EntityAINpcMate(this.entity));
|
||||||
this.tasks.addTask(2, new EntityAIAvoidEntity(this.getEntity(), EntityLiving.class, new Predicate<EntityLiving>() {
|
this.tasks.addTask(2, new EntityAIAvoidEntity(this.entity, EntityLiving.class, new Predicate<EntityLiving>() {
|
||||||
public boolean test(EntityLiving entity) {
|
public boolean test(EntityLiving entity) {
|
||||||
return entity != EntityNPCNode.this.entity && EntityNPC.this.shouldFlee(entity);
|
return entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity);
|
||||||
}
|
}
|
||||||
}, 8.0F, 1.1D, 1.1D) {
|
}, 8.0F, 1.1D, 1.1D) {
|
||||||
{
|
{
|
||||||
|
@ -105,27 +105,27 @@ public class EntityNPCNode extends EntityNode {
|
||||||
// EntityNPC.this.isFleeing = false;
|
// EntityNPC.this.isFleeing = false;
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
this.tasks.addTask(3, new EntityAIAvoidEntity(this, EntityLiving.class, new Predicate<EntityLiving>() {
|
this.tasks.addTask(3, new EntityAIAvoidEntity(this.entity, EntityLiving.class, new Predicate<EntityLiving>() {
|
||||||
public boolean test(EntityLiving entity) {
|
public boolean test(EntityLiving entity) {
|
||||||
return entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity);
|
return entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity);
|
||||||
}
|
}
|
||||||
}, 8.0F, 1.1D, 1.1D) {
|
}, 8.0F, 1.1D, 1.1D) {
|
||||||
public void startExecuting() {
|
public void startExecuting() {
|
||||||
super.startExecuting();
|
super.startExecuting();
|
||||||
EntityNPC.this.setAttackTarget(null);
|
EntityNPCNode.this.setAttackTarget(null);
|
||||||
EntityNPC.this.fleeing = true;
|
EntityNPCNode.this.fleeing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetTask() {
|
public void resetTask() {
|
||||||
super.resetTask();
|
super.resetTask();
|
||||||
EntityNPC.this.fleeing = false;
|
EntityNPCNode.this.fleeing = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false));
|
// this.tasks.addTask(2, new EntityAITempt(this, 1.0D, Items.golden_apple, false));
|
||||||
this.tasks.addTask(4, new EntityAIOpenDoor(this, true));
|
this.tasks.addTask(4, new EntityAIOpenDoor(this.entity, true));
|
||||||
this.tasks.addTask(5, new EntityAINagPlayer(this));
|
this.tasks.addTask(5, new EntityAINagPlayer(this.entity));
|
||||||
this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this));
|
this.tasks.addTask(5, new EntityAILookAtTalkingPlayer(this.entity));
|
||||||
this.tasks.addTask(6, new EntityAIWatchClosest2(this, null, 3.0F, 1.0F) {
|
this.tasks.addTask(6, new EntityAIWatchClosest2(this.entity, null, 3.0F, 1.0F) {
|
||||||
private int sneakTime;
|
private int sneakTime;
|
||||||
|
|
||||||
public void updateTask()
|
public void updateTask()
|
||||||
|
@ -134,15 +134,15 @@ public class EntityNPCNode extends EntityNode {
|
||||||
boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking();
|
boolean flag = this.closestEntity.isPlayer() && this.closestEntity.isSneaking();
|
||||||
if(this.sneakTime > 0) {
|
if(this.sneakTime > 0) {
|
||||||
if(--this.sneakTime == 0) {
|
if(--this.sneakTime == 0) {
|
||||||
EntityNPC.this.setSneaking(false);
|
EntityNPCNode.this.entity.setSneaking(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(EntityNPC.this.getAttackTarget() == null && EntityNPC.this.rand.chance(flag ? 5 : 200)) {
|
else if(EntityNPCNode.this.getAttackTarget() == null && EntityNPCNode.this.rand.chance(flag ? 5 : 200)) {
|
||||||
EntityNPC.this.setSneaking(true);
|
EntityNPCNode.this.entity.setSneaking(true);
|
||||||
this.sneakTime = EntityNPC.this.rand.range(60, flag ? 160 : 120);
|
this.sneakTime = EntityNPCNode.this.rand.range(60, flag ? 160 : 120);
|
||||||
}
|
}
|
||||||
else if(EntityNPC.this.getAttackTarget() != null) {
|
else if(EntityNPCNode.this.getAttackTarget() != null) {
|
||||||
EntityNPC.this.setSneaking(false);
|
EntityNPCNode.this.entity.setSneaking(false);
|
||||||
this.sneakTime = 0;
|
this.sneakTime = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,42 +150,76 @@ public class EntityNPCNode extends EntityNode {
|
||||||
public void resetTask()
|
public void resetTask()
|
||||||
{
|
{
|
||||||
super.resetTask();
|
super.resetTask();
|
||||||
EntityNPC.this.setSneaking(false);
|
EntityNPCNode.this.entity.setSneaking(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.tasks.addTask(7, new EntityAINpcInteract(this));
|
this.tasks.addTask(7, new EntityAINpcInteract(this.entity));
|
||||||
this.tasks.addTask(8, new EntityAIWander(this, 1.0D));
|
this.tasks.addTask(8, new EntityAIWander(this.entity, 1.0D));
|
||||||
this.tasks.addTask(8, new EntityAIPlay(this, 1.1D));
|
this.tasks.addTask(8, new EntityAIPlay(this.entity, 1.1D));
|
||||||
this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F));
|
this.tasks.addTask(9, new EntityAIWatchClosest(this.entity, EntityLiving.class, 8.0F));
|
||||||
this.targets.addTask(1, new EntityAIHurtByTarget(this, false, /* EntityNPC.class, */ EntityLiving.class) {
|
this.targets.addTask(1, new EntityAIHurtByTarget(this.entity, false, /* EntityNPC.class, */ EntityLiving.class) {
|
||||||
protected boolean isSuitableTarget(EntityLiving entity) {
|
protected boolean isSuitableTarget(EntityLiving entity) {
|
||||||
if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) {
|
if(entity != null && entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity)) {
|
||||||
EntityNPC.this.setAttackTarget(null);
|
EntityNPCNode.this.setAttackTarget(null);
|
||||||
EntityNPC.this.fleeing = true;
|
EntityNPCNode.this.fleeing = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return entity != null && entity != EntityNPC.this && (!(entity.isPlayer()) || EntityNPC.this.rand.chance(entity.getAttackedBy() == EntityNPC.this ? 2 : 4))
|
return entity != null && entity != EntityNPCNode.this.entity && (!(entity.isPlayer()) || EntityNPCNode.this.rand.chance(entity.getAttackedBy() == EntityNPCNode.this.entity ? 2 : 4))
|
||||||
&& EntityNPC.this.canCounter(entity) && super.isSuitableTarget(entity);
|
&& EntityNPCNode.this.canCounter(entity) && super.isSuitableTarget(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.targets.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 10, true, false, new Predicate<EntityLiving>() {
|
this.targets.addTask(2, new EntityAINearestAttackableTarget(this.entity, EntityLiving.class, 10, true, false, new Predicate<EntityLiving>() {
|
||||||
public boolean test(EntityLiving entity) {
|
public boolean test(EntityLiving entity) {
|
||||||
if(entity != null && entity != EntityNPC.this && EntityNPC.this.shouldFlee(entity)) {
|
if(entity != null && entity != EntityNPCNode.this.entity && EntityNPCNode.this.shouldFlee(entity)) {
|
||||||
EntityNPC.this.setAttackTarget(null);
|
EntityNPCNode.this.setAttackTarget(null);
|
||||||
EntityNPC.this.fleeing = true;
|
EntityNPCNode.this.fleeing = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return entity != null && entity != EntityNPC.this && !EntityNPC.this.fleeing && EntityNPC.this.canAmbush(entity) && EntityNPC.this.canAttack(entity);
|
return entity != null && entity != EntityNPCNode.this.entity && !EntityNPCNode.this.fleeing && EntityNPCNode.this.entity.canAmbush(entity) && EntityNPCNode.this.canAttack(entity);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
// this.setCanPickUpLoot(true);
|
// this.setCanPickUpLoot(true);
|
||||||
|
|
||||||
if (worldIn != null && !worldIn.client)
|
|
||||||
{
|
|
||||||
this.setCombatTask();
|
this.setCombatTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean canInfight(Alignment align) {
|
||||||
|
Alignment alignment = this.entity.getAlignmentCached();
|
||||||
|
return alignment.chaotic || (!alignment.lawful &&
|
||||||
|
((alignment.good && align.evil) || (alignment.evil && align.good)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean canMurder(Alignment align) {
|
||||||
|
Alignment alignment = this.entity.getAlignmentCached();
|
||||||
|
return alignment.chaotic && ((alignment.good && align.evil) || (alignment.evil && align.good));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canCounter(EntityLiving entity) {
|
||||||
|
return !(entity instanceof EntityNPC) ||
|
||||||
|
(this.entity.getClass() == entity.getClass() ? this.canInfight(((EntityNPC)entity).getAlignmentCached()) :
|
||||||
|
!this.entity.isPeaceful(((EntityNPC)entity).getClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canAttack(EntityLiving entity) {
|
||||||
|
return entity instanceof EntityNPC && (this.entity.getClass() == entity.getClass() ? this.canMurder(((EntityNPC)entity).getAlignmentCached()) :
|
||||||
|
this.entity.isAggressive(((EntityNPC)entity).getClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldFlee(EntityLiving entity) {
|
||||||
|
return (this.entity.getHealth() <= (this.entity.getMaxHealth() / 4) || !this.canCounter(entity)) &&
|
||||||
|
((entity instanceof EntityNPC && ((EntityNPC)entity).getNode().canAttack(this.entity) ||
|
||||||
|
(entity == this.entity.getAttackedBy() && ((EntityNPC)entity).getNode().canCounter(this.entity))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRangedWeapon(ItemStack stack) {
|
||||||
|
return stack != null && (stack.getItem() == Items.bow || stack.getItem() instanceof ItemGunBase ||
|
||||||
|
stack.getItem() == Items.snowball || stack.getItem() == Items.potion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public boolean isRangedWeapon(ItemStack stack) { // EntityGargoyle
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
public void updateLeashedState() {
|
public void updateLeashedState() {
|
||||||
if(!this.player)
|
if(!this.player)
|
||||||
super.updateLeashedState();
|
super.updateLeashedState();
|
||||||
|
@ -205,9 +239,9 @@ public class EntityNPCNode extends EntityNode {
|
||||||
if(!this.player) {
|
if(!this.player) {
|
||||||
this.tasks.removeTask(this.aiMelee);
|
this.tasks.removeTask(this.aiMelee);
|
||||||
this.tasks.removeTask(this.aiRanged);
|
this.tasks.removeTask(this.aiRanged);
|
||||||
ItemStack itemstack = this.getEntity().getHeldItem();
|
ItemStack itemstack = this.entity.getHeldItem();
|
||||||
|
|
||||||
if (this.getEntity().isRangedWeapon(itemstack))
|
if (this.isRangedWeapon(itemstack))
|
||||||
{
|
{
|
||||||
this.tasks.addTask(3, this.aiRanged);
|
this.tasks.addTask(3, this.aiRanged);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,436 +1,29 @@
|
||||||
package server.ai;
|
package server.ai;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import common.ai.EntityAIBase;
|
|
||||||
import common.ai.EntityAIMoveTowardsRestriction;
|
|
||||||
import common.ai.EntityAITasks;
|
|
||||||
import common.ai.EntityJumpHelper;
|
|
||||||
import common.ai.EntityLookHelper;
|
|
||||||
import common.ai.EntityMoveHelper;
|
|
||||||
import common.ai.EntitySenses;
|
|
||||||
import common.ai.IEntityNode;
|
import common.ai.IEntityNode;
|
||||||
import common.block.Block;
|
|
||||||
import common.collect.Lists;
|
|
||||||
import common.color.TextColor;
|
|
||||||
import common.entity.DamageSource;
|
|
||||||
import common.entity.Entity;
|
import common.entity.Entity;
|
||||||
import common.entity.EntityDamageSource;
|
|
||||||
import common.entity.item.EntityLeashKnot;
|
|
||||||
import common.entity.npc.EntityNPC;
|
|
||||||
import common.entity.types.CombatEntry;
|
|
||||||
import common.entity.types.EntityBodyHelper;
|
|
||||||
import common.entity.types.EntityLiving;
|
|
||||||
import common.entity.types.EntityTameable;
|
|
||||||
import common.init.Blocks;
|
|
||||||
import common.item.ItemStack;
|
|
||||||
import common.nbt.NBTTagCompound;
|
import common.nbt.NBTTagCompound;
|
||||||
import common.network.IPlayer;
|
import common.world.World;
|
||||||
import common.pathfinding.PathNavigate;
|
|
||||||
import common.pathfinding.PathNavigateGround;
|
|
||||||
import common.util.BlockPos;
|
|
||||||
import common.world.WorldServer;
|
import common.world.WorldServer;
|
||||||
|
|
||||||
public abstract class EntityNode implements IEntityNode {
|
public class EntityNode<T extends Entity> implements IEntityNode {
|
||||||
protected final EntityLiving entity;
|
protected final T entity;
|
||||||
protected final boolean player;
|
protected final boolean player;
|
||||||
private final List<CombatEntry> combat = Lists.<CombatEntry>newArrayList();
|
protected WorldServer world;
|
||||||
private EntityLookHelper lookHelper;
|
|
||||||
protected EntityMoveHelper moveHelper;
|
|
||||||
protected EntityJumpHelper jumpHelper;
|
|
||||||
private EntityBodyHelper bodyHelper;
|
|
||||||
protected PathNavigate navigator;
|
|
||||||
protected final EntityAITasks tasks;
|
|
||||||
protected final EntityAITasks targets;
|
|
||||||
private EntityLiving target;
|
|
||||||
private EntitySenses senses;
|
|
||||||
private Runnable tickFunc;
|
|
||||||
private NBTTagCompound leashTag;
|
|
||||||
private boolean isMovementAITaskSet;
|
|
||||||
private EntityAIBase aiBase;
|
|
||||||
private boolean attacked;
|
|
||||||
private boolean damaged;
|
|
||||||
private String blockType;
|
|
||||||
private int lastDamaged;
|
|
||||||
|
|
||||||
public EntityNode(EntityLiving entity) {
|
public EntityNode(T entity) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.player = entity.isPlayer();
|
this.player = entity.isPlayer();
|
||||||
this.tasks = new EntityAITasks();
|
this.world = (WorldServer)entity.worldObj;
|
||||||
this.targets = new EntityAITasks();
|
|
||||||
this.lookHelper = new EntityLookHelper(entity);
|
|
||||||
this.moveHelper = new EntityMoveHelper(entity);
|
|
||||||
this.jumpHelper = new EntityJumpHelper(entity);
|
|
||||||
this.bodyHelper = new EntityBodyHelper(entity);
|
|
||||||
this.navigator = this.getNewNavigator();
|
|
||||||
this.senses = new EntitySenses(entity);
|
|
||||||
this.aiBase = new EntityAIMoveTowardsRestriction(entity, 1.0D);
|
|
||||||
this.registerTasks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PathNavigate getNewNavigator() {
|
public void setWorld(World world) {
|
||||||
return new PathNavigateGround(this.entity, this.entity.worldObj);
|
this.world = (WorldServer)world;
|
||||||
}
|
}
|
||||||
|
|
||||||
// protected PathNavigate getNewNavigator() { EntityArachnoid
|
public void readNbt(NBTTagCompound tag) {
|
||||||
// return new PathNavigateClimber(this.entity, this.entity.worldObj);
|
|
||||||
// }
|
|
||||||
|
|
||||||
protected abstract void registerTasks();
|
|
||||||
|
|
||||||
public void setTickFunction(Runnable func) {
|
|
||||||
this.tickFunc = func;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityLookHelper getLookHelper() {
|
public void writeNbt(NBTTagCompound tag) {
|
||||||
return this.lookHelper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityMoveHelper getMoveHelper() {
|
|
||||||
return this.moveHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityJumpHelper getJumpHelper() {
|
|
||||||
return this.jumpHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PathNavigate getNavigator() {
|
|
||||||
return this.navigator;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntitySenses getEntitySenses() {
|
|
||||||
return this.senses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityLiving getAttackTarget() {
|
|
||||||
return this.target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAttackTarget(EntityLiving entitylivingbaseIn) {
|
|
||||||
this.target = entitylivingbaseIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasPath()
|
|
||||||
{
|
|
||||||
return !this.navigator.noPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateRenderAngles() {
|
|
||||||
this.bodyHelper.updateRenderAngles();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
this.senses.clearSensingCache();
|
|
||||||
this.targets.onUpdateTasks();
|
|
||||||
this.tasks.onUpdateTasks();
|
|
||||||
this.navigator.onUpdateNavigation();
|
|
||||||
if(this.tickFunc != null)
|
|
||||||
this.tickFunc.run();
|
|
||||||
this.moveHelper.onUpdateMoveHelper();
|
|
||||||
this.lookHelper.onUpdateLook();
|
|
||||||
this.jumpHelper.doJump();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLeashTag(NBTTagCompound tag) {
|
|
||||||
this.leashTag = tag;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void recreateLeash() {
|
|
||||||
if(this.entity.getLeashed() && this.leashTag != null) {
|
|
||||||
// if(this.leashTag.hasKey("PlayerName", 8)) {
|
|
||||||
// String id = this.leashTag.getString("PlayerName");
|
|
||||||
// if(!id.isEmpty()) {
|
|
||||||
// for(EntityNPC entitylivingbase : this.worldObj.getEntitiesWithinAABB(EntityNPC.class,
|
|
||||||
// this.getEntityBoundingBox().expand(10.0D, 10.0D, 10.0D))) {
|
|
||||||
// if(entitylivingbase.getUser().equals(id)) {
|
|
||||||
// this.leashedTo = entitylivingbase;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
if(this.leashTag.hasKey("X", 99) && this.leashTag.hasKey("Y", 99) && this.leashTag.hasKey("Z", 99)) {
|
|
||||||
BlockPos blockpos = new BlockPos(this.leashTag.getInteger("X"), this.leashTag.getInteger("Y"),
|
|
||||||
this.leashTag.getInteger("Z"));
|
|
||||||
EntityLeashKnot entityleashknot = EntityLeashKnot.getKnotForPosition(this.entity.worldObj, blockpos);
|
|
||||||
|
|
||||||
if(entityleashknot == null) {
|
|
||||||
entityleashknot = EntityLeashKnot.createKnot(this.entity.worldObj, blockpos);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entity.setLeashedTo(entityleashknot, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.entity.clearLeashed(false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.leashTag = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onUpdateLeashed(float distance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// protected void onUpdateLeashed(float distance) EntityHorse
|
|
||||||
// {
|
|
||||||
// if (distance > 6.0F && this.entity.isEatingHaystack())
|
|
||||||
// {
|
|
||||||
// this.entity.setEatingHaystack(false);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void updateLeashedState() {
|
|
||||||
if(this.leashTag != null) {
|
|
||||||
this.recreateLeash();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.entity.getLeashed()) {
|
|
||||||
if(!this.entity.isEntityAlive()) {
|
|
||||||
this.entity.clearLeashed(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.entity.getLeashedTo() == null || this.entity.getLeashedTo().dead) {
|
|
||||||
this.entity.clearLeashed(true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.entity.getLeashed() && this.entity.getLeashedTo() != null && this.entity.getLeashedTo().worldObj == this.entity.worldObj)
|
|
||||||
{
|
|
||||||
Entity entity = this.entity.getLeashedTo();
|
|
||||||
this.entity.setHomePosAndDistance(new BlockPos((int)entity.posX, (int)entity.posY, (int)entity.posZ), 5);
|
|
||||||
float f = this.entity.getDistanceToEntity(entity);
|
|
||||||
|
|
||||||
if (this.entity instanceof EntityTameable && ((EntityTameable)this.entity).isSitting())
|
|
||||||
{
|
|
||||||
if (f > 10.0F)
|
|
||||||
{
|
|
||||||
this.entity.clearLeashed(true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.isMovementAITaskSet)
|
|
||||||
{
|
|
||||||
this.tasks.addTask(2, this.aiBase);
|
|
||||||
|
|
||||||
if (this.getNavigator() instanceof PathNavigateGround)
|
|
||||||
{
|
|
||||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isMovementAITaskSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.onUpdateLeashed(f);
|
|
||||||
|
|
||||||
if (f > 4.0F)
|
|
||||||
{
|
|
||||||
this.getNavigator().tryMoveToEntityLiving(entity, 1.0D);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f > 6.0F)
|
|
||||||
{
|
|
||||||
double d0 = (entity.posX - this.entity.posX) / (double)f;
|
|
||||||
double d1 = (entity.posY - this.entity.posY) / (double)f;
|
|
||||||
double d2 = (entity.posZ - this.entity.posZ) / (double)f;
|
|
||||||
this.entity.motionX += d0 * Math.abs(d0) * 0.4D;
|
|
||||||
this.entity.motionY += d1 * Math.abs(d1) * 0.4D;
|
|
||||||
this.entity.motionZ += d2 * Math.abs(d2) * 0.4D;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f > 10.0F)
|
|
||||||
{
|
|
||||||
this.entity.clearLeashed(true, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!this.entity.getLeashed() && this.isMovementAITaskSet)
|
|
||||||
{
|
|
||||||
this.isMovementAITaskSet = false;
|
|
||||||
this.tasks.removeTask(this.aiBase);
|
|
||||||
|
|
||||||
if (this.getNavigator() instanceof PathNavigateGround)
|
|
||||||
{
|
|
||||||
((PathNavigateGround)this.getNavigator()).setAvoidsWater(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.entity.detachHome();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void trackDamage(DamageSource source, int amount) {
|
|
||||||
this.resetCombat();
|
|
||||||
this.blockType = null;
|
|
||||||
if(this.entity.isOnLadder()) {
|
|
||||||
Block block = this.entity.worldObj
|
|
||||||
.getState(new BlockPos(this.entity.posX, this.entity.getEntityBoundingBox().minY, this.entity.posZ)).getBlock();
|
|
||||||
if(block == Blocks.ladder)
|
|
||||||
this.blockType = "von einer Leiter";
|
|
||||||
else if(block == Blocks.vine)
|
|
||||||
this.blockType = "von Ranken";
|
|
||||||
}
|
|
||||||
else if(this.entity.isInLiquid()) {
|
|
||||||
this.blockType = "aus dem Wasser";
|
|
||||||
}
|
|
||||||
CombatEntry entry = new CombatEntry(source, amount, this.blockType, this.entity.fallDistance);
|
|
||||||
this.combat.add(entry);
|
|
||||||
this.lastDamaged = this.entity.ticksExisted;
|
|
||||||
this.damaged = true;
|
|
||||||
if(entry.getSource().getEntity() instanceof EntityLiving && !this.attacked && this.entity.isEntityAlive())
|
|
||||||
this.attacked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendDeathMessage() {
|
|
||||||
this.sendDeathMessage(false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void sendDeathMessage(boolean natural, boolean forAll) {
|
|
||||||
// if(this.entity.worldObj.client)
|
|
||||||
// return;
|
|
||||||
String msg;
|
|
||||||
String kill;
|
|
||||||
IPlayer receiver = null;
|
|
||||||
if(this.combat.size() == 0) {
|
|
||||||
msg = kill = natural ? String.format("%s starb", this.entity.getColoredName(TextColor.LGRAY)) : null;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
CombatEntry strong = null;
|
|
||||||
CombatEntry block = null;
|
|
||||||
int min = 0;
|
|
||||||
float max = 0.0F;
|
|
||||||
|
|
||||||
for(int z = 0; z < this.combat.size(); ++z) {
|
|
||||||
CombatEntry entry = (CombatEntry)this.combat.get(z);
|
|
||||||
CombatEntry last = z > 0 ? (CombatEntry)this.combat.get(z - 1) : null;
|
|
||||||
|
|
||||||
if((entry.getSource() == DamageSource.fall || entry.getSource() == DamageSource.outOfWorld) &&
|
|
||||||
entry.getFallDistance() > 0.0F && (strong == null || entry.getFallDistance() > max)) {
|
|
||||||
if(z > 0) {
|
|
||||||
strong = last;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
strong = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
max = entry.getFallDistance();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(entry.getBlockType() != null && (block == null || entry.getDamage() > min)) {
|
|
||||||
block = entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CombatEntry fall = max > 5.0F && strong != null ? strong : (min > 5 && block != null ? block : null);
|
|
||||||
CombatEntry last = (CombatEntry)this.combat.get(this.combat.size() - 1);
|
|
||||||
Entity lastEnt = last.getSource().getEntity();
|
|
||||||
|
|
||||||
if(fall != null && last.getSource() == DamageSource.fall) {
|
|
||||||
if(fall.getSource() != DamageSource.fall && fall.getSource() != DamageSource.outOfWorld) {
|
|
||||||
Entity fallEnt = fall.getSource().getEntity();
|
|
||||||
if(fallEnt != null && (lastEnt == null || fallEnt != lastEnt)) {
|
|
||||||
ItemStack fallItem = fallEnt instanceof EntityLiving ? ((EntityLiving)fallEnt).getHeldItem() : null;
|
|
||||||
receiver = fallEnt.isPlayer() ? ((EntityNPC)fallEnt).connection : null;
|
|
||||||
if(fallItem != null) { // && fallItem.hasDisplayName()) {
|
|
||||||
msg = String.format("%s wurde von %s mit %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN),
|
|
||||||
fallEnt.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN));
|
|
||||||
kill = String.format(TextColor.CYAN + "* %s mit %s zum Fallen verdammt",
|
|
||||||
this.entity.getColoredName(TextColor.CYAN), fallItem.getColoredName(TextColor.CYAN));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
msg = String.format("%s wurde von %s zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN),
|
|
||||||
fallEnt.getColoredName(TextColor.CYAN));
|
|
||||||
kill = String.format(TextColor.CYAN + "* %s zum Fallen verdammt",
|
|
||||||
this.entity.getColoredName(TextColor.CYAN));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(lastEnt != null) {
|
|
||||||
ItemStack lastItem = lastEnt instanceof EntityLiving ? ((EntityLiving)lastEnt).getHeldItem() : null;
|
|
||||||
receiver = lastEnt.isPlayer() ? ((EntityNPC)lastEnt).connection : null;
|
|
||||||
if(lastItem != null) { // && lastItem.hasDisplayName()) {
|
|
||||||
msg = String.format("%s fiel zu tief und wurde von %s mit %s erledigt",
|
|
||||||
this.entity.getColoredName(TextColor.BLUE),
|
|
||||||
lastEnt.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE));
|
|
||||||
kill = String.format(TextColor.BLUE + "* %s mit %s erledigt",
|
|
||||||
this.entity.getColoredName(TextColor.BLUE), lastItem.getColoredName(TextColor.BLUE));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
msg = String.format("%s fiel zu tief und wurde von %s erledigt", this.entity.getColoredName(TextColor.BLUE),
|
|
||||||
lastEnt.getColoredName(TextColor.BLUE));
|
|
||||||
kill = String.format(TextColor.BLUE + "%s erledigt", this.entity.getColoredName(TextColor.BLUE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
msg = kill = natural ? String.format("%s wurde zum Fallen verdammt", this.entity.getColoredName(TextColor.CYAN)) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
msg = kill = natural ? String.format("%s fiel " + (fall.getBlockType() == null ? "aus zu großer Höhe" : fall.getBlockType()),
|
|
||||||
this.entity.getColoredName(TextColor.NEON)) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
receiver = last.getSource().getEntity() != null && last.getSource().getEntity().isPlayer() ? ((EntityNPC)last.getSource().getEntity()).connection : null;
|
|
||||||
msg = natural || (last.getSource() instanceof EntityDamageSource ? last.getSource().getEntity() != null : this.entity.getAttackingEntity() != null) ? last.getSource().getDeathMessage(this.entity) : null;
|
|
||||||
kill = msg == null ? null : last.getSource().getKillMessage(this.entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(msg == null)
|
|
||||||
return;
|
|
||||||
if(receiver != null)
|
|
||||||
receiver.addFeed(kill);
|
|
||||||
if(forAll)
|
|
||||||
for(IPlayer player : ((WorldServer)this.entity.worldObj).getServer().getIPlayers()) {
|
|
||||||
if(player != receiver)
|
|
||||||
player.addFeed(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityLiving getAttacking() {
|
|
||||||
EntityLiving entity = null;
|
|
||||||
EntityNPC player = null;
|
|
||||||
int edmg = 0;
|
|
||||||
int pdmg = 0;
|
|
||||||
for(CombatEntry entry : this.combat) {
|
|
||||||
if(entry.getSource().getEntity() != null && entry.getSource().getEntity().isPlayer() && (player == null || entry.getDamage() > pdmg)) {
|
|
||||||
pdmg = entry.getDamage();
|
|
||||||
player = (EntityNPC)entry.getSource().getEntity();
|
|
||||||
}
|
|
||||||
if(entry.getSource().getEntity() instanceof EntityLiving && (entity == null || entry.getDamage() > edmg)) {
|
|
||||||
edmg = entry.getDamage();
|
|
||||||
entity = (EntityLiving)entry.getSource().getEntity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return player != null && pdmg >= edmg / 3 ? player : entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetCombat() {
|
|
||||||
int timeout = this.attacked ? 300 : 100;
|
|
||||||
if(this.damaged && (!this.entity.isEntityAlive() || this.entity.ticksExisted - this.lastDamaged > timeout)) {
|
|
||||||
this.damaged = false;
|
|
||||||
this.attacked = false;
|
|
||||||
this.combat.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxFallHeight() {
|
|
||||||
if(this.target == null) {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int i = (int)((float)this.entity.getHealth() - (float)this.entity.getMaxHealth() * 0.33F);
|
|
||||||
// i = i - (3 - this.worldObj.getDifficulty().getId()) * 4;
|
|
||||||
|
|
||||||
if(i < 0) {
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i + 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// public int getMaxFallHeight() EntityHaunter
|
|
||||||
// {
|
|
||||||
// return this.getAttackTarget() == null ? 3 : 3 + (this.getHealth() - 1);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
136
server/src/server/init/NodeRegistry.java
Normal file
136
server/src/server/init/NodeRegistry.java
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
package server.init;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import common.ai.IEntityNode;
|
||||||
|
import common.collect.Maps;
|
||||||
|
import common.entity.Entity;
|
||||||
|
import common.entity.animal.EntityBat;
|
||||||
|
import common.entity.animal.EntityChicken;
|
||||||
|
import common.entity.animal.EntityCow;
|
||||||
|
import common.entity.animal.EntityDragon;
|
||||||
|
import common.entity.animal.EntityHorse;
|
||||||
|
import common.entity.animal.EntityMooshroom;
|
||||||
|
import common.entity.animal.EntityMouse;
|
||||||
|
import common.entity.animal.EntityOcelot;
|
||||||
|
import common.entity.animal.EntityPig;
|
||||||
|
import common.entity.animal.EntityRabbit;
|
||||||
|
import common.entity.animal.EntitySheep;
|
||||||
|
import common.entity.animal.EntitySquid;
|
||||||
|
import common.entity.animal.EntityWolf;
|
||||||
|
import common.entity.item.EntityBoat;
|
||||||
|
import common.entity.item.EntityChestCart;
|
||||||
|
import common.entity.item.EntityCrystal;
|
||||||
|
import common.entity.item.EntityExplosion;
|
||||||
|
import common.entity.item.EntityFalling;
|
||||||
|
import common.entity.item.EntityFireworks;
|
||||||
|
import common.entity.item.EntityHopperCart;
|
||||||
|
import common.entity.item.EntityItem;
|
||||||
|
import common.entity.item.EntityLeashKnot;
|
||||||
|
import common.entity.item.EntityMinecart;
|
||||||
|
import common.entity.item.EntityNuke;
|
||||||
|
import common.entity.item.EntityOrb;
|
||||||
|
import common.entity.item.EntityTnt;
|
||||||
|
import common.entity.item.EntityTntCart;
|
||||||
|
import common.entity.item.EntityXp;
|
||||||
|
import common.entity.item.EntityXpBottle;
|
||||||
|
import common.entity.npc.SpeciesInfo;
|
||||||
|
import common.entity.projectile.EntityArrow;
|
||||||
|
import common.entity.projectile.EntityBox;
|
||||||
|
import common.entity.projectile.EntityBullet;
|
||||||
|
import common.entity.projectile.EntityDie;
|
||||||
|
import common.entity.projectile.EntityDynamite;
|
||||||
|
import common.entity.projectile.EntityEgg;
|
||||||
|
import common.entity.projectile.EntityFireCharge;
|
||||||
|
import common.entity.projectile.EntityFireball;
|
||||||
|
import common.entity.projectile.EntityHook;
|
||||||
|
import common.entity.projectile.EntityPotion;
|
||||||
|
import common.entity.projectile.EntitySnowball;
|
||||||
|
import common.entity.types.EntityLiving;
|
||||||
|
import common.entity.types.IObjectData;
|
||||||
|
import common.log.Log;
|
||||||
|
import common.nbt.NBTTagCompound;
|
||||||
|
import common.world.World;
|
||||||
|
|
||||||
|
public abstract class NodeRegistry {
|
||||||
|
private static final Map<Class<? extends Entity>, Class<? extends IEntityNode>> NODES = Maps.newHashMap();
|
||||||
|
|
||||||
|
private static void registerNode(Class<? extends Entity> clazz, Class<? extends IEntityNode> node) {
|
||||||
|
if(clazz == null)
|
||||||
|
throw new IllegalArgumentException("Kann keine null-Klasse registrieren");
|
||||||
|
if(NODES.containsKey(clazz))
|
||||||
|
throw new IllegalArgumentException("Klasse ist bereits registriert: " + clazz);
|
||||||
|
NODES.put(clazz, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addNode(Entity entity) {
|
||||||
|
IEntityNode node = null;
|
||||||
|
Class<? extends IEntityNode> oclass = NODES.get(entity.getClass());
|
||||||
|
Constructor[] consts = oclass.getConstructors();
|
||||||
|
if(consts.length != 1)
|
||||||
|
throw new IllegalArgumentException("Klasse " + oclass + " hat mehr als einen Konstruktor");
|
||||||
|
try {
|
||||||
|
node = (IEntityNode)consts[0].newInstance(entity);
|
||||||
|
}
|
||||||
|
catch(InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
entity.setNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<? extends IEntityNode> getNodeClass(Class<? extends Entity> clazz) {
|
||||||
|
return NODES.get(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
registerNode(EntityItem.class, );
|
||||||
|
registerNode(EntityXp.class, );
|
||||||
|
registerNode(EntityEgg.class, );
|
||||||
|
registerNode(EntityLeashKnot.class, );
|
||||||
|
registerNode(EntityArrow.class, );
|
||||||
|
registerNode(EntitySnowball.class, );
|
||||||
|
registerNode(EntityFireball.class, );
|
||||||
|
registerNode(EntityFireCharge.class, );
|
||||||
|
registerNode(EntityOrb.class, );
|
||||||
|
registerNode(EntityPotion.class, );
|
||||||
|
registerNode(EntityXpBottle.class, );
|
||||||
|
registerNode(EntityBox.class, );
|
||||||
|
registerNode(EntityTnt.class, );
|
||||||
|
registerNode(EntityFalling.class, );
|
||||||
|
registerNode(EntityFireworks.class, );
|
||||||
|
registerNode(EntityBoat.class, );
|
||||||
|
registerNode(EntityMinecart.class, );
|
||||||
|
registerNode(EntityChestCart.class, );
|
||||||
|
registerNode(EntityTntCart.class, );
|
||||||
|
registerNode(EntityHopperCart.class, );
|
||||||
|
registerNode(EntityHook.class, );
|
||||||
|
registerNode(EntityDynamite.class, );
|
||||||
|
registerNode(EntityNuke.class, );
|
||||||
|
registerNode(EntityDie.class, );
|
||||||
|
registerNode(EntityExplosion.class, );
|
||||||
|
registerNode(EntityCrystal.class, );
|
||||||
|
registerNode(EntityBullet.class, );
|
||||||
|
|
||||||
|
registerNode(EntityDragon.class, );
|
||||||
|
registerNode(EntityBat.class, );
|
||||||
|
registerNode(EntityPig.class, );
|
||||||
|
registerNode(EntitySheep.class, );
|
||||||
|
registerNode(EntityCow.class, );
|
||||||
|
registerNode(EntityChicken.class, );
|
||||||
|
registerNode(EntitySquid.class, );
|
||||||
|
registerNode(EntityWolf.class, );
|
||||||
|
registerNode(EntityMooshroom.class, );
|
||||||
|
registerNode(EntityOcelot.class, );
|
||||||
|
registerNode(EntityHorse.class, );
|
||||||
|
registerNode(EntityRabbit.class, );
|
||||||
|
registerNode(EntityMouse.class, );
|
||||||
|
|
||||||
|
for(int z = 0; z < SpeciesRegistry.SPECIMEN.size(); z++) {
|
||||||
|
SpeciesInfo info = SpeciesRegistry.SPECIMEN.get(z);
|
||||||
|
registerNode(info.clazz, );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package client.world;
|
package server.world;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
@ -7,16 +7,14 @@ import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
import client.Client;
|
|
||||||
import client.gui.GuiConvert;
|
|
||||||
import client.gui.GuiLoading;
|
|
||||||
import client.gui.GuiLoading.Callback;
|
|
||||||
import common.biome.Biome;
|
import common.biome.Biome;
|
||||||
import common.block.Block;
|
import common.block.Block;
|
||||||
import common.block.BlockCactus;
|
import common.block.BlockCactus;
|
||||||
|
@ -92,14 +90,25 @@ import common.world.Region;
|
||||||
import common.world.State;
|
import common.world.State;
|
||||||
import common.world.Weather;
|
import common.world.Weather;
|
||||||
import common.world.World;
|
import common.world.World;
|
||||||
import common.world.Region.FolderInfo;
|
import server.Server;
|
||||||
import common.world.Region.SaveVersion;
|
|
||||||
|
|
||||||
public final class Converter {
|
public abstract class Converter {
|
||||||
// public static interface Callback {
|
private static enum SaveVersion {
|
||||||
// void postMessage(String msg);
|
ALPHA_1_0("Alpha 1.0 - Beta 1.2"),
|
||||||
// void postProgress(int progress);
|
BETA_1_3("Beta 1.3 - Release 1.8.9"),
|
||||||
// }
|
RELEASE_1_9("Release 1.9 - Release 1.12.2"),
|
||||||
|
RELEASE_1_13("Release 1.13 +");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private SaveVersion(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class AnvilRegion {
|
private static class AnvilRegion {
|
||||||
private final int[] offsets = new int[1024];
|
private final int[] offsets = new int[1024];
|
||||||
|
@ -182,11 +191,7 @@ public final class Converter {
|
||||||
State getState(int id, int data);
|
State getState(int id, int data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Converter() {
|
private static long postProgress(long start, int progress) {
|
||||||
}
|
|
||||||
|
|
||||||
private long postProgress(long start, int progress) {
|
|
||||||
// SKC.info("... " + progress + "%");
|
|
||||||
if(System.currentTimeMillis() - start >= 500L) {
|
if(System.currentTimeMillis() - start >= 500L) {
|
||||||
start = System.currentTimeMillis();
|
start = System.currentTimeMillis();
|
||||||
Log.JNI.info("... " + progress + "%");
|
Log.JNI.info("... " + progress + "%");
|
||||||
|
@ -198,17 +203,8 @@ public final class Converter {
|
||||||
private static final Map<String, String> ENTITY_MAP = Maps.newHashMap();
|
private static final Map<String, String> ENTITY_MAP = Maps.newHashMap();
|
||||||
private static final Map<String, String> TILE_MAP = Maps.newHashMap();
|
private static final Map<String, String> TILE_MAP = Maps.newHashMap();
|
||||||
private static final char[] BLOCK_MAP = new char[65536];
|
private static final char[] BLOCK_MAP = new char[65536];
|
||||||
// private static final Map<Character, BlockFunction> BLOCK_FUNCS = Maps.newHashMap();
|
|
||||||
private static final Map<String, String> OLD_GAMERULES = Maps.newHashMap();
|
private static final Map<String, String> OLD_GAMERULES = Maps.newHashMap();
|
||||||
|
|
||||||
private String action;
|
|
||||||
private String task;
|
|
||||||
private String file;
|
|
||||||
private int totalRegions;
|
|
||||||
private int doneRegions;
|
|
||||||
private int totalChunks;
|
|
||||||
private int doneChunks;
|
|
||||||
|
|
||||||
private static void mapEntity(Class<? extends Entity> clazz, String ... names) {
|
private static void mapEntity(Class<? extends Entity> clazz, String ... names) {
|
||||||
String name = EntityRegistry.getEntityString(clazz);
|
String name = EntityRegistry.getEntityString(clazz);
|
||||||
for(String oldname : names) {
|
for(String oldname : names) {
|
||||||
|
@ -253,17 +249,6 @@ public final class Converter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static void mapBlockDynamic(BlockFunction func, int id, int data) {
|
|
||||||
// BLOCK_MAP[(id << 4) | data] = (char)0x000f;
|
|
||||||
// BLOCK_FUNCS.put((char)((id << 4) | data), func);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private static void mapBlockDynamic(BlockFunction func, int id) {
|
|
||||||
// for(int z = 0; z < 16; z++) {
|
|
||||||
// mapBlockDynamic(func, id, z);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
OLD_GAMERULES.put("doFireTick", "fireTick");
|
OLD_GAMERULES.put("doFireTick", "fireTick");
|
||||||
OLD_GAMERULES.put("mobGriefing", "mobGriefing");
|
OLD_GAMERULES.put("mobGriefing", "mobGriefing");
|
||||||
|
@ -273,7 +258,6 @@ public final class Converter {
|
||||||
OLD_GAMERULES.put("doEntityDrops", "dropObjects");
|
OLD_GAMERULES.put("doEntityDrops", "dropObjects");
|
||||||
OLD_GAMERULES.put("naturalRegeneration", "naturalRegeneration");
|
OLD_GAMERULES.put("naturalRegeneration", "naturalRegeneration");
|
||||||
OLD_GAMERULES.put("doDaylightCycle", "daylightCycle");
|
OLD_GAMERULES.put("doDaylightCycle", "daylightCycle");
|
||||||
// OLD_GAMERULES.put("showDeathMessages", "deathMessages");
|
|
||||||
OLD_GAMERULES.put("keepInventory", "keepInventory");
|
OLD_GAMERULES.put("keepInventory", "keepInventory");
|
||||||
OLD_GAMERULES.put("doWeatherCycle", "weatherChanges");
|
OLD_GAMERULES.put("doWeatherCycle", "weatherChanges");
|
||||||
OLD_GAMERULES.put("randomTickSpeed", "randomTickSpeed");
|
OLD_GAMERULES.put("randomTickSpeed", "randomTickSpeed");
|
||||||
|
@ -306,7 +290,6 @@ public final class Converter {
|
||||||
mapTile(TileEntityDaylightDetector.class, "DLDetector", "daylight_detector");
|
mapTile(TileEntityDaylightDetector.class, "DLDetector", "daylight_detector");
|
||||||
mapTile(TileEntityHopper.class, "Hopper", "hopper");
|
mapTile(TileEntityHopper.class, "Hopper", "hopper");
|
||||||
mapTile(TileEntityComparator.class, "Comparator", "comparator");
|
mapTile(TileEntityComparator.class, "Comparator", "comparator");
|
||||||
// mapTile(TileEntityFlowerPot.class, "FlowerPot", "flower_pot");
|
|
||||||
mapTile(TileEntityBanner.class, "Banner", "banner");
|
mapTile(TileEntityBanner.class, "Banner", "banner");
|
||||||
|
|
||||||
mapBlock(Blocks.stone.getState(), 1);
|
mapBlock(Blocks.stone.getState(), 1);
|
||||||
|
@ -609,11 +592,6 @@ public final class Converter {
|
||||||
mapBlockData(Blocks.stonebrick_stairs, 109);
|
mapBlockData(Blocks.stonebrick_stairs, 109);
|
||||||
mapBlock(Blocks.mycelium, 110);
|
mapBlock(Blocks.mycelium, 110);
|
||||||
mapBlockData(Blocks.waterlily, 111);
|
mapBlockData(Blocks.waterlily, 111);
|
||||||
// mapBlockDynamic(new BlockFunction() {
|
|
||||||
// public IBlockState getState(int id, int data) {
|
|
||||||
// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM));
|
|
||||||
// }
|
|
||||||
// }, 111);
|
|
||||||
mapBlock(Blocks.blood_brick, 112);
|
mapBlock(Blocks.blood_brick, 112);
|
||||||
mapBlockData(Blocks.blood_brick_fence, 113);
|
mapBlockData(Blocks.blood_brick_fence, 113);
|
||||||
mapBlockData(Blocks.blood_brick_stairs, 114);
|
mapBlockData(Blocks.blood_brick_stairs, 114);
|
||||||
|
@ -822,97 +800,7 @@ public final class Converter {
|
||||||
return Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.byMetadata(data));
|
return Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.byMetadata(data));
|
||||||
}
|
}
|
||||||
}, 252);
|
}, 252);
|
||||||
// 253, 254
|
|
||||||
mapBlock(Blocks.obsidian, 255);
|
mapBlock(Blocks.obsidian, 255);
|
||||||
|
|
||||||
// addBlock(137, 49); // Command Block
|
|
||||||
// addBlock(166, 0); // Barrier
|
|
||||||
// addBlock(168, 98); // Prismarine
|
|
||||||
// // addBlock(169, 169); // Sea Lantern --> Lamp
|
|
||||||
// addBlock(179, 24); // Red Sandstone
|
|
||||||
// addBlock(180, 128); // Red Sandstone Stairs
|
|
||||||
// addBlock(181, 43, 1); // Red Sandstone Double Slab
|
|
||||||
//
|
|
||||||
// addBlock(198, 101); // End Rod
|
|
||||||
// addBlock(199, 102); // Chorus Plant
|
|
||||||
// addBlock(200, 102); // Chorus Flower
|
|
||||||
// addBlock(201, 155); // Purpur Block
|
|
||||||
// addBlock(203, 156); // Purpur Stairs
|
|
||||||
// addBlock(206, 98); // End Stone Bricks
|
|
||||||
// addBlock(207, 142); // Beetroot Block
|
|
||||||
// addBlock(208, 60); // Grass Path
|
|
||||||
// addBlock(209, 20); // End Gateway
|
|
||||||
// addBlock(210, 137); // Repeating Command Block
|
|
||||||
// addBlock(211, 137); // Chain Command Block
|
|
||||||
// addBlock(212, 79); // Frosted Ice
|
|
||||||
// addBlock(213, 87); // Magma Block
|
|
||||||
// addBlock(214, 100); // Nether Wart Block
|
|
||||||
// addBlock(215, 112); // Red Nether Brick
|
|
||||||
// addBlock(216, 155); // Bone Block
|
|
||||||
// addBlock(217, 20); // Structure Void
|
|
||||||
// addBlock(218, 158); // Observer
|
|
||||||
// addBlock(255, 49); // Structure Block
|
|
||||||
// addBlock(202, 155, 2); // Purpur Pillar
|
|
||||||
// addBlock(204, 43, 7); // Purpur Double Slab
|
|
||||||
|
|
||||||
// if(block > 197 && adddata != null)
|
|
||||||
// adddata.set(cx, cy, cz, 0);
|
|
||||||
// if(block == 1 || block == 19) { // Stone, Sponge
|
|
||||||
// data.set(cx, cy, cz, 0);
|
|
||||||
// }
|
|
||||||
// else if(block == 29 || block == 33 || block == 34) { // Piston, Sticky Piston, Piston Head
|
|
||||||
// int dt = data.get(cx, cy, cz);
|
|
||||||
// if((dt & 7) == 6)
|
|
||||||
// data.set(cx, cy, cz, (dt & 8) | 1);
|
|
||||||
// }
|
|
||||||
// else if(block == 97) { // Monster Egg
|
|
||||||
// int dt = data.get(cx, cy, cz);
|
|
||||||
// switch(dt) {
|
|
||||||
// case 0:
|
|
||||||
// default:
|
|
||||||
// blocks[c] = (byte)1;
|
|
||||||
// data.set(cx, cy, cz, 0);
|
|
||||||
// break;
|
|
||||||
// case 1:
|
|
||||||
// blocks[c] = (byte)4;
|
|
||||||
// data.set(cx, cy, cz, 0);
|
|
||||||
// break;
|
|
||||||
// case 2:
|
|
||||||
// case 3:
|
|
||||||
// case 4:
|
|
||||||
// case 5:
|
|
||||||
// blocks[c] = (byte)98;
|
|
||||||
// data.set(cx, cy, cz, dt - 2);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// mapBlock(new BlockFunction() {
|
|
||||||
// public IBlockState getState(int id, int data) {
|
|
||||||
// return Blocks.waterlily.getDefaultState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(RANDOM));
|
|
||||||
// }
|
|
||||||
// }, 111);
|
|
||||||
// else if(block == 111) { // Water Lily
|
|
||||||
// data.set(cx, cy, cz, RANDOM.zrange(4));
|
|
||||||
// }
|
|
||||||
// else if(block == 251 || block == 252) { // Concrete, Concrete Powder
|
|
||||||
// blocks[c] = (byte)159;
|
|
||||||
// }
|
|
||||||
// else if(block >= 235 && block <= 250) { // Glazed Terracotta
|
|
||||||
// blocks[c] = (byte)159;
|
|
||||||
// data.set(cx, cy, cz, block - 235);
|
|
||||||
// }
|
|
||||||
// else if(block >= 219 && block <= 234) { // Shulker Box
|
|
||||||
// blocks[c] = (byte)35;
|
|
||||||
// data.set(cx, cy, cz, block - 219);
|
|
||||||
// }
|
|
||||||
// else if(block == 205) { // Purpur Slab
|
|
||||||
// blocks[c] = (byte)44;
|
|
||||||
// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 15 : 7);
|
|
||||||
// }
|
|
||||||
// else if(block == 182) { // Red Sandstone Slab
|
|
||||||
// blocks[c] = (byte)44;
|
|
||||||
// data.set(cx, cy, cz, (data.get(cx, cy, cz) & 8) == 8 ? 9 : 1);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void convertTile(NBTTagCompound ent) {
|
private static void convertTile(NBTTagCompound ent) {
|
||||||
|
@ -1113,17 +1001,13 @@ public final class Converter {
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long convertChunks(File dir, File file, long start, int progress, int total) {
|
private static long convertChunks(File dir, File file, long start, int progress, int total) {
|
||||||
String name = file.getName();
|
String name = file.getName();
|
||||||
this.file = name;
|
|
||||||
this.totalChunks = 1024;
|
|
||||||
boolean legacy = name.endsWith(".mcr");
|
boolean legacy = name.endsWith(".mcr");
|
||||||
int rx, rz;
|
int rx, rz;
|
||||||
String[] reg = name.split("\\.");
|
String[] reg = name.split("\\.");
|
||||||
if(reg.length != 4) {
|
if(reg.length != 4) {
|
||||||
Log.JNI.warn("Unbekannte Region " + file);
|
Log.JNI.warn("Unbekannte Region " + file);
|
||||||
this.doneChunks = 0;
|
|
||||||
this.file = null;
|
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -1132,8 +1016,6 @@ public final class Converter {
|
||||||
}
|
}
|
||||||
catch(NumberFormatException e) {
|
catch(NumberFormatException e) {
|
||||||
Log.JNI.warn("Unbekannte Region " + file);
|
Log.JNI.warn("Unbekannte Region " + file);
|
||||||
this.doneChunks = 0;
|
|
||||||
this.file = null;
|
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -1146,7 +1028,6 @@ public final class Converter {
|
||||||
for(int bx = 0; bx < 4; bx++) {
|
for(int bx = 0; bx < 4; bx++) {
|
||||||
for(int bz = 0; bz < 4; bz++) {
|
for(int bz = 0; bz < 4; bz++) {
|
||||||
if(!oldreg.hasRegion(bx, bz)) {
|
if(!oldreg.hasRegion(bx, bz)) {
|
||||||
this.doneChunks += 64;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
areas++;
|
areas++;
|
||||||
|
@ -1161,7 +1042,6 @@ public final class Converter {
|
||||||
DataInputStream in = oldreg.getInputStream(x, z);
|
DataInputStream in = oldreg.getInputStream(x, z);
|
||||||
if(in == null) {
|
if(in == null) {
|
||||||
Log.JNI.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen");
|
Log.JNI.warn("Konnte " + file.getPath() + "@" + x + "," + z + " nicht lesen");
|
||||||
this.doneChunks += 1;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
NBTTagCompound tag = NBTLoader.read(in);
|
NBTTagCompound tag = NBTLoader.read(in);
|
||||||
|
@ -1172,7 +1052,6 @@ public final class Converter {
|
||||||
// out.close();
|
// out.close();
|
||||||
newreg.writeTag(nx, nz, tag);
|
newreg.writeTag(nx, nz, tag);
|
||||||
}
|
}
|
||||||
this.doneChunks += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newreg.close(false);
|
newreg.close(false);
|
||||||
|
@ -1190,36 +1069,26 @@ public final class Converter {
|
||||||
catch(IOException e) {
|
catch(IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
this.doneChunks = 0;
|
|
||||||
this.file = null;
|
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FolderInfo convertMapFormat(File dir, boolean load) {
|
public static boolean convert() {
|
||||||
long cur = System.currentTimeMillis();
|
long cur = System.currentTimeMillis();
|
||||||
if(load)
|
if(new File("server.nbt").exists())
|
||||||
Log.JNI.info("Welt '" + dir + "' wird konvertiert");
|
return false;
|
||||||
if(new File(dir, "level.nbt").exists()) {
|
File ldat = new File("level.dat");
|
||||||
if(load)
|
|
||||||
Log.JNI.error("Datei level.nbt existiert bereits");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
File ldat = new File(dir, "level.dat");
|
|
||||||
if(!ldat.exists())
|
if(!ldat.exists())
|
||||||
ldat = new File(dir, "level.dat_old");
|
ldat = new File("level.dat_old");
|
||||||
if(!ldat.exists()) {
|
if(!ldat.exists())
|
||||||
if(load)
|
return false;
|
||||||
Log.JNI.error("Datei level.dat und level.dat_old nicht gefunden");
|
Log.JNI.info("Welt wird konvertiert");
|
||||||
return null;
|
|
||||||
}
|
|
||||||
NBTTagCompound nbt;
|
NBTTagCompound nbt;
|
||||||
try {
|
try {
|
||||||
nbt = NBTLoader.readGZip(ldat);
|
nbt = NBTLoader.readGZip(ldat);
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
catch(Exception e) {
|
||||||
if(load)
|
|
||||||
Log.JNI.error(e, "Fehler beim Lesen von level.dat");
|
Log.JNI.error(e, "Fehler beim Lesen von level.dat");
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
nbt = nbt.getCompoundTag("Data");
|
nbt = nbt.getCompoundTag("Data");
|
||||||
int version = nbt.getInteger("version");
|
int version = nbt.getInteger("version");
|
||||||
|
@ -1227,47 +1096,18 @@ public final class Converter {
|
||||||
// nbt.setBoolean("incompatible", data >= 1400);
|
// nbt.setBoolean("incompatible", data >= 1400);
|
||||||
SaveVersion ver = data >= 1400 ? SaveVersion.RELEASE_1_13 : (data >= 100 ? SaveVersion.RELEASE_1_9 : (version == 19132 || version == 19133 ? SaveVersion.BETA_1_3 : (version == 0 ? SaveVersion.ALPHA_1_0 : null)));
|
SaveVersion ver = data >= 1400 ? SaveVersion.RELEASE_1_13 : (data >= 100 ? SaveVersion.RELEASE_1_9 : (version == 19132 || version == 19133 ? SaveVersion.BETA_1_3 : (version == 0 ? SaveVersion.ALPHA_1_0 : null)));
|
||||||
if(ver == null) {
|
if(ver == null) {
|
||||||
if(load)
|
|
||||||
Log.IO.error("Version %d ist unbekannt", version);
|
Log.IO.error("Version %d ist unbekannt", version);
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
long wtime = nbt.getLong(nbt.hasKey("DayTime", 99) ? "DayTime" : "Time") + World.START_TIME;
|
long wtime = nbt.getLong(nbt.hasKey("DayTime", 99) ? "DayTime" : "Time") + World.START_TIME;
|
||||||
if(!load)
|
|
||||||
return new FolderInfo(wtime, nbt.getLong("LastPlayed"), ver, null);
|
|
||||||
// nbt.setString("verdesc", ver);
|
|
||||||
// NBTTagCompound nbt = getLegacyWorldInfo(dir);
|
|
||||||
// if(nbt == null)
|
|
||||||
// return false;
|
|
||||||
final Converter conv = new Converter();
|
|
||||||
Client.CLIENT.displayGuiScreen(new GuiLoading("Konvertiere Welt ...", new Callback() {
|
|
||||||
public void poll(Client gm, GuiLoading gui) {
|
|
||||||
if(conv.totalRegions > 0) {
|
|
||||||
gui.setBar(conv.task, "Regionen", conv.totalRegions);
|
|
||||||
gui.setProgress(conv.doneRegions);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gui.resetBar();
|
|
||||||
}
|
|
||||||
if(conv.totalChunks > 0) {
|
|
||||||
gui.setSub(conv.file, "Chunks", conv.totalChunks);
|
|
||||||
gui.setSubProgress(conv.doneChunks);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
gui.resetSub();
|
|
||||||
}
|
|
||||||
gui.setTask(conv.action);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
final NBTTagCompound tag = nbt;
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
Log.IO.info("Version: %s", ver);
|
Log.IO.info("Version: %s", ver);
|
||||||
|
Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", wtime, wtime / 20L);
|
||||||
|
Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(nbt.getLong("LastPlayed"))));
|
||||||
if(ver != SaveVersion.RELEASE_1_13) {
|
if(ver != SaveVersion.RELEASE_1_13) {
|
||||||
conv.action = "Suche nach Chunk-Daten";
|
|
||||||
Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr");
|
Log.JNI.info("Konvertiere Chunk-Daten von region/*.mca,*.mcr");
|
||||||
File regionDir = new File(dir, "region");
|
File regionDir = new File("region");
|
||||||
if(regionDir.exists()) {
|
if(regionDir.exists()) {
|
||||||
File chunkDir = new File(new File(dir, "chunk"), "terra");
|
File chunkDir = new File(new File("chunk"), "terra");
|
||||||
Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ...");
|
Log.JNI.info("Konvertiere Welt nach '" + chunkDir + "' ...");
|
||||||
Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ...");
|
Log.JNI.info("Durchsuche Ordner unter '" + regionDir + "' nach .mca- und .mcr-Dateien ...");
|
||||||
File[] files = regionDir.listFiles(new FilenameFilter() {
|
File[] files = regionDir.listFiles(new FilenameFilter() {
|
||||||
|
@ -1279,22 +1119,19 @@ public final class Converter {
|
||||||
Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden.");
|
Log.JNI.info("Keine .mca- oder .mcr-Dateien gefunden.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conv.task = "Konvertiere Chunkdaten";
|
|
||||||
conv.totalRegions = files.length;
|
|
||||||
Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ...");
|
Log.JNI.info("Ingesamt wurden " + files.length + " .mca-Dateien und .mcr-Dateien gefunden, konvertiere ...");
|
||||||
if(ver == SaveVersion.RELEASE_1_9)
|
if(ver == SaveVersion.RELEASE_1_9)
|
||||||
Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ...");
|
Log.JNI.info("Konvertiere von neuerer Version, dies wird Blöcke entfernen ...");
|
||||||
chunkDir.mkdirs();
|
chunkDir.mkdirs();
|
||||||
int progress = 0;
|
int progress = 0;
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
long start = conv.postProgress(time, 0);
|
long start = postProgress(time, 0);
|
||||||
for(File file : files) {
|
for(File file : files) {
|
||||||
int percent = (int)Math.round(100.0D * (double)progress / (double)files.length);
|
int percent = (int)Math.round(100.0D * (double)progress / (double)files.length);
|
||||||
Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")");
|
Log.JNI.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")");
|
||||||
start = conv.convertChunks(chunkDir, file, start, progress, files.length);
|
start = convertChunks(chunkDir, file, start, progress, files.length);
|
||||||
++progress;
|
++progress;
|
||||||
start = conv.postProgress(start, percent);
|
start = postProgress(start, percent);
|
||||||
conv.doneRegions += 1;
|
|
||||||
}
|
}
|
||||||
time = System.currentTimeMillis() - time;
|
time = System.currentTimeMillis() - time;
|
||||||
Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden.");
|
Log.JNI.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden.");
|
||||||
|
@ -1304,86 +1141,24 @@ public final class Converter {
|
||||||
else {
|
else {
|
||||||
Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu");
|
Log.JNI.warn("Konvertiere keine Chunk-Daten, da Version zu neu");
|
||||||
}
|
}
|
||||||
conv.doneRegions = 0;
|
|
||||||
conv.task = null;
|
|
||||||
conv.action = "Konvertiere level.dat";
|
|
||||||
Log.JNI.info("Konvertiere Daten von level.dat");
|
Log.JNI.info("Konvertiere Daten von level.dat");
|
||||||
Config.clear();
|
Config.clear();
|
||||||
UniverseRegistry.clear();
|
UniverseRegistry.clear();
|
||||||
if(tag.hasKey("GameRules", 10)) {
|
if(nbt.hasKey("GameRules", 10)) {
|
||||||
NBTTagCompound rules = tag.getCompoundTag("GameRules");
|
NBTTagCompound rules = nbt.getCompoundTag("GameRules");
|
||||||
for(Entry<String, String> rule : OLD_GAMERULES.entrySet()) {
|
for(Entry<String, String> rule : OLD_GAMERULES.entrySet()) {
|
||||||
if(rules.hasKey(rule.getKey(), 8))
|
if(rules.hasKey(rule.getKey(), 8))
|
||||||
Config.set(rule.getValue(), rules.getString(rule.getKey()), null);
|
Config.set(rule.getValue(), rules.getString(rule.getKey()), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Config.setVar("noRespawn", "" + nbt.getBoolean("hardcore"), false);
|
Log.JNI.info("Speichere neue server.nbt ...");
|
||||||
// int id = nbt.getInteger("GameType");
|
Server.saveServerConfig(wtime);
|
||||||
// Config.set("defaultNoCreative", "" + (id == 2 || id == 0), false);
|
Weather weather = nbt.getBoolean("thundering") ? Weather.THUNDER : (nbt.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR);
|
||||||
Log.JNI.info("Speichere neue level.nbt ...");
|
|
||||||
Region.saveWorldInfo(dir, wtime);
|
|
||||||
// if(tag.hasKey("Player", 10)) {
|
|
||||||
// conv.action = "Konvertiere Spielerdaten";
|
|
||||||
// NBTTagCompound player = tag.getCompoundTag("Player");
|
|
||||||
// NBTTagList pos = player.getTagList("Pos", 6);
|
|
||||||
// NBTTagList motion = player.getTagList("Motion", 6);
|
|
||||||
// NBTTagList rotation = player.getTagList("Rotation", 5);
|
|
||||||
// boolean ground = player.getBoolean("OnGround");
|
|
||||||
// BlockPos spawn = null;
|
|
||||||
// // boolean force = player.getBoolean("OnGround");
|
|
||||||
// // int mode = -1;
|
|
||||||
// // if(player.hasKey("playerGameType", 99)) {
|
|
||||||
// // mode = player.getInteger("playerGameType");
|
|
||||||
// // mode = mode == 0 || mode == 2 ? 0 : (mode == 1 || mode == 3 ? 1 : -1);
|
|
||||||
// // }
|
|
||||||
// if(player.hasKey("SpawnX", 99) && player.hasKey("SpawnY", 99) && player.hasKey("SpawnZ", 99)) {
|
|
||||||
// spawn = new BlockPos(player.getInteger("SpawnX"), player.getInteger("SpawnY"),
|
|
||||||
// player.getInteger("SpawnZ"));
|
|
||||||
// // force = player.getBoolean("SpawnForced");
|
|
||||||
// }
|
|
||||||
// player.getKeySet().clear();
|
|
||||||
// player.setTag("Pos", pos);
|
|
||||||
// player.setTag("Motion", motion);
|
|
||||||
// player.setTag("Rotation", rotation);
|
|
||||||
// player.setBoolean("OnGround", ground);
|
|
||||||
// player.setInteger("Dimension", 1);
|
|
||||||
// player.setString("id", EntityRegistry.getEntityString(EntityHuman.class));
|
|
||||||
// if(spawn != null) {
|
|
||||||
// player.setInteger("SpawnX", spawn.getX());
|
|
||||||
// player.setInteger("SpawnY", spawn.getY());
|
|
||||||
// player.setInteger("SpawnZ", spawn.getZ());
|
|
||||||
// player.setInteger("SpawnDim", 1);
|
|
||||||
// // player.setBoolean("SpawnForced", force);
|
|
||||||
// }
|
|
||||||
// player.setInteger("OriginX", tag.getInteger("SpawnX"));
|
|
||||||
// player.setInteger("OriginY", tag.getInteger("SpawnY"));
|
|
||||||
// player.setInteger("OriginZ", tag.getInteger("SpawnZ"));
|
|
||||||
// player.setInteger("OriginDim", 1);
|
|
||||||
// player.setString("CustomName", user.substring(0, 1).toUpperCase() + user.substring(1));
|
|
||||||
// NBTTagCompound plr = new NBTTagCompound();
|
|
||||||
// plr.setInteger("selected", 0);
|
|
||||||
// NBTTagList list = new NBTTagList();
|
|
||||||
// list.appendTag(player);
|
|
||||||
// plr.setTag("characters", list);
|
|
||||||
// // if(mode >= 0)
|
|
||||||
// // player.setBoolean("creative", mode == 1);
|
|
||||||
// Log.JNI.info("Speichere neue Spielerdaten " + user.toLowerCase() + ".nbt ...");
|
|
||||||
// File pdat = new File(new File(dir, "players"), user.toLowerCase() + ".nbt");
|
|
||||||
// try {
|
|
||||||
// pdat.getParentFile().mkdirs();
|
|
||||||
// NBTLoader.writeGZip(plr, pdat);
|
|
||||||
// }
|
|
||||||
// catch(Exception e) {
|
|
||||||
// Log.JNI.error(e, "Fehler beim Schreiben von " + pdat);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
Weather weather = tag.getBoolean("thundering") ? Weather.THUNDER : (tag.getBoolean("raining") ? Weather.RAIN : Weather.CLEAR);
|
|
||||||
if(weather != Weather.CLEAR) {
|
if(weather != Weather.CLEAR) {
|
||||||
conv.action = "Konvertiere Dimensionsdaten";
|
|
||||||
NBTTagCompound dataTag = new NBTTagCompound();
|
NBTTagCompound dataTag = new NBTTagCompound();
|
||||||
dataTag.setString("Weather", weather.getName());
|
dataTag.setString("Weather", weather.getName());
|
||||||
Log.JNI.info("Speichere neue data.nbt ...");
|
Log.JNI.info("Speichere neue data.nbt ...");
|
||||||
File dataFile = new File(new File(new File(dir, "chunk"), "terra"), "data.nbt");
|
File dataFile = new File(new File(new File("chunk"), "terra"), "data.nbt");
|
||||||
try {
|
try {
|
||||||
NBTLoader.writeGZip(dataTag, dataFile);
|
NBTLoader.writeGZip(dataTag, dataFile);
|
||||||
}
|
}
|
||||||
|
@ -1391,18 +1166,7 @@ public final class Converter {
|
||||||
Log.JNI.error(e, "Konnte Weltdaten nicht speichern");
|
Log.JNI.error(e, "Konnte Weltdaten nicht speichern");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.IO.info("Welt '" + dir + "' wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L);
|
Log.IO.info("Welt wurde in %d Sekunden konvertiert", (System.currentTimeMillis() - cur) / 1000L);
|
||||||
Client.CLIENT.schedule(new Runnable() {
|
return true;
|
||||||
public void run() {
|
|
||||||
Client.CLIENT.displayGuiScreen(GuiConvert.INSTANCE);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
}, "Converter Thread").start();
|
|
||||||
return new FolderInfo(wtime, System.currentTimeMillis(), null, Config.VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
// public static NBTTagCompound getLegacyWorldInfo(File worldDir) {
|
|
||||||
// return nbt;
|
|
||||||
// }
|
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue