Jump to content

[1.8] Multi-layer block model


xilef11

Recommended Posts

Hello

 

I have blocks with a texture composed of a background and a foreground layer, both of which can be of any color. The colors are static for each block, but they are "discovered" on initialisation (i.e in preInit()), and unknown at compile time.

 

I have been told this could be achieved with either the "tintindex" field of the json models, or with a custom baked model, however, I can't figure out how to use either of those :(

 

I also thought I could generate and save the textures to disk on the first run, but I'm not too sure how to integrate the external folder in the json models

 

Link to comment
Share on other sites

Hi

 

Some examples of these

Some info on the tint index

http://greyminecraftcoder.blogspot.com.au/2014/12/block-models-18.html

using Block.colorMultiplier()

 

Alternatively, this tutorial project shows how you can bake your own models with custom faces / face colours

https://github.com/TheGreyGhost/MinecraftByExample

(see MBE04, MBE05 for block model generation and MBE15 for how to generate quads)

 

-TGG

Link to comment
Share on other sites

Thanks, I had seen those already (and the example on the TESR has been quite useful), but I don't seem to be able to understand how to put it together to do what I want...

 

My biggest issue is probably because my models don't need to be "smart" (they're static for each block), they just need to be generated on startup

Link to comment
Share on other sites

Hi

 

The key bits to put together are:

- the loading methods in MBE04 or MBE05 which are used to insert your model into the registry.  Your model can be just an IBakedModel, it doesn't have to be smart.

- your IBakedModel class should return the custom quads for your model in getGeneralQuads in MBE15.

 

-TGG

 

 

Link to comment
Share on other sites

Hi

 

If you're using arbitrary colours, then yes you will.  If you want, you could copy the face information from the loaded json model and overwrite just the colour ints in the int[], leaving the x,y,z, u,v information unchanged.

 

-TGG

 

  /**
   * Converts the vertex information to the int array format expected by BakedQuads.
   * @param x x coordinate
   * @param y y coordinate
   * @param z z coordinate
   * @param color RGBA colour format - white for no effect, non-white to tint the face with the specified colour
   * @param texture the texture to use for the face
   * @param u u-coordinate of the texture (0 - 16) corresponding to [x,y,z]
   * @param v v-coordinate of the texture (0 - 16) corresponding to [x,y,z]
   * @return
   */
  private int[] vertexToInts(float x, float y, float z, int color, TextureAtlasSprite texture, float u, float v)
  {
    return new int[] {
            Float.floatToRawIntBits(x),
            Float.floatToRawIntBits(y),
            Float.floatToRawIntBits(z),
            color,
            Float.floatToRawIntBits(texture.getInterpolatedU(u)),
            Float.floatToRawIntBits(texture.getInterpolatedV(v)),
            0
    };
  }

Link to comment
Share on other sites

Also you can use some IModel implementation for that.

It allows to render multiple IBakedModel-form models.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

  • 2 weeks later...

1. You should wrap the existing model.

  First just set all methods return the result of same method in existing model.

  Then change some methods in your needs

2. You can change the tint value when quads are baked.

  You can first get the quads from existing model's getGeneralQuads, and change the tint, after that return that in your own getGeneralQuads.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

thing is, I don't have an existing modelfor this block...

 

You know what TGG said earlier about copying the code from the .JSON to generate the quads yourself? First, make a regular block model in .JSON and register it normally. Then, wrap it in the IBakedModel type to change the color or do whatever you need. Do this in the ModelBakeEvent.

Development of Plugins [2012 - 2014] Development of Mods [2012 - Current]

Link to comment
Share on other sites

So I managed to get the models to load (they render as dirt when returning the sane thing as dirt in all methods), but when I try to make the BakedQuads I get an IndexOutOfBoundsException

 

Model class:

/** Runes of Wizardry Mod for Minecraft
*  Licensed under the GNU GPL version 3
*  
*  this file was created by Xilef11 on 2015-09-06
*/
package com.zpig333.runesofwizardry.client.model;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javafx.scene.shape.VertexFormat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.FaceBakery;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;

import org.apache.commons.lang3.ArrayUtils;

import com.zpig333.runesofwizardry.api.IDustStorageBlock;
import com.zpig333.runesofwizardry.client.TextureStitchEventHandler;
import com.zpig333.runesofwizardry.core.References;
import com.zpig333.runesofwizardry.core.WizardryLogger;

/**
* @author Xilef11
*
*/
public class ModelDustStorage implements IBakedModel {
private static Map<String,ModelResourceLocation> resourceMap = new HashMap<String, ModelResourceLocation>();
private IDustStorageBlock block;
private int meta;
private int bgColor,fgColor;
// create a tag (ModelResourceLocation) for our model.
  public final ModelResourceLocation modelResourceLocation;

  public ModelDustStorage(IDustStorageBlock block, int meta) {
	WizardryLogger.logInfo("Creating model for block: "+block.getName()+" "+meta);
	this.block=block;
	this.meta=meta;
	this.modelResourceLocation = new ModelResourceLocation(getModelResourceLocationPath(block,meta));
	this.bgColor = block.getIDust().getPrimaryColor(new ItemStack(block.getIDust(),1,meta));
	this.fgColor = block.getIDust().getSecondaryColor(new ItemStack(block.getIDust(),1,meta));
}
public static String getModelResourceLocationPath(IDustStorageBlock block, int meta){
	return References.texture_path+block.getName()+"_"+meta;
}
public static ModelResourceLocation getModelResourceLocation(String path){
	ModelResourceLocation current = resourceMap.get(path);
    if(current==null){
    	current=new ModelResourceLocation(path);
    	resourceMap.put(path, current);
    }
    return current;
}
public static ModelResourceLocation getModelResourceLocation(IDustStorageBlock block, int meta){
	return getModelResourceLocation(getModelResourceLocationPath(block, meta));
}

/* (non-Javadoc)
 * @see net.minecraft.client.resources.model.IBakedModel#getFaceQuads(net.minecraft.util.EnumFacing)
 */
@Override
public List getFaceQuads(EnumFacing face) {
	List r = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelForState(Blocks.dirt.getDefaultState()).getFaceQuads(face);
	List<BakedQuad> result = new LinkedList<BakedQuad>();
	int[] bg =null;
	int[] fg = null;
	TextureAtlasSprite bgTex = TextureStitchEventHandler.getDustStorageBG();
	TextureAtlasSprite fgTex = TextureStitchEventHandler.getDustStorageFG();
	//looks like a bakedquad is a full square, and we have to pass it all its vertices in the int array...
	//also, tintindex should be -1
	//FIXME no more crash, but rendering is broken again
	//Feels like the ints are not in the right order...
	if(face==EnumFacing.EAST){
		//BG color
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 0, 0, bgColor, bgTex, 16, 16));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 1, 0, bgColor, bgTex, 16, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 1, 1, bgColor, bgTex, 0, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 0, 1, bgColor, bgTex, 0, 16));
		//fg
		fg = ArrayUtils.addAll(fg, vertexToInts(1.001F, 0, 0, fgColor, fgTex, 16, 16));
		fg = ArrayUtils.addAll(fg, vertexToInts(1.001F, 1, 0, fgColor, fgTex, 16, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(1.001F, 1, 1, fgColor, fgTex, 0, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(1.001F, 0, 1, fgColor, fgTex, 0, 16));
	}else if(face==EnumFacing.WEST){
		//BG color
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 0, 1, bgColor, bgTex, 16, 16));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 1, 1, bgColor, bgTex, 16, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 1, 0, bgColor, bgTex, 0, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 0, 0, bgColor, bgTex, 0, 16));
		//fg
		fg = ArrayUtils.addAll(fg, vertexToInts(-0.001F, 0, 1, fgColor, fgTex, 16, 16));
		fg = ArrayUtils.addAll(fg, vertexToInts(-0.001F, 1, 1, fgColor, fgTex, 16, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(-0.001F, 1, 0, fgColor, fgTex, 0, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(-0.001F, 0, 0, fgColor, fgTex, 0, 16));
	}else if(face==EnumFacing.NORTH){
		//BG color
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 0, 0, bgColor, bgTex, 16, 16));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 1, 0, bgColor, bgTex, 16, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 1, 0, bgColor, bgTex, 0, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 0, 0, bgColor, bgTex, 0, 16));
		//fg
		fg = ArrayUtils.addAll(fg, vertexToInts(0, 0, -0.001F, fgColor, fgTex, 16, 16));
		fg = ArrayUtils.addAll(fg, vertexToInts(0, 1, -0.001F, fgColor, fgTex, 16, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(1, 1, -0.001F, fgColor, fgTex, 0, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(1, 0, -0.001F, fgColor, fgTex, 0, 16));
	}else if(face==EnumFacing.SOUTH){
		//BG color
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 0, 1, bgColor, bgTex, 16, 16));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 1, 1, bgColor, bgTex, 16, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 1, 1, bgColor, bgTex, 0, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 0, 1, bgColor, bgTex, 0, 16));
		//fg
		fg = ArrayUtils.addAll(fg, vertexToInts(1, 0, 1.001F, fgColor, fgTex, 16, 16));
		fg = ArrayUtils.addAll(fg, vertexToInts(1, 1, 1.001F, fgColor, fgTex, 16, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(0, 1, 1.001F, fgColor, fgTex, 0, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(0, 0, 1.001F, fgColor, fgTex, 0, 16));
	}else if(face==EnumFacing.DOWN){
		//BG color
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 0, 0, bgColor, bgTex, 16, 16));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 0, 1, bgColor, bgTex, 16, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 0, 1, bgColor, bgTex, 0, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 0, 0, bgColor, bgTex, 0, 16));
		//fg
		fg = ArrayUtils.addAll(fg, vertexToInts(1,-0.001F,0, fgColor, fgTex, 16, 16));
		fg = ArrayUtils.addAll(fg, vertexToInts(1,-0.001F,1, fgColor, fgTex, 16, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(0, -0.001F,1, fgColor, fgTex, 0, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(0, -0.001F,0, fgColor, fgTex, 0, 16));
	}else if(face==EnumFacing.UP){
		//BG color
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 1, 1, bgColor, bgTex, 16, 16));
		bg = ArrayUtils.addAll(bg, vertexToInts(1, 1, 0, bgColor, bgTex, 16, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 1, 0, bgColor, bgTex, 0, 0));
		bg = ArrayUtils.addAll(bg, vertexToInts(0, 1, 1, bgColor, bgTex, 0, 16));
		//fg
		fg = ArrayUtils.addAll(fg, vertexToInts(1,1.001F,1, fgColor, fgTex, 16, 16));
		fg = ArrayUtils.addAll(fg, vertexToInts(1,1.001F,0, fgColor, fgTex, 16, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(0, 1.001F,0, fgColor, fgTex, 0, 0));
		fg = ArrayUtils.addAll(fg, vertexToInts(0, 1.001F,1, fgColor, fgTex, 0, 16));
	}else{
		throw new IllegalArgumentException("Wrong EnumFacing: "+face);//is that even possible...
	}
	//int[] test = ArrayUtils.addAll(new int[]{1,2,3,4},new int[]{5,6,7,8});
	result.add(new BakedQuad(bg, -1, face));
	result.add(new BakedQuad(fg, -1, face));
	return result;
	// TODO Auto-generated method stub
}

/* (non-Javadoc)
 * @see net.minecraft.client.resources.model.IBakedModel#getGeneralQuads()
 */
@Override
public List getGeneralQuads() {
	List<BakedQuad> res = new LinkedList<BakedQuad>();
	for(EnumFacing face : EnumFacing.VALUES){
		res.addAll(getFaceQuads(face));
	}
	//return res;
	// TODO Auto-generated method stub
	List r = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelForState(Blocks.dirt.getDefaultState()).getGeneralQuads();
	return r;
}

/* (non-Javadoc)
 * @see net.minecraft.client.resources.model.IBakedModel#isAmbientOcclusion()
 */
@Override
public boolean isAmbientOcclusion() {
	//return true;
	return false;
}

/* (non-Javadoc)
 * @see net.minecraft.client.resources.model.IBakedModel#isGui3d()
 */
@Override
public boolean isGui3d() {
	return true;
}

/* (non-Javadoc)
 * @see net.minecraft.client.resources.model.IBakedModel#isBuiltInRenderer()
 */
@Override
public boolean isBuiltInRenderer() {
	return false;
}

/* (non-Javadoc)
 * @see net.minecraft.client.resources.model.IBakedModel#getTexture()
 */
@Override
public TextureAtlasSprite getTexture() {
	//TODO getTexture might need to get tweaked
	return TextureStitchEventHandler.getDustStorageBG();
}

/* (non-Javadoc)
 * @see net.minecraft.client.resources.model.IBakedModel#getItemCameraTransforms()
 */
@Override
public ItemCameraTransforms getItemCameraTransforms() {
	return ItemCameraTransforms.DEFAULT;
}

  /**
   * Converts the vertex information to the int array format expected by BakedQuads.
   * @param x x coordinate
   * @param y y coordinate
   * @param z z coordinate
   * @param color RGBA colour format - white for no effect, non-white to tint the face with the specified colour
   * @param texture the texture to use for the face
   * @param u u-coordinate of the texture (0 - 16) corresponding to [x,y,z]
   * @param v v-coordinate of the texture (0 - 16) corresponding to [x,y,z]
   * @return
   */
  private static int[] vertexToInts(float x, float y, float z, int color, TextureAtlasSprite texture, float u, float v)
  {
    return new int[] {
            Float.floatToRawIntBits(x),
            Float.floatToRawIntBits(y),
            Float.floatToRawIntBits(z),
            color,
            Float.floatToRawIntBits(texture.getInterpolatedU(u)),
            Float.floatToRawIntBits(texture.getInterpolatedV(v)),
            0
    };
  }


}

 

ModelBake Event Handler

/** Runes of Wizardry Mod for Minecraft
*  Licensed under the GNU GPL version 3
*  
*  this file was created by Xilef11 on 2015-09-06
*/
package com.zpig333.runesofwizardry.client;

import com.zpig333.runesofwizardry.api.DustRegistry;
import com.zpig333.runesofwizardry.api.IDustStorageBlock;
import com.zpig333.runesofwizardry.client.model.ModelDustStorage;
import com.zpig333.runesofwizardry.core.WizardryLogger;

import net.minecraft.client.resources.model.IBakedModel;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

/**
* @author Xilef11
*
*/
public class ModelBakeEventHandler {
public static final ModelBakeEventHandler instance=new ModelBakeEventHandler();
private ModelBakeEventHandler() {};

@SubscribeEvent
public void onModelBake(ModelBakeEvent event){
	WizardryLogger.logInfo("Registering models on ModelBakeEvent");
	// Find the existing mapping for the block - it will have been added automatically because
    //  we registered a custom BlockStateMapper for it (using ModelLoader.setCustomStateMapper)
    // Replace the mapping with our ISmartBlockModel.
	for(IDustStorageBlock block: DustRegistry.getAllBlocks()){
		WizardryLogger.logInfo("ModelBake: processing "+block.getName());//XXX this happens
		for(int meta : block.getIDust().getMetaValues()){
			WizardryLogger.logInfo("meta is "+meta);//XXX this happens
			ModelResourceLocation location = ModelDustStorage.getModelResourceLocation(block, meta);
			Object object =  event.modelRegistry.getObject(location);
			WizardryLogger.logInfo("object is "+object);
			if (object instanceof IBakedModel) {//FIXME object is null
				IBakedModel existingModel = (IBakedModel)object;
				ModelDustStorage customModel = new ModelDustStorage(block, meta);
				event.modelRegistry.putObject(location, customModel);
			}else if(object==null){
				ModelDustStorage model = new ModelDustStorage(block, meta);
				event.modelRegistry.putObject(location, model);

			}
		}
	}
}
}

Methods (in client proxy) that load the stuff...

	/* (non-Javadoc)
 * @see com.zpig333.runesofwizardry.proxy.CommonProxy#registerDustStorageRendering()
 */
@Override
public void registerDustStorageRendering() {
	WizardryLogger.logInfo("Registering Dust Storage rendering");
	// We need to tell Forge how to map our BlockCamouflage's IBlockState to a ModelResourceLocation.
	// For example, the BlockStone granite variant has a BlockStateMap entry that looks like
	//   "stone[variant=granite]" (iBlockState)  -> "minecraft:granite#normal" (ModelResourceLocation)
	// For the camouflage block, we ignore the iBlockState completely and always return the same ModelResourceLocation,
	//   which is done using the anonymous class below
	for(final IDustStorageBlock block : DustRegistry.getAllBlocks()){
		WizardryLogger.logInfo("Creating StateMapper for "+block.getName());//XXX This happens
		StateMapperBase mapper = new StateMapperBase() {
			@Override
			protected ModelResourceLocation getModelResourceLocation(IBlockState iBlockState) {
				int meta = (Integer) iBlockState.getValue(IDustStorageBlock.PROPERTYMETA);
				return ModelDustStorage.getModelResourceLocation(block, meta);
			}
		};
		ModelLoader.setCustomStateMapper(block, mapper);
	}

	// ModelBakeEvent will be used to add our ISmartBlockModel to the ModelManager's registry (the
	//  registry used to map all the ModelResourceLocations to IBlockModels).  For the stone example there is a map from
	// ModelResourceLocation("minecraft:granite#normal") to an IBakedModel created from models/block/granite.json.
	// For the camouflage block, it will map from
	// CamouflageISmartBlockModelFactory.modelResourceLocation to our CamouflageISmartBlockModelFactory instance
	MinecraftForge.EVENT_BUS.register(ModelBakeEventHandler.instance);
	//register the handler to create the textures
	MinecraftForge.EVENT_BUS.register(new TextureStitchEventHandler());
}

public void registerDustStorageItemRendering() {
	WizardryLogger.logInfo("Registering dust storage item rendering");
	// This is currently necessary in order to make your block render properly when it is an item (i.e. in the inventory
    //   or in your hand or thrown on the ground).
    // Minecraft knows to look for the item model based on the GameRegistry.registerBlock.  However the registration of
    //  the model for each item is normally done by RenderItem.registerItems(), and this is not currently aware
    //   of any extra items you have created.  Hence you have to do it manually.  This will probably change in future.
    // It must be done in the init phase, not preinit, and must be done on client only.
	for(IDustStorageBlock b:DustRegistry.getAllBlocks()){
		WizardryLogger.logInfo("Processing item: "+b.getName());
		Item itemBlockDustStorage = GameRegistry.findItem(References.modid, b.getName());
		for(int meta: b.getIDust().getMetaValues()){
			WizardryLogger.logInfo("meta: "+meta);
			//ModelResourceLocation itemModelResourceLocation = new ModelResourceLocation(ModelDustStorage.getModelResourceLocationPath(b, meta), "inventory");
			ModelResourceLocation itemModelResourceLocation = ModelDustStorage.getModelResourceLocation(b, meta);				Minecraft.getMinecraft().getRenderItem().getItemModelMesher().register(itemBlockDustStorage, meta, itemModelResourceLocation);
		}
	}
}

TextureStitch Event Handler

package com.zpig333.runesofwizardry.client;

import com.zpig333.runesofwizardry.core.References;

import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

public class TextureStitchEventHandler {
private static TextureAtlasSprite dust_storage_bg, dust_storage_fg;
public static TextureAtlasSprite getDustStorageBG(){
	return dust_storage_bg;
}
public static TextureAtlasSprite getDustStorageFG(){
	return dust_storage_fg;
}
@SubscribeEvent
public void onTextureStitch(TextureStitchEvent.pre event){
	dust_storage_bg = event.map.registerSprite(new ResourceLocation(References.texture_path+"blocks/dustStorage_bg"));
	dust_storage_fg = event.map.registerSprite(new ResourceLocation(References.texture_path+"blocks/dustStorage_fg"));
}
}

EDIT: Turns out I derped and didn't notice the int[] was supposed to contian the data for all four vertices of the quad... I no longer crash, but the blocks get rendered in dark colors with no texture

EDIT2: textures were fixed, I had to register for TextureStitchEvent.pre . However, the two layers don't blend (alpha in the foreground renders as black) and the colors are off.

Link to comment
Share on other sites

I managed to fix the color, turns out I had to modify TGG's vertexToInts, since my color was in the 0x00RRGGBB format, while the int[] expected 0x00BBGGRR ( so I used Integer.reverseBytes(color)>>8 ).

 

I still have a few issues though,

  • the transparent pixels in the foreground layer are rendered as black instead of transparent - solved by setting my block to render in the CUTOUT layer and adding 0xFF000000 to my colors
  • my block extends BlockFalling, but when it falls it becomes invisible instead of using my model - working now, don't know why
  • In the inventory, the texture returned from MyModel#gettexture() is used instead of the quads I made - fixed by using ColoredBakedQuad instead of BakedQuad
  • The console still gets spammed with model not found messages

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

    • Jos77 adalah situs slot terpercaya yang menawarkan proses pendaftaran dan login yang mudah. Dengan deposit minimal hanya 5000 rupiah, Jos77 membuat perjudian slot online menjadi lebih terjangkau untuk semua orang. Bergabunglah sekarang dan nikmati pengalaman bermain yang seru dan menguntungkan dengan Jos77!  
    • EXTRAWD disini menjadi salah satu situs agen judi slot gacor terpercaya yang memungkinkan pemainnya bisa memenangkan jackpot uang asli dengan mudah setiap harinya. HOEXTRAWD  I77 memiliki berbagai jenis game slot gacor resmi terbaik hari ini yang memungkinkan member untuk menikmati permainan yang menyenangkan dan menarik. Ada banyak variasi permainan yang dapat dipilih mulai dari game jackpot, game mesin slot, dan banyak lagi. Selain itu, disini juga memberikan banyak bonus dan hadiah yang membuat member setia lebih tertarik untuk bermain di agen situs judi slot gacor gampang menang JP Maxwin. EXTRAWD  merupakan platform yang memiliki link demo gratis tanpa daftar dan kini akan memberikan kalian banyak sekali bocoran yang lebih efektif untuk memperoleh kemudahan menang jackpot terbesar dan bisa mencapai puluhan hingga ratusan juta rupiah. Pasti kalian sudah tidak sabar untuk menunggunya bukan? Langsung saja kalian kunjungi EXTRAWD  dimana seluruh permainan dapat memberikan untung ratusan juta bahkan hingga puluhan juta rupiah hanya dengan bet yang rendah. Sebagai tempat bertaruh gampang menang tentu kami memiliki fasilitas terbaik untuk seluruh member setia yang telah bergabung bersama website EXTRAWD  . Anda dapat menikmati berbagai layanan di situs EXTRAWD  yang selalu online 24jam dihadirkan dengan fasilitas seperti anda bisa memaksimalkan setiap bermain dengan mendapatkan kemenangan besar. Maka dari itu tidak ada salahnya jika kini anda bisa untuk mencobanya sekarang juga dengan meraih keuntungan dengan bisa langsung WD sekarang juga. Skema Jackpot ! 8 Provider Slot Gacor Maxwin Hari Ini Demi menyajikan permainan slot gacor online gampang menang berkualitas maka EXTRAWD sebagai situs judi slot online terbaik no 1 di Indonesia berkerja sama dengan beberapa provider slot terbaik. Dan game-game slot dari provider terkemuka ini bisa anda mainkan kapan saja dan dimana saja. Penasaran siapa saja yang membantu menghadirkan game slot gacor maxwin? Berikut adalah daftar 8 provider judi slot online yang wajib untuk dimainkan. Slot Gacor Pragmatic Play Semua player slot pasti sudah mengenal provider slot yang populer ini. Ya dia adalah Pragmatic Play yang merupakan salah satu penyedia game slot gacor terbaik yang masih beroperasi hingga saat ini. Pragmatic Play sangat populer karena produk-produknya terkenal mudah untuk dimainkan. Slot Gacor Habanero Selanjutnya adalah Habanero yang merupakan salah satu pemasok game slot gacor yang populer di Indonesia. Game slot dari Habanero sudah dilengkapi dengan grafik bagus dan efek suara yang terdengar nyata sehingga akan memberikan pengalaman bermain yang lebih menyenangkan. Slot Gacor Joker123 Joker123 atau Joker Gaming adalah salah satu provider yang membantu kami menghadirkan game slot gacor gampang maxwin. Joker123 termasuk salah satu provider yang sudah beroperasi lama dan tentunya bisa dipercaya. Sudah banyak produk slot yang dihadirkan oleh Joker123 ini diminati masyarakat di Indonesia. Slot Gacor Microgaming Sudah tidak diragukan lagi kualitas dari provider slot satu ini. Provider tersebut ialah Microgaming yang telah memproduksi ratusan macam game slot gacor gampang menang JP dengan tema menarik. Banyak slotter yang bersaksi bahwa mereka dapat dengan mudah memperoleh uang tunai bila memainkan game judi slot online dari Microgaming. Slot Gacor Spadegaming Spadegaming sangat cocok untuk kalian yang mencari game judi slot online gacor dengan winrate yang tinggi. Biasanya, para pemain baru akan mencoba game slot spadegaming ini karena sangat mudah dimainkan dan mudah menang. Selain itu, terdapat fitur-fitur bonus yang menarik dan menggiurkan di setiap mesin slot Spadegaming. Slot Gacor Playtech Playtech merupakan sebuah provider slot online yang sedang populer-populernya di tahun 2024 ini karena banyak game dari Playtech yang menarik perhatian para bettor untuk mencobanya. Mungkin salah satu faktornya adalah terdapat hadiah Jackpot yang besar bila memainkan produk slot dari Playtech. Slot Gacor EXTRAWD Slot88 adalah perusahaan penyedia permainan slot terbaik yang populer sejak tahun 2022-2024. Yang menjadi ciri khas dari provider ini ialah anda dapat bermain dengan menggunakan modal yang kecil namun berkesempatan memperoleh uang tunai yang banyak. Tidak heran banyak bettor memfavoritkan permainan slot online EXTRAWD ini. Slot Gacor PG Soft PG Soft atau Pocket Game Soft merupakan provider slot yang sudah lama berdiri dan tetap konsisten menyajikan permainan slot terbaik hingga saat ini. Lebih dari 100 game slot gacor sudah disajikan oleh PG Soft. Selain itu, tidak sedikit bettor yang menyukai game dari PG Soft karena seru dan menguntungkan. Daftar Game Slot Gacor Terbaru Viral di Tahun 2024 Permainan mesin slot gacor telah berkembang dengan pesat saat ini. Berbagai macam game mesin slot terbaru gampang menang tumbuh setiap hari dan permainan ini sering memberikan cuan yang begitu sensasional, menawarkan berbagai macam variasi mesin slot online gacor yang unik dan menarik. Banyak pilihan yang bisa kalian mainkan dari berbagai provider terbaik seperti pragmatic play, EXTRAWD , joker123, playtech dan lain sebagainya. Game online telah menjadi salah satu jenis taruhan yang viral dan sangat populer dikalangan pecintanya. Sehingga Platform EXTRAWD dipenuhi oleh pemain yang berhasil mengumpulkan kemanangan jackpot terbesar yang dapat di withdraw kapan pun. Lalu apa saja sih game yang dimainkan oleh pemainnya untuk mendapatkan kemenangan besar, inilah daftar game yang sering dimainkan di website EXTRAWD : Great Rhino Megaways : RTP 98,01% Aztec Gems : RTP 87,42% Mahjong Ways : RTP 91,06% Koi Gates : RTP 95% Spaceman : RTP 92,85% Madame Destiny : RTP 77,93% Gates of Olympus : RTP 54% Zeus : RTP 96% Gates of Gatot Kaca : RTP 90% Queen of Wands : RTP 94,81% Itulah deretan game slot gacor hari ini gampang menang yang disediakan oleh EXTRAWD dimana hampir seluruh permainan memiliki tingkat kemenangan yang sangat tinggi sehingga diyakini oleh bettor sebagai tempat untuk mencari cuan. Website Slot Gacor Hari ini EXTRAWD Provider Slot Terbaik 🔵 PRAGMATIC PLAY, 🟢 HABANERO SLOT, 🟠 PG SOFT. Game Slot Online Gacor 🔱 Gates Of Olympus, 🍭 Sweet Bonanza Xmas, 🀄️ Mahjong Ways 2, Bonanza Gold 💎. Winrate RTP 98.54% Metode Deposit BCA, BRI, BNI, MANDIRI, CIMB, PULSA, E-Walet (DANA, OVO, GOPAY). Minimal Deposit 💰 Min Deposit Rp 10.000 Minimal WD 💰 Min WD Rp 25.000 BONUS Hoki77 Bonus Deposit Harian 50%, Bonus Mingguan 20%, Bonus New Member 100%, Bonus Referral 100% Link Daftar EXTRAWD Website EXTRAWD
    • LINK ADA DI BAWAH INI  LINK LOGIN LINK DAFTAR LINK ALTERNATIF EXTRAWD adalah situs togel online yang terbaik dan bonafit yang merupakan anak cabang dari EXTRAWD Group. Permainan Togel Online ini sangat booming di Indonesia sehingga EXTRAWD juga ikut hadir untuk menaungi setiap member togel online. Selain itu EXTRAWD juga berperan sebagai Agen EXTRAWD terbesar yang ada di Indonesia, agar mengurangi oknum oknum lain yang ingin menipu anda. Agen EXTRAWD Bonafit 2019 Situs EXTRAWD Memang EXTRAWD mengakui bahwa banyak agen EXTRAWD yang ada di Indonesia, akan tetapi agen toto paling bonafit hanya ada di EXTRAWD Group. Setiap bulannya akan menghadirkan Lomba dengan Hadiah yang Besar sehingga member yang bermain di situs EXTRAWD  kami tidak selalu berakhir dengan kekalahan. Selain lomba dan event event yang disediakan agen EXTRAWD ini , EXTRAWD juga selalu menjaga keamanan privacy anda dengan baik. Kelebihan dari Situs Togel Online Terpercaya kami BBFS 10 DIGIT Hadiah yang disediakan di Kingdomtoto yaitu : 4D = 10 JT - 3D = 1 JT - 2D = 100 RIBU. Setelah hadiah permainan yang diberikan sangat besar, tentu saja kami telah mengatur minimal bet menjadi Rp. 100,- agar tidak membebani anda yang ingin bermain untuk melepas hobby. Situs Togel Online ini juga menyediakan 88 Pasaran Togel WLA yang bisa dimainkan 24jam full tanpa berhenti supaya yang hobby ngamen bisa tetap melanjutkan permainannya. Setiap pasaran togel yang tersedia di Kingdomtoto bisa dimainkan dengan bebas invest tanpa ada batasan line. Bisa dipastikan bahwa Agen Judi Togel yang terbaik hanyalah kami EXTRAWD
    • LINK ADA DI BAWAH INI  LINK LOGIN LINK DAFTAR LINK ALTERNATIF EXTRAWD adalah Daftar Situs Judi Slot Terbaik dan terlengkap di Indonesia, salah satu judi online terpercaya yang sudah lama berdiri di dunia judi online. Kini EXTRAWD Slot memberikan slot games gampang jackpot dan gampang menang untuk anda yang bermain di provider slot manapun, jadi bagi anda yang suka bermain di mesin slot online terpercaya ini sebaiknya segera Daftar Slot Online deposit pulsa bersama EXTRAWD yang sudah siap melayani anda kapanpun dan dimanapun anda berada untuk bagi yang siap bermain di mobile versi dan desktop versi. Kini sudah sangat gampang untuk bisa bermain dan daftar slot pragmatic play, di karenakan memang di zaman sekarang sudah berbeda di mana semua daftar situs judi slot sudah menggunakan Online. Tidak bisa di pungkiri, zaman sekarang semua sudah serba online, pastinya harus daftar slot online dengan situs slot resmi seperti EXTRAWD . Agen Slot Online Terlengkap EXTRAWD Agen slot terpercaya EXTRAWD sudah menjadi favorit bagi para pemain game slot penghasil uang. Dari sisi daftar slot deposit pulsa tanpa potongan yang sangat gampang, sehingga jackpot slot, scatter juga sangat mudah untuk di dapatan ketika bermain dengan EXTRAWD Slot. Untuk mengakses di situs EXTRAWD juga sangat mudah, anda hanya cukup menulis di google dengan pencarian EXTRAWD Link alternatif. Sebagai agen slot resmi di Indonesia, kami siap melayani para pemain judi slot online gacor . Provider yang kami sediakan juga sangat banyak dengan variasi dan jackpot yang banyak untuk anda. Berikut Provider slot online resmi: Pragmatic Play. Joker gaming ( Joker123 ). PG Soft. Spadegaming. Playtech. Microgaming. Habanero. JDB. Ameba. CQ9. OneGame. RedTiger. Total provider slot yang disediakan adalah 12 Provider, dengan variasi yang berbeda-beda. Pastinya kenyamanan bermain game slot juga sangat ramah dan nyaman, tidak sedikit yang sudah bergabung dan daftar slot via dana bersama kami, bahkan daftar slot via ovo & gopay juga sudah banyak. Situs Daftar Judi Slot Terbaru - EXTRAWD Selain permainan judi slot terbaru yang sudah kami sediakan, permainan kasino online seperti judi kasino juga kami sediakan. Seperti judi dadu online, sabung ayam online, togel sgp, sicbo online, judi bola, tembak ikan dan akan ada banyak lagi permainan judi online yang menghasilkan uang banyak untuk anda. Tak hanya itu, daftar slot pulsa simpati juga kami sediakan, dan slot deposit xl. Kami sebagai situs judi online terbaik akan memberikan layanan terbaik untuk anda dengan permainan slot gacor hari ini, akan memberikan kenyamanan, dan juga pengalaman bermain judi online paling baik. Mengapa harus daftar slot online pragmatic EXTRAWD ? Banyak keuntungan yang bisa anda peroleh selain mendapatkan Jackpot bersama EXTRAWD , anda juga diberikan Bonus-bonus yang sangat baik. Bonus seperti dibawah ini : Bonus New Member Bonus Cashback Bonus Referral Bonus Turnover banyak lagi, untuk melihat selengkapnya anda bisa Klik Disini. Agen Togel Online, Bandar Togel Terpercaya EXTRAWD merupakan salah satu agen togel online terbaik yang sudah berdiri sejak lama dan sangat profesional serta akan memberikan keamanan dan kenyamanan bagi seluruh member kami saat bermain di bandar EXTRAWD terpercaya. Kebanggaan kami adalah kepuasan Anda bermain dan menghabiskan waktu bersama kami, beruntung bersama kami dan menjadi pemenang. Link Alternatif EXTRAWD merupakan salah satu tempat bermain permainan Togel terbaik yang menawarkan 8 pasaran terlengkap seperti Pasar Togel Singapura dan Pasar Togel Hongkong. Sebuah situs yang fokus pada permainan Togel Online dan Togel Hongkong tentunya mengutamakan memberikan pelayanan yang terbaik, terbukti dengan cara kami beroperasi selama 24 jam dengan asumsi proses deposit dan penarikan kurang lebih 3 menit saja. Apa keunggulan bergabung di EXTRAWD ? Dengan keunggulan seperti bonus anda juga bisa melakukan deposit dengan berbagai macam metode pembayaran, seperti metode bank yaitu, Bank BCA, Bank Mandiri, Bank BRI, Bank BNI, Bank CIMBNiaga, SeaBank, BankJAGO, & Bank NeoCommerce. Keunggulan menggunakan metode pembayaran uang online seperti OVO, GoPay, DANA, SakuKu, LinkAja, & ShopeePay. Bisa juga menggunakan slot dan juga tidak lupa keunggulan dalam metode scan QRIS yang dalam hitungan detik diproses. Kami sarankan bagi kalian yang tidak sabar lagi ingin mendapatkan jackpot, maka segera bergabung dan Daftar Garuda4D diri anda bersama Garuda game slot sekarang juga. Kami juga menyediakan Aplikasi Android dan iPhone, yang bisa di Download secara gratis, untuk mendukung permainan Anda. Dan juga Minimal Deposit 10rb dan Withdraw hanya 50ribu.
    • LINK ADA DI BAWAH INI  LINK LOGIN LINK DAFTAR LINK ALTERNATIF LINK LIVE CHAT EXTRAWD EXTRAWD adalah salah satu Situs Slot Megawin Login Link Alternatif Untuk Mengunakan Satu ID EXTRAWD Untuk mendapatkan Untung Gacor EXTRAWD. Situs judi online terpercaya dan terpopuler di Indonesia. Kami menyediakan platform judi yang menawarkan berbagai jenis permainan, mulai dari Sportsbook Odds hingga Live Casino, semuanya dirancang untuk memberikan pengalaman bermain yang tidak terlupakan. EXTRAWD adalah tempat yang sempurna bagi para pemain judi online yang mencari keuntungan ekstra. SE EXTRAWD menawarkan berbagai manfaat dan keuntungan bagi para pemain setia kami, membuat bermain di situs kami menjadi sebuah pengalaman yang menguntungkan dan menyenangkan. EXTRAWD Merupakan Slot Megawin Tak peduli apakah Anda merupakan pemain baru atau pemain berpengalaman, bermain di EXTRAWDakan membuat Anda merasa terhibur dan tertantang. Dengan berbagai macam permainan yang kami tawarkan, Anda bisa memilih permainan yang paling sesuai dengan selera dan kemampuan Anda. EXTRAWD jangan khawatir, kami juga menyediakan panduan bermain yang mudah dipahami agar Anda bisa segera mulai bermain dan menikmati EXTRAWD permainan yang kami tawarkan. Bahwa modal kecil dapat menghasilkan keuntungan besar di EXTRAWD , tetapi penting bagi kami untuk mengingatkan bahwa modal juga mempengaruhi besar kecilnya keuntungan yang bisa Anda peroleh. Jadi, biar berapapun modal yang Anda miliki, pastikan untuk bermain dengan bijak dan bertanggung jawab. Selamat bermain dan semoga beruntung di  EXTRAWD Mengapa Memilih EXTRAWD Sebagai Situs Judi Online Anda Mengapa EXTRAWD sebaiknya menjadi pilihan Anda untuk situs judi online? Alasan pertama adalah variasi permainan yang kami tawarkan. Dari Sportsbook Odds hingga Live Casino, kami memiliki sesuatu untuk setiap penikmat judi online. Alasan kedua adalah manfaat dan keuntungan ekstra yang kami tawarkan kepada para pemain setia kami. Di EXTRAWD , setiap taruhan yang Anda pasang dapat memberi Anda lebih banyak keuntungan dan hadiah. Alasan ketiga adalah dukungan pelanggan kami yang responsif dan profesional, selalu siap membantu Anda kapan saja Anda membutuhkan bantuan. Jadi tunggu apalagi? Bergabunglah dengan EXTRAWD  hari ini EXTRAWD dan nikmati pengalaman judi online terbaik yang Anda inginkan. Manfaat dan Keuntungan Bermain di EXTRAWD  Bermain di EXTRAWD bukan hanya tentang hiburan, namun juga tentang keuntungan dan manfaat yang dapat Anda peroleh. Pertama, kami menawarkan peluang menang yang lebih tinggi dibandingkan situs judi online lainnya. Kedua, kami memberikan bonus dan promosi menggiurkan yang EXTRAWD bisa meningkatkan modal Anda dan memberi Anda lebih banyak peluang untuk bermain dan menang. Ketiga, kami memberikan dukungan pelanggan 24/7 yang siap membantu Anda menjawab pertanyaan dan mengatasi masalah yang mungkin Anda hadapi saat bermain. Keempat, kami menjamin keamanan dan kerahasiaan data pribadi Anda, sehingga Anda bisa bermain dengan tenang dan nyaman. Dengan semua manfaat dan keuntungan ini, tidak ada alasan untuk tidak bermain di EXTRAWD . Daftar sekarang juga dan mulai raih keuntungan Anda! Mengoptimalkan Modal Anda untuk Keuntungan Maksimal di EXTRAWD Memaksimalkan modal Anda saat bermain di EXTRAWD bisa menjadi strategi kunci dalam meraih keuntungan besar. Memulai dengan taruhan kecil adalah pilihan yang bijaksana, khususnya bagi pemain baru. Ini memungkinkan Anda untuk memahami permainan dan mengembangkan strategi tanpa risiko EXTRAWD . Selanjutnya, gunakan bonus dan promosi yang kami tawarkan untuk meningkatkan modal Anda. Ini tidak hanya memberi Anda lebih banyak peluang untuk bermain, tetapi juga menambah peluang Anda untuk menang. Selalu ingat, bermain dengan bijak dan bertanggung jawab adalah kunci untuk mengoptimalkan keuntungan Anda. Di EXTRAWD, kami berkomitmen untuk membuat pengalaman bermain Anda tidak hanya menyenangkan, tetapi juga menguntungkan. Bermain dengan Bijak dan Bertanggung Jawab di EXTRAWD Bermain judi online di EXTRAWD  bukan hanya tentang menang, tetapi juga tentang bermain dengan bijak dan bertanggung jawab. Kami sangat menekankan pentingnya bermain dengan cara yang bertanggung jawab untuk memastikan bahwa Anda selalu menikmati pengalaman bermain Anda dan menghindari potensi masalah. Ingatlah untuk selalu menetapkan batas untuk diri Anda sendiri, baik itu batas waktu, batas uang, atau keduanya. Jangan pernah menghabiskan lebih banyak uang atau waktu daripada yang Anda mampu, dan selalu beristirahat jika Anda merasa lelah atau frustasi. Selain itu, jangan pernah bermain ketika Anda merasa pemarah, sedih, atau di bawah pengaruh alkohol. Di EXTRAWD, kami mendukung permainan yang bertanggung jawab dan kami selalu siap membantu jika Anda membutuhkan bantuan atau nasihat. Bagaimana EXTRAWD Meningkatkan Pengalaman Bermain Judi Situs Slot Megawin EXTRAWD  bekerja tanpa henti untuk meningkatkan pengalaman bermain judi online Anda. Kami berkomitmen dalam menghadirkan layanan terbaik dengan berbagai fitur dan fasilitas yang bertujuan untuk meningkatkan kepuasan dan kenyamanan Anda. Pertama, kami menyediakan berbagai pilihan permainan yang luas dan bervariasi, mencakup semua genre populer seperti Sportsbook Odds dan Live Casino. Kedua, platform kami dirancang dengan antarmuka yang mudah digunakan dan responsif, memastikan bahwa Anda bisa bermain dengan lancar tanpa hambatan teknis. Ketiga, kami menawarkan sistem keamanan yang solid untuk melindungi data dan transaksi Anda, sehingga Anda bisa bermain dengan tenang tanpa khawatir. Keempat, dukungan pelanggan kami selalu siap 24/7 untuk membantu Anda dengan setiap pertanyaan atau masalah yang mungkin timbul. Melalui kombinasi pilihan permainan yang berlimpah, platform yang user-friendly, keamanan yang terjamin, dan layanan pelanggan yang responsif, EXTRAWD berusaha keras untuk membuat pengalaman bermain judi online Anda menjadi yang terbaik.
  • Topics

×
×
  • Create New...

Important Information

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