void TensegrityModel::setup(tgWorld& world) { // create the build spec that uses tags to turn the structure into a model tgBuildSpec spec; // add default rod and string builders that match the tags rods & strings // (these will be overwritten if a different builder is specified for those tags) Yam emptyYam = Yam(); addRodBuilder("tgRodInfo", "rod", emptyYam, spec); addBasicActuatorBuilder("tgBasicActuatorInfo", "string", emptyYam, spec); tgStructure structure; buildStructure(structure, topLvlStructurePath, spec); tgStructureInfo structureInfo(structure, spec); structureInfo.buildInto(*this, world); // use tgCast::filterto pull out the muscles that we want to control allActuators = tgCast::filter<tgModel, tgSpringCableActuator> (getDescendants()); // notify controllers that setup has finished notifySetup(); // actually setup the children tgModel::setup(world); }
void TensegrityModel::addChild(tgStructure& structure, const std::string &parentPath, const std::string& childName, const Yam& childStructurePath, tgBuildSpec& spec) { if (!childStructurePath) return; std::string childPath = childStructurePath.as<std::string>(); // if path is relative, use path relative to parent structure if (childPath[0] != '/') { childPath = parentPath.substr(0, parentPath.rfind("/") + 1) + childPath; } tgStructure childStructure = tgStructure(childName); buildStructure(childStructure, childPath, spec); structure.addChild(childStructure); }
// //////////////////////////////////////////////////////////////////////////// BOOL recvBuildFinished(NETQUEUE queue) { uint32_t structId; STRUCTURE *psStruct; Position pos; uint32_t type,typeindex; uint8_t player; NETbeginDecode(queue, GAME_BUILDFINISHED); NETuint32_t(&structId); // get the struct id. NETuint32_t(&type); // Kind of building. NETPosition(&pos); // pos NETuint8_t(&player); NETend(); ASSERT( player < MAX_PLAYERS, "invalid player %u", player); psStruct = IdToStruct(structId,ANYPLAYER); if (psStruct) { // make it complete. psStruct->currentBuildPts = psStruct->pStructureType->buildPoints+1; if (psStruct->status != SS_BUILT) { debug(LOG_SYNC, "Synch error, structure %u was not complete, and should have been.", structId); psStruct->status = SS_BUILT; buildingComplete(psStruct); } debug(LOG_SYNC, "Created normal building %u for player %u", psStruct->id, player); return true; } // The building wasn't started, so we'll have to just plonk it down in the map. // Find the structures stats for (typeindex=0; // Find structure target (typeindex<numStructureStats ) && (asStructureStats[typeindex].ref != type); typeindex++); // Check for similar buildings, to avoid overlaps if (TileHasStructure(mapTile(map_coord(pos.x), map_coord(pos.y)))) { // Get the current structure psStruct = getTileStructure(map_coord(pos.x), map_coord(pos.y)); if (asStructureStats[typeindex].type == psStruct->pStructureType->type) { // Correct type, correct location, just rename the id's to sync it.. (urgh) psStruct->id = structId; psStruct->status = SS_BUILT; buildingComplete(psStruct); debug(LOG_SYNC, "Created modified building %u for player %u", psStruct->id, player); #if defined (DEBUG) NETlogEntry("structure id modified", SYNC_FLAG, player); #endif return true; } } // Build the structure psStruct = buildStructure(&(asStructureStats[typeindex]), pos.x, pos.y, player, true); if (psStruct) { psStruct->id = structId; psStruct->status = SS_BUILT; buildingComplete(psStruct); debug(LOG_SYNC, "Huge synch error, forced to create building %u for player %u", psStruct->id, player); #if defined (DEBUG) NETlogEntry("had to plonk down a building", SYNC_FLAG, player); #endif } else { debug(LOG_SYNC, "Gigantic synch error, unable to create building for player %u", player); NETlogEntry("had to plonk down a building, BUT FAILED!", SYNC_FLAG, player); } return false; }
// //////////////////////////////////////////////////////////////////////////// BOOL recvBuildFinished(NETMSG *m) { UDWORD strId;//,i; STRUCTURE *psStr; UWORD x,y,z; UDWORD type,typeindex; UBYTE player; NetGet(m,0,strId); // get the struct id. psStr = IdToStruct(strId,ANYPLAYER); if(psStr) { // make it complete. psStr->currentBuildPts = psStr->pStructureType->buildPoints+1; if(psStr->status != SS_BUILT) { psStr->status = SS_BUILT; buildingComplete(psStr); } NETlogEntry("building finished ok." ,0,0); return TRUE; } // the building wasn't started, so we'll have to just plonk it down in the map. NetGet(m,4,type); // kind of building. NetGet(m,8,x); // x pos NetGet(m,10,y); // y pos NetGet(m,12,z); // z pos player = m->body[14]; // player for(typeindex=0; // find structure target (typeindex<numStructureStats ) && (asStructureStats[typeindex].ref != type); typeindex++); psStr = 0; // check for similar buildings, to avoid overlaps if( TILE_HAS_STRUCTURE(mapTile(x>>TILE_SHIFT,y>>TILE_SHIFT)) ) { // get structure; psStr = getTileStructure(x>>TILE_SHIFT, y>>TILE_SHIFT); if(asStructureStats[typeindex].type == psStr->pStructureType->type) { // correct type, correct location, just rename the id's to sync it.. (urgh) psStr->id = strId; psStr->status = SS_BUILT; buildingComplete(psStr); NETlogEntry("structure id modified" ,0,player); return TRUE; } } psStr = buildStructure(&(asStructureStats[typeindex]), // build the structure. x,y, player,TRUE); if (psStr) { psStr->id = strId; psStr->status = SS_BUILT; buildingComplete(psStr); DBCONPRINTF(ConsoleString,(ConsoleString,"MultiPlayer: Struct not found on recvbuildcomplete :%d",strId )); NETlogEntry("had to plonk down a building" ,0,player); } else { DBCONPRINTF(ConsoleString,(ConsoleString,"MultiPlayer: Struct not found on recvbuildcomplete BUILDIT FAILED TOO!:%d",strId )); NETlogEntry("had to plonk down a building, BUT FAILED OH S**T." ,0,player); } return FALSE; }
// receive checking info about a structure and update local world state BOOL recvStructureCheck(NETQUEUE queue) { uint32_t synchTime; STRUCTURE *pS; BOOL hasCapacity = true; int j; Rotation rot; uint8_t player, ourCapacity; uint32_t body; uint32_t ref; uint32_t type; NETbeginDecode(queue, GAME_CHECK_STRUCT); NETuint8_t(&player); NETuint32_t(&synchTime); NETuint32_t(&ref); NETuint32_t(&body); NETuint32_t(&type); NETRotation(&rot); if (player >= MAX_PLAYERS) { debug(LOG_ERROR, "Bad GAME_CHECK_STRUCT received!"); NETend(); return false; } if (structureCheckLastSent != synchTime) { debug(LOG_ERROR, "We got a structure synch at the wrong time."); } if (ref != structureCheckLastId[player]) { debug(LOG_ERROR, "We got a structure %u synch, but had chosen %u instead.", ref, structureCheckLastId[player]); NETend(); return false; } // If the structure exists our job is easy pS = IdToStruct(ref, player); if (pS) { syncDebugStructure(pS, '<'); if (pS->pStructureType->type != structureCheckLastType[player] || type != structureCheckLastType[player]) { debug(LOG_ERROR, "GAME_CHECK_STRUCT received, wrong structure type!"); NETend(); return false; } // Check its finished if (pS->status != SS_BUILT) { pS->rot = rot; pS->id = ref; pS->status = SS_BUILT; buildingComplete(pS); } // If the structure has a capacity switch (pS->pStructureType->type) { case REF_RESEARCH: ourCapacity = ((RESEARCH_FACILITY *) pS->pFunctionality)->capacity; j = researchModuleStat; break; case REF_FACTORY: case REF_VTOL_FACTORY: ourCapacity = ((FACTORY *) pS->pFunctionality)->capacity; j = factoryModuleStat; break; case REF_POWER_GEN: ourCapacity = ((POWER_GEN *) pS->pFunctionality)->capacity; j = powerModuleStat; break; default: hasCapacity = false; break; } // So long as the struct has a capacity fetch it from the packet if (hasCapacity) { uint8_t actualCapacity = 0; NETuint8_t(&actualCapacity); // If our capacity is different upgrade ourself for (; ourCapacity < actualCapacity; ourCapacity++) { debug(LOG_SYNC, "Structure %u out of synch, adding module.", ref); buildStructure(&asStructureStats[j], pS->pos.x, pS->pos.y, pS->player, false); // Check it is finished if (pS && pS->status != SS_BUILT) { pS->id = ref; pS->status = SS_BUILT; buildingComplete(pS); } } } #define MERGEDELTA(x, y, ya, z) if (y != ya) { debug(LOG_SYNC, "Structure %u out of synch, changing "#x" from %"z" to %"z".", ref, x, x + y - ya); x += y - ya; } MERGEDELTA(pS->body, body, structureCheckLastBody[player], "u"); MERGEDELTA(pS->rot.direction, rot.direction, structureCheckLastDirection[player].direction, "d"); MERGEDELTA(pS->rot.pitch, rot.pitch, structureCheckLastDirection[player].pitch, "d"); MERGEDELTA(pS->rot.roll, rot.roll, structureCheckLastDirection[player].roll, "d"); #undef MERGEDELTA syncDebugStructure(pS, '>'); } else { debug(LOG_ERROR, "We got a structure %u synch, but can't find the structure.", ref); } NETend(); return true; }
// //////////////////////////////////////////////////////////////////////////// BOOL recvBuildFinished() { uint32_t structId; STRUCTURE *psStruct; int32_t x,y,z; uint32_t type,typeindex; uint8_t player; uint32_t power; NETbeginDecode(NET_BUILDFINISHED); NETuint32_t(&power); // get the player's power level NETuint32_t(&structId); // get the struct id. NETuint32_t(&type); // Kind of building. NETint32_t(&x); // x pos NETint32_t(&y); // y pos NETint32_t(&z); // z pos NETuint8_t(&player); NETend(); ASSERT( player < MAX_PLAYERS, "invalid player %u", player); psStruct = IdToStruct(structId,ANYPLAYER); setPower( (uint32_t)player, power); // we sync the power level as well if (psStruct) { // make it complete. psStruct->currentBuildPts = psStruct->pStructureType->buildPoints+1; if (psStruct->status != SS_BUILT) { psStruct->status = SS_BUILT; buildingComplete(psStruct); } debug(LOG_SYNC, "Created normal building %u for player %u", psStruct->id, player); return true; } // The building wasn't started, so we'll have to just plonk it down in the map. // Find the structures stats for (typeindex=0; // Find structure target (typeindex<numStructureStats ) && (asStructureStats[typeindex].ref != type); typeindex++); // Check for similar buildings, to avoid overlaps if (TileHasStructure(mapTile(map_coord(x), map_coord(y)))) { // Get the current structure psStruct = getTileStructure(map_coord(x), map_coord(y)); if (asStructureStats[typeindex].type == psStruct->pStructureType->type) { // Correct type, correct location, just rename the id's to sync it.. (urgh) psStruct->id = structId; psStruct->status = SS_BUILT; buildingComplete(psStruct); debug(LOG_SYNC, "Created modified building %u for player %u", psStruct->id, player); #if defined (DEBUG) NETlogEntry("structure id modified", SYNC_FLAG, player); #endif return true; } } // Build the structure psStruct = buildStructure(&(asStructureStats[typeindex]), x, y, player, true); if (psStruct) { psStruct->id = structId; psStruct->status = SS_BUILT; buildingComplete(psStruct); debug(LOG_SYNC, "Forced to create building %u for player %u", psStruct->id, player); #if defined (DEBUG) NETlogEntry("had to plonk down a building" ,SYNC_FLAG, player); #endif } else { debug(LOG_SYNC, "Unable to create building for player %u", player); NETlogEntry("had to plonk down a building, BUT FAILED!" , SYNC_FLAG, player); } return false; }