2016-02-19 23 views
5

Korzystanie z Forge 1.8.9 w środowisku Eclipse (wydanie Mars.1 (4.5.1)) w lokalnym środowisku programistycznym.Minecraft Forge EntityJoinWorldEvent zwraca nieprawidłową lokalizację! Błąd

Próbuję ustawić lokalizację gracza za każdym razem, gdy dołączą lub przyłączą się ponownie do świata. Zawsze działa po raz pierwszy (np. Biegnij i dołącz do świata. Zobacz pierwszy zrzut ekranu). First appearance in World - works as expected

Po pewnym poruszeniu się po świecie, a następnie wylogowaniu z tego świata i powrocie (ta sama sesja bez zamykania MC), świat nie pojawia się w konsoli. Lokalizacja jest taka sama jak w logowaniu "wszystko w porządku". Plus jest niewłaściwa lokalizacja! Błąd.

Location OK, but World does not appear

Błąd z konsoli jest tutaj:

[05:47:53] [Server thread/INFO]: Player992 joined the game 
[05:47:53] [Server thread/WARN]: Wrong location! (9, 9) should be (9, 6), EntityPlayerMP['Player992'/2371, l='world', x=145.00, y=73.00, z=145.00] 
[05:48:18] [Server thread/INFO]: Saving and pausing game... 
[05:48:18] [Server thread/INFO]: Saving chunks for level 'world'/Overworld 
[05:48:18] [Server thread/INFO]: Saving chunks for level 'world'/Nether 
[05:48:18] [Server thread/INFO]: Saving chunks for level 'world'/The End 

Próbowałem kilka odmian tego, w tym Minecraft Forge: Using correct Join Game listener for setLocationAndAngles ale bez kości (różne zachowanie).

Zignoruj ​​wszystkie "importowane", które nie są istotne. Są to artefakty moich wielokrotnych prób.

import net.minecraft.util.ChatComponentText; 
import net.minecraft.util.EnumChatFormatting; 
import net.minecraft.entity.player.EntityPlayer; 
import net.minecraft.util.EnumChatFormatting; 
import net.minecraftforge.event.entity.EntityJoinWorldEvent; 
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; 
//import cpw.mods.fml.common.eventhandler.SubscribeEvent; 
import net.minecraftforge.client.event.RenderWorldEvent; 
import net.minecraftforge.event.world.WorldEvent; 
public class JoinGameLocation { 

    @SubscribeEvent 
    public void onEntityJoinWorld(EntityJoinWorldEvent event) { 
     if (event.entity != null && event.entity instanceof EntityPlayer && !event.entity.worldObj.isRemote) { 
     event.entity.setLocationAndAngles(145, 73, 145, 0, 0); 
     } 
    } 

} 

Zrobiłem kilka czytania na niewłaściwym błędu lokalizacji, ale coś nie wydaje się słuszne, biorąc pod uwagę, że mogę pojawić się w tym miejscu za pierwszym razem, więc to nie jest tak jak ja pojawiające Wewnątrz blok. Próbowałem utworzyć krótkie opóźnienie (1-3s), ale błąd nadal występuje.

+0

"Nieprawidłowa lokalizacja" występuje, gdy jednostka jest dodawana do porcji, która nie jest zgodna z porcją, która powinna być użyta, biorąc pod uwagę pozycję jednostki. Będę musiał sprawdzić źródło surowego kucia, ale wygląda na to, że nie obsługuje on poprawnie zmiany pozycji podczas dodawania jednostki ... Zajmę się tym dalej, gdy dostanę szansę. Może to być błąd kuźni. – Pokechu22

Odpowiedz

0

"Nieprawidłowa lokalizacja!" jest używany, gdy jednostka jest dodawana do kawałka, z którego nie powinno być współrzędnych.

Oto gdzie (w World.java) zdarzenie zostanie zwolniony (no, rzeczywiście, istnieje kilka innych miejsc, ale jest to jeden używany przez graczy spośród innych podmiotów):

/** 
* 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; 
    } 
} 

Zauważ, że i i j (współrzędne fragmentów) nie są zmieniane po aktualizacji lokalizacji gracza. Więc kiedy Chunk.addEntity (patrz niżej) nazywa rzeczy nie działają:

/** 
* 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 
} 

To zabija gracza.


Nie jestem do końca pewien, dlaczego działa po raz pierwszy. Będzie działać zawsze, gdy zalogujesz się w tym samym kawałku, do którego zostaniesz przeniesiony, więc jeśli wylogujesz się po znalezieniu się w niewłaściwym miejscu, następnym razem zalogujesz się pomyślnie.

Zanim przejdę do poprawki, oto kilka innych rzeczy do uwaga:

  • Nie trzeba robić null czek z instanceof - null nigdy nie przejdzie testu instanceof.
  • (Przynajmniej zgodnie z CommandTeleport), musisz teleportować EntityPlayerMP s inaczej, używając EntityPlayerMP.playerNetServerHandler.setPlayerLocation.

Aby to naprawić, musisz opóźnić teleportację o 1 znacznik.Nie jestem pewien, co całkiem kanoniczny metoda Forge za to, ale coś jak to powinno działać:

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(); 
    } 
} 

Jeśli potrzebujesz, aby móc zmienić pozycję gracz będzie się raczej niż zawsze będzie ci określonych współrzędnych, oto jeden ze sposobów tak:

@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(); 
      } 
     } 
    } 
} 

należy również pamiętać, że aby skorzystać TickEvent, trzeba zarejestrować się na osobnej magistrali, niż można by wykorzystać z EntityJoinWorldEvent, tak aby w pełni zarejestrować wydarzenia użyte tutaj, możesz to zrobić:

MinecraftForge.EVENT_BUS.register(this); 
FMLCommonHandler.instance().bus().register(this); 
+0

Dzięki, prawdopodobnie uruchomię pierwszą wersję, ale sprawdzę je na EOD. –

+0

Wypróbowałem prostszą odpowiedź i zwrócono niewłaściwą lokalizację! Może połowę czasu. Nie jestem pewien co z tym. Daję to "go", ponieważ jest to więcej niż musiałem pracować, odkąd to opublikowałem. Dziękuję za pomoc w tej sprawie. –

+0

@joseph_pindi Właściwie, patrząc na mój kod ponownie, mogłem popełnić błąd w tej połowie - nie ma rewizji, którą zrobiłem z drugą, gdzie sprawdza świat podczas kleszcza ... Ja to zredagowałem. – Pokechu22