「場所が間違っています!エンティティがチャンクに追加されるときに使用されます。
はここでどこ(World.java
中)イベントが発生しているのです(まあ、実際には、いくつかの他の場所があるが、これは他のエンティティ間のプレーヤーで使用されるものである):
/**
* Called when an entity is spawned in the world. This includes players.
*/
public boolean spawnEntityInWorld(Entity p_72838_1_)
{
// do not drop any items while restoring blocksnapshots. Prevents dupes
if (!this.isRemote && (p_72838_1_ == null || (p_72838_1_ instanceof net.minecraft.entity.item.EntityItem && this.restoringBlockSnapshots))) return false;
int i = MathHelper.floor_double(p_72838_1_.posX/16.0D);
int j = MathHelper.floor_double(p_72838_1_.posZ/16.0D);
boolean flag = p_72838_1_.forceSpawn;
if (p_72838_1_ instanceof EntityPlayer)
{
flag = true;
}
if (!flag && !this.isChunkLoaded(i, j, true))
{
return false;
}
else
{
if (p_72838_1_ instanceof EntityPlayer)
{
EntityPlayer entityplayer = (EntityPlayer)p_72838_1_;
this.playerEntities.add(entityplayer);
this.updateAllPlayersSleepingFlag();
}
if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(p_72838_1_, this)) && !flag) return false;
this.getChunkFromChunkCoords(i, j).addEntity(p_72838_1_);
this.loadedEntityList.add(p_72838_1_);
this.onEntityAdded(p_72838_1_);
return true;
}
}
なおi
とj
(チャンク座標)は、プレーヤーの位置を更新した後は変更されません。 Chunk.addEntity
が(下記参照)と呼ばれているときに、物事は動作しません:
/**
* Adds an entity to the chunk. Args: entity
*/
public void addEntity(Entity entityIn)
{
this.hasEntities = true;
int i = MathHelper.floor_double(entityIn.posX/16.0D);
int j = MathHelper.floor_double(entityIn.posZ/16.0D);
if (i != this.xPosition || j != this.zPosition)
{
logger.warn("Wrong location! (" + i + ", " + j + ") should be (" + this.xPosition + ", " + this.zPosition + "), " + entityIn, new Object[] {entityIn});
entityIn.setDead();
}
// ... rest of the method
}
これはプレイヤーを殺します。
なぜ初めて動作するのかわかりません。あなたがテレポートされたチャンクと同じチャンクにログインするたびに動作します。間違った場所にいるとログアウトすると、次回には正常にログインします。私は修正に入る前に
、ここで注意すべきいくつか他のものです:
- あなたがinstanceofのではnullチェックをする必要はありません -
null
はinstanceofは試験に合格することはありません。
- (少なくともCommandTeleportによると)
EntityPlayerMP.playerNetServerHandler.setPlayerLocation
を使用してEntityPlayerMP
を異なる方法でテレポートする必要があります。
修正するには、テレポートを1ティック遅らせる必要があります。私はそのための標準的な鍛造方法が非常にわからないんだけど、このようなものは動作するはずです:
List<Entity> playersToTeleport = new ArrayList<Entity>();
@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event) {
if (event.entity instanceof EntityPlayer && !event.entity.worldObj.isRemote) {
playersToTeleport.add(event.entity);
}
}
@SubscribeEvent
public void teleportEntiesOnWorldTick(TickEvent.WorldTickEvent event) {
// Make sure that this is the type of tick we want.
if (event.phase == TickEvent.Phase.START && event.type == TickEvent.Type.WORLD) {
for (Entity entity : playersToTeleport) {
if (entity.worldObj == event.world) {
if (entity instanceof EntityPlayerMP) {
((EntityPlayerMP) entity).playerNetServerHandler.setPlayerLocation(145, 73, 145, 0, 0);
} else {
entity.setLocationAndAngles(145, 73, 145, 0, 0);
}
}
}
playersToTeleport.clear();
}
}
あなたは常にそれらに行くプレイヤーはなく、になります位置を変更できるようにする必要がある場合特定の座標は、ここではそうすることの一つの方法です:
また
@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event) {
if (event.entity instanceof EntityPlayer && !event.entity.worldObj.isRemote) {
queueTeleportNextTick(event.entity, Math.random() * 200 - 100, 73,
Math.random() * 200 - 100, 0, 0);
}
}
/**
* List of teleports to perform next tick.
*/
private List<TeleportInfo> queuedTeleports = new ArrayList<TeleportInfo>();
/**
* Stores information about a future teleport.
*/
private static class TeleportInfo {
public TeleportInfo(Entity entity, double x, double y, double z,
float yaw, float pitch) {
this.entity = entity;
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
}
public final Entity entity;
public final double x;
public final double y;
public final double z;
public final float yaw;
public final float pitch;
}
/**
* Teleport the given entity to the given coordinates on the next game tick.
*/
public void queueTeleportNextTick(Entity entity, double x, double y,
double z, float yaw, float pitch) {
System.out.printf("Preparing to teleport %s to %f, %f, %f%n", entity, x, y, z);
queuedTeleports.add(new TeleportInfo(entity, x, y, z, yaw, pitch));
}
@SubscribeEvent
public void teleportEntiesOnWorldTick(TickEvent.WorldTickEvent event) {
// Make sure that this is the type of tick we want.
if (event.phase == TickEvent.Phase.START && event.type == TickEvent.Type.WORLD) {
// Perform each teleport
Iterator<TeleportInfo> itr = queuedTeleports.iterator();
while (itr.hasNext()) {
TeleportInfo info = itr.next();
if (info.entity.worldObj == event.world) {
System.out.printf("Teleporting %s to %f, %f, %f%n", info.entity, info.x, info.y, info.z);
if (info.entity instanceof EntityPlayerMP) {
// EntityPlayerMPs are handled somewhat differently.
((EntityPlayerMP) info.entity).playerNetServerHandler
.setPlayerLocation(info.x, info.y, info.z,
info.pitch, info.yaw);
} else {
info.entity.setLocationAndAngles(info.x, info.y, info.z,
info.pitch, info.yaw);
}
itr.remove();
}
}
}
}
、あなたは完全にここで使用したイベントを登録するので、EntityJoinWorldEvent
で使用したいよりも、あなたは別のバスに登録する必要があり、TickEvent
を使用することに注意し、あなたはこれを行うでしょう:
MinecraftForge.EVENT_BUS.register(this);
FMLCommonHandler.instance().bus().register(this);
エンティティの位置に応じて使用するチャンクと一致しないチャンクにエンティティを追加すると、「間違った場所」が発生します。私は生の鍛造源をチェックしなければならないでしょうが、エンティティが追加されている間に位置を変更するのが適切に処理されないようです...私はチャンスが得られたらそれをさらに調べます。偽造バグかもしれない。 – Pokechu22