示例#1
0
SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
									 SCA_IObject* gameobj,
									 const STR_String& propname,
									 const STR_String& propval,
									 const STR_String& propmaxval,
									 KX_PROPSENSOR_TYPE checktype)
	: SCA_ISensor(gameobj,eventmgr),
	  m_checktype(checktype),
	  m_checkpropval(propval),
	  m_checkpropmaxval(propmaxval),
	  m_checkpropname(propname),
	  m_range_expr(NULL)
{
	//CParser pars;
	//pars.SetContext(this->AddRef());
	//CValue* resultval = m_rightexpr->Calculate();

	CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
	if (!orgprop->IsError())
	{
		m_previoustext = orgprop->GetText();
	}
	orgprop->Release();

	if (m_checktype==KX_PROPSENSOR_INTERVAL)
	{
		PrecalculateRangeExpression();
	}
	Init();
}
示例#2
0
void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr)
{

	bool expressionresult = false;
	if (!m_exprCache)
	{
		CParser parser;
		parser.SetContext(this->AddRef());
		m_exprCache = parser.ProcessText(m_exprText);
	}
	if (m_exprCache)
	{
		CValue* value = m_exprCache->Calculate();
		if (value)
		{
			if (value->IsError())
			{
				printf("%s\n", value->GetText().ReadPtr());
			} else
			{
				float num = (float)value->GetNumber();
				expressionresult = !MT_fuzzyZero(num);
			}
			value->Release();

		}
	}

	for (vector<SCA_IActuator*>::const_iterator i=m_linkedactuators.begin();
	!(i==m_linkedactuators.end());i++)
	{
		SCA_IActuator* actua = *i;
		logicmgr->AddActiveActuator(actua,expressionresult);
	}
}
示例#3
0
int SCA_ILogicBrick::CheckProperty(void *self, const PyAttributeDef *attrdef)
{
	if (attrdef->m_type != KX_PYATTRIBUTE_TYPE_STRING || attrdef->m_length != 1) {
		PyErr_SetString(PyExc_AttributeError, "inconsistent check function for attribute type, report to blender.org");
		return 1;
	}
	SCA_ILogicBrick* brick = reinterpret_cast<SCA_ILogicBrick*>(self);
	STR_String* var = reinterpret_cast<STR_String*>((char*)self+attrdef->m_offset);
	CValue* prop = brick->GetParent()->FindIdentifier(*var);
	bool error = prop->IsError();
	prop->Release();
	if (error) {
		PyErr_SetString(PyExc_ValueError, "string does not correspond to a property");
		return 1;
	}
	return 0;
}
示例#4
0
bool	SCA_PropertySensor::CheckPropertyCondition()
{

	m_recentresult=false;
	bool result=false;
	bool reverse = false;
	switch (m_checktype)
	{
	case KX_PROPSENSOR_NOTEQUAL:
		reverse = true;
	case KX_PROPSENSOR_EQUAL:
		{
			CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
			if (!orgprop->IsError())
			{
				const STR_String& testprop = orgprop->GetText();
				// Force strings to upper case, to avoid confusion in
				// bool tests. It's stupid the prop's identity is lost
				// on the way here...
				if ((&testprop == &CBoolValue::sTrueString) || (&testprop == &CBoolValue::sFalseString)) {
					m_checkpropval.Upper();
				}
				result = (testprop == m_checkpropval);
				
				/* Patch: floating point values cant use strings usefully since you can have "0.0" == "0.0000"
				 * this could be made into a generic Value class function for comparing values with a string.
				 */
				if (result==false && dynamic_cast<CFloatValue *>(orgprop) != NULL) {
					float f;
					
					if (EOF == sscanf(m_checkpropval.ReadPtr(), "%f", &f))
					{
						//error
					} 
					else {
						result = (f == ((CFloatValue *)orgprop)->GetFloat());
					}
				}
				/* end patch */
			}
			orgprop->Release();

			if (reverse)
				result = !result;
			break;

		}

	case KX_PROPSENSOR_EXPRESSION:
		{
			/*
			if (m_rightexpr)
			{
				CValue* resultval = m_rightexpr->Calculate();
				if (resultval->IsError())
				{
					int i=0;
					STR_String errortest = resultval->GetText();
					printf(errortest);

				} else
				{
					result = resultval->GetNumber() != 0;
				}
			}
			*/
			break;
		}
	case KX_PROPSENSOR_INTERVAL:
		{
			//CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
			//if (orgprop)
			//{
				if (m_range_expr)
				{
					CValue* vallie = m_range_expr->Calculate();
					if (vallie)
					{
						const STR_String& errtext = vallie->GetText();
						if (&errtext == &CBoolValue::sTrueString)
						{
							result = true;
						} else
						{
							if (vallie->IsError())
							{
								//printf (errtext.ReadPtr());
							} 
						}
						
						vallie->Release();
					}
				}

				
			//}
			
		//cout << " \nSens:Prop:interval!"; /* need implementation here!!! */

		break;
		}
	case KX_PROPSENSOR_CHANGED:
		{
			CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
				
			if (!orgprop->IsError())
			{
				if (m_previoustext != orgprop->GetText())
				{
					m_previoustext = orgprop->GetText();
					result = true;
				}
			}
			orgprop->Release();

			//cout << " \nSens:Prop:changed!"; /* need implementation here!!! */
			break;
		}
	default:
		; /* error */
	}

	//the concept of Edge and Level triggering has unwanted effect for KX_PROPSENSOR_CHANGED
	//see Game Engine bugtracker [ #3809 ]
	if (m_checktype != KX_PROPSENSOR_CHANGED)
	{
		m_recentresult=result;
	} else
	{
		m_recentresult=result;//true;
	}
	return result;
}
示例#5
0
bool	SCA_PropertySensor::CheckPropertyCondition()
{
	m_recentresult=false;
	bool result=false;
	bool reverse = false;
	switch (m_checktype)
	{
	case KX_PROPSENSOR_NOTEQUAL:
		reverse = true;
		/* fall-through */
	case KX_PROPSENSOR_EQUAL:
		{
			CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
			if (!orgprop->IsError())
			{
				const std::string& testprop = orgprop->GetText();
				// Force strings to upper case, to avoid confusion in
				// bool tests. It's stupid the prop's identity is lost
				// on the way here...
				if ((testprop == CBoolValue::sTrueString) || (testprop == CBoolValue::sFalseString)) {
					boost::to_upper(m_checkpropval);
				}
				result = (testprop == m_checkpropval);
				
				/* Patch: floating point values cant use strings usefully since you can have "0.0" == "0.0000"
				 * this could be made into a generic Value class function for comparing values with a string.
				 */
				if (result==false && (orgprop->GetValueType() == VALUE_FLOAT_TYPE)) {
					float f = std::stof(m_checkpropval);
					result = (f == ((CFloatValue *)orgprop)->GetFloat());
				}
				/* end patch */
			}
			orgprop->Release();

			if (reverse)
				result = !result;
			break;

		}

	case KX_PROPSENSOR_EXPRESSION:
		{
			break;
		}
	case KX_PROPSENSOR_INTERVAL:
		{
			CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
			if (!orgprop->IsError())
			{
				const float min = std::stof(m_checkpropval);
				const float max = std::stof(m_checkpropmaxval);
				float val;

				if (orgprop->GetValueType() == VALUE_STRING_TYPE) {
					val = std::stof(orgprop->GetText());
				}
				else {
					val = orgprop->GetNumber();
				}

				result = (min <= val) && (val <= max);
			}
			orgprop->Release();

		break;
		}
	case KX_PROPSENSOR_CHANGED:
		{
			CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
				
			if (!orgprop->IsError())
			{
				if (m_previoustext != orgprop->GetText())
				{
					m_previoustext = orgprop->GetText();
					result = true;
				}
			}
			orgprop->Release();

			break;
		}
	case KX_PROPSENSOR_LESSTHAN:
		reverse = true;
		/* fall-through */
	case KX_PROPSENSOR_GREATERTHAN:
		{
			CValue* orgprop = GetParent()->FindIdentifier(m_checkpropname);
			if (!orgprop->IsError())
			{
				const float ref = std::stof(m_checkpropval);
				float val;

				if (orgprop->GetValueType() == VALUE_STRING_TYPE) {
					val = std::stof(orgprop->GetText());
				}
				else {
					val = orgprop->GetNumber();
				}

				if (reverse) {
					result = val < ref;
				}
				else {
					result = val > ref;
				}

			}
			orgprop->Release();

			break;
		}
	default:
		; /* error */
	}

	//the concept of Edge and Level triggering has unwanted effect for KX_PROPSENSOR_CHANGED
	//see Game Engine bugtracker [ #3809 ]
	m_recentresult = result;

	return result;
}