[技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

クライアント/サーバーMODの開発に関する話題、技術交換はこちらで。質問は質問フォーラムへお願いします。
  • (PostNo.196344)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by kegare » 2014年9月28日(日) 19:42

主に自分用の備忘録ですが、ご紹介。
プレイヤーのディメンション移動をTeleporterを介さずに安全に行います。
ライセンスはWTFPLライセンスです。勝手に改変だとかコピペだとかしちゃってください。

環境: Forge 10.13.0.1180
他のバージョンでも必要に応じて多少修正すれば使えると思います。

コード: 全て選択
public static EntityPlayerMP respawnPlayer(EntityPlayerMP player, int dim)
{
    player.isDead = false;
    player.forceSpawn = true;
    player.timeUntilPortal = player.getPortalCooldown();
    player.playerNetServerHandler.playerEntity = player.mcServer.getConfigurationManager().respawnPlayer(player, dim, true);

    return player.playerNetServerHandler.playerEntity;
}

public static EntityPlayerMP forceTeleport(EntityPlayerMP player, int dim)
{
    MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
    int dimOld = player.dimension;
    WorldServer world = server.worldServerForDimension(dim);

    if (dim != player.dimension)
    {
        player = respawnPlayer(player, dim);

        FMLCommonHandler.instance().bus().post(new PlayerChangedDimensionEvent(player, dimOld, dim));
    }

    ChunkCoordinates spawn = world.getSpawnPoint();
    int var1 = 64;

    for (int x = spawn.posX - var1; x < spawn.posX + var1; ++x)
    {
        for (int z = spawn.posZ - var1; z < spawn.posZ + var1; ++z)
        {
            for (int y = world.getActualHeight() - 3; y > world.provider.getAverageGroundLevel(); --y)
            {
                if (world.isAirBlock(x, y, z) && world.isAirBlock(x, y + 1, z) &&
                    world.isAirBlock(x - 1, y, z) && world.isAirBlock(x - 1, y + 1, z) &&
                    world.isAirBlock(x + 1, y, z) && world.isAirBlock(x + 1, y + 1, z) &&
                    world.isAirBlock(x, y, z - 1) && world.isAirBlock(x, y + 1, z - 1) &&
                    world.isAirBlock(x, y, z + 1) && world.isAirBlock(x, y + 1, z + 1) &&
                    !world.getBlock(x, y - 1, z).getMaterial().isLiquid())
                {
                    while (world.isAirBlock(x, y - 1, z))
                    {
                        --y;
                    }

                    if (!world.getBlock(x, y - 1, z).getMaterial().isLiquid())
                    {
                        player.playerNetServerHandler.setPlayerLocation(x + 0.5D, y + 0.8D, z + 0.5D, player.rotationYaw, player.rotationPitch);
                        player.addExperienceLevel(0);

                        return player;
                    }
                }
            }
        }
    }

    return player;
}


respawnPlayerメソッドで実際にディメンションを移動させた後、forceTeleportで安全な場所を探しまわっています。

別のディメンションに手っ取り早く強制送還したいときに使ってます。
アバター
kegare
ID:e34c5163
レッドスト―ン掘り
 
記事: 678
登録日時: 2012年10月27日(土) 06:06

  • (PostNo.196352)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by kegare » 2014年9月28日(日) 20:15

上に同じくです。
エンティティのインスタンスをクラスから生成します。
エンティティ登録名とかいちいち指定するの面倒くさいので、特定のエンティティのインスタンスを生成シたいときはこれを使ってヤッてます。

コード: 全て選択
public static <T extends Entity> T createEntity(Class<T> clazz, World world)
{
    try
    {
        String name = String.valueOf(EntityList.classToStringMapping.get(clazz));

        if (name == null || name.length() <= 0)
        {
            return null;
        }

        Entity entity = EntityList.createEntityByName(name, world);

        if (entity == null || entity.getClass() != clazz)
        {
            return null;
        }

        return clazz.cast(entity);
    }
    catch (Exception e)
    {
        System.err.println("Failed to create entity: " + clazz.getSimpleName());
        e.printStackTrace();

        return null;
    }
}
アバター
kegare
ID:e34c5163
レッドスト―ン掘り
 
記事: 678
登録日時: 2012年10月27日(土) 06:06

  • (PostNo.199302)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by redolyr 75724 » 2014年10月18日(土) 15:06

NBTとHashMap管理でレシピを追加する

Forge Mod Loader Ver: 6.4.3.883
Minecraft Forge Ver: 9.11.0.883

ライセンス(?): 書き換えが無い場合、パッケージの移動を禁止します。

コード: 全て選択
package redolyr.library.minecraft;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import cpw.mods.fml.common.registry.GameRegistry;

/**
 *
 * Minecraft Version is: 1.6.4
 *
 * Licence: Don't replace of package.
 *
 * @author redolyr
 *
 */
public class CraftingNBTManager
{
   public static final CraftingNBTManager instance = new CraftingNBTManager();
   
   private CraftingNBTManager() {}
   
   public void writeRecipeToNBT(NBTTagCompound nbtTagCompound, Map<ItemStack, ItemStack[]> recipes)
   {
      NBTTagList nbtTagList = new NBTTagList();
      {
         NBTTagCompound nbtTagCompounds = new NBTTagCompound();
         ItemStack exportItemStack = null;
         ItemStack[] importItemStacks = new ItemStack[9];
         
         Iterator<ItemStack> itemStackIterator = recipes.keySet().iterator();
         while (itemStackIterator.hasNext())
         {
            exportItemStack = itemStackIterator.next();
            importItemStacks = recipes.get(exportItemStack);
         }
         
         NBTTagList importList = new NBTTagList();
         for (int len = 0; len < importItemStacks.length; ++len)
         {
            ItemStack itemStack = importItemStacks[len];
            if (itemStack != null) importList.appendTag(itemStack.writeToNBT(new NBTTagCompound()));
            else importList.appendTag(new NBTTagCompound());
         }
         nbtTagCompounds.setTag("Import", importList);
         nbtTagCompounds.setTag("Export", exportItemStack != null ? exportItemStack.writeToNBT(new NBTTagCompound()) : new NBTTagCompound());
         nbtTagList.appendTag(nbtTagCompounds);
      }
      nbtTagCompound.setTag("Recipes", nbtTagList);
   }
   
   public Map<ItemStack, ItemStack[]> readRecipeFromNBT(NBTTagCompound nbtTagCompound)
   {
      Map<ItemStack, ItemStack[]> recipes = new HashMap<ItemStack, ItemStack[]>();
      NBTTagList nbtTagList = nbtTagCompound.getTagList("Recipes");
      for (int count = 0; count < nbtTagList.tagCount(); ++count)
      {
         NBTTagCompound nbtTagCompounds = (NBTTagCompound) nbtTagList.tagAt(count);
         ItemStack[] recipeItemStacks = new ItemStack[9];
         NBTTagList importList = nbtTagCompounds.getTagList("Import");
         ItemStack exportItemStack = ItemStack.loadItemStackFromNBT((NBTTagCompound) nbtTagCompounds.getTag("Export"));
         for (int len = 0; len < importList.tagCount(); ++len) recipeItemStacks[len] = ItemStack.loadItemStackFromNBT((NBTTagCompound) importList.tagAt(len));
         recipes.put(exportItemStack, recipeItemStacks);
      }
      return recipes;
   }
   
   public void addRecipes(Map<ItemStack, ItemStack[]> recipes)
   {
      Iterator<ItemStack> itemStackIterator = recipes.keySet().iterator();
      while (itemStackIterator.hasNext())
      {
         ItemStack key = itemStackIterator.next();
         ItemStack[] value = recipes.get(key);
         String[] buffer = new String[3];
         buffer[0] = "abc".replace('a', value[0] == null ? ' ' : 'a').replace('b', value[1] == null ? ' ' : 'b').replace('c', value[2] == null ? ' ' : 'c');
         buffer[1] = "def".replace('d', value[3] == null ? ' ' : 'd').replace('e', value[4] == null ? ' ' : 'e').replace('f', value[5] == null ? ' ' : 'f');
         buffer[2] = "ghi".replace('g', value[6] == null ? ' ' : 'g').replace('h', value[7] == null ? ' ' : 'h').replace('i', value[8] == null ? ' ' : 'i');
         if (key != null && buffer[0] != "   " && buffer[1] != "   " && buffer[2] != "   ")
         {
            GameRegistry.addRecipe(key, new Object[] {
                  buffer[0],
                  buffer[1],
                  buffer[2],
                  'a', value[0],
                  'b', value[1],
                  'c', value[2],
                  'd', value[3],
                  'e', value[4],
                  'f', value[5],
                  'g', value[6],
                  'h', value[7],
                  'i', value[8]});
         }
      }
   }
}


例:
コード: 全て選択
NBTTagCompound nbtTagCompound = new NBTTagCompound();
Map<ItemStack, ItemStack[]> recipes = readRecipeFromNBT(nbtTagCompound);
recipes.put(new ItemStack(Item.ingotGold), new ItemStack[] {
   new ItemStack(Item.ingotIron), null, new ItemStack(Item.ingotIron),
   null, new ItemStack(Item.ingotIron), null,
   null, new ItemStack(Item.ingotIron), null
});
writeRecipeToNBT(nbtTagCompound);
addRecipes(recipes);
画像
MiningTools 公開中
1.7.2公開
トピック: MiningTools
Github: Source
アバター
redolyr 75724
ID:c7b00cd6
石掘り
 
記事: 70
登録日時: 2013年10月12日(土) 23:38

  • (PostNo.206186)

Forge による Server-side Mod のすすめ

投稿記事by GreenStone » 2014年12月04日(木) 18:33

Minecraft Forge を利用したサーバーサイドModがあまりにも少ないので。
コマンドの追加程度ならば、クライアント側への導入の必要のないModが作れます。

Forgeでは、Modの構成とサーバー側かクライアント側かという情報から、プレイヤーのログインをさせるさせないを決定する処理があります。
例として、ExampleMod.java がありますが、素の ExampleMod はサーバーに入れると、プレイヤーがログインできません。
そこで、メソッドを追加します。
コード: 全て選択
   @NetworkCheckHandler
   public boolean accept(Map<String, String>modList, Side side) {
      return true;
   }

意味は、『Modが入っているのがクライアント側かサーバー側かに関わらず、ExampleModはクライアントのログインを許可する』といった感じです。
ソースコード
ExampleMod.java
コード: 全て選択
package com.example.examplemod;

import 略

@Mod(modid = "examplemod", version = "1.0")
public class ExampleMod
{

   @EventHandler
   public void init(FMLInitializationEvent event) {}

   @NetworkCheckHandler
   public boolean accept(Map<String, String>modList, Side side) {
      return true;
   }
}

ExampleMod.scala (Scala版)
コード: 全て選択
package com.example.examplemod;

import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.network.NetworkCheckHandler;
import cpw.mods.fml.relauncher.Side;

@Mod(modid = "examplemod", version = "1.0")
class ExampleMod
{

  @EventHandler
  def init(event: FMLInitializationEvent): Unit = {}

  @NetworkCheckHandler
  def accept(modList: java.util.Map[String, String], side: Side): Boolean = true;
}


もっと広がれサーバーサイド、というわけで、参考にどうぞ。バージョン1.7以降です
サイン @Twitter / チャンクローダーコマンドMod / ComputerCraftサーバー

プログラミングに憑りつかれている一人のクラフター。あほかわいいタートルたちを愛でるために今日もサーバーを運営中。
   "Do not fold, spindle or mutilate"
GreenStone
ID:4fa3de10
木を殴ってる
 
記事: 14
登録日時: 2012年12月19日(水) 00:35

  • (PostNo.206226)

Scala による modding のすすめ with Eclipse

投稿記事by GreenStone » 2014年12月05日(金) 00:19

やってみたらできたので、手順を公開します。
  1. Scala IDE for Eclipse の導入
  2. Forge のセットアップ
    コード: 全て選択
    ./gradlew setupDecompWorkspace eclipse
  3. build.gradle, .project, .classpath の編集
    編集手順
    build.gradle
    apply plugin: 'forge' の前の行に apply plugin: 'scala'

    どこかの行に
    sourceSets.main.scala.srcDir "src/main/java"
    sourceSets.main.java.srcDirs = []

    .project
    <nature>org.eclipse.jdt.core.javanature</nature>とあるので、その前の行に<nature>org.scala-ide.sdt.core.scalanature</nature>
    <name>org.eclipse.jdt.core.javabuilder</name>とあるので、書き換え<name>org.scala-ide.sdt.core.scalabuilder</name>

    .classpath
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER" とあるので、その前の行に<classpathentry kind="con" path="org.scala-\
    ide.sdt.launching.SCALA_CONTAINER"/>

*nix, OS X の方向け
patch.sh
コード: 全て選択
#!/bin/sh
cat $0 | awk 'NR>=4 {print}' | ed -s
return $?
e .project
/<nature>/i
                <nature>org.scala-ide.sdt.core.scalanature</nature>
.
/<name>org.eclipse.jdt.core.javabuilder/c
                        <name>org.scala-ide.sdt.core.scalabuilder</name>
.
w
e .classpath
/JRE_CONTAINER/y
/JRE_CONTAINER/s/org\.eclipse\.jdt\.launching\.JRE_CONTAINER/org.scala-ide.sdt.launching.SCALA_CONTAINER/
x
w
e build.gradle
/apply plugin: 'forge'/i
apply plugin: 'scala'
.
//a

sourceSets.main.scala.srcDir "src/main/java"
sourceSets.main.java.srcDirs = []
.
wq
サイン @Twitter / チャンクローダーコマンドMod / ComputerCraftサーバー

プログラミングに憑りつかれている一人のクラフター。あほかわいいタートルたちを愛でるために今日もサーバーを運営中。
   "Do not fold, spindle or mutilate"
GreenStone
ID:4fa3de10
木を殴ってる
 
記事: 14
登録日時: 2012年12月19日(水) 00:35

  • (PostNo.226962)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by smn » 2015年4月11日(土) 14:22

「こりゃたまらん」
smn
ID:4c1ce306
木を殴ってる
 
記事: 24
登録日時: 2014年1月03日(金) 08:22

  • (PostNo.281455)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by gatya1129 » 2016年8月25日(木) 14:05

1.7.10の自分の環境で
コード: 全て選択
world.destroyBlock()
が使えなかったので代用品のメモを。

ライセンス?いらないです。
煮るなり焼くなり食べるなりしてください。

コード: 全て選択
world.func147480_a()
でできました。

なお、引数は以下のようになっています。
コード: 全て選択
第一引数:壊すブロックのx座標(int)
第二引数:   〃   y座標(int)
第三引数:   〃   z座標(int)
第四引数:壊したブロックをドロップさせるか(boolean)
modの公開をしています。
ProactiveMod他バージョン対応版、整地系ツール追加modなど)
また、簡単なmodの制作依頼も受け付けています。
よかったらどうぞ
Modding歴=Java歴<プログラム歴ッ!
gatya1129
ID:fa4b0917
石掘り
 
記事: 72
登録日時: 2015年2月21日(土) 21:01
お住まい: どこだと思う?ねえ、どこだと思う?

  • (PostNo.299175)

[1.7.10]EntityFallingBlockを破壊&入手できるように

投稿記事by 新人もっだー » 2017年3月29日(水) 15:12

備忘録。
1.7.10でのEntityFallingBlockの改良。ご自由に再利用ください。
*EntityFallingBreakableBlock.java
コード: 全て選択
import net.minecraft.block.Block;
import net.minecraft.entity.item.EntityFallingBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;

public class EntityFallingBreakableBlock extends EntityFallingBlock{

   public EntityFallingBreakableBlock(World world)
    { super(world); }

   public EntityFallingBreakableBlock(World world, double x, double y, double z, Block block)
   { super(world, x, y, z, block); }

   public EntityFallingBreakableBlock(World world, double x, double y, double z, Block block, int meta)
   { super(world, x, y, z, block, meta); }

   public boolean attackEntityFrom(DamageSource p_70097_1_, float p_70097_2_)
    {
      
      if(p_70097_1_.getEntity() == null)
         return false;
      
        if (!this.worldObj.isRemote && !this.isDead)
        {
            if(this.isEntityInvulnerable())//Mobからでないならreturn。
                return false;

            else if(!this.onGround)//二重取得防止(?)
            {

               this.setDead();
               this.entityDropItem(new ItemStack(this.func_145805_f(), 1, this.field_145814_a), 0);
               p_70097_1_.getEntity().playSound(this.func_145805_f().stepSound.getBreakSound(), this.func_145805_f().stepSound.getVolume(), this.func_145805_f().stepSound.getPitch());
                return true;
            }
            else
               return false;
        }
        else
            return true;
    }

}


*BlockFallingBreakable
コード: 全て選択
import java.util.Random;

import eggpower.entity.EntityFallingBreakableBlock;
import net.minecraft.block.BlockFalling;
import net.minecraft.block.material.Material;
import net.minecraft.world.World;

public class BlockFallingBreakable extends BlockFalling {

   public BlockFallingBreakable(Material material) {
      super(material);
   }

   @Override
   public void updateTick(World p_149674_1_, int p_149674_2_, int p_149674_3_, int p_149674_4_, Random p_149674_5_)
    {
        if (!p_149674_1_.isRemote)
            this.update(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_);
    }

    private void update(World p_149830_1_, int p_149830_2_, int p_149830_3_, int p_149830_4_)//privateの為、func_149830_mの再実装&EntityFallingBreakableBlockへの変更
    {
        if (func_149831_e(p_149830_1_, p_149830_2_, p_149830_3_ - 1, p_149830_4_) && p_149830_3_ >= 0)
        {
            byte b0 = 32;

            if (!fallInstantly && p_149830_1_.checkChunksExist(p_149830_2_ - b0, p_149830_3_ - b0, p_149830_4_ - b0, p_149830_2_ + b0, p_149830_3_ + b0, p_149830_4_ + b0))
            {
                if (!p_149830_1_.isRemote)
                {
                   EntityFallingBreakableBlock entityfallingblock = new EntityFallingBreakableBlock(p_149830_1_, (double)((float)p_149830_2_ + 0.5F), (double)((float)p_149830_3_ + 0.5F), (double)((float)p_149830_4_ + 0.5F), this, p_149830_1_.getBlockMetadata(p_149830_2_, p_149830_3_, p_149830_4_));
                    this.func_149829_a(entityfallingblock);
                    p_149830_1_.spawnEntityInWorld(entityfallingblock);
                }
            }
            else
            {
                p_149830_1_.setBlockToAir(p_149830_2_, p_149830_3_, p_149830_4_);

                while (func_149831_e(p_149830_1_, p_149830_2_, p_149830_3_ - 1, p_149830_4_) && p_149830_3_ > 0)
                {
                    --p_149830_3_;
                }

                if (p_149830_3_ > 0)
                {
                    p_149830_1_.setBlock(p_149830_2_, p_149830_3_, p_149830_4_, this);
                }
            }
        }
    }

   @Override
    public int tickRate(World p_149738_1_)
    {
        return 1;//落ちるのが早くなる。(気持ち程度)
    }

}
instance().instance().instance() = null;
アバター
新人もっだー
ID:f4092567
石掘り
 
記事: 131
登録日時: 2015年6月22日(月) 17:58

  • (PostNo.299419)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by zyando123 » 2017年4月01日(土) 00:25

InputStreamからテクスチャを生成するやつです。
GIFアニメーションも読み込めますが、アニメーションを進めるのが適当な作りなのでTextureAnimationのupdataらへんを改良してください。
ライセンスなどはないので煮るなり焼くなりどうぞ。

textureloader.zip
(3.14 KiB) ダウンロード数: 4 回


使用例(テクスチャのパスは拡張子判別とMapに登録することにしか使わないので、実際に存在しないパスでも問題ないです)
コード: 全て選択
ITexture texture = TextureLoader.instance.getTexture(inputStream, texturePath);
texture.bindTexture();
ろくな事を呟かないTwitterアカウント→@zyando79
アバター
zyando123
ID:c7117ea2
石掘り
 
記事: 92
登録日時: 2016年8月29日(月) 13:28

  • (PostNo.300119)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by zyando123 » 2017年4月08日(土) 15:50

.obj(WavefrontObject)形式のファイルを読み込み、VBOで描画するやつです。
利用条件などは一つ上のものと同じです。

source.zip
(4.62 KiB) ダウンロード数: 7 回
ろくな事を呟かないTwitterアカウント→@zyando79
アバター
zyando123
ID:c7117ea2
石掘り
 
記事: 92
登録日時: 2016年8月29日(月) 13:28

  • (PostNo.301729)

Re: [技術共有] トピックを立てるまでもないライブラリとかコードとかの公開所

投稿記事by MG36 » 2017年5月06日(土) 10:44

1.8から廃止されたAdvancedModelLoaderを1.10以降用に対応させたライブラリです。
インポート先をこちらのライブラリ内に指定すれば1.7.10と同じようにobjモデル等が読み込めます。

<使用方法>
1..zipを解凍する。
2.中のobjmodelフォルダを、開発環境/src/main/java内に配置する。
3.モデル使用時にライブラリ内のAdvancedModelLoaderおよびIModelCustom等をインポートして使用する。
添付ファイル
AdvancedModelLoader-1.10.2.zip
(15.46 KiB) ダウンロード数: 8 回
AdvancedModelLoader-1.11.2.zip
(15.46 KiB) ダウンロード数: 5 回
だれか時間をください
MG36
ID:c5159f94
金掘り
 
記事: 391
登録日時: 2013年8月13日(火) 19:58

  • (PostNo.306174)

spigot-api:1.11.2-R0.1-SNAPSHOTのPlayerInteractEventでハマった

投稿記事by tsuttsu305 » 2017年8月12日(土) 00:55

4年ぐらい前に作ったBukkitPluginをSpigot用に書き直したときにハマったメモ

PlayerInteractEventを使うときにメインのHANDと反対のHANDの二回Eventが呼ばれる…

ブロックを右クリックした時になんかしたいときのEventHandlerの書き方メモ…
コード: 全て選択
@EventHandler
    public void onPlayerRightClick(PlayerInteractEvent event) {
        if (event.getHand() != EquipmentSlot.HAND) return;
        if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
    }


アバター
tsuttsu305
ID:bee4b613
ダイヤモンド掘り
 
記事: 751
登録日時: 2011年10月18日(火) 17:49
お住まい: CloudFormationで建てたスタック

1つ前へ

Return to 開発関連

x