bool CScriptRMI::SerializeScript( TSerialize ser, IEntity * pEntity ) { SSerializeFunctionParams p( ser, pEntity ); ScriptHandle hdl( &p ); IScriptTable * pTable = pEntity->GetScriptTable(); if (pTable) { SmartScriptTable serTable; SmartScriptTable synchedTable; pTable->GetValue( "synched", synchedTable ); if (synchedTable.GetPtr()) { synchedTable->GetValue( HIDDEN_FIELD, serTable ); if (serTable.GetPtr()) { IScriptSystem * pScriptSystem = pTable->GetScriptSystem(); pScriptSystem->BeginCall( serTable.GetPtr(), SERIALIZE_FUNCTION ); pScriptSystem->PushFuncParam( serTable ); pScriptSystem->PushFuncParam( hdl ); return pScriptSystem->EndCall(); } } } return true; }
//------------------------------------------------------------------------ void CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo) { switch (simpleHitInfo.type) { case 0: // tag { if (!simpleHitInfo.targetId) { return; } // tagged entities are temporary in MP, not in SP. bool temp = gEnv->bMultiplayer; AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp); } break; case 1: // tac { if (!simpleHitInfo.targetId) { return; } CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId); if (pActor && pActor->CanSleep()) { pActor->Fall(Vec3(0.0f, 0.0f, 0.0f), simpleHitInfo.value); } } break; case 0xe: // freeze { if (!simpleHitInfo.targetId) { return; } // call OnFreeze bool allow = true; if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze") == svtFunction) { HSCRIPTFUNCTION func = 0; m_serverStateScript->GetValue("OnFreeze", func); Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow); gEnv->pScriptSystem->ReleaseFunc(func); } if (!allow) { return; } if (IEntity *pEntity = gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId)) { IScriptTable *pScriptTable = pEntity->GetScriptTable(); // call OnFrost if (pScriptTable && pScriptTable->GetValueType("OnFrost") == svtFunction) { HSCRIPTFUNCTION func = 0; pScriptTable->GetValue("OnFrost", func); Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value); gEnv->pScriptSystem->ReleaseFunc(func); } FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value > 0.999f); } } break; default: assert(!"Unknown Simple Hit type!"); } }
// initialize an entity for networked methods void CScriptRMI::SetupEntity( EntityId eid, IEntity * pEntity, bool client, bool server ) { if (!m_pParent) { GameWarning( "Trying to setup an entity for network with no game started... failing" ); return; } IEntityClass * pClass = pEntity->GetClass(); stack_string className = pClass->GetName(); IScriptTable * pEntityTable = pEntity->GetScriptTable(); IScriptSystem * pSS = pEntityTable->GetScriptSystem(); SmartScriptTable clientDispatchTable, serverDispatchTable, serverSynchedTable; pEntityTable->GetValue( CLIENT_DISPATCH_FIELD, clientDispatchTable ); pEntityTable->GetValue( SERVER_DISPATCH_FIELD, serverDispatchTable ); pEntityTable->GetValue( SERVER_SYNCHED_FIELD, serverSynchedTable ); bool validated; if (clientDispatchTable.GetPtr()) { if (!clientDispatchTable->GetValue(VALIDATED_FIELD, validated)) return; if (!validated) { SmartScriptTable methods; if (!pEntityTable->GetValue( "Client", methods )) { GameWarning( "No Client table, but has a client dispatch on class %s", pEntity->GetClass()->GetName() ); return; } if (!ValidateDispatchTable( pEntity->GetClass()->GetName(), clientDispatchTable, methods, false )) return; } } if (serverDispatchTable.GetPtr()) { if (!serverDispatchTable->GetValue(VALIDATED_FIELD, validated)) return; if (!validated) { SmartScriptTable methods; if (!pEntityTable->GetValue( "Server", methods )) { GameWarning( "No Server table, but has a server dispatch on class %s", pEntity->GetClass()->GetName() ); return; } if (!ValidateDispatchTable( pEntity->GetClass()->GetName(), serverDispatchTable, methods, true )) return; } } ScriptHandle id; id.n = eid; ScriptHandle flags; if (client && serverDispatchTable.GetPtr()) { flags.n = eDF_ToServer; AddProxyTable( pEntityTable, id, flags, "server", serverDispatchTable ); } if (server && clientDispatchTable.GetPtr()) { // only expose ownClient, otherClients for actors with a channelId flags.n = eDF_ToClientOnChannel; AddProxyTable( pEntityTable, id, flags, "onClient", clientDispatchTable ); flags.n = eDF_ToClientOnOtherChannels; AddProxyTable( pEntityTable, id, flags, "otherClients", clientDispatchTable ); flags.n = eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels; AddProxyTable( pEntityTable, id, flags, "allClients", clientDispatchTable ); } if (serverSynchedTable.GetPtr()) { AddSynchedTable( pEntityTable, id, "synched", serverSynchedTable ); } CryAutoCriticalSection lkDispatch(m_dispatchMutex); std::map<string, size_t>::iterator iter = m_entityClassToEntityTypeID.find(CONST_TEMP_STRING(pEntity->GetClass()->GetName())); if (iter == m_entityClassToEntityTypeID.end()) { //[Timur] commented out as spam. //GameWarning("[scriptrmi] unable to find class %s", pEntity->GetClass()->GetName()); } else m_entities[eid] = iter->second; }