本帖最后由 yuxuanchiadm 于 2013-8-4 15:16 编辑

利用Forge API开发联机MOD【基础篇】【第七章】
改善你制作的方块的功能
作者:yuxuanchiadm

索引贴地址:http://www.mcbbs.net/thread-38211-1-1.html

请确定你已经阅读完成第六章的内容:
http://www.mcbbs.net/thread-38526-1-1.html
否则不要阅读此贴!

序:
在上一章里,我们创建了一个极不完善的刷怪笼方块,而我们的目标是制作一个能够自定义所刷生物和刷怪间隔的高级刷怪笼。所以,在这一章里,首先让我们让这个方块具有基本的刷怪功能吧!:)。

使你的MOD具有基本的刷怪功能:
首先,刷怪笼需要一个继承自TileEntity的子类,用于储存所刷生物和刷怪间隔和刷新间隔计数。
/**知识点:什么是TileEntity
TileEntity也能算一种实体,只不过它是一种特殊的实体,而且不继承自Entity,用于记录方块的附加信息,比如箱子里的物品等,它与方块紧密相连,另外还可以对这个实体进行渲染。

**/
在myFirstMod包下新建包TileEntity,再新建一个类,命名为TileEntityAdvancedMobSpawner,出于简单考虑,继承自TileEntityMobSpawner,输入以下内容:
  1. package myFirstMod.TileEntity;

  2. import java.lang.reflect.Field;

  3. import net.minecraft.entity.Entity;
  4. import net.minecraft.entity.EntityList;
  5. import net.minecraft.tileentity.TileEntityMobSpawner;

  6. public class TileEntityAdvancedMobSpawner extends TileEntityMobSpawner
  7. {
  8.     private Field minSpawnDelayField;
  9.     private Field maxSpawnDelayField;
  10.     private Field cachedEntity;
  11.     private Field spawnerTags;
  12.     private Field mobID;
  13.     public TileEntityAdvancedMobSpawner()
  14.     {
  15.         Class<TileEntityMobSpawner> TileEntityMobSpawnerClass =TileEntityMobSpawner.class;
  16.         try
  17.         {
  18.             minSpawnDelayField = TileEntityMobSpawnerClass.getDeclaredField("minSpawnDelay");
  19.             minSpawnDelayField.setAccessible(true);
  20.             maxSpawnDelayField = TileEntityMobSpawnerClass.getDeclaredField("maxSpawnDelay");
  21.             maxSpawnDelayField.setAccessible(true);
  22.             cachedEntity = TileEntityMobSpawnerClass.getDeclaredField("field_92017_j");
  23.             cachedEntity.setAccessible(true);
  24.             spawnerTags = TileEntityMobSpawnerClass.getDeclaredField("spawnerTags");
  25.             spawnerTags.setAccessible(true);
  26.             mobID = TileEntityMobSpawnerClass.getDeclaredField("mobID");
  27.             mobID.setAccessible(true);
  28.         }
  29.         catch (Exception e)
  30.         {
  31.             e.printStackTrace();
  32.         }
  33.     }
  34.     public void setMobID(String id)
  35.     {
  36.         try
  37.         {
  38.             mobID.set(this, id);
  39.             cachedEntity.set(this, null);
  40.             spawnerTags.set(this, null);
  41.         }
  42.         catch (Exception e)
  43.         {
  44.             e.printStackTrace();
  45.         }
  46.     }
  47.     public String getMobID()
  48.     {
  49.         try
  50.         {
  51.             if(((Entity)cachedEntity.get(this)) != null)
  52.             {
  53.                 return EntityList.getEntityString(((Entity)cachedEntity.get(this)));
  54.             }
  55.             else
  56.             {
  57.                 return func_92015_a();
  58.             }
  59.         }
  60.         catch (Exception e)
  61.         {
  62.             e.printStackTrace();
  63.             return null;
  64.         }
  65.     }
  66.     public int getSpawnDelay()
  67.     {
  68.         try
  69.         {
  70.             int max = ((Integer)maxSpawnDelayField.get(this)).intValue();
  71.             int min = ((Integer)minSpawnDelayField.get(this)).intValue();
  72.             return min + (max - min) / 2;
  73.         }
  74.         catch (Exception e)
  75.         {
  76.             e.printStackTrace();
  77.         }
  78.         return 0;
  79.     }
  80.     public void setSpawnDelay(int value)
  81.     {
  82.         try
  83.         {
  84.             maxSpawnDelayField.set(this, value);
  85.             minSpawnDelayField.set(this, value);
  86.             if(delay > value)
  87.             {
  88.                 delay = value;
  89.             }
  90.         }
  91.         catch (Exception e)
  92.         {
  93.             e.printStackTrace();
  94.         }
  95.     }
  96.     public int getMaxSpawnDelay()
  97.     {
  98.         try
  99.         {
  100.             return ((Integer)maxSpawnDelayField.get(this)).intValue();
  101.         }
  102.         catch (Exception e)
  103.         {
  104.             e.printStackTrace();
  105.         }
  106.         return 0;
  107.     }
  108.     public int getMinSpawnDelay()
  109.     {
  110.         try
  111.         {
  112.             return ((Integer)minSpawnDelayField.get(this)).intValue();
  113.         }
  114.         catch (Exception e)
  115.         {
  116.             e.printStackTrace();
  117.         }
  118.         return 0;
  119.     }
  120.     public void setMaxSpawnDelay(int value)
  121.     {
  122.         try
  123.         {
  124.             maxSpawnDelayField.set(this, value);
  125.         }
  126.         catch (Exception e)
  127.         {
  128.             e.printStackTrace();
  129.         }
  130.     }
  131.     public void setMinSpawnDelay(int value)
  132.     {
  133.         try
  134.         {
  135.             minSpawnDelayField.set(this, value);
  136.         }
  137.         catch (Exception e)
  138.         {
  139.             e.printStackTrace();
  140.         }
  141.     }
  142. }
复制代码

以上的公共实例方法主要是为了获取、设置刷怪间隔和所刷怪物,包括一些通过反射来越权访问。
然后,在mod_myFirstMod的load方法里注册它:

  1. TileEntity.addMapping(TileEntityAdvancedMobSpawner.class, "AdvancedMobSpawner");
复制代码

现在,保存你的代码,并编译运行,你就可以用一个刷怪笼和8个钻石得到一个高级刷怪笼,虽然和普通刷怪笼看上去没啥区别。

总结:
这一章里,我们让我们的高级刷怪笼已经有了普通刷怪笼的功能,下一章里,我们将要为刷怪笼能够实现更多功能做准备,建立我们的网络通信框架!