2017-04-13 60 views
0

我正在將我的Minecraft塊保護插件從Bukkit移植到海綿,因此我可以使用SpongeForge添加修改。 Bukkit使用Material enum來標識遊戲中所有有效的塊類型。我所有的保護都在config.yml文件中指定這樣的:如何將現有靜態常量包裝到枚舉中?

CHEST: 
    Price: 0.75 
    InteractMember: R 
    ... 

隨着枚舉是很容易拿在配置文件中的鍵名,胸部,並獲得與Bukkit.getMaterial實際枚舉值(字符串名稱)。不幸的是,海綿拒絕在代碼中的任何地方使用枚舉,所以它們的塊類型列表是一個只包含靜態final int常量的類,我無法遍歷或通過名稱進行檢索。我試圖反思..

HashMap<String,Integer> blockTypes = new HashMap<String,Integer>(); 

for(Field field, BlockTypes.class.getFields()) 
    blockMap.put(field.getName(), field.getInt(null)); 

但我只能得到常數的int值。我需要的常量自己在代碼中使用了,我找不到任何方式做到這一點不使我自己的枚舉包裝器的靜態常量:

public enum Blocks { 
    ACACIA_FENCE(BlockTypes.ACACIA_FENCE), 
    ACACIA_STEPS(BlockTypes.ACACIA_STEPS), 
    ... 
    YELLOW_FLOWER(BlockTypes.YELLOW_FLOWER); 

    private final BlockTypes type; 
    Blocks(BlockTypes type) { 
     this.type = type; 
    } 
    public BlockTypes getType() { return type; } 
    public static BlockTypes getByName(String name) { 
     // retrieve enum by name 
    } 
} 

我真能堅持這樣做,或者有其他我失蹤的方式?

回答

0

海綿不使用枚舉有一個原因:既然你可以添加其他mods,常量將不得不動態添加(這是不可能的),並假設在香草遊戲中的塊是唯一的塊不是有效。支持其他MODS是海綿API的主要目標之一。

如果你的目標是讓所有有效BlockType S IN的遊戲列表,你應該使用GameRegistry

// Getting a list of all types 
Collection<BlockType> types = Sponge.getRegistry().getAllOf(BlockType.class) 
for (BlockType type : types) { 
    System.out.println(type.getName()); 
} 

// Getting a single type by name 
Optional<BlockType> type = Sponge.getRegistry().getType(BlockType.class, "minecraft:chest"); 
if (!type.isPresent()) { 
    // show some error, as the given type doesn't exist 
} else { 
    return type.get(); 
} 

你應該可以在地圖中使用BlockType作爲重點,或者String id。你不需要爲它做一個枚舉(並且不能自動完成)。

值得注意的是,您在示例中也使用了反射錯誤,但我認爲解釋如何立即使用它是非常重要的,因爲這是錯誤的方法。

+0

很好的答案,謝謝!我沒有意識到BlockType和BlockTypes類之間的關係。我也不知道CatalogType接口如何工作,但現在我做到了!海綿還是很新的,我還有很多要學習。我看到這種編目方法比使用枚舉更靈活。是的,反思代碼很差,我只是把它扔在一起,試圖讓一些東西工作。 –