Example #1
0
// NOTE Mrz 21, 2007: <pvl> might need to handle the params the way SetGrab()
// does (separate param table for each of the grabbed objects).
// UPDATE Mrz 26, 2007: <pvl> done
bool CMultipleGrabHandler::SetDrop(SmartScriptTable &rParams)
{
	SmartScriptTable dropParamsTable;
	if (rParams->GetValue("params",dropParamsTable))
	{
		bool result = true;

		IScriptTable::Iterator iter = dropParamsTable->BeginIteration();
		int numGrabHandlers = m_handlers.size();

		for (int i=0; dropParamsTable->MoveNext(iter) && i < numGrabHandlers; ++i)
		{
			SmartScriptTable params;
			iter.value.CopyTo (params);
			result = m_handlers[i]->SetDrop(params) & result;
		}

		dropParamsTable->EndIteration(iter);

		return result;
	}
	else
	{
		bool result = true;

		std::vector <CAnimatedGrabHandler*>::iterator it = m_handlers.begin();
		std::vector <CAnimatedGrabHandler*>::iterator end = m_handlers.end();
		for ( ; it != end; ++it)
			result = (*it)->SetDrop(rParams) & result;

		return result;
	}
}
Example #2
0
// add a synch proxy table to an entity
void CScriptRMI::AddSynchedTable( IScriptTable * pEntityTable, 
																  ScriptHandle id,
																  const char * name, SmartScriptTable dispatchTable )
{
	SmartScriptTable synchedTable( pEntityTable->GetScriptSystem() );
	SmartScriptTable hiddenTable( pEntityTable->GetScriptSystem() );
	SmartScriptTable origTable;
	pEntityTable->GetValue( name, origTable );

	hiddenTable->Clone( dispatchTable );
	hiddenTable->SetValue( "__index", hiddenTable );

	IScriptTable::Iterator iter = origTable->BeginIteration();
	while (origTable->MoveNext(iter))
	{
		if (iter.sKey)
		{
			if (hiddenTable->GetValueType( iter.sKey ) != svtNull)
				GameWarning( "Replacing non-null value %s", iter.sKey );

			ScriptAnyValue value;
			origTable->GetValueAny( iter.sKey, value );
			hiddenTable->SetValueAny( iter.sKey, value );
		}
	}
	origTable->EndIteration(iter);

	synchedTable->Delegate( hiddenTable );
	synchedTable->SetValue( ID_FIELD, id );
	synchedTable->SetValue( HIDDEN_FIELD, hiddenTable );
	pEntityTable->SetValue( name, synchedTable );
}
Example #3
0
bool CMultipleGrabHandler::SetGrab(SmartScriptTable &rParams)
{
	// NOTE Mrz 20, 2007: <pvl> if we don't find 'params' param in the table,
	// we assume that this is an old-style grab param table that's not aware of
	// the possibility of multiple objects grabbed simultaneously.  

	SmartScriptTable grabParamsTable;
	if (rParams->GetValue("params",grabParamsTable))
	{
		bool result = true;

		IScriptTable::Iterator iter = grabParamsTable->BeginIteration();

		while(grabParamsTable->MoveNext(iter))
		{
			CAnimatedGrabHandler * handler = new CAnimatedGrabHandler (m_pActor);
			SmartScriptTable params;
			iter.value.CopyTo (params);
			result = handler->SetGrab(params) & result;
			m_handlers.push_back (handler);
		}

		grabParamsTable->EndIteration(iter);

		return result;
	}
	else
	{
		CAnimatedGrabHandler * handler = new CAnimatedGrabHandler (m_pActor);
		m_handlers.push_back (handler);
		return handler->SetGrab(rParams);
	}
}
Example #4
0
//------------------------------------------------------------------------
int CScriptBind_Actor::CheckVirtualInventoryRestrictions(IFunctionHandler *pH, SmartScriptTable inventory, const char *itemClassName)
{
	CActor *pActor = GetActor(pH);
	if (!pActor)
		return pH->EndFunction();

	static std::vector<string> virtualInventory;
	virtualInventory.reserve(inventory->Count());

	IScriptTable::Iterator it=inventory->BeginIteration();
	while(inventory->MoveNext(it))
	{
		const char *itemClass=0;
		it.value.CopyTo(itemClass);

		if (itemClass && itemClass[0])
			virtualInventory.push_back(itemClass);
	}

	inventory->EndIteration(it);

	bool result=pActor->CheckVirtualInventoryRestrictions(virtualInventory, itemClassName);
	virtualInventory.resize(0);

	if (result)
		return pH->EndFunction(1);

	return pH->EndFunction();
}
Example #5
0
bool CAnimatedGrabHandler::SetGrab(SmartScriptTable &rParams)
{
	// NOTE Aug 16, 2007: <pvl> if there's another grab action under way, this one fails
	// first the cheaper check (should also cover the case when output is not yet set because of longer transition time)
	if (m_grabStats.IKActive == true)
		return false;
	// then the more expensive check
	if (IAnimationGraphState* pAGState = m_pActor->GetAnimationGraphState())
	{
		const char* grabActive = pAGState->QueryOutput("GrabActive");
		if (grabActive != NULL && grabActive[0] != 0)
			return false;
	}
	if (m_grabStats.grabId > 0)
		Reset();

	m_grabStats.useIKRotation = false;
	rParams->GetValue("useIKRotation",m_grabStats.useIKRotation);

	m_grabStats.limbNum = 0;

	SmartScriptTable limbsTable;
	if (rParams->GetValue("limbs",limbsTable))
	{
		IScriptTable::Iterator iter = limbsTable->BeginIteration();
	
		while(limbsTable->MoveNext(iter))
		{
			const char *pLimb;
			iter.value.CopyTo(pLimb);

			int limbIdx = m_pActor->GetIKLimbIndex(pLimb);
			if (limbIdx > -1 && m_grabStats.limbNum<GRAB_MAXLIMBS)
				m_grabStats.limbId[m_grabStats.limbNum++] = limbIdx;
		}

		limbsTable->EndIteration(iter);
	}

	m_grabStats.usingAnimation = false;

	const char * pCarryAnimGraphInput = 0;
	if (rParams->GetValue("carryAnimGraphInput",pCarryAnimGraphInput))
	{
		const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
		strncpy(m_grabStats.carryAnimGraphInput,pCarryAnimGraphInput,maxNameLen);
		m_grabStats.carryAnimGraphInput[maxNameLen-1] = 0;
	}
	
	SmartScriptTable animationTable;
	if (rParams->GetValue("animation",animationTable))
	{
		const char *pAnimGraphSignal = NULL;

		if (animationTable->GetValue("animGraphSignal",pAnimGraphSignal))
		{
			const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
			strncpy(m_grabStats.grabAnimGraphSignal,pAnimGraphSignal,maxNameLen);
			m_grabStats.grabAnimGraphSignal[maxNameLen-1] = 0;
		}

		// TODO Dez 15, 2006: <pvl> if there's no graph signal, consider
		// returning false - won't work without graph signal anyway
		if (pAnimGraphSignal)
		{
			m_grabStats.usingAnimation = true;
			m_grabStats.usingAnimationForDrop = true;
			m_grabStats.usingAnimationForGrab = true;
		}

		if (animationTable->GetValue("forceThrow",m_grabStats.throwDelay))
		{
			//m_grabStats.grabDelay = 0.0f;
			m_grabStats.maxDelay = m_grabStats.throwDelay;
		}

		m_grabStats.grabbedObjOfs.zero();
		animationTable->GetValue("grabbedObjOfs",m_grabStats.grabbedObjOfs);

		m_grabStats.releaseIKTime = 0.0f;
		animationTable->GetValue("releaseIKTime",m_grabStats.releaseIKTime);
	} else {
		if (rParams->GetValue("grabAnim",animationTable))
		{
			m_grabStats.usingAnimationForGrab = true;

			m_grabStats.releaseIKTime = 0.0f;
			animationTable->GetValue("releaseIKTime",m_grabStats.releaseIKTime);

			m_grabStats.grabbedObjOfs.zero();
			animationTable->GetValue("grabbedObjOfs",m_grabStats.grabbedObjOfs);

			const char *pAnimGraphSignal = NULL;
			if (animationTable->GetValue("animGraphSignal",pAnimGraphSignal))
			{
				const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
				strncpy(m_grabStats.grabAnimGraphSignal,pAnimGraphSignal,maxNameLen);
				m_grabStats.grabAnimGraphSignal[maxNameLen-1] = 0;
			}
		}
		if (rParams->GetValue("dropAnim",animationTable))
		{
			m_grabStats.usingAnimationForDrop = true;

			// NOTE Feb 10, 2007: <pvl> this is just to get around the
			// condition in CBaseGrabHandler::SetDrop().  If we don't set
			// throwDelay to something bigger than zero SetDrop() executes
			// StartDrop() immediately.
			// All of this stuff around maxDelay, throwDelay etc. should be
			// rewritten but in a way that doesn't break existing behaviour.
			m_grabStats.throwDelay = 1000.0f;

			const char *pAnimGraphSignal = NULL;
			if (animationTable->GetValue("animGraphSignal",pAnimGraphSignal))
			{
				const int maxNameLen = SGrabStats::s_maxAGInputNameLen;
				strncpy(m_grabStats.dropAnimGraphSignal,pAnimGraphSignal,SGrabStats::s_maxAGInputNameLen);
				m_grabStats.dropAnimGraphSignal[maxNameLen-1] = 0;
			}
		}
		m_grabStats.usingAnimation = m_grabStats.usingAnimationForDrop || m_grabStats.usingAnimationForGrab;
	}

	m_grabStats.followBoneID = -1;

	const char *followBone;
	if (rParams->GetValue("followBone",followBone))
	{
		ICharacterInstance *pCharacter = m_pActor->GetEntity()->GetCharacter(0);
		if (pCharacter)
			m_grabStats.followBoneID = pCharacter->GetISkeletonPose()->GetJointIDByName(followBone);
	}
	// TODO Dez 15, 2006: <pvl> consider returning false if bone ID is -1
	// at this point - it won't work anyway without bone ID
	

	//FIXME:remove this garbage when the grabbing setup is refactored too
	float savedThrowDelay(m_grabStats.throwDelay);
	if ( ! CBaseGrabHandler::SetGrab(rParams))
		return false;

	m_grabStats.additionalRotation.SetIdentity();
	m_grabStats.origRotation.SetIdentity();

	if (m_grabStats.carryAnimGraphInput[0])
	{
		m_pActor->SetAnimationInput("CarryItem",m_grabStats.carryAnimGraphInput);	
	}
	if (m_grabStats.grabAnimGraphSignal[0])
	{
		m_pActor->SetAnimationInput("Signal",m_grabStats.grabAnimGraphSignal);
	}
	if ( ! m_grabStats.usingAnimationForGrab)
	{
		StartGrab();
	}

	m_grabStats.maxDelay = m_grabStats.throwDelay = savedThrowDelay;

	return true;
}
Example #6
0
// one-time validation of entity tables
bool CScriptRMI::ValidateDispatchTable( const char * clazz, SmartScriptTable dispatch, SmartScriptTable methods, bool bServerTable )
{
	CryAutoCriticalSection lkDispatch(m_dispatchMutex);

	std::map<string,size_t>::iterator iterN = m_entityClassToEntityTypeID.lower_bound(clazz);
	if (iterN == m_entityClassToEntityTypeID.end() || iterN->first != clazz)
	{
		iterN = m_entityClassToEntityTypeID.insert( iterN, std::make_pair(clazz, m_entityClassToEntityTypeID.size()) );
		CRY_ASSERT(iterN->second == m_dispatch.size());
		m_dispatch.push_back(SDispatch());
	}
	SDispatch& dispatchTblCont = m_dispatch[iterN->second];
	SFunctionDispatchTable& dispatchTbl = bServerTable ? dispatchTblCont.server : dispatchTblCont.client;

	IScriptTable::Iterator iter = dispatch->BeginIteration();
	while (dispatch->MoveNext(iter))
	{
		if (iter.sKey)
		{
			if (iter.sKey[0] == '_' && iter.sKey[1] == '_')
				continue;

			ScriptVarType type = methods->GetValueType( iter.sKey );
			if (type != svtFunction)
			{
				GameWarning( "In class %s: function %s is exposed but not defined",
					clazz, iter.sKey );
				dispatch->EndIteration(iter);
				return false;
			}
		}
		else
		{
			int id = iter.nKey;
			CRY_ASSERT(id>0);
			id--;

			if (id >= dispatchTbl.size())
				dispatchTbl.resize(id+1);
			SFunctionDispatch& dt = dispatchTbl[id];
			if (iter.value.GetVarType() != svtString)
			{
				GameWarning("Expected a string in dispatch table, got type %d", iter.value.GetVarType());
				dispatch->EndIteration(iter);
				return false;
			}

			const char * funcData = iter.value.str;
			const char * colon = strchr(funcData, ':');
			if (colon == NULL)
			{
				dispatch->EndIteration(iter);
				return false;
			}
			if (colon - funcData > MaxSynchedPropertyNameLength)
			{
				dispatch->EndIteration(iter);
				return false;
			}
			memcpy( dt.name, funcData, colon-funcData );
			dt.name[colon-funcData] = 0;
			strcpy(dt.format, colon + 1);
		}
	}
	dispatch->EndIteration(iter);
	dispatch->SetValue( VALIDATED_FIELD, true );

	if (bServerTable)
	{
		dispatchTblCont.m_serverDispatchScriptTable = dispatch;
	}
	else
	{
		dispatchTblCont.m_clientDispatchScriptTable = dispatch;
	}

	return true;
}
Example #7
0
// setup the meta-table for synched variables
bool CScriptRMI::BuildSynchTable( SmartScriptTable vars, SmartScriptTable cls, const char * name )
{
	IScriptSystem * pSS = vars->GetScriptSystem();
	SmartScriptTable synched( pSS );
	SmartScriptTable defaultValues( pSS );

	// TODO: Improve
	IScriptTable::SUserFunctionDesc fd;
	fd.pFunctor = functor_ret( SynchedNewIndexFunction );
	fd.sFunctionName = "__newindex";
	fd.sGlobalName = "<net-dispatch>";
	fd.sFunctionParams = "(...)";
	synched->AddFunction( fd );

	std::vector<SSynchedPropertyInfo> properties;

	IScriptTable::Iterator iter = vars->BeginIteration();
	while (vars->MoveNext(iter))
	{
		if (iter.sKey)
		{
			int type;
			if (!vars->GetValue(iter.sKey, type))
			{
				vars->EndIteration(iter);
				pSS->RaiseError( "No type for %s", iter.sKey );
				return false;
			}
			size_t len = strlen(iter.sKey);
			if (len > MaxSynchedPropertyNameLength)
			{
				vars->EndIteration(iter);
				pSS->RaiseError( "Synched var name '%s' too long (max is %d)",
					iter.sKey, (int)MaxSynchedPropertyNameLength );
				return false;
			}
			SSynchedPropertyInfo info;
			strcpy( info.name, iter.sKey );
			info.type = (EScriptSerializeType) type;
			properties.push_back( info );

			if (info.type == eSST_String)
				defaultValues->SetValue( iter.sKey, "" );
			else
				defaultValues->SetValue( iter.sKey, 0 );
		}
	}
	vars->EndIteration( iter );

	if (properties.empty())
		return true;

	fd.pFunctor = NULL;
	fd.pUserDataFunc = SerializeFunction;
	fd.nDataSize = sizeof(SSynchedPropertyInfo) * properties.size();
	fd.pDataBuffer = &properties[0];
	fd.sFunctionName = SERIALIZE_FUNCTION;
	fd.sFunctionParams = "(...)";
	fd.sGlobalName = "<net-dispatch>";
	synched->AddFunction( fd );

	cls->SetValue( SERVER_SYNCHED_FIELD, synched );
	cls->SetValue( "synched", defaultValues );

	return true;
}
Example #8
0
// build a script dispatch table - this table is the metatable for all
// dispatch proxy tables used (onClient, allClients, otherClients)
bool CScriptRMI::BuildDispatchTable( 
	SmartScriptTable methods, 
	SmartScriptTable classMethodTable, 
	SmartScriptTable cls, 
	const char * name )
{
	IScriptSystem * pSS = methods->GetScriptSystem();
	SmartScriptTable dispatch( pSS );

	uint8 funcID = 0;

	IScriptTable::SUserFunctionDesc fd;
	SFunctionInfo info;

	IScriptTable::Iterator iter = methods->BeginIteration();
	while (methods->MoveNext(iter))
	{
		if (iter.sKey)
		{
			const char * function = iter.sKey;

			if (strlen(function)>=2 && function[0] == '_' && function[1] == '_')
			{
				methods->EndIteration(iter);
				pSS->RaiseError( "In Net.Expose: can't expose functions beginning with '__' (function was %s)",
					function );
				return false;
			}

			SmartScriptTable specTable;
			if (!methods->GetValue(function, specTable))
			{
				methods->EndIteration(iter);
				pSS->RaiseError( "In Net.Expose: function %s entry is not a table (in %s)", 
					function, name );
				return false;
			}

			// fetch format
			int count = specTable->Count();
			if (count < 1)
			{
				methods->EndIteration(iter);
				pSS->RaiseError( "In Net.Expose: function %s entry is an empty table (in %s)", 
					function, name );
				return false;
			}
			else if (count-1 > MaxRMIParameters)
			{
				methods->EndIteration(iter);
				pSS->RaiseError( "In Net.Expose: function %s has too many parameters (%d) (in %s)", 
					function, count-1, name );
				return false;
			}
			int tempReliability;
			if (!specTable->GetAt(1, tempReliability) || tempReliability < 0 || tempReliability >= eNRT_NumReliabilityTypes)
			{
				methods->EndIteration(iter);
				pSS->RaiseError( "In Net.Expose: function %s has invalid reliability type %d (in %s)", 
					function, tempReliability, name );
				return false;
			}
			ENetReliabilityType reliability = (ENetReliabilityType) tempReliability;
			if (!specTable->GetAt(2, tempReliability) || tempReliability < 0 || tempReliability >= eRAT_NumAttachmentTypes)
			{
				methods->EndIteration(iter);
				pSS->RaiseError( "In Net.Expose: function %s has invalid attachment type %d (in %s)", 
					function, tempReliability, name );
			}
			ERMIAttachmentType attachment = (ERMIAttachmentType) tempReliability;
			string format;
			format.reserve(count-1);
			for (int i=3; i<=count; i++)
			{
				int type = 666;
				if (!specTable->GetAt( i, type ) || type<-128 || type>127)
				{
					methods->EndIteration(iter);
					pSS->RaiseError( "In Net.Expose: function %s has invalid serialization policy %d at %d (in %s)", 
						function, type, i, name );
					return false;
				}
				format.push_back( (char) type );
			}

			CRY_ASSERT( format.length() <= MaxRMIParameters );
			strcpy( info.format, format.c_str() );
			info.funcID = funcID;
			info.reliability = reliability;
			info.attachment = attachment;

			fd.pUserDataFunc = ProxyFunction;
			fd.sFunctionName = function;
			fd.nDataSize = sizeof(SFunctionInfo);
			fd.pDataBuffer = &info;
			fd.sGlobalName = "<net-dispatch>";
			fd.sFunctionParams = "(...)";

			dispatch->AddFunction( fd );

			string lookupData = function;
			lookupData += ":";
			lookupData += format;
			dispatch->SetAt( funcID+1, lookupData.c_str() );


			funcID ++;
			if (funcID == 0)
			{
				funcID--;
				methods->EndIteration(iter);
				pSS->RaiseError( "Too many functions... max is %d", funcID );
				return false;
			}
		}
		else
		{
			GameWarning( "In Net.Expose: non-string key ignored" );
		}
	}
	methods->EndIteration(iter);

	dispatch->SetValue( VALIDATED_FIELD, false );
	cls->SetValue( name, dispatch );

	return true;
}