Jump to content

[1.7.10] How would you sync a mobs inventory Server n Client side


Recommended Posts

Posted

Hi everyone, I have a method that gives my mob attacks which are basically customized items (it works). But I need to sync the mobs inventory so that the attack items also exist on the client. Im not sure how to do this. (And Dont just say "Packets" I know that it requires packets or use of a datawatcher but I am stumped how to do this) Currently I have tried the following see below).

 

This method is called server side only when my entity gets constructed and then again whenever my entity levels up (this works)

public void attacks(EntityCustom customEntity){
	if(customEntity instanceof EntityMyMob){
		int lvl = customEntity.getStats().level;
		if(lvl <= 5){
		customEntity.attacks[0] = new ItemStack(CommonProxy.itemAttack_Primary);
		PacketOverlord.sendToAll(new PacketSyncAttacks(customEntity)); <- need to update the attacks when they are given
		}
		if(lvl > 5){
		customEntity.attacks[1] = new ItemStack(CommonProxy.itemAttack_Secondary);
                         PacketOverlord.sendToAll(new PacketSyncAttacks(customEntity)); <- need to update the attacks when they are given
		  	}
		if (lvl >= 12){
		customEntity.attacks[2] = new ItemStack(CommonProxy.itemAttack_Tertiary);
                        PacketOverlord.sendToAll(new PacketSyncAttacks(customEntity)); <- need to update the attacks when they are given
		}
		if(lvl >= 18){
		customEntity.attacks[3] = new ItemStack(CommonProxy.itemAttack_Quaternary);
                        PacketOverlord.sendToAll(new PacketSyncAttacks(customEntity)); <- need to update the attacks when they are given
		}

	}
}

 

My packet class - The issue is my entity is null when I send the packet for some reason, So I am unsure how to update the entity on its client side so that it has the attacks on both sides. Currently the attacks are only present on server side

public class PacketSyncAttacks extends AbstractMessageToClient<PacketSyncAttacks> {

private NBTTagCompound data;
EntityCustom custom;

public PacketSyncAttacks() {}

public PacketSyncAttacks(EntityCustom custom) {

	this.custom= custom; <- Entity is not null here
	data = new NBTTagCompound();
	custom.writeEntityToNBT(data);
}

@Override
protected void read(PacketBuffer buffer) throws IOException {

	data = buffer.readNBTTagCompoundFromBuffer();
}

@Override
protected void write(PacketBuffer buffer) throws IOException {
	System.out.println("FUCK3");
	buffer.writeNBTTagCompoundToBuffer(data);
}

@Override
public void process(EntityPlayer player, Side side) {
//But my entity is null here. So I am unsure what to do to update my entities inventory
	if(data != null && custom!= null){ <- this is never called since entity is null here on client side
	this.custom.readFromNBT(data);
	}
}
}

 

My Packet Handler class

 

 

public class PacketOverlord {
private static byte packetId = 0;

private static final SimpleNetworkWrapper dispatcher = NetworkRegistry.INSTANCE
		.newSimpleChannel(CustomMod.CHANNEL);

/**
 * Register all packets and handlers here - this should be called during
 * {@link FMLPreInitializationEvent}
 */
public static final void preInit() {

           registerMessage(PacketSyncAttacks.class);

	}

/**
 * Register an {@link AbstractMessageOverlord} to the correct side
 */
private static final <T extends AbstractMessageOverlord<T> & IMessageHandler<T, IMessage>> void registerMessage(
		Class<T> clazz) {
	if (AbstractMessageOverlord.AbstractMessageToClient.class.isAssignableFrom(clazz)) {
		PacketOverlord.dispatcher.registerMessage(clazz, clazz,	packetId++, Side.CLIENT);
	} else if (AbstractMessageOverlord.AbstractMessageToServer.class.isAssignableFrom(clazz)) {
		PacketOverlord.dispatcher.registerMessage(clazz, clazz,	packetId++, Side.SERVER);
	} else {
		PacketOverlord.dispatcher.registerMessage(clazz, clazz, packetId,Side.CLIENT);
		PacketOverlord.dispatcher.registerMessage(clazz, clazz,	packetId++, Side.SERVER);
	}
}

/**
 * This message is sent to the specified player's client-side counterpart. See
 * {@link SimpleNetworkWrapper#sendTo(IMessage, EntityPlayerMP)}
 */
public static final void sendTo(IMessage message, EntityPlayerMP player) {
	PacketOverlord.dispatcher.sendTo(message, player);
}

public static final void sendToPlayers(IMessage message, Set<EntityPlayer> players) {
	for(EntityPlayer player : players) {
		//System.out.println("player"+player);
		//System.out.println("players"+players);
	 PacketOverlord.dispatcher.sendTo(message, (EntityPlayerMP) player);
	}
	}



/**This sends a message to everyone. See
 * {@link SimpleNetworkWrapper#sendToAll(IMessage)}
 */
public static void sendToAll(IMessage message) {
	PacketOverlord.dispatcher.sendToAll(message);
}

/**
 * This sends a message to everyone within a specified range of a specified point. See
 * {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)}
 */
public static final void sendToAllAround(IMessage message,
		NetworkRegistry.TargetPoint point) {
	PacketOverlord.dispatcher.sendToAllAround(message, point);
}

/**
 * This sends a message to everyone within a specified range of the passed in coordinates in
 * the same MC dimension. Shortcut to
 * {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)}
 */
public static final void sendToAllAroundCoordinates(IMessage message, int dimension, double x, double y, double z, double range) {
	PacketOverlord.sendToAllAround(message,	new NetworkRegistry.TargetPoint(dimension, x, y, z, range));
}

/**
 * This sends a message to everyone within a specified range of the passed in player
 * Shortcut to
 * {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)}
 */
public static final void sendToAllAround(IMessage message, EntityPlayer player, double range) {
	PacketOverlord.sendToAllAroundCoordinates(message,	player.worldObj.provider.dimensionId, player.posX, player.posY,	player.posZ, range);
}

/**
 * This sends a message to everyone within a specified range of the passed in pkmn
 * Shortcut to
 * {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)}
 */
public static final void sendToAllAround(IMessage message, EntityCustom entityCustom, double range) {
	PacketOverlord.sendToAllAroundCoordinates(message,	entityCustom.worldObj.provider.dimensionId, entityCustom.posX, entityCustom.posY, entityCustom.posZ, range);
}

/**
 * this sends a message to everyone within the passed in dimension that is denoted by its id. See
 * {@link SimpleNetworkWrapper#sendToDimension(IMessage, int)}
 */
public static final void sendToDimension(IMessage message, int dimensionId) {
	PacketOverlord.dispatcher.sendToDimension(message, dimensionId);
}

/**
 * This sends a message to the server. See
 * {@link SimpleNetworkWrapper#sendToServer(IMessage)}
 */
public static final void sendToServer(IMessage message) {
	PacketOverlord.dispatcher.sendToServer(message);
}

public static final SimpleNetworkWrapper getInstance()
{
	return dispatcher;
}
}

 

 

 

Anyone know of a good way to do this I am stumped atm

Posted

I don't think you need custom packets for this. Inventories can be synced by built in methods if you make them part of a Container along with an IGuiHandler. The IGuiHandler is what syncs up the client and server for you. I have a tutorial for inventory GUIs for blocks, but I'm fairly certain it would work same way for any inventory: http://jabelarminecraft.blogspot.com/p/minecraft-modding-blocks-with-guis.html

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted

Thornack, you are misunderstanding how packets work.

 

A packet is created on one side, populating all the class fields as needed and then writing those to an output stream so it can be sent to the other side; when this data is received on the other side, a COMPLETELY NEW instance of the packet is created, meaning NONE of your class fields have any information in them yet.

 

The data is then parsed by the packet's read method, which is generally where you initialize class fields, and then those fields can be used when the handler processes the packet.

 

That said, Jabelar is correct - you shouldn't need to manually sync inventory information, as that is done by the Container class. If you don't have a Container class, you probably don't have a GUI, and if you don't have a GUI, then why does the client need to know the information anyway?

Posted

Ok Thanks for clarifying that up, coolAlias I think I understand packets a bit better now, but I still need to send my packet and still have the same problem. I dont know how to sync my attack items client and server side.. I dont have a gui for my entity, I need to make my items exist on client side also so that my mob entity can use them. Currently what I have is the following.

 

Entity is spawned -> Entities level is generated -> Entities attacks are calculated based on level -> This is done server side -> Entity can be added to players party -> Entity can then be spawned by player as an ownable entity -> Player can become this entity by morphing into it -> Player gets all entity stats, inventory and items in inventory -> Items are attacks that the player can then use.

 

All of that works great. Im trying ot now write an AI to use my entities attack items so that the untamed entity can attack other entities using the attack items (just like the player can).

 

my partial entity class (sorry  alot of the code is pretty complicated so I omitted the crazy stuff cause this entity can do a lot atm) Hopefully this is sufficient to help grasp the issue. I need this entity to be able to use my attack items with onItem Right Click and on Item Use -> and onUsingTick-> to spawn custom particles and deal custom damage from a custom DamageSource.

 

I left in every line related to my attack items. The attacks only exist on server side however for my entity. Currently My entity spawns the attack item particles but the attack does no damage (for some reason)

 

 

 

public class EntityCustom extends EntityAnimal implements IEntityAdditionalSpawnData
{

    public ItemStack[] attacks = new ItemStack[4];
    public int currentAttack;
    private ItemStack attackInUse;
    private int attackInUseCount;
    
    
public CustomStats stats;

public EntityCustom(World world)
{
	super(world);
	this.setSize(0.9F, 0.9F);

	this.setupAI();		

	this.stats = new CustomStats(this);
	if(!world.isRemote){
		stats.calculateNewStats();
		stats.recalculateStats(this);
	}		
}


public CustomStats getStats()
{
	return this.stats;
}



  public ItemStack getCurrentAttack()
    {
        return this.currentAttack < 4 && this.currentAttack >= 0 ? this.attacks[this.currentAttack] : null;
    }
  
  public void setAttackItemInUse(ItemStack itemStack, int maxItemUseDuration)
    {  
        if (itemStack != this.attackInUse)
        {  
            if (maxItemUseDuration <= 0){ 
            	return;
            }
            
            this.attackInUse = itemStack;
            this.attackInUseCount = maxItemUseDuration;
            
            if (!this.worldObj.isRemote)
            {
                this.setEating(true);
            }
        }
    }
  
  public void clearAttackInUse()
    {
        this.attackInUse = null;
        this.attackInUseCount = 0;

        if (!this.worldObj.isRemote)
        {
            this.setEating(false);
        }
    }
  
  protected void onAttackUseFinish()
    {
        if (this.attackInUse != null)
        {
            int i = this.attackInUse.stackSize;
            /**may cause problems*/
            ItemStack itemstack = this.attackInUse.onFoodEaten(this.worldObj, null);

           if (itemstack != this.attackInUse || itemstack != null && itemstack.stackSize != i)
            {
            	this.attacks[this.currentAttack] = itemstack;

                if (itemstack != null && itemstack.stackSize == 0)
                {
                    this.attacks[this.currentAttack] = null;
                }
            }

            this.clearAttackInUse();
        }
    }
  
  
  
@Override
 public void onLivingUpdate(){
	super.onLivingUpdate();
	///////////////////////////////////

	Attack att = (Attack)  attacks[0].getItem();
	att.onItemRightClick( attacks[0], this.worldObj, this);

        if (this.attackInUse != null)
        {
        	ItemStack itemstack = this.getCurrentAttack();

            if (itemstack == this.attackInUse)
            {
            	
            	if (attackInUseCount <= 0)
                {
            		this.onAttackUseFinish();
                }
                else
                {
                	
                	if(attackInUse.getItem() instanceof PWItem){
                		
                		PWItem attack = (PWItem) attackInUse.getItem();
                		attack.onUsingTick(attackInUse, this, attackInUseCount);
                	}
                	                      
                    if (--this.attackInUseCount == 0 && !this.worldObj.isRemote)
                    {
                    	this.onAttackUseFinish();
                    }
                }
            }
            else
            {            	
                this.clearAttackInUse();
            }
            
        }
        /////////////////////////////////////+

 }
   

@Override
protected void entityInit()
{
	super.entityInit();

}

@Override
public boolean attackEntityFrom(DamageSource damageSource, float damageAmount)
{
	if (!this.worldObj.isRemote)
	{
		if(this.stats.currentHp > 0)
		{
			this.stats.currentHp = (int) this.getHealth() - (int) damageAmount;
		}
		else
		{
			this.stats.currentHp = 0;
		}
		MessageUpdateCustomStats msg = new MessageUpdateCustomStats(this);
		msg.sendToAll();
	}
	return super.attackEntityFrom(damageSource, damageAmount);
}

@Override
public boolean isAIEnabled()
{
	return true;
}

@Override
protected void updateAITasks()
{
	super.updateAITasks();
}

private void setupAI()
{	
	this.getNavigator().setAvoidsWater(true);
	clearAITasks();
	double speed = 0.5F;
	//this.tasks.addTask(0, new EntityAISwimming(this));
	this.tasks.addTask(1, new EntityAIWander(this, speed));
	this.tasks.addTask(2, new EntityAIWatchClosest(this, EntityPlayer.class, 12.0F));
	this.tasks.addTask(3, new EntityAIPanic(this, speed)); // speed is the second parameter
	this.tasks.addTask(4, new EntityAILookIdle(this));
	this.tasks.addTask(5, new EntityAIWatchClosest(this, EntityCustom.class, 6.0F));
}

private void clearAITasks()
{
	tasks.taskEntries.clear();
	targetTasks.taskEntries.clear();
}

@Override
public void writeSpawnData(ByteBuf buffer)
{
	this.stats.toBytes(buffer);
}

@Override
public void readSpawnData(ByteBuf additionalData)
{
	this.stats.fromBytes(additionalData);
}

  /**
     * Returns the item that this EntityLiving is holding, if any.
     */
    public ItemStack getFirstAttack()
    {
        return this.attacks[0];
    }
    
    public ItemStack getAttackFromSlot(int slot)
    {
        return this.attacks[slot];
    }
    
    public ItemStack deleteAttackInSlot(int slot)
    {
        return this.attacks[slot] = null;
    }

    @Override
public void writeEntityToNBT(NBTTagCompound nbt)
{ 
	super.writeEntityToNBT(nbt);

	NBTTagList nbttaglist = new NBTTagList();
        NBTTagCompound attackNBT;
        
	  
	for (int i = 0; i < this.attacks.length; ++i) {
		attackNBT = new NBTTagCompound();

		if (this.attacks[i] != null) {
			this.attacks[i].writeToNBT(attackNBT);
		}

		nbttaglist.appendTag(attackNBT);
	}
	nbt.setTag("Attacks", nbttaglist);
	this.stats.saveNBT(nbt);

	}

@Override
public void readEntityFromNBT(NBTTagCompound nbt)
{   super.readEntityFromNBT(nbt);

	NBTTagList nbttaglist;
	 if (nbt.hasKey("Attacks", 9)){
            nbttaglist = nbt.getTagList("Attacks", 10);

            for (int i = 0; i < this.attacks.length; ++i)
            {
                this.attacks[i] = ItemStack.loadItemStackFromNBT(nbttaglist.getCompoundTagAt(i));
            }
        }
	this.stats.loadNBT(nbt);

	}



}

 

 

 

When I get the entities that the attack is supposed to target (they return correctly Sorry I also removed a lot of logic here cause its kinda huge atm) BUT for some reason

List<EntityLivingBase> targets = TargetingHelper.acquireAllLookTargets(customEntity, Math.round(damageRadius), 1.0F);
		for (EntityLivingBase target : targets) {
                                System.out.println("Damage Done: " + appliedDmg + " target " + target);
			target.attackEntityFrom(getDamageSource(customEntity), appliedDmg);

}

The damage isnt done since when I call

 target.attackEntityFrom(getDamageSource(customEntity), appliedDmg); 

the appliedDmg variable is there and calculated correctly, the entity is there, the damage source is there, but the attackEntityFrom bit is never called (I checked with a break point)!! But for the player (when player is morphed into the entity and gets the entities attack) everything is there and damage does get dealt...So I checked whether or not my item exists client side for my entity and it does not, I suspect this is the problem. The onLivingUpdate method crashes the game when I allow it to call the following on client side because the item is null when I call.

if(this.worldObj.isRemote){
	System.out.println(attacks[0]); <- this is null on client side but not null on server side
	Attack att = (Attack)  attacks[0].getItem();
	att.onItemRightClick( attacks[0], this.worldObj, this);
	}

 

So my item is only there on server side and this is probably why I am having issues.

 

Its basically driving me crazy how hard this "get mobs to use my items" is to implement ugh. The good thing though if I get this one class implemented then all of my attacks will work because they are all set up the same. Any ideas anybody?

 

I am basically trying to take all of the onItemRightClick stuff and onItemUse, and onUsingTick etc etc and implement it for my entity so that it can use my item. I believe the important classes/methods have already been posted

Posted

Why do you care if the code runs on the client side, though? Only the server side should care about whether an attack or action is performed - the only exception is if you need some animation or something to happen on the client, and then you can just send a packet or health update flag saying 'this action was done on the server, so do your thing now client'.

 

So the solution is to only run the code on the server side - there is no reason to run it on both sides for a non-player entity.

Posted

My customized onItemRightClick method from my attack item class that I changed to work for my custom entity (it works for the player). Currently just trying to get the else if(ball ==false){} attacks done and working as they represent the majority of my attacks (the last else statement in this method). The ball type attacks are kind of like a snowball projectile but they do damage and have a trailing particle behind them and use a custom model. For now the non ball attacks is what I am looking at.

 

 

public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityCustom entityCustom) {
				int fatigueMultiplier = 1;

				if(ball == true && (getCooldown(itemStack) == 0)){
				 fatigueMultiplier = 2;

				EntityRangedAttackBase distanceAttack = new EntityRangedAttack(world, entityCustom).setType(attackType).setArea(damageRadius);
      				distanceAttack.setBaseDamageForProjectileAttack(baseDmg);
      				setCooldown(itemStack, 30);

      				if (!world.isRemote) {//spawn the bomb entity if your on the server
      					WorldHelper.playSoundAtEntity(entityCustom,BattleSoundsList.WHOOSH, 0.4F, 0.5F);
      					world.spawnEntityInWorld(distanceAttack);
      				}

      				
		      }	else if(ball ==false){	
		    	 //This is the bit that I care about atm as these are the main attacks
		    	  entityCustom.setAttackItemInUse(itemStack,getMaxItemUseDuration(itemStack));
			    }


	return itemStack;
}

 

 

 

My onUsingTickMethod inside my attack item class (atm I only care about the non stationary attacks (again since they represent the majority) (last else statement in this method

 

 

public void onUsingTick(ItemStack itemStack, EntityCustom entityCustom, int count) {

	if(entityCustom.worldObj.isRemote){
		System.out.println("NEVER CALLED"); //This is never called because my item is serverside only so the aiming logic for the attack doesnt work properly atm.
		MovingObjectPosition mop = entityCustom.rayTrace(15, 1F);
		if (mop != null && !entityCustom.worldObj.isAirBlock(mop.blockX, mop.blockY, mop.blockZ) && (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK || mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY)) {
			PacketOverlord.sendToServer(new PacketUpdateOnUsingTickTargetCoord(mop.blockX, mop.blockY, mop.blockZ));
		}
	}

	if (!entityCustom.worldObj.isRemote) {

               int ticksInUse = getMaxItemUseDuration(itemStack) - count;
			// Spawn stationary particle attack on right click
			if (this == CommonProxy.itemAttack_Stationary) {

				if (ticksInUse % 10 == 0) {

				EntityStationary entityStationary = new EntityStationary(entityCustom.worldObj, xTargetCoord + 0.5, yTargetCoord + 1, zTargetCoord + 0.5).disableGriefing();
				entityStationary .thrower = entityCustom;
				entityStationary .setBaseDamageForProjectileAttack(baseDmg);
				entityCustom.worldObj.spawnEntityInWorld(entityStationary);
				}
			} else {
				//This is what I care about here because I want to deal with the non stationary attacks
				handleUpdateTick(itemStack, entityCustom.worldObj, entityCustom, ticksInUse);
			}

	}
}

 

 

 

The handleUpdateTick method  inside my attack item class that I use for my main attacks. The non ball non stationary attacks (these are the majority of my particle attacks and they behave like a flamethrower essentially but all have different particles that are set elsewhere. All particles spawn normally but damage isnt done ever

 

 

private void handleUpdateTick(ItemStack itemStack, World world, EntityCustom entityCustom, int ticksInUse) {
	PacketOverlord.sendToAllAround(new PacketISpawnParticles(entityCustom, this, (float) (damageRadius)), entityCustom, 64.0D); <- works to spawn my particles (and they do actually show up)
	if (ticksInUse % 4 == 3) {
		float radius = 1;
		if(entityCustom.entID != -1){
			 radius = 10;
			}		
		List<EntityLivingBase> targets = TargetingHelper.acquireAllLookTargets(entityCustom, Math.round(1*damageRadius), 1.0F);
		for (EntityLivingBase target : targets) {
		//////////DAMAGE LOGIC FOR NON BALL TYPE ATTACKS////////////
			int defense = 1;
			if(target instanceof EntityCustom){
				defense = ((EntityCustom) target).stats.currentDef;
			} else if (target instanceof EntityPlayer){
					defense = 1;
			  }

			if(entityCustom.entID != -1){

			float calcPartTwo = ((float)entityCustom.stats.currentAtt/defense);
			float modifier = 1.0F;
			float appliedDmg = ((calcPartTwo*baseDmg)+2.0F)*modifier;
			System.out.println("Damage Done: " + appliedDmg); <-This prints correctly
			target.attackEntityFrom(getDamageSource(entityCustom), appliedDmg); //BUT DAMAGE ISNT ACTUALLY DONE!!!!!!!!!!
			System.out.println("damage source "+getDamageSource(entityCustom)); <-This prints correctly
			System.out.println(entityCustom);<-This prints correctly
			}	
	         ////////////////////////////////////////////////////////////////////
		}
	}

}

 

 

Posted

Ok I got my damage working but now I still need the targeting to work. It was a simple fix ish where I passed in the the target as an entity player so that the player into the

target.attackEntityFrom(getDamageSource((EntityPlayer) target), appliedDmg); 

can take damage from the wild entities. Im not sure if the damage is the correct damage but the player can now be hurt by the entity so that seems to work good.

Posted

I still need to figure out how to get the aiming code working (that would require the invnetory to be on client side also so that the onItemRightClick method can be called on client and server just like the player one does

Posted

I still need to figure out how to get the aiming code working (that would require the invnetory to be on client side also so that the onItemRightClick method can be called on client and server just like the player one does

Is the aiming code the reason you think you need the code to run client side? If so, you don't. You can write aiming code that works just fine on the server - the only reason the player has code running on the client side is because that's where player input (i.e. mouse and keyboard) comes from, so it makes sense to say 'hey client, where is the player's mouse pointing right now?'.

 

In the context of a non-player entity, however, that doesn't make much sense. Much better to use the server side values for the entity to determine if it can attack the player or not, using the entity's look vector to determine what it is looking at, geometry based on the entity's rotation vs. the player's position, or even just proximity as most vanilla mobs do.

Posted

Its not just the aiming however but ok ill try youre suggestion and maybe see if i can only use server side values

Okay, so what other reasons do you have for wanting your code to run on the client side?

 

Keep in mind that the client is ONLY responsible for things like rendering the world, displaying GUIs on the screen, and taking input from the player and sending it to the server. Some methods run on both sides to make the interaction smoother, but the server is the final arbiter of the outcome.

 

E.g. when you (a player) attack an entity, the client also runs the code so that the player can immediately see the visible result of their action (the attacked entity appearing to take damage, the sword losing durability, etc.) without waiting for a response from the server, but that is only for visuals - the server is the one that actually determines if the entity takes damage, how much, etc., and the sword's new durability, etc. The client side values are irrelevant except for that immediate feedback to the player.

 

Look at every other mob's AI / attack code and you will see it only runs on the server. At most, the entity will send a packet to notify the client that it is attacking so that it can perform an animation or spawn particles, nothing more.

 

LivingAttackEvent, LivingHurtEvent, etc. all only fire on the server side, with the sole exception of when the aggressor is an EntityPlayer, in which case some of those events fire on both sides.

 

My point is that even if you allow the code to run on both sides, it sounds like you are using it wrong. 'Aiming' only occurs due to player input on the client - every other entity determines what it can strike on the server.

 

If you have animations or particles that you want to happen, use #setEntityState on the server at the appropriate time to send a custom flag to #handleHealthUpdate - open up the call hierarchy of both methods to see how they are used in many entities, e.g. EntityIronGolem, EntityVillager, etc.

Posted

One of the main reasons really is so I dont have to rewrite a ton of logic that works currently if it is called client and server side for the player. My attacks recalculate an effective distance based on a ray trace (that bit isnt shown but ray trace needs to be client side only), they can "affect blocks" ie set blocks on fire, or spawn ice blocks to freeze things... etc etc and they also have a few visual effects. The aiming code works for me atm I like the ray trace since it lets me control the max distance,  etc etc... But out of curiosity in case I do feel like rewriting a bunch of stuff how would you suggest I do the aiming bit

Posted

Ray tracing is available on the server side as well...

MovingObjectPosition mop = world.rayTraceBlocks(vec3OriginPosition, vec3TargetPosition);

Where both arguments are a Vec3, the first being the point of origin, and the second being some location off in the distance you are trying to reach - if the mop is null, there is nothing in the way; otherwise it will have information about the first block encountered between the two positions.

 

Like I mentioned above, you don't want any of your logic that is responsible for affecting the world to run on the client - this includes setting blocks on fire, spawning blocks, etc. Do ALL of that on the server.

 

For your visuals, if you don't need them to be super precise, you can do what the Explosion class does and allow the code to run on the client, too, for the sole purpose of spawning particles. The affected block positions will not necessarily be identical to what the server decides was affected, so there can/will be some mismatch. If you need the positions to be exact, then you will probably need to send a packet with each or all of the affected positions to notify the client where to spawn the particles.

 

Note how the above solution is 'server affects blocks, sends notification to client' rather than 'client determines affected blocks, sends list to server'. That is always the flow you should aim for.

 

As for targeting code, what exactly are you trying to do? What I mean is, non-player entities don't aim, they target whatever you tell them to target, so I'm not sure what problem you are trying to solve here. Do you only want your entity to be able to attack players in front of it? Are you having issues finding a player to attack? I need more information.

Posted

Currently i got my entity to "use the attack item" this works, it spawns a stream of particles infront of it and anything within the calculated radius of effect (directly in front of my entity) will take damage. that is working. But when my mob rotates the "aiming" for the attack is incorrect. currently the particles are spawned along one set direction and the attack happens in that direction only. Im looking for a way to get my attack to follow the entities rotation. Just like for my player, if my player rotates the attack follows his look vector and the particles get spawned along that vector. Currently this is what I am trying to fix. I am going to implement a targeting AI later that will determine the ttack frequency and all of that. but for now I just made it so the attack pulses as so.

 

@Override
 public void onLivingUpdate(){
	super.onLivingUpdate();

	////////////////////////The pulsing code///////////////////////////////////////////////////
	if(!this.worldObj.isRemote){

		if(attackInUse == null && this.ticksExisted % 20 == 0){
			Attack att = (Attack)  attacks[0].getItem();
			att.onItemRightClick( attacks[0], this.worldObj, this);
		} else {
			if(this.ticksExisted % 20 == 0){
				attackInUse = null;
			}
		    }
	}
	///////////////////////////////////////////////////////////////////////////
        if (this.attackInUse != null)
        {
        	ItemStack itemstack = this.getCurrentAttack();

            if (itemstack == this.attackInUse)
            {
            	
            	if (attackInUseCount <= 0)
                {
            		this.onAttackUseFinish();
                }
                else
                {
                	
                	if(attackInUse.getItem() instanceof PWItem){
                		
                		PWItem attack = (PWItem) attackInUse.getItem();
                		attack.onUsingTick(attackInUse, this, attackInUseCount);
                	}
                	                      
                    if (--this.attackInUseCount == 0 && !this.worldObj.isRemote)
                    {
                    	this.onAttackUseFinish();
                    }
                }
            }
            else
            {            	
                this.clearAttackInUse();
            }
            
        }
        /////////////////////////////////////+

 

This bit of code is the part I need to change since my method never gets called on client

if(customEntity.worldObj.isRemote){
		System.out.println("NEVER CALLED");
		MovingObjectPosition mop = customEntity.rayTrace(15, 1F);
		if (mop != null && !customEntity.worldObj.isAirBlock(mop.blockX, mop.blockY, mop.blockZ) && (mop.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK || mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY)) {
			PacketOverlord.sendToServer(new PacketUpdateOnUsingTickTargetCoord(mop.blockX, mop.blockY, mop.blockZ));
		}
	}

 

it is located inside my onUsingTick method. Basically I need the look vector of the entities model so that when the model rotates inside its collision box the attack also rotates accordingly.

Posted

I cant seem to just be able to use the entities look vector coordinates directly to determine my attack coordinates since the look vector coordinates are all really really small values like

 X is -1.2246468525851679E-16 Y is 0.0 Z is 1.0 

That is the output I get from

 

inside my onUsingTick method

System.out.println(" X is "+customEntity.getLookVec().xCoord + " Y is "+ customEntity.getLookVec().yCoord + " Z is "+customEntity.getLookVec().zCoord)

Posted

Entity#getLookVec returns a normalized vector, which means the 'length' of the vector should equal 1. X, Y, and Z should all be values between -1.0F and 1.0F, i.e. values on the unit circle.

 

The look vector is determined using the entity's head rotation, not their body rotation - these are separate values. If you want to use the entity's body rotation to determine the path of the attack, you will need to copy the Entity#getLook method and swap in this.rotationYaw in place of this.rotationYawHead:

// from Entity#getLook(float) when the parameter = 1.0F, which is what is called from #getLookVec
return this.getVectorForRotation(this.rotationPitch, this.rotationYawHead); // note it uses HEAD yaw

Using #getVectorForRotation with the entity's body rotation should work, I would imagine.

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

    • Temu continues to reward loyal customers in the USA with exceptional savings opportunities through exclusive coupon codes designed specifically for existing users. The Temu coupon code $100 off remains one of the most popular discount offers available to returning customers who have already discovered the platform's incredible value proposition. Our featured Temu Coupon code (ACW472253) provides maximum benefits for people across the USA, Canada, and European nations, making it an ideal choice for USA shoppers seeking substantial savings.   Existing customers can take advantage of the comprehensive Temu coupon $100 offand Temu 100 off coupon code opportunities that extend well beyond first-time purchase incentives. These codes ensure that customer loyalty is rewarded with continued access to premium discounts and exclusive offers throughout the year.   What Is The Coupon Code For Temu $100 Off? Both new and existing customers can get amazing benefits if they use our $100 coupon code on the Temu app and website. The Temu coupon $100 offand $100 offTemu coupon provide substantial savings across thousands of product categories available on the platform. Our ACW472253 code offers multiple benefit structures designed to maximize customer value:   ACW472253 - Flat $100 offqualifying orders for immediate savings   ACW472253 - $100 coupon pack for multiple uses across different purchases   ACW472253 - $100 flat discount for new customers joining the platform   ACW472253 - Extra $100 promo code for existing customers continuing their shopping journey   ACW472253 - $100 coupon for USA/Canada users with worldwide shipping benefits   Temu Coupon Code $100 offFor New Users In 2025 New users can get the highest benefits if they use our coupon code on the Temu app. The Temu coupon $100 offand Temu coupon code $100 offprovide exceptional value for first-time shoppers exploring the platform's extensive product catalog. The ACW472253 code delivers comprehensive benefits specifically tailored for newcomers:   ACW472253 - Flat $100 discount for new users on qualifying first orders   ACW472253 - $100 coupon bundle for new customers enabling multiple discounted purchases   ACW472253 - Up to $100 coupon bundle for multiple uses across various product categories   ACW472253 - Free shipping to 68 countries ensuring global accessibility   ACW472253 - Extra 30% off on any purchase for first-time users maximizing initial savings   How To Redeem The Temu Coupon $100 offFor New Customers? The Temu $100 coupon and Temu $100 offcoupon code for new users can be easily applied through a straightforward redemption process. Follow these simple steps to maximize your savings:   Download the Temu app from your device's official app store or visit the Temu website   Create your new account using a valid email address and phone number   Browse through thousands of products and add desired items to your shopping cart   Proceed to checkout and locate the "Promo Code" or "Coupon Code" field   Enter ACW472253 exactly as shown and click "Apply"   Verify that your discount has been applied before completing your purchase   Complete your order using your preferred payment method   Temu Coupon $100 offFor Existing Customers Existing users can also get benefits if they use our coupon code on the Temu app. The Temu $100 coupon codes for existing users and Temu coupon $100 offfor existing customers free shipping ensure that customer loyalty is continuously rewarded with substantial savings opportunities. The ACW472253 code provides specialized benefits for returning customers:   ACW472253 - $100 extra discount for existing Temu users on qualified orders   ACW472253 - $100 coupon bundle for multiple purchases enabling extended savings   ACW472253 - Free gift with express shipping all over the USA/Canada region   ACW472253 - Extra 30% off on top of the existing discount for maximum value   ACW472253 - Free shipping to 68 countries with expedited delivery options   How To Use The Temu Coupon Code $100 offFor Existing Customers? The Temu coupon code $100 offand Temu coupon $100 offcode application process for existing customers follows a similar streamlined approach:   Log into your existing Temu account through the app or website   Add your desired products to the shopping cart   Navigate to the checkout page   Locate the promotional code entry field   Input ACW472253 and confirm the code application   Review your order summary to ensure the discount is properly applied   Complete your purchase with confidence   Latest Temu Coupon $100 offFirst Order Customers can get the highest benefits if they use our coupon code during the first order. The Temu coupon code $100 offfirst order, Temu coupon code first order, and Temu coupon code $100 offfirst time user provide exceptional value for initial platform experiences. The ACW472253 code offers comprehensive first-order benefits:   ACW472253 - Flat $100 discount for the first order on qualifying purchases   ACW472253 - $100 Temu coupon code for the first order with extended validity   ACW472253 - Up to $100 coupon for multiple uses across different product categories   ACW472253 - Free shipping to 68 countries ensuring global accessibility   ACW472253 - Extra 30% off on any purchase for the first order maximizing initial savings   How To Find The Temu Coupon Code $100 Off? The Temu coupon $100 offand Temu coupon $100 offReddit can be located through various reliable channels. Any user can get verified and tested coupons by signing up for the Temu newsletter, which provides regular updates on the latest promotional offers and exclusive discount codes. We also recommend visiting Temu's social media pages to get the latest coupons and promos, as the platform frequently shares time-sensitive offers across their official channels.   You can find the latest and working Temu coupon codes by visiting any trusted coupon site that specializes in verified promotional offers. These platforms regularly test and validate coupon codes to ensure customers receive legitimate savings opportunities.   Is Temu $100 offCoupon Legit? The Temu $100 offCoupon Legit and Temu 100 off coupon legit status is absolutely verified and confirmed. Our Temu coupon code ACW472253 is absolutely legit and has been tested across multiple user accounts and purchase scenarios. Any customers can safely use our Temu coupon code to get $100 offon the first order and then on the recurring orders without concerns about legitimacy or validity.   Our code is not only legit but also regularly tested and verified by our team to ensure consistent performance across different user scenarios. Our Temu coupon code is valid worldwide and doesn't have any expiration date, providing customers with flexible redemption opportunities regardless of timing or location.   How Does Temu $100 offCoupon Work? The Temu coupon code $100 offfirst-time user and Temu coupon codes 100 off operate through a straightforward discount application system that reduces your total order value by the specified coupon amount.   When you apply the ACW472253 coupon code at checkout, the system automatically calculates your eligibility based on your order value, account status, and product selection. The discount is then applied to qualifying items in your cart, reducing your total payment amount by up to $100 depending on your purchase value. For orders exceeding the minimum threshold, the full $100 discount is applied immediately, while smaller orders receive proportional discounts based on the total value. The system also accounts for any additional promotions or discounts that may be running simultaneously, ensuring you receive the maximum possible savings on your purchase.   How To Earn Temu $100 Coupons As A New Customer? The Temu coupon code $100 offand 100 off Temu coupon code can be earned through various customer engagement activities designed to reward platform participation and loyalty.   New customers can earn $100 coupons by downloading the official Temu mobile application, which provides access to exclusive in-app promotions and coupon offers not available through the website. Creating a complete user profile with verified contact information also unlocks additional coupon opportunities. Participating in Temu's referral program allows new users to earn coupon credits by inviting friends and family members to join the platform. Additionally, engaging with daily check-in features, spinning promotional wheels, and participating in limited-time games and challenges can generate coupon credits that accumulate toward $100 discount opportunities.   What Are The Advantages Of Using The Temu Coupon $100 Off? The Temu coupon code 100 off and Temu coupon code $100 offprovide numerous advantages for savvy shoppers:   $100 discount on the first order providing immediate substantial savings   $100 coupon bundle for multiple uses extending value across multiple purchases   70% discount on popular items when combined with existing promotions   Extra 30% off for existing Temu customers maximizing repeat purchase value   Up to 90% off in selected items during special promotional periods   Free gift for new users adding extra value to initial purchases   Free delivery to 68 countries ensuring global accessibility   Temu $100 Discount Code And Free Gift For New And Existing Customers The Temu $100 offcoupon code and $100 offTemu coupon code provide multiple benefits for customers regardless of their account status. There are multiple benefits to using our Temu coupon code that extend beyond simple price reductions:   ACW472253 - $100 discount for the first order with immediate application   ACW472253 - Extra 30% off on any item across all product categories   ACW472253 - Free gift for new Temu users adding tangible value   ACW472253 - Up to 70% discount on any item on the Temu app   ACW472253 - Free gift with free shipping in 68 countries including the USA and USA   Pros And Cons Of Using The Temu Coupon Code $100 offThis Month The Temu coupon $100 offcode and Temu 100 off coupon offer several advantages and considerations:   Pros:   Substantial immediate savings of up to $100 on qualifying orders   No expiration date providing flexible redemption timing   Valid for both new and existing customers ensuring inclusive access   Combines with other promotions for maximum savings potential   Free shipping benefits reducing overall order costs   Cons:   Minimum order requirements may apply to certain discount tiers   Limited to specific product categories during promotional periods   Terms And Conditions Of Using The Temu Coupon $100 offIn 2025 The Temu coupon code $100 offfree shipping and latest Temu coupon code $100 offoperate under specific terms and conditions designed to ensure fair usage:   Our coupon code doesn't have any expiration date allowing flexible redemption timing   Valid for both new and existing users in 68 countries worldwide providing global accessibility   No minimum purchase requirements for using our Temu coupon code ACW472253   Free returns within 90 days of purchase ensuring customer satisfaction   Price adjustment policy within 30 days protecting against price fluctuations   Free standard shipping on qualifying orders reducing additional costs   One-time use per customer account preventing multiple redemptions   Final Note: Use The Latest Temu Coupon Code $100 Off The Temu coupon code $100 offrepresents one of the most valuable savings opportunities available to USA customers shopping on the platform today. Whether you're a first-time user or a loyal existing customer, these substantial discounts provide genuine value across thousands of product categories.   Take advantage of the Temu coupon $100 offwhile these promotional offers remain available to maximize your shopping budget and discover why millions of customers worldwide trust Temu for their online shopping needs. The combination of substantial discounts, free shipping benefits, and comprehensive return policies makes this an ideal time to experience everything Temu has to offer.   FAQs Of Temu $100 offCoupon Q: How do I apply the Temu $100 offcoupon code? A: Enter the code ACW472253 at checkout in the promotional code field. The discount will be automatically applied to qualifying orders, reducing your total by up to $100 depending on your purchase value.   Q: Can existing customers use the $100 offTemu coupon? A: Yes, the ACW472253 coupon code is valid for both new and existing customers. Existing users can benefit from additional discounts and free shipping offers when using this code on qualifying orders.   Q: Is there a minimum order requirement for the Temu $100 coupon? A: No minimum purchase requirements apply when using our ACW472253 coupon code. However, the discount amount may vary based on your total order value and product selection at checkout.   Q: How long is the Temu $100 offcoupon valid? A: The ACW472253 coupon code does not have an expiration date, allowing customers to use it whenever convenient. This provides flexibility for both immediate purchases and future shopping plans on the platform.   Q: Can I combine the $100 Temu coupon with other offers? A: Yes, the ACW472253 coupon can often be combined with existing promotions, flash sales, and other discount offers to maximize your total savings. Check at checkout to see available stacking opportunities.  
    • Looking for a fantastic way to save big on your next Temu order? The acr639380 Temu coupon code is exactly what you need! Whether you're shopping from the USA, Canada, or Europe, this code offers unbeatable savings — up to $100 off your next purchase. If you’ve been eyeing something on Temu, now’s the perfect time to grab it with this exclusive offer!  What Is the Coupon Code for Temu $100 Off? Both new and existing customers can benefit from this incredible deal when shopping on the Temu app or website. Just use code acr639380 at checkout to unlock your $100 discount. Here’s what it offers: acr639380: Flat $100 off your next purchase.   acr639380: Receive a $100 coupon pack for multiple uses.   acr639380: New customers get an exclusive $100 off their first purchase.   acr639380: Existing customers can claim an extra $100 off future purchases.   acr639380: Valid in the USA, Canada, and across Europe.    Temu $100 Off Coupon for New Users in 2025 If you're new to Temu, this coupon code is perfect for you. It’s your chance to enjoy huge savings right from your very first order. Here’s what new customers get with acr639380: Flat $100 discount on your first order.   Access to a $100 coupon bundle for multiple purchases.   Stack up to $100 in discounts across various orders.   Free shipping to 68 countries, including the USA, Canada, and UK.   An additional 30% off any item on your first purchase.    How to Redeem the Temu $100 Off Coupon (For New Users) It’s simple! Follow these quick steps: Visit the Temu website or download the Temu app.   Create a new account.   Add your favorite products to your cart.   At checkout, enter the Temu $100 off coupon code: acr639380.   Apply the code, enjoy the savings, and complete your purchase!    Temu Coupon $100 Off for Existing Customers Good news — existing customers aren’t left out! Temu rewards loyal shoppers too. Perks for returning users with acr639380: Get an extra $100 off your next order.   A $100 coupon bundle for multiple future purchases.   Free gifts with express shipping (USA & Canada).   An additional 30% off on any purchase.   Free shipping to 68 countries globally.    How to Use Temu $100 Off Coupon (For Existing Customers) To redeem: Log into your Temu account.   Add your items to the cart.   At checkout, enter acr639380.   Apply the code and enjoy your savings!    Temu $100 Off Coupon for First Orders Your first Temu order just got better with acr639380: $100 off your initial purchase.   Access to exclusive first-time user discounts.   Up to $100 in savings on multiple items.   Free shipping to 68 countries.   Extra 30% off your first order.    Where to Find the Latest Temu $100 Off Coupon Looking for the newest and verified Temu coupon codes? Here’s where you can find them: Temu’s newsletter: Subscribe for email-exclusive deals.   Official Temu social media pages.   Trusted coupon websites.   Community threads like Temu coupon $100 off Reddit where users share legit codes.    Is the Temu $100 Off Coupon Legit? Absolutely — the acr639380 coupon is verified, tested, and 100% legit. It works for both new and existing customers worldwide, with no expiration date. Use it with confidence!  How Does the Temu $100 Off Coupon Work? Simple — enter acr639380 at checkout, and the discount is applied automatically. Whether it’s your first order or a repeat purchase, you’ll enjoy direct savings.  How to Earn Temu $100 Coupons as a New Customer New customers can score extra Temu savings by: Signing up for a new Temu account.   Making your first purchase using acr639380.   Watching for special promotions and email deals.   Checking Temu’s homepage for limited-time coupon bundles.    Advantages of Using the Temu $100 Off Coupon Here’s what makes this coupon so appealing: Flat $100 discount on first-time and future orders.   $100 coupon bundle for multiple uses.   Up to 90% off popular products.   Extra 30% off for existing customers.   Free gifts for new users.   Free shipping to 68 countries, including the USA, UK, and Canada.    Temu $100 Discount Code + Free Gift for Everyone Both new and existing customers get added perks: $100 off your first order.   An extra 30% off any product.   Free gifts on first purchases.   Up to 90% off select deals on the Temu app.   Free shipping to 68 countries.    Pros and Cons of Using the Temu Coupon Code $100 Off in 2025 Pros: Massive $100 discount.   Up to 90% off on select items.   Free global shipping to 68 countries.   30% off bonus for existing users.   Verified, legit, and no expiration date.   Cons: Free shipping limited to select countries.   Some exclusions may apply to already discounted items.    Terms and Conditions (2025) No expiration date.   Valid in 68 countries.   No minimum spend required.   Applicable for multiple purchases.   Some product exclusions may apply.    Final Note: Don’t Miss Out on the $100 Temu Coupon If you’re shopping on Temu, don’t leave money on the table. Use coupon code acr639380 to unlock $100 off, free shipping, extra discounts, and exclusive perks. It’s one of the easiest ways to make your shopping spree even more rewarding.  FAQs: Temu $100 Off Coupon Q: Is the $100 off coupon available for both new and existing customers? A: Yes! Both can use acr639380 for amazing discounts. Q: How do I redeem the Temu $100 coupon? A: Enter acr639380 at checkout to instantly save $100. Q: Does the Temu coupon expire? A: No — this coupon currently has no expiration date. Q: Can the coupon be used for multiple purchases? A: Yes, the $100 off coupon and bundle can apply to multiple orders. Q: Does it work for international users? A: Absolutely! It’s valid in 68 countries, including the USA, Canada, and Europe.
    • Go to the config folder and open the secretroomsmod.cfg   At the bottom, you will find:   # Check for mod updates on startup B:update_checker=true   Change it to false:   # Check for mod updates on startup B:update_checker=false  
    • The mod yetanotherchancebooster is conflicting or running into an issue with cobblemon Remove yetanotherchancebooster
    • Looking to save big on your next shopping spree? With our Temu coupon code $100 off, you can grab massive savings right from your first order! We bring you the verified acw696499 coupon code that unlocks exclusive discounts for shoppers in the USA, Canada, and across European countries. With this exclusive Temu coupon $100 off and Temu 100 off coupon code, you're not just shopping smart—you're shopping the best deal available. What Is The Coupon Code For Temu $100 Off? If you're searching for a way to make your Temu shopping even more affordable, look no further. Both new and existing users can enjoy amazing deals by using our Temu coupon $100 off and $100 off Temu coupon. acw696499: Get a flat $100 off on select orders for maximum savings. acw696499: Enjoy a $100 coupon pack you can redeem across multiple purchases. acw696499: Exclusive $100 flat discount available for first-time users. acw696499: Extra $100 promo value available even for returning users. acw696499: Get access to a $100 coupon tailored specifically for USA and Canada shoppers. Temu Coupon Code $100 Off For New Users In 2025 As a new user, you're entitled to enjoy incredible perks from your very first purchase. By using our Temu coupon $100 off and Temu coupon code $100 off, you get unmatched value. acw696499: Flat $100 discount for new Temu users across all eligible items. acw696499: Unlock a $100 coupon bundle that can be used for multiple orders. acw696499: Redeem up to $100 in coupons over your next few purchases. acw696499: Take advantage of free shipping to over 68 countries worldwide. acw696499: Get an additional 30% off on your entire first purchase. How To Redeem The Temu Coupon $100 Off For New Customers? Redeeming your Temu $100 coupon and Temu $100 off coupon code for new users is a simple, step-by-step process: Download the Temu app or visit the official Temu website. Create a new account using your email or phone number. Add your favorite products to the cart. At checkout, enter the coupon code acw696499. Hit apply and enjoy the $100 discount on your first order. Temu Coupon $100 Off For Existing Customers Great news! Existing customers can also reap rewards using our Temu $100 coupon codes for existing users and Temu coupon $100 off for existing customers free shipping. acw696499: Receive a $100 discount on your next Temu order. acw696499: Use the $100 coupon bundle over multiple purchases. acw696499: Enjoy free express shipping and surprise gifts in the USA/Canada. acw696499: Stack up with an additional 30% discount on current deals. acw696499: Access free shipping to 68 countries around the globe. How To Use The Temu Coupon Code $100 Off For Existing Customers? To redeem your Temu coupon code $100 off and Temu coupon $100 off code as an existing user: Log in to your existing Temu account. Add desired items to your shopping cart. Proceed to the checkout page. Enter the coupon code acw696499 in the promo code section. Apply the code and enjoy instant $100 off benefits. Latest Temu Coupon $100 Off First Order If you’re placing your first order, the timing couldn’t be better. Using the Temu coupon code $100 off first order, Temu coupon code first order, and Temu coupon code $100 off first time user, you unlock exclusive bonuses. acw696499: Flat $100 discount applied instantly at checkout. acw696499: Redeem a $100 coupon specifically for your first order. acw696499: Use up to $100 in coupons for multiple uses. acw696499: Enjoy free international shipping to 68 countries. acw696499: Grab an extra 30% discount on top of the $100 coupon. How To Find The Temu Coupon Code $100 Off? Finding a working Temu coupon $100 off and Temu coupon $100 off Reddit is easier than ever. Simply subscribe to the Temu newsletter and receive verified deals right in your inbox. You can also follow Temu on social media to stay updated on flash sales and fresh coupons. Lastly, always check reliable coupon-sharing websites like ours to get working and tested coupon codes like acw696499. Is Temu $100 Off Coupon Legit? Yes, the Temu $100 Off Coupon Legit and Temu 100 off coupon legit concerns can be put to rest. Our coupon code acw696499 is 100% legitimate and trusted by users worldwide. You can safely apply this code to get $100 off on your first purchase and also enjoy recurring discounts. It’s fully verified, tested, and available globally without any expiry date. How Does Temu $100 Off Coupon Work? The Temu coupon code $100 off first-time user and Temu coupon codes 100 off work like a digital voucher. Once you enter the code acw696499 during checkout, it automatically deducts up to $100 from your total order. The coupon can be redeemed on eligible products, and sometimes includes extra discounts, free shipping, or bonus items. How To Earn Temu $100 Coupons As A New Customer? To earn your Temu coupon code $100 off and 100 off Temu coupon code, you simply need to sign up as a new customer on the Temu platform. After registration, use the acw696499 code to immediately unlock $100 in coupon value, and continue to receive bonus discounts and perks via email or app notifications. What Are The Advantages Of Using The Temu Coupon $100 Off? Here are the major advantages of using our Temu coupon code 100 off and Temu coupon code $100 off: $100 discount on your first order. $100 coupon bundle redeemable across multiple purchases. Up to 70% discount on popular Temu products. Additional 30% discount for returning users. Up to 90% off on select items during promotions. Free gift included for new users. Free shipping to 68 countries including the USA, Canada, UK, and more. Temu $100 Discount Code And Free Gift For New And Existing Customers Our Temu $100 off coupon code and $100 off Temu coupon code don’t just offer discounts—they deliver value-packed shopping experiences. acw696499: $100 discount for your first Temu purchase. acw696499: Extra 30% off on all items sitewide. acw696499: Free surprise gift for new Temu shoppers. acw696499: Up to 70% off on trending products. acw696499: Free gift + free shipping to 68 countries including the USA and UK. Pros And Cons Of Using The Temu Coupon Code $100 Off This Month Here are the pros and cons of the Temu coupon $100 off code and Temu 100 off coupon: Pros: Verified and tested code: acw696499. Available for both new and returning users. Valid worldwide including USA, Canada, and Europe. Provides free shipping and gifts. No expiration date. Cons: Limited to select product categories. Cannot be combined with certain Temu internal promotions. Terms And Conditions Of Using The Temu Coupon $100 Off In 2025 Here are the Temu coupon code $100 off free shipping and latest Temu coupon code $100 off terms and conditions: The coupon code acw696499 does not have any expiration date. Valid for both new and existing users. Works in 68 countries including USA, Canada, and UK. No minimum purchase is required to activate the coupon. The coupon can be used multiple times for select offers. Shipping is free when the coupon is used. Final Note: Use The Latest Temu Coupon Code $100 Off Don't miss out on this incredible chance to save with the Temu coupon code $100 off. Your shopping journey with Temu just got a lot more affordable! Take advantage of this Temu coupon $100 off deal before it disappears. It's time to upgrade your cart without upgrading your expenses.
  • Topics

×
×
  • Create New...

Important Information

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