Jump to content

[Solved but weird] TileEntity Client and Server doing unsynchronized stuff


Xerus

Recommended Posts

Problem 1 is solved: In short, i needed to send Server information to the client while i had an Container open - A quick look into ContainerFurnace showed the solution, using detectAndSendChanges()

 

I have a tileentity that uses fuel to plant plants. how much fuel it has in it is displayed in a gui, that is obviously a client thing. update() gets called on both client and server, but since it only uses fuel and plants if there is space, sometimes the client uses fuel(I would conclude when it is called first) and the server too and sometimes only the server uses fuel. this then makes the gui display the wrong, client-side information.

 

 

After implementing this, a new problem occured. Go 2 posts down to look at it.

 

Ok I now solved the issue by simply introducing a new value for the gui and only changing it if the values from the tileentity for lastfuel and fuel are different:

    int lastfuel;
    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
    	if(te.getField(1)!=te.getField(0))
    		lastfuel=te.getField(1);
        ...
    }

still wondering how the problem occured tho

Link to comment
Share on other sites

Ok well now I implemented this into my container:

 

private int fuel;
private int lastfuelvalue;
    public void detectAndSendChanges(){
        super.detectAndSendChanges();
        for (int i = 0; i<this.listeners.size(); ++i) {
            IContainerListener listener = (IContainerListener)this.listeners.get(i);
            if (this.fuel!=this.te.getField(0)){
            	listener.sendProgressBarUpdate(this, 0, this.te.getField(0));
            }
            if (this.lastfuelvalue!=this.te.getField(1)){
            	listener.sendProgressBarUpdate(this, 1, this.te.getField(1));
            }
        }
        this.fuel=this.te.getField(0);
        this.lastfuelvalue=this.te.getField(1);
    }
    @SideOnly(Side.CLIENT)
    public void updateProgressBar(int id, int data){
        this.te.setField(id, data);
    }

 

 

the really weird thing is, when the variable in field 0(fuel) changes and the gui is open, it kinda sets lastfuelvalue to fuel(what I dont want), but when i reopen the gui the packet is send again and it gets displayed correct. maybe i didnt explain it good but I just dont understand what mc is doing here...

lemme show pictures:

2016-08-14.png

normal gui(fuel value in top left only for debug)

2016-08-141.png

after it used fuel while keeping the gui open

2016-08-142.png

after reopening the gui

 

just want to remind: this ONLY happened after i added all this listening stuff!

 

Link to comment
Share on other sites

You also need to add

public void addListener(IContainerListener listener) {
     super.addListeners(listener);
     listener.sendAllWindowProperties(this, tileEntity);
}

to your containers class.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

get/setfield:

 

	
@Override
public int getField(int id) {
	switch (id){
	case 0: return this.fuel;
	case 1: return this.lastfuel;
	}
	return 0;
}
@Override
public void setField(int id, int value) {
	switch (id){
	case 0: fuel=value;
	case 1: lastfuel=value;
	}
}

 

@Animefan I already had it but it changed nothing. Do you even know what i does?

Link to comment
Share on other sites

get/setfield:

@Animefan I already had it but it changed nothing. Do you even know what i does?

I believe it sends all of the properties aka the fields from server to client.

Did you return 2 on getFieldCount?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

it is actually this but i thought it is unnecessary:

 

@Override
public int getField(int id) {
	switch (id){
	case 0: return this.fuel;
	case 1: return this.lastfuel;
	case 2: return this.yoffset;
	case 3: return this.actualslots;
	}
	return 0;
}
@Override
public void setField(int id, int value) {
	switch (id){
	case 0: fuel=value;
	case 1: lastfuel=value;
	case 2: yoffset=value;
	}
}

@Override
public int getFieldCount() {
	return 4;
}

 

Link to comment
Share on other sites

Always post all of the code even if you think it unnecessary. Was that all of the code in your container?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

apart from the constructor, yes

if you want it:

 

private IInventory te;

    public FarmerContainer(IInventory playerInv, IInventory te) {
        this.te = te;
        //Farmer-Inventar
        this.addSlotToContainer(new CustomSlot(te, 0, 26, 45));
        int xslots=te.getField(te.getFieldCount()-1);
        for (int y = 0; y < 2; ++y) {
            for (int x = 0; x < xslots; ++x) {
                this.addSlotToContainer(new CustomSlot(te, x + y * xslots + 1, 62 + x * 18, 45 - y * 21));
            }
        }
        //Player-Inventar
        for (int y = 0; y < 3; ++y) {
            for (int x = 0; x < 9; ++x) {
                this.addSlotToContainer(new Slot(playerInv, x + y * 9 + 9, 8 + x * 18, 84 + y * 18));
            }
        }
        for (int x = 0; x < 9; ++x) {
            this.addSlotToContainer(new Slot(playerInv, x, 8 + x * 18, 142));
        }
    }

 

nothing fancy

Link to comment
Share on other sites

Well you definitely could, but using the in place system is easier. And I assume it would be more internet intensive. Give me a minute to look at the code...

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

Here you go:

public class FarmerTE extends TEInventory implements ITickable,ISidedInventory {
    
int fuel;
    int lastfuel;
    int yoffset;
    private static int rowslots=5;

    public FarmerTE() {
        super("farmer",rowslots*2+1,new String[]{"fuel","lastfuel","yoffset"});
        fuel=0;
        lastfuel=1;
        yoffset=-1;
    }

private int delay=2;
@Override
    public void update(){
	if(worldObj.isRemote)
		return;
	if(delay>0){
		delay--;
		return;
	}
	delay=5;
	BlockPos position=nextpos();
	Block b=util.blockat(worldObj,position);
	if(b!=null){
		// entferne hohes Gras
		if(util.blockat(worldObj, position.up()).equals(Blocks.TALLGRASS)) worldObj.setBlockState(position.up(),Blocks.AIR.getDefaultState());
		// erde zu farmland
		if((b.equals(Blocks.DIRT)||b.equals(Blocks.GRASS))&&util.blockat(worldObj, position.up()).equals(Blocks.AIR)&&useFuel()){
			worldObj.playSound(null, position, SoundEvents.ITEM_HOE_TILL, SoundCategory.BLOCKS, 1.0F, 1.0F);
			if(!worldObj.isRemote) worldObj.setBlockState(position, Blocks.FARMLAND.getDefaultState(), 11);
		}
		// pflanzen/ernten
		Block s=util.blockat(worldObj,position.up());
		if(s.equals(Blocks.AIR)){
			plant(position);
		} else if(s instanceof BlockCrops){
			if(((BlockCrops)s).isMaxAge(worldObj.getBlockState(position.up()))&&useFuel()) harvest(position,s);
		} else if(s instanceof BlockNetherWart){
			if(worldObj.getBlockState(position.up()).getValue(BlockNetherWart.AGE).intValue()>=3&&useFuel()) harvest(position,s);
		}
	}
    }

private void plant(BlockPos position){
	for(int slot=1;slot<rowslots+1;slot++){
		ItemStack stack=this.getStackInSlot(slot);
		if(stack!=null&&isplantable(stack)){
			IPlantable item=(IPlantable)stack.getItem();		if(util.blockat(worldObj,position).canSustainPlant(worldObj.getBlockState(position),worldObj,position,EnumFacing.UP,item)&&useFuel()){
			    worldObj.setBlockState(position.up(),item.getPlant(null, null));
		    	decrStackSize(slot,1);
		    	return;
			}
		}
	}
}

private void harvest(BlockPos position,Block plant){
	java.util.List<ItemStack> items=plant.getDrops(worldObj, position.up(), worldObj.getBlockState(position.up()), 0);
        for(ItemStack stack : items){
        	int start=rowslots+1;
        	if(isplantable(stack))
        		start=1;
        	for(int slot=start;slot<getSizeInventory();slot++){
        		ItemStack content=getStackInSlot(slot);
        		if(content==null){
        			setInventorySlotContents(slot,stack);
        			break;
        		} else if(content.getItem().equals(stack.getItem())){
        			if(content.stackSize+stack.stackSize<=64){
        				content.stackSize+=stack.stackSize;
        				setInventorySlotContents(slot,content);
        				break;
        			} else {
        				stack.stackSize-=64-content.stackSize;
        				content.stackSize=64;
        				setInventorySlotContents(slot,content);
        			}
        		}
        	}
        }
    	worldObj.setBlockToAir(position.up());
    	plant(position);
}

private boolean isplantable(ItemStack stack){
	return stack.getItem() instanceof IPlantable;
}

private boolean useFuel(){
	int fuelPerOperation=50;
	if(fuel<fuelPerOperation){
		if(getStackInSlot(0)!=null&&TileEntityFurnace.isItemFuel(getStackInSlot(0))){
			lastfuel=TileEntityFurnace.getItemBurnTime(getStackInSlot(0));
			fuel+=lastfuel;
			decrStackSize(0,1);
		}
	}
	if(fuel>=fuelPerOperation){
		fuel-=fuelPerOperation;
		return true;
	}
	return false;
}

private int[][] get=new int[][]{{-1,-1,-1,0,1,1,1,0},{-1,0,1,1,1,0,-1,-1}};
private int currentblock=0;
private BlockPos nextpos(){
	if(currentblock==7) currentblock=0;
	else currentblock++;
	return pos.add(get[0][currentblock],0-yoffset,get[1][currentblock]);
}

@Override
public boolean isItemValidForSlot(int index, ItemStack stack) {
	if(index==0&&TileEntityFurnace.isItemFuel(stack))
		return true;
	if(index>0&&index<rowslots+1&&isplantable(stack))
		return true;
	return false;
}

@Override
public boolean canInsertItem(int index, ItemStack stack, EnumFacing direction) {
	return isItemValidForSlot(index, stack);
}
@Override
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction) {
	if(index>rowslots)
		return true;
	return false;
}

@Override
public int[] getSlotsForFace(EnumFacing side) {
	return new int[]{0,1,2,3,4,5,6,7,8,9,10};
}

@Override
public int getField(int id) {
	switch (id){
	case 0: return this.fuel;
	case 1: return this.lastfuel;
	case 2: return this.yoffset;
	case 3: return this.rowslots;
	}
	throw new RuntimeException("field "+id+" not found");
}
@Override
public void setField(int id, int value) {
	switch (id){
	case 0: fuel=value;
	case 1: lastfuel=value;
	case 2: yoffset=value;
	}
}

@Override
public int getFieldCount() {
	return 4;
}

}

Link to comment
Share on other sites

I'm not sure if I understand the current problem, but is it that the current fuel can be greater than lastFuel? If so the problem is

 

			lastfuel=TileEntityFurnace.getItemBurnTime(getStackInSlot(0));
			fuel+=lastfuel;

 

If not please explain it to me.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

and it cant be the problem since update() only performs on server side since I check for worldObj.isRemote

Well if it only updates server side then we send the data to the client...The client has the same data.

 

Well could you explain the problem.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

yes i am

just for completeness my gui class:

public class FarmerGui extends BaseGui {

    public FarmerGui(IInventory playerInv, TEInventory te) {
    	super(new FarmerContainer(playerInv, te), playerInv, te);
    }

    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
        drawBackgroundImage("farmer");
        // fuel blueprint
    if(te.getStackInSlot(0)==null)
    	this.drawRect(26, 45, 176, 0, 16, 16);
    // seeds blueprint
        for(int i=1;i-1<te.getField(te.getFieldCount()-1);i++)
        	if(te.getStackInSlot(i)==null)
        		this.drawRect(44+18*i, 45, 176, 16, 16, 16);
        // progress bar
        int progress=te.getField(0)>0?12-(te.getField(0)*12/te.getField(1)):14;
        this.drawRect(26, 28+progress, 176, 32+progress, 14, 14-progress);
    }
    
    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
    	super.drawGuiContainerForegroundLayer(mouseX, mouseY);
    	// temporary debug output
    	drawString("Fuel: "+te.getField(0)+"/"+te.getField(1), 2, 2);
    }
    
}

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • 东京都酒吧招聘广告↑BCGAME55·COM◎东京都酒吧Kakao Talk真实东京都酒吧地图棒球酒吧地址菜马酒吧广播[本社的Tele @JBOX7] 东京都酒吧度假村掷铁饼 东京都酒吧系统跆拳道酒吧链接[总经销的Kakao Talk JBOX7] 东京都酒店链接阿尔法-东京都酒店酒店单角球馆制作单角球杆公寓[Talk Talk Talk Talk Talk Talk] 聚会信息 [赌场总公司] 东京都丹兰酒馆位置滑雪 东京都丹兰酒馆Youtube柔道丹兰酒馆推荐 拳击丹兰酒馆地图 [体育总公司] 东京都丹兰酒馆 影像乒乓球 东京都丹兰酒馆 Youtube Pickle Ball 丹兰酒馆Line[TOTO总公司咨询] 东京都丹兰酒馆故事马拉松比赛东京都验证藤球单板滑雪 [TOTOTO总店购买单板滑雪] DANTACTALKTALKTALKSETALKTALKETALKETALKETALKYOOKSATINGOOK YouTube自行车短跑酒吧验证排球短跑酒吧位置[百家乐总经销]东京短跑酒吧广播击剑东京短跑酒吧视频掷铁饼短跑酒吧广播E体育短跑酒吧社区[赛马总经销] 东京短跑酒吧总经销调整短跑酒吧联谊会硬地滚滚酒庄店业所招募[BCGAME BC游戏总经销咨询] 设置通知 订阅 点赞
    • 国内チャンピオンリーグツアー▥BCGAME33·COM■BCGAMEカジノチャンピオンリーグサイト国内ベラジオカジノチャンピオンリーグ接続[本社お問い合わせテレJBOX7]国内チャンピオンリーグ=▧サイトタジキスタンチャンピオンリーググループチャットルーム国内ウクライナ国内チャンピオンリーグアドレス[総販お問い合わせカカオトークJBOX7]国内チャンピオンリーグ♨↗キャッシュゲームパキスタンチャンピオンリーグ接続国内ウルグアイ国内チャンピオンシップユーチューブ[各種オフィコミュニティ制作]韓国チャンピオンズリーグ※ºユーチューブセントルシアチャンピオンズツアー韓国ハイチ韓国内チャンピオンシップ検証[マーケティングに関するお問い合わせ]韓国チャンピオンシップ◑↘募集ベリーズチャンピオンシップメーカー 北マケドニアチャンピオンリーグ本社 国内西アジア国内チャンピオンリーグカジノパブ [スポーツ本社]国内チャンピオンリーグ▽♡映像西アフリカチャンピオンリーグキャッシュゲーム国内クウェート国内チャンピオンリーグ接続 [ト本社お問い合わせ]国内チャンピオンリーグ↖↖住所ガイアナチャンピオンリーグ推薦国内ジブチ国内チャンピオンリーグユーチューブ[トト総販売]韓国チャンピオンシップ ▧▒本社サンマリノチャンピオンシップグループトーク 国内ブルキナファソ 国内チャンピオンシップ グループトーク [カジノ総販] 国内チャンピオンシップ ▽♥ 方法 チャドチャンピオンシップ バカラパブ 韓国チリ国内チャンピオンシップサイト [大和本社] 韓国チャンピオンシップサイト ポーカー大会 西アジアチャンピオンリーグ接続 国内ウィンカジノ 国内チャンピオンリーグ放送 [競馬総販]バチカン時局チャンピオンリーグサイト デンマークチャンピオンリーグサイト [BCGAMEBCゲーム総販お問い合わせ] お知らせ設定おすすめ購読いいですね
    • Chiba寄宿家庭地图㏇BCGAME55·COM☞Chiba寄宿家庭影像 美式足球 chiba寄宿家庭故事 庭具 chiba寄宿家庭广告 推特 寄宿家庭广告 排球chiba寄宿家庭 摔跤度假村寄宿家庭社区 JBOX7] Chiba寄宿家庭社区 JBOX7推荐自行车FFree社区1 在短道速滑宿舍TikTalk[总经销文的kakaKakao Talk JBOX7] 故事平均对齐巴寄宿家庭广播跳马寄宿家庭广播扔标枪寄宿家庭故事[体育总公司] 齐巴寄宿家庭视频壁球 齐巴寄宿家庭地图排球寄宿家庭羽毛球寄宿家庭系列[TOTO总公司咨询] 齐巴寄宿家庭巡回摔跤 齐巴宿舍儿童 功夫宿舍招聘广告 短道速滑 宿舍 Kakao Talk [购买托托托总经销] 齐巴宿舍系统 Real Chiba地址八种牛膝下宿舍运动推荐下榻酒店运动[Technology] 滑雪寄宿家庭住址水上运动寄宿家庭旅行[赛马总经销] 千叶寄宿家庭新住址 E体育 千叶寄宿家庭网站 摔跤寄宿家庭 功夫寄宿家庭验证[BCGAME BC游戏总经销咨询] 设置通知 推荐 订阅 点赞
    • 海外グラフ募集←BCGAME33·COM▒ジョージアグラフ映像海外インドグラフおすすめ【本社お問い合わせテレJBOX7】海外グラフ☎▷ホールダンバドミニカグラフメーカー海外ギニア海外グラフ映像[総販お問い合わせカカオトークJBOX7]海外グラフ♤#グループトークケニアグラフ遊び場海外サウジアラビア海外グラフホールダンパブ[各種オフィコミュニティ制作] 海外グラフ▣▨募集カーボベルデグラフ検証 海外ソマリア 海外グラフ旅行[マーケティングお問い合わせ] 海外グラフ♤☜住所ブルネイグラフポーカー大会 海外アルゼンチン 海外グラフ募集[カジノ本社] 海外グラフ# 海外パレットコミュニティ本社 京畿モザンビークグラフ グループトーク 海外南アジア 海外グラフ放送 [ト本社お問い合わせ] 海外グラフ § 募集南アジアグラフ ホールダンバー 海外バハマ 海外グラフ クープーン [ト総販購入] 海外グラフ ▷住所 エジプトグラフ ゲーム場 海外東南アジア海外グラフ旅行 [カジノ総販] 海外グラフ ▲▧ゲーム場 バングラデシュグラフ賭博場海外ヘルツェゴビナ海外グラフサイト[ヤマト本社]海外グラフゲーム場海外アラブ首長国連邦海外グラフゲーム場 [バカラ総販]海外グラフ △↙本社 コンゴ民主主義 コミュニティ海外コンゴビコンゴ旅行 設定おすすめ購読いいですね
    • 浦和单身妈妈故事℡BCGAME55·COM◇浦和单身妈妈旅行格斗浦和单身妈妈指导台球单身妈妈系统跆拳道单身妈妈Kakao Talk[本社文之电讯@JBOX7]浦和单身妈妈位置定具浦和单身妈妈总经销摔跤单身妈妈聚会信息滑雪单人妈联谊会[总经销文之Kakao Talk JBOWN] 浦和单人妈位置定具广告巡回赛[浦和拳击广告] 乌拉瓦单身妈妈推荐的足球单身妈妈Instagram E体育单身妈妈Kakao Talk [体育总公司]乌拉瓦单身妈妈招聘广告 篮球乌拉瓦单身妈妈Instagram 跆拳道单身妈妈总经销 匹克球 单身妈妈故事[TOTO总公司咨询]乌拉瓦单身妈妈推特举重乌拉瓦单身母亲推荐 扔铅球 单打游戏 野洞 Nordic Single Mom YouTube[TOTOTO总经总经销 购买]乌拉瓦单身母亲系统篮球乌拉瓦做标枪弹射枪,验证,橄榄球运动。 LINE柔道Urawa单身妈妈地址足球单身妈妈度假村摔跤单身妈妈最新地址[赛马总经销]Urawa单身妈妈LINE F1大奖赛Urawa单身妈妈巡回赛 单身妈妈巡回赛 跳马单身妈妈营业招集[BCGAME BC游戏总经销咨询] 设置通知 推荐 订阅 点赞
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.