Jump to content

Recommended Posts

Posted

I have created a custom mob, but for some reason the default ModelBiped animations (walking, arms swinging, etc) are not displaying.  Here are the appropriate files:

 

package timeTraveler.render;

import static net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED;
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.IImageBuffer;
import net.minecraft.client.renderer.ImageBufferDownload;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.ThreadDownloadImageData;
import net.minecraft.client.renderer.entity.RenderBiped;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureObject;
import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StringUtils;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.client.MinecraftForgeClient;

import org.lwjgl.opengl.GL11;

import timeTraveler.entities.EntityPlayerPast;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

@SideOnly(Side.CLIENT)
public class RenderPastPlayer extends RenderBiped
{
    public static final ResourceLocation locationStevePng = new ResourceLocation("textures/entity/steve.png");

    public RenderPastPlayer(ModelBiped par1ModelBase, float par2)
    {
        super(par1ModelBase, par2);
    }

    //private static final ResourceLocation Your_Texture = new ResourceLocation("mocap","test.png");  //refers to:assets/yourmod/models/optionalfile/yourtexture.png

    /**
     * Called from doRenderLiving in RenderBiped.
     */
    @Override
    protected void func_82420_a(EntityLiving par1EntityLiving, ItemStack par2ItemStack)
    {
        return;
    }

    @Override
    public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9)
    {
        EntityPlayerPast par1EntityMocap = (EntityPlayerPast)par1EntityLiving;
        ItemStack itemstack = par1EntityLiving.getHeldItem();
        this.field_82423_g.heldItemRight = this.field_82425_h.heldItemRight = this.modelBipedMain.heldItemRight = itemstack != null ? 1 : 0;

        if (itemstack != null && par1EntityMocap.isEating())
        {
            EnumAction enumaction = itemstack.getItemUseAction();

            if (enumaction == EnumAction.eat)
            {
                this.field_82423_g.heldItemRight = this.field_82425_h.heldItemRight = this.modelBipedMain.heldItemRight = 4;
            }

            if (enumaction == EnumAction.block)
            {
                this.field_82423_g.heldItemRight = this.field_82425_h.heldItemRight = this.modelBipedMain.heldItemRight = 3;
            }
            else if (enumaction == EnumAction.bow)
            {
                this.field_82423_g.aimedBow = this.field_82425_h.aimedBow = this.modelBipedMain.aimedBow = true;
            }
        }

        this.field_82423_g.isSneak = this.field_82425_h.isSneak = this.modelBipedMain.isSneak = par1EntityLiving.isSneaking();
        super.doRenderLiving(par1EntityLiving, par2, par4, par6, par8, par9);
    }

    /**
     * Called from renderEquippedItems in RenderBiped.
     */
    @Override
    protected void func_130005_c(EntityLiving par1EntityLiving, float par2)
    {
    	EntityPlayerPast par1EntityMocap = (EntityPlayerPast)par1EntityLiving;
        ItemStack itemstack1 = par1EntityLiving.getHeldItem();
        ItemStack helmetItem = par1EntityLiving.func_130225_q(3);
        float f1 = 1.0F;
        GL11.glColor3f(f1, f1, f1);
        /*
         * Render Skulls, etc.
         */
        float f2;

        if (helmetItem != null)
        {
            GL11.glPushMatrix();
            this.modelBipedMain.bipedHead.postRender(0.0625F);
            IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(helmetItem, EQUIPPED);
            boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper(EQUIPPED, helmetItem, BLOCK_3D));

            if (helmetItem.getItem() instanceof ItemBlock)
            {
                if (is3D || RenderBlocks.renderItemIn3d(Block.blocksList[helmetItem.itemID].getRenderType()))
                {
                    f2 = 0.625F;
                    GL11.glTranslatef(0.0F, -0.25F, 0.0F);
                    GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
                    GL11.glScalef(f2, -f2, -f2);
                }

                this.renderManager.itemRenderer.renderItem(par1EntityLiving, helmetItem, 0);
            }
            else if (helmetItem.getItem().itemID == Item.skull.itemID)
            {
                f2 = 1.0625F;
                GL11.glScalef(f2, -f2, -f2);
                String s = "";

                if (helmetItem.hasTagCompound() && helmetItem.getTagCompound().hasKey("SkullOwner"))
                {
                    s = helmetItem.getTagCompound().getString("SkullOwner");
                }

                TileEntitySkullRenderer.skullRenderer.func_82393_a(-0.5F, 0.0F, -0.5F, 1, 180.0F, helmetItem.getItemDamage(), s);
            }

            GL11.glPopMatrix();
        }

        if (itemstack1 != null)
        {
            GL11.glPushMatrix();
            this.modelBipedMain.bipedRightArm.postRender(0.0625F);
            GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F);
            EnumAction enumaction = null;

            if (par1EntityMocap.isEating())
            {
                enumaction = itemstack1.getItemUseAction();
            }

            float f11;
            IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(itemstack1, EQUIPPED);
            boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper(EQUIPPED, itemstack1, BLOCK_3D));
            boolean isBlock = itemstack1.itemID < Block.blocksList.length && itemstack1.getItemSpriteNumber() == 0;

            if (is3D || (isBlock && RenderBlocks.renderItemIn3d(Block.blocksList[itemstack1.itemID].getRenderType())))
            {
                f11 = 0.5F;
                GL11.glTranslatef(0.0F, 0.1875F, -0.3125F);
                f11 *= 0.75F;
                GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F);
                GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
                GL11.glScalef(-f11, -f11, f11);
            }
            else if (itemstack1.itemID == Item.bow.itemID)
            {
                f11 = 0.625F;
                GL11.glTranslatef(0.0F, 0.125F, 0.3125F);
                GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F);
                GL11.glScalef(f11, -f11, f11);
                GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F);
                GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
            }
            else if (Item.itemsList[itemstack1.itemID].isFull3D())
            {
                f11 = 0.625F;

                if (Item.itemsList[itemstack1.itemID].shouldRotateAroundWhenRendering())
                {
                    GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
                    GL11.glTranslatef(0.0F, -0.125F, 0.0F);
                }

                if (par1EntityMocap.isEating()  && enumaction == EnumAction.block)
                {
                    GL11.glTranslatef(0.05F, 0.0F, -0.1F);
                    GL11.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F);
                    GL11.glRotatef(-10.0F, 1.0F, 0.0F, 0.0F);
                    GL11.glRotatef(-60.0F, 0.0F, 0.0F, 1.0F);
                }

                GL11.glTranslatef(0.0F, 0.1875F, 0.0F);
                GL11.glScalef(f11, -f11, f11);
                GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F);
                GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
            }
            else
            {
                f11 = 0.375F;
                GL11.glTranslatef(0.25F, 0.1875F, -0.1875F);
                GL11.glScalef(f11, f11, f11);
                GL11.glRotatef(60.0F, 0.0F, 0.0F, 1.0F);
                GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F);
                GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F);
            }

            float f12;
            float f13;
            float f6;
            int j;

            if (itemstack1.getItem().requiresMultipleRenderPasses())
            {
                for (j = 0; j < itemstack1.getItem().getRenderPasses(itemstack1.getItemDamage()); ++j)
                {
                    int k = itemstack1.getItem().getColorFromItemStack(itemstack1, j);
                    f13 = (float)(k >> 16 & 255) / 255.0F;
                    f12 = (float)(k >> 8 & 255) / 255.0F;
                    f6 = (float)(k & 255) / 255.0F;
                    GL11.glColor4f(f13, f12, f6, 1.0F);
                    this.renderManager.itemRenderer.renderItem(par1EntityLiving, itemstack1, j);
                }
            }
            else
            {
                j = itemstack1.getItem().getColorFromItemStack(itemstack1, 0);
                float f14 = (float)(j >> 16 & 255) / 255.0F;
                f13 = (float)(j >> 8 & 255) / 255.0F;
                f12 = (float)(j & 255) / 255.0F;
                GL11.glColor4f(f14, f13, f12, 1.0F);
                this.renderManager.itemRenderer.renderItem(par1EntityLiving, itemstack1, 0);
            }

            GL11.glPopMatrix();
        }
    }

    //@Override
    protected void renderModelTest(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4, float par5, float par6, float par7)
    {
        this.bindEntityTexture(par1EntityLivingBase);
        GL11.glPushMatrix();
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 0.35F);
        GL11.glDepthMask(false);
        GL11.glEnable(GL11.GL_BLEND);
        GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
        GL11.glAlphaFunc(GL11.GL_GREATER, 0.003921569F);
        this.mainModel.render(par1EntityLivingBase, par2, par3, par4, par5, par6, par7);
        GL11.glDisable(GL11.GL_BLEND);
        GL11.glAlphaFunc(GL11.GL_GREATER, 0.1F);
        GL11.glPopMatrix();
        GL11.glDepthMask(true);
    }
}

 

package timeTraveler.entities;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import timeTraveler.core.TimeTraveler;
import timeTraveler.pasttravel.PastAction;
import timeTraveler.pasttravel.PastActionTypes;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.server.FMLServerHandler;

public class EntityPlayerPast extends EntityLiving
{
    /**
     * A list of pending actions the Entity has to perform, injected
     * by the replay thread.
     */
    private int itemInUseCount = 0;

    public List<PastAction> eventsList = Collections.synchronizedList(new ArrayList<PastAction>());

    public EntityPlayerPast(World par1World)
    {
        super(par1World);
        this.tasks.taskEntries.clear();
        this.targetTasks.taskEntries.clear();
    }

    public void onLivingUpdate() {
	if (eventsList.size() > 0) {
		PastAction ma = eventsList.remove(0);
		processActions(ma);
	}

	this.updateArmSwingProgress();

	if (this.newPosRotationIncrements > 0) {
		double d0 = this.posX + (this.newPosX - this.posX)
				/ (double) this.newPosRotationIncrements;
		double d1 = this.posY + (this.newPosY - this.posY)
				/ (double) this.newPosRotationIncrements;
		double d2 = this.posZ + (this.newPosZ - this.posZ)
				/ (double) this.newPosRotationIncrements;
		double d3 = MathHelper.wrapAngleTo180_double(this.newRotationYaw
				- (double) this.rotationYaw);
		this.rotationYaw = (float) ((double) this.rotationYaw + d3
				/ (double) this.newPosRotationIncrements);
		this.rotationPitch = (float) ((double) this.rotationPitch + (this.newRotationPitch - (double) this.rotationPitch)
				/ (double) this.newPosRotationIncrements);
		--this.newPosRotationIncrements;
		this.setPosition(d0, d1, d2);
		this.setRotation(this.rotationYaw, this.rotationPitch);
	} else if (!this.isClientWorld()) {
		this.motionX *= 0.98D;
		this.motionY *= 0.98D;
		this.motionZ *= 0.98D;
	}

	if (Math.abs(this.motionX) < 0.005D) {
		this.motionX = 0.0D;
	}

	if (Math.abs(this.motionY) < 0.005D) {
		this.motionY = 0.0D;
	}

	if (Math.abs(this.motionZ) < 0.005D) {
		this.motionZ = 0.0D;
	}

	if (!this.isClientWorld()) {
		this.rotationYawHead = this.rotationYaw;
	}

	this.prevLimbSwingAmount = this.limbSwingAmount;
	double d0 = this.posX - this.prevPosX;
	double d1 = this.posZ - this.prevPosZ;
	float f6 = MathHelper.sqrt_double(d0 * d0 + d1 * d1) * 4.0F;

	if (f6 > 1.0F) {
		f6 = 1.0F;
	}

	this.limbSwingAmount += (f6 - this.limbSwingAmount) * 0.4F;
	this.limbSwing += this.limbSwingAmount;
}

    public boolean interact(EntityPlayer par1EntityPlayer)
    {
        //System.out.println(worldObj.isRemote);
        //System.out.println(getSkinSource());
        //System.out.println(posY);
        return true;
    }

    protected boolean isAIEnabled()
    {
        return false;
    }
    
/* public void onEntityUpdate()
   {
        super.onEntityUpdate();
        if(isPlayerSeen(FMLClientHandler.instance().getClient().thePlayer))
        {
        	System.out.println("PLAYER SPOTTED!");
		int paradox = TimeTraveler.vars.getParadoxAmt();
		paradox = paradox + 3;
		TimeTraveler.vars.setParadoxAmt(paradox);

        }
    }*/
}

 

package timeTraveler.proxies;

import net.minecraft.client.model.ModelBiped;
import net.minecraftforge.client.MinecraftForgeClient;
import timeTraveler.core.TimeTraveler;
import timeTraveler.entities.EntityParadoxHunter;
import timeTraveler.entities.EntityPlayerPast;
import timeTraveler.models.ModelParadoxHunter;
import timeTraveler.render.ItemCondenserRenderer;
import timeTraveler.render.ItemTimeMachineRenderer;
import timeTraveler.render.RenderCondenser;
import timeTraveler.render.RenderExtractor;
import timeTraveler.render.RenderParadoxHunter;
import timeTraveler.render.RenderPastPlayer;
import timeTraveler.render.RenderTimeMachine;
import timeTraveler.tileentity.TileEntityExtractor;
import timeTraveler.tileentity.TileEntityParadoxCondenser;
import timeTraveler.tileentity.TileEntityTimeTravel;

import com.jadarstudios.developercapes.DevCapes;

import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;


public class ClientProxy extends CommonProxy {

public void registerRenderThings()
{		
    ClientRegistry.bindTileEntitySpecialRenderer(TileEntityExtractor.class, new RenderExtractor());
    ClientRegistry.bindTileEntitySpecialRenderer(TileEntityParadoxCondenser.class, new RenderCondenser());
    ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTimeTravel.class, new RenderTimeMachine());
    
    RenderingRegistry.registerEntityRenderingHandler(EntityParadoxHunter.class,  new RenderParadoxHunter(new ModelParadoxHunter(),  0.3F));
    RenderingRegistry.registerEntityRenderingHandler(EntityPlayerPast.class, new RenderPastPlayer(new ModelBiped(), 0.3F));
    
    MinecraftForgeClient.registerItemRenderer(TimeTraveler.paradoxCondenser.blockID, new ItemCondenserRenderer());
    MinecraftForgeClient.registerItemRenderer(TimeTraveler.timeTravel.blockID, new ItemTimeMachineRenderer());
}
@Override
public void initCapes()
{
    // move this to dropbox
	DevCapes.getInstance().registerConfig("https://raw2.github.com/jadar/TimeTraveler/master/capes/capes.json", TimeTraveler.modid);
}

}

 

package timeTraveler.core;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.PlayerSelector;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityEggInfo;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.MinecraftForge;
import timeTraveler.blocks.BlockParadoxCondenser;
import timeTraveler.blocks.BlockTime;
import timeTraveler.blocks.BlockTimeTraveler;
import timeTraveler.blocks.Collision;
import timeTraveler.blocks.ParadoxExtractor;
import timeTraveler.entities.EntityChair;
import timeTraveler.entities.EntityParadoxHunter;
import timeTraveler.entities.EntityPlayerPast;
import timeTraveler.futuretravel.FutureTravelMechanics;
import timeTraveler.futuretravel.WorldProviderFuture;
import timeTraveler.gui.GuiHandler;
import timeTraveler.items.BottledParadox;
import timeTraveler.items.CondensedParadox;
import timeTraveler.items.EmptyBottle;
import timeTraveler.items.ItemExpEnhance;
import timeTraveler.items.ItemFlashback;
import timeTraveler.items.ItemParadoximer;
import timeTraveler.mechanics.TTEventHandler;
import timeTraveler.network.TimeTravelerPacketHandler;
import timeTraveler.pasttravel.PastAction;
import timeTraveler.pasttravel.TimeTravelerPastRecorder;
import timeTraveler.pasttravel.TimeTravelerPlayerTracker;
import timeTraveler.proxies.CommonProxy;
import timeTraveler.structures.StructureGenerator;
import timeTraveler.ticker.TickerClient;
import timeTraveler.tileentity.TileEntityCollision;
import timeTraveler.tileentity.TileEntityExtractor;
import timeTraveler.tileentity.TileEntityParadoxCondenser;
import timeTraveler.tileentity.TileEntityTimeTravel;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.network.NetworkMod.SidedPacketHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.relauncher.Side;


@Mod(modid = TimeTraveler.modid, name = "Time Traveler", version = "0.1")
@NetworkMod(clientSideRequired = true, serverSideRequired = false, serverPacketHandlerSpec = @SidedPacketHandler (channels = {"futuretravel", "paradoxgui", "entityspawn"}, packetHandler = TimeTravelerPacketHandler.class))

/**
* Main launcher for TimeTraveler
* @author Charsmud6
*
*/
public class TimeTraveler
{
@SidedProxy(clientSide = "timeTraveler.proxies.ClientProxy", serverSide = "timeTraveler.proxies.CommonProxy")
public static CommonProxy proxy;

@Instance
public static TimeTraveler instance = new TimeTraveler();


/**
 * Initiates mod, registers block and item for use.  Generates the necessary folders.
 */
@EventHandler
public void load(FMLInitializationEvent event)
{  			
	EntityRegistry.registerGlobalEntityID(EntityPlayerPast.class, "PlayerPast", EntityRegistry.findGlobalUniqueEntityId(), 0x191919, 0x000000);//registers the mobs name and id
	EntityRegistry.registerGlobalEntityID(EntityChair.class, "Chiar", EntityRegistry.findGlobalUniqueEntityId());


	proxy.registerRenderThings();

}
/**
 * Registers Entities
 */
public void registerEntities()
{
	EntityRegistry.registerModEntity(EntityParadoxHunter.class, "ParadoxHunter", 1, this, 80, 1, true);
	EntityRegistry.registerModEntity(EntityPlayerPast.class, "PastPlayer", 2, this, 80, 1, true);
	EntityRegistry.addSpawn(EntityParadoxHunter.class, 10, 2, 4, EnumCreatureType.creature, BiomeGenBase.beach, BiomeGenBase.extremeHills, BiomeGenBase.extremeHillsEdge, BiomeGenBase.forest, BiomeGenBase.forestHills, BiomeGenBase.jungle, BiomeGenBase.jungleHills, BiomeGenBase.mushroomIsland, BiomeGenBase.mushroomIslandShore, BiomeGenBase.ocean, BiomeGenBase.plains, BiomeGenBase.river, BiomeGenBase.swampland);
	LanguageRegistry.instance().addStringLocalization("entity.Charsmud_TimeTraveler.ParadoxHunter.name", "Paradox Hunter");


	registerEntityEgg(EntityParadoxHunter.class, 0xffffff, 0x000000);
}
}

Note that I have trimmed the files to contain only the necessary code.  Any ideas?

Posted

i usually do it differently, following how things like EntityWolf and such do it.  The Renderer class mostly just associates the model and texture to the entity.  The Model class is usually where I do the animations and actually rendering -- there is a render() method in the Model class.

 

Also, you need to make sure you register the model to the renderer -- you should post your code for where you register the renderer class (usually in ClientProxy).

 

Anyway, I think the animation usually happens in the model class but I guess for player bipeds it might be different.

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

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



×
×
  • Create New...

Important Information

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