6

我正在为 Minecraft 制作基于文本的雷达。如果玩家距离您 20 格以内,它会在聊天中显示。截至目前,它在聊天中发送垃圾邮件。我怎样才能让它只写一次关于那个玩家的聊天?即使你不玩游戏,也应该很容易理解。

if (Camb.radar)
{
  for (Entity e: (List < Entity > ) mc.theWorld.loadedEntityList)
  {
    if (e instanceof EntityPlayer)
    {
      EntityPlayer player = (EntityPlayer) e;
      if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0)
        continue;
      mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName() + " has entered your 20 block radius!"); //Write to chat, only want this line done once for every player
    }
  }
}
4

6 回答 6

15

您需要跟踪玩家何时离开范围并设置标志,这样您就会知道他们何时从“范围外”过渡到“范围内”。可能还想添加一个计时器,以便您每 N 秒只能发出一次警报。

于 2013-08-01T18:50:24.600 回答
2

如果你创建一个 PlayerData 类,它可以包含一个映射到布尔值的玩家姓名哈希图。你给每个玩家一个 PlayerData 对象,然后当有人进入该玩家的半径时,你切换他/她的布尔值。

public class PlayerData {
    public Player thePlayer;
    public HashMap<String,boolean> inRadius = new HashMap<String,boolean>();

    public PlayerData(Player thePlayer) {
       this.thePlayer = thePlayer;
    }

    public void checkRadius(P Entity player) {
    /**function that checks radius and if a new player is there, notify thePlayer*/
      if(inRadius.get(player.getEntityName()) == true || thePlayer == player || thePlayer.getDistanceToEntity(player) > 20.0) return;
      else {
        thePlayer.addChatMessage("whatever you want to say");
        inRadius.put(player.getEntityName(), true);
      }
      for(Iterator<String> key=inRadius.keySet().Iterator();key.hasNext()) {
        String name = key.next();
        /**Check to see if that player is still within 20 meters. If not, set value to false*/
        /** also be careful to check if player is online*/
      }
    }

}
于 2013-08-01T18:54:24.570 回答
2

您可以尝试创建附近玩家的列表或数组,并在他们在 20 个街区内时将他们添加到该列表中。当您在范围内找到一个实体时,请检查它是否在您的列表中。如果没有,请通知并将其添加到列表中,如果是,请继续游戏:)

要从列表中删除项目,请检查列表中的实体并将它们与玩家位置进行比较。如果它们超出范围,请将它们删除。这可能需要在单独的循环中发生。

于 2013-08-01T18:54:29.770 回答
0

您需要在已经提醒玩家的方法之外存储。AMap非常适合这个。更好的是WeakHashMap,以防你不想泄露那些Entities

private final Set<EntityPlayer> playersInRange = Collections
        .newSetFromMap(new WeakHashMap<EntityPlayer, Boolean>());

void onMove() {
    if (Camb.radar) {
        for (Entity e : (List<Entity>) mc.theWorld.loadedEntityList) {
            if (e instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer) e;

                if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0) {
                    // make sure player is (no longer) in set
                    playersInRange.remove(player);
                    continue;
                }

                if (!playersInRange.contains(player)) {
                    playersInRange.add(player);
                    mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName()
                            + " has entered your 20 block radius!");
                }
            }
        }
    }
}

您还可以与他们一起存储一个时间,以便每 X 次重新提醒。

private static final long WAIT_BETWEEN_ALERTS = 30000;
private final WeakHashMap<EntityPlayer, Long> map = new WeakHashMap<EntityPlayer, Long>();
void onMove() {
    if (Camb.radar) {
        for (Entity e : (List<Entity>) mc.theWorld.loadedEntityList) {
            if (e instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer) e;

                if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0) {
                    // clear alerts
                    map.remove(player);
                    continue;
                }

                Long lastTimeAlerted = map.get(player);
                long minimumLastAlert = System.currentTimeMillis() - WAIT_BETWEEN_ALERTS;

                if (lastTimeAlerted == null || lastTimeAlerted < minimumLastAlert) {
                    map.put(player, System.currentTimeMillis());
                    mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName()
                            + " has entered your 20 block radius!");
                } // else, already alerted recently.
            }
        }
    }
}
于 2013-08-01T19:07:29.687 回答
0

detected使用 getter/setter 方法向 EntityPlayer 添加一个布尔标志。

在你的循环内:

if (Camb.radar) {
    for (....) {
        if (e instanceof EntityPlayer) {
            EntityPlayer player = (EntityPlayer) e;
            if (player.isDetected() || player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0) {
                continue;
            }

            if (!player.isDetected()) {
                mc.thePlayer.addChatMessage(....); 
                player.setDetected(true); // reset this flag when player goes out of radar
            }
        }
    }
}    
于 2013-08-01T19:12:23.433 回答
0

我建议这样做:

int radius = 0;
if (Camb.radar) for (Entity e : (List <Entity>) mc.theWorld.loadedEntityList)
    if (e instanceof EntityPlayer) {
        EntityPlayer player = (EntityPlayer) e;
        if (player == mc.thePlayer || mc.thePlayer.getDistanceToEntity(e) > 20.0)
            continue;
        while (radius < 1) {
            mc.thePlayer.addChatMessage("\2479[CAMB] \247e" + player.getEntityName() + " has
            entered your 20 block radius!");

        }    
    }
于 2014-10-26T16:22:09.300 回答