AnyType TPTScriptInterface::tptS_create(std::deque<std::string> * words)
{
	//Arguments from stack
	AnyType createType = eval(words);
	PointType position = eval(words);

	Simulation * sim = m->GetSimulation();

	int type;
	if(createType.GetType() == TypeNumber)
		type = ((NumberType)createType).Value();
	else if(createType.GetType() == TypeString)
		type = GetParticleType(((StringType)createType).Value());
	else
		throw GeneralException("Invalid type");

	if(type == -1)
		throw GeneralException("Invalid particle type");

	ui::Point tempPoint = position.Value();
	if(tempPoint.X<0 || tempPoint.Y<0 || tempPoint.Y >= YRES || tempPoint.X >= XRES)
				throw GeneralException("Invalid position");

	int returnValue = sim->create_part(-1, tempPoint.X, tempPoint.Y, type);

	return NumberType(returnValue);
}
void CTEParticleRenderer::SimulateParticles( CParticleSimulateIterator *pIterator )
{
	StandardParticle_t *pParticle = (StandardParticle_t*)pIterator->GetFirst();
	while ( pParticle )
	{
		// Remove the particle?
		SetParticleLifetime(pParticle, GetParticleLifetime(pParticle) - pIterator->GetTimeDelta());
		if(GetParticleLifetime(pParticle) < 0)
		{
			pIterator->RemoveParticle( pParticle );
		}
		else
		{
			float	ft = pIterator->GetTimeDelta();
			float	time3 = 15.0 * ft;
			float	time2 = 10.0 * ft;
			float	time1 = 5.0 * ft;
			float	dvel = 4* ft ;

			float grav = ft * sv_gravity.GetFloat() * 0.05f;

			int		(*colorIndex)[3];
			int		iRamp;

			switch(GetParticleType(pParticle))
			{
			case pt_static:
				break;

			case pt_fire:
				pParticle->m_EffectDataWord += (unsigned short)(time1 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= 6)
				{
					pParticle->m_Lifetime = -1;
				}
				else
				{
					colorIndex = &ramp3[ iRamp ];
					pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				}
				pParticle->m_Velocity[2] += grav;
				break;

			case pt_explode:
				pParticle->m_EffectDataWord += (unsigned short)(time2 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= 8)
				{
					pParticle->m_Lifetime = -1;
				}
				else
				{
					colorIndex = &ramp1[ iRamp ];
					pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				}
				pParticle->m_Velocity = pParticle->m_Velocity + pParticle->m_Velocity * dvel;
				pParticle->m_Velocity[2] -= grav;
				break;

			case pt_explode2:
				pParticle->m_EffectDataWord += (unsigned short)(time3 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= 8)
				{
					pParticle->m_Lifetime = -1;
				}
				else
				{
					colorIndex = &ramp2[ iRamp ];
					pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				}
				pParticle->m_Velocity = pParticle->m_Velocity - pParticle->m_Velocity * ft;
				pParticle->m_Velocity[2] -= grav;
				break;

			case pt_grav:
				pParticle->m_Velocity[2] -= grav * 20;
				break;
			case pt_slowgrav:
				pParticle->m_Velocity[2] = grav;
				break;

			case pt_vox_grav:
				pParticle->m_Velocity[2] -= grav * 8;
				break;
				
			case pt_vox_slowgrav:
				pParticle->m_Velocity[2] -= grav * 4;
				break;

				
			case pt_blob:
			case pt_blob2:
				pParticle->m_EffectDataWord += (unsigned short)(time2 * (1 << SIMSHIFT));
				iRamp = pParticle->m_EffectDataWord >> SIMSHIFT;
				if(iRamp >= SPARK_COLORCOUNT)
				{
					pParticle->m_EffectDataWord = 0;
					iRamp = 0;
				}
				
				colorIndex = &gSparkRamp[ iRamp ];
				pParticle->SetColor((float)(*colorIndex)[0] / 255.0f, (float)(*colorIndex)[1] / 255.0f, (float)(*colorIndex)[2] / 255.0f);
				
				pParticle->m_Velocity[0] -= pParticle->m_Velocity[0]*0.5*ft;
				pParticle->m_Velocity[1] -= pParticle->m_Velocity[1]*0.5*ft;
				pParticle->m_Velocity[2] -= grav * 5;

				if ( random->RandomInt(0,3) )
				{
					SetParticleType(pParticle, pt_blob);
					pParticle->SetAlpha(0);
				}
				else
				{
					SetParticleType(pParticle, pt_blob2);
					pParticle->SetAlpha(255.9f);
				}
				break;
			}
			// Update position.
			pParticle->m_Pos = pParticle->m_Pos + pParticle->m_Velocity * ft;
		}

		pParticle = (StandardParticle_t*)pIterator->GetNext();
	}
}
AnyType TPTScriptInterface::tptS_set(std::deque<std::string> * words)
{
	//Arguments from stack
	StringType property = eval(words);
	AnyType selector = eval(words);
	AnyType value = eval(words);

	Simulation * sim = m->GetSimulation();
	unsigned char * partsBlock = (unsigned char*)&sim->parts[0];

	int returnValue = 0;

	FormatType propertyFormat;
	int propertyOffset = GetPropertyOffset(property.Value(), propertyFormat);

	if(propertyOffset==-1)
		throw GeneralException("Invalid property");

	//Selector
	int newValue;
	float newValuef;
	if (value.GetType() == TypeNumber)
	{
		newValue = newValuef = ((NumberType)value).Value();
	}
	else if (value.GetType() == TypeFloat)
	{
		newValue = newValuef = ((FloatType)value).Value();
	}
	else if(value.GetType() == TypeString)
	{
		if (property.Value() == "temp")
		{
			std::string newString = ((StringType)value).Value();
			if (newString.at(newString.length()-1) == 'C')
				newValuef = atof(newString.substr(0, newString.length()-1).c_str())+273.15;
			else if (newString.at(newString.length()-1) == 'F')
				newValuef = (atof(newString.substr(0, newString.length()-1).c_str())-32.0f)*5/9+273.15f;
			else
				throw GeneralException("Invalid value for assignment");
		}
		else
		{
			newValue = GetParticleType(((StringType)value).Value());
			if (newValue < 0 || newValue >= PT_NUM)
			{
				// TODO: add element CAKE to invalidate this
				if (!strcasecmp(((StringType)value).Value().c_str(),"cake"))
					throw GeneralException("Cake is a lie, not an element");
				throw GeneralException("Invalid element");
			}
		}
	}
	else
		throw GeneralException("Invalid value for assignment");
	if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM || !sim->elements[newValue].Enabled))
		throw GeneralException("Invalid element");

	if(selector.GetType() == TypePoint || selector.GetType() == TypeNumber)
	{
		int partIndex = -1;
		if(selector.GetType() == TypePoint)
		{
			ui::Point tempPoint = ((PointType)selector).Value();
			if(tempPoint.X<0 || tempPoint.Y<0 || tempPoint.Y >= YRES || tempPoint.X >= XRES)
				throw GeneralException("Invalid position");

		}
		else
			partIndex = ((NumberType)selector).Value();
		if(partIndex<0 || partIndex>NPART || sim->parts[partIndex].type==0)
			throw GeneralException("Invalid particle");

		switch(propertyFormat)
		{
		case FormatInt:
			*((int*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
			break;
		case FormatFloat:
			*((float*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValuef;
			break;
		}
		returnValue = 1;
	}
	else if(selector.GetType() == TypeString && ((StringType)selector).Value() == "all")
	{
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValuef;
					}
			}
			break;
		}
	}
	else if(selector.GetType() == TypeString || selector.GetType() == TypeNumber)
	{
		int type;
		if(selector.GetType() == TypeNumber)
			type = ((NumberType)selector).Value();
		else if(selector.GetType() == TypeString)
			type = GetParticleType(((StringType)selector).Value());

		if(type<0 || type>=PT_NUM)
			throw GeneralException("Invalid particle type");
		if(type==0)
			throw GeneralException("Cannot set properties of particles that do not exist");
		std::cout << propertyOffset << std::endl;
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValuef;
					}
			}
			break;
		}
	}
	else
		throw GeneralException("Invalid selector");
	return NumberType(returnValue);
}
AnyType TPTScriptInterface::tptS_set(std::deque<std::string> * words)
{
	//Arguments from stack
	StringType property = eval(words);
	AnyType selector = eval(words);
	AnyType value = eval(words);

	Simulation * sim = m->GetSimulation();
	unsigned char * partsBlock = (unsigned char*)&sim->parts[0];

	int returnValue = 0;

	FormatType propertyFormat;
	int propertyOffset = GetPropertyOffset(property.Value(), propertyFormat);

	if(propertyOffset==-1)
		throw GeneralException("Invalid property");

	//Selector
	int newValue;
	if(value.GetType() == TypeNumber)
		newValue = ((NumberType)value).Value();
	else if(value.GetType() == TypeString)
	{
		newValue = GetParticleType(((StringType)value).Value());
		if (newValue < 0 || newValue >= PT_NUM)
			throw GeneralException("Invalid element");
	}
	else
		throw GeneralException("Invalid value for assignment");
	if (property.Value() == "type" && (newValue < 0 || newValue >= PT_NUM))
		throw GeneralException("Invalid element");

	if(selector.GetType() == TypePoint || selector.GetType() == TypeNumber)
	{
		int partIndex = -1;
		if(selector.GetType() == TypePoint)
		{
			ui::Point tempPoint = ((PointType)selector).Value();
			if(tempPoint.X<0 || tempPoint.Y<0 || tempPoint.Y >= YRES || tempPoint.X >= XRES)
				throw GeneralException("Invalid position");

		}
		else
			partIndex = ((NumberType)selector).Value();
		if(partIndex<0 || partIndex>NPART || sim->parts[partIndex].type==0)
			throw GeneralException("Invalid particle");

		switch(propertyFormat)
		{
		case FormatInt:
			*((int*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
			break;
		case FormatFloat:
			*((float*)(partsBlock+(partIndex*sizeof(Particle))+propertyOffset)) = newValue;
			break;
		}
		returnValue = 1;
	}
	else if(selector.GetType() == TypeString && ((StringType)selector).Value() == "all")
	{
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		}
	}
	else if(selector.GetType() == TypeString || selector.GetType() == TypeNumber)
	{
		int type;
		if(selector.GetType() == TypeNumber)
			type = ((NumberType)selector).Value();
		else if(selector.GetType() == TypeString)
			type = GetParticleType(((StringType)selector).Value());

		if(type<0 || type>=PT_NUM)
			throw GeneralException("Invalid particle type");
		std::cout << propertyOffset << std::endl;
		switch(propertyFormat)
		{
		case FormatInt:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((int*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		case FormatFloat:
			{
				for(int j = 0; j < NPART; j++)
					if(sim->parts[j].type == type)
					{
						returnValue++;
						*((float*)(partsBlock+(j*sizeof(Particle))+propertyOffset)) = newValue;
					}
			}
			break;
		}
	}
	else
		throw GeneralException("Invalid selector");
	return NumberType(returnValue);
}