/* Create a feature on the map */ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,bool FromSave) { UDWORD mapX, mapY; UDWORD width,breadth, foundationMin,foundationMax, height; UDWORD startX,startY,max,min; //try and create the Feature FEATURE *psFeature = new FEATURE(generateSynchronisedObjectId(), psStats); if (psFeature == NULL) { debug(LOG_WARNING, "Feature couldn't be built."); return NULL; } // features are not in the cluster system // this will cause an assert when they still end up there psFeature->cluster = ~0; //add the feature to the list - this enables it to be drawn whilst being built addFeature(psFeature); // get the terrain average height startX = map_coord(x); startY = map_coord(y); foundationMin = TILE_MAX_HEIGHT; foundationMax = TILE_MIN_HEIGHT; for (breadth = 0; breadth < psStats->baseBreadth; breadth++) { for (width = 0; width < psStats->baseWidth; width++) { getTileMaxMin(startX + width, startY + breadth, &max, &min); if (foundationMin > min) { foundationMin = min; } if (foundationMax < max) { foundationMax = max; } } } //return the average of max/min height height = (foundationMin + foundationMax) / 2; // snap the coords to a tile if (!FromSave) { x = (x & ~TILE_MASK) + psStats->baseWidth %2 * TILE_UNITS/2; y = (y & ~TILE_MASK) + psStats->baseBreadth%2 * TILE_UNITS/2; } else { if ((x & TILE_MASK) != psStats->baseWidth %2 * TILE_UNITS/2 || (y & TILE_MASK) != psStats->baseBreadth%2 * TILE_UNITS/2) { debug(LOG_WARNING, "Feature not aligned. position (%d,%d), size (%d,%d)", x, y, psStats->baseWidth, psStats->baseBreadth); } } psFeature->pos.x = x; psFeature->pos.y = y; if (psStats->subType == FEAT_TREE) { psFeature->rot.direction = gameRand(DEG_360); } else { psFeature->rot.direction = 0; } psFeature->body = psStats->body; psFeature->inFire = false; objSensorCache((BASE_OBJECT *)psFeature, NULL); objEcmCache((BASE_OBJECT *)psFeature, NULL); // it has never been drawn psFeature->sDisplay.frameNumber = 0; for (int j = 0; j < WC_NUM_WEAPON_CLASSES; j++) { psFeature->armour[j] = psFeature->psStats->armourValue; } memset(psFeature->seenThisTick, 0, sizeof(psFeature->seenThisTick)); memset(psFeature->visible, 0, sizeof(psFeature->visible)); //load into the map data mapX = map_coord(x) - psStats->baseWidth/2; mapY = map_coord(y) - psStats->baseBreadth/2; // set up the imd for the feature psFeature->sDisplay.imd = psStats->psImd; ASSERT_OR_RETURN(NULL, psFeature->sDisplay.imd, "No IMD for feature"); // make sure we have an imd. for (width = 0; width < psStats->baseWidth; width++) { for (breadth = 0; breadth < psStats->baseBreadth; breadth++) { MAPTILE *psTile = mapTile(mapX + width, mapY + breadth); //check not outside of map - for load save game ASSERT_OR_RETURN(NULL, mapX + width < mapWidth, "x coord bigger than map width - %s, id = %d", getName(psFeature->psStats->pName), psFeature->id); ASSERT_OR_RETURN(NULL, mapY + breadth < mapHeight, "y coord bigger than map height - %s, id = %d", getName(psFeature->psStats->pName), psFeature->id); if (width != psStats->baseWidth && breadth != psStats->baseBreadth) { if (TileHasFeature(psTile)) { FEATURE *psBlock = (FEATURE *)psTile->psObject; debug(LOG_ERROR, "%s(%d) already placed at (%d+%d, %d+%d) when trying to place %s(%d) at (%d+%d, %d+%d) - removing it", getName(psBlock->psStats->pName), psBlock->id, map_coord(psBlock->pos.x), psBlock->psStats->baseWidth, map_coord(psBlock->pos.y), psBlock->psStats->baseBreadth, getName(psFeature->psStats->pName), psFeature->id, mapX, psStats->baseWidth, mapY, psStats->baseBreadth); removeFeature(psBlock); } psTile->psObject = (BASE_OBJECT*)psFeature; // if it's a tall feature then flag it in the map. if (psFeature->sDisplay.imd->max.y > TALLOBJECT_YMAX) { auxSetBlocking(mapX + width, mapY + breadth, AIR_BLOCKED); } if (psStats->subType != FEAT_GEN_ARTE && psStats->subType != FEAT_OIL_DRUM) { auxSetBlocking(mapX + width, mapY + breadth, FEATURE_BLOCKED); } } if( (!psStats->tileDraw) && (FromSave == false) ) { psTile->height = height; } } } psFeature->pos.z = map_TileHeight(mapX,mapY);//jps 18july97 return psFeature; }
/* Create a feature on the map */ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,BOOL FromSave) { UDWORD mapX, mapY; UDWORD width,breadth, foundationMin,foundationMax, height; UDWORD startX,startY,max,min; SDWORD i; UBYTE vis; //try and create the Feature FEATURE* psFeature = createFeature(); if (psFeature == NULL) { debug(LOG_WARNING, "Feature couldn't be built."); return NULL; } psFeature->psStats = psStats; // features are not in the cluster system // this will cause an assert when they still end up there psFeature->cluster = ~0; //add the feature to the list - this enables it to be drawn whilst being built addFeature(psFeature); // get the terrain average height startX = map_coord(x); startY = map_coord(y); foundationMin = TILE_MAX_HEIGHT; foundationMax = TILE_MIN_HEIGHT; for (breadth = 0; breadth < psStats->baseBreadth; breadth++) { for (width = 0; width < psStats->baseWidth; width++) { getTileMaxMin(startX + width, startY + breadth, &max, &min); if (foundationMin > min) { foundationMin = min; } if (foundationMax < max) { foundationMax = max; } } } //return the average of max/min height height = (foundationMin + foundationMax) / 2; // snap the coords to a tile if (!FromSave) { x = (x & ~TILE_MASK) + psStats->baseWidth %2 * TILE_UNITS/2; y = (y & ~TILE_MASK) + psStats->baseBreadth%2 * TILE_UNITS/2; } else { if ((x & TILE_MASK) != psStats->baseWidth %2 * TILE_UNITS/2 || (y & TILE_MASK) != psStats->baseBreadth%2 * TILE_UNITS/2) { debug(LOG_WARNING, "Feature not aligned. position (%d,%d), size (%d,%d)", x, y, psStats->baseWidth, psStats->baseBreadth); } } psFeature->pos.x = x; psFeature->pos.y = y; /* Dump down the building wrecks at random angles - still looks shit though */ if(psStats->subType == FEAT_BUILD_WRECK || psStats->subType == FEAT_TREE) { psFeature->rot.direction = gameRand(DEG_360); } else { psFeature->rot.direction = 0; } psFeature->selected = false; psFeature->body = psStats->body; psFeature->player = MAX_PLAYERS+1; //set the player out of range to avoid targeting confusions objSensorCache((BASE_OBJECT *)psFeature, NULL); objEcmCache((BASE_OBJECT *)psFeature, NULL); psFeature->bTargetted = false; psFeature->timeLastHit = 0; psFeature->lastHitWeapon = WSC_NUM_WEAPON_SUBCLASSES; // no such weapon // it has never been drawn psFeature->sDisplay.frameNumber = 0; if(getRevealStatus()) { vis = 0; } else { if(psStats->visibleAtStart) { vis = UBYTE_MAX; } else { vis = 0; } } // note that the advanced armour system current unused for features for (i = 0; i < NUM_HIT_SIDES; i++) { int j; for (j = 0; j < WC_NUM_WEAPON_CLASSES; j++) { psFeature->armour[i][j] = psFeature->psStats->armourValue; } } memset(psFeature->seenThisTick, 0, sizeof(psFeature->seenThisTick)); memset(psFeature->visible, 0, sizeof(psFeature->visible)); //load into the map data mapX = map_coord(x) - psStats->baseWidth/2; mapY = map_coord(y) - psStats->baseBreadth/2; // set up the imd for the feature if(psFeature->psStats->subType==FEAT_BUILD_WRECK) { psFeature->sDisplay.imd = getRandomWreckageImd(); } else { psFeature->sDisplay.imd = psStats->psImd; } ASSERT_OR_RETURN(NULL, psFeature->sDisplay.imd, "No IMD for feature"); // make sure we have an imd. for (width = 0; width < psStats->baseWidth; width++) { for (breadth = 0; breadth < psStats->baseBreadth; breadth++) { MAPTILE *psTile = mapTile(mapX + width, mapY + breadth); //check not outside of map - for load save game ASSERT_OR_RETURN(NULL, mapX + width < mapWidth, "x coord bigger than map width - %s, id = %d", getName(psFeature->psStats->pName), psFeature->id); ASSERT_OR_RETURN(NULL, mapY + breadth < mapHeight, "y coord bigger than map height - %s, id = %d", getName(psFeature->psStats->pName), psFeature->id); if (width != psStats->baseWidth && breadth != psStats->baseBreadth) { if (TileHasFeature(psTile)) { FEATURE *psBlock = (FEATURE *)psTile->psObject; debug(LOG_ERROR, "%s(%d) already placed at (%d+%d, %d+%d) when trying to place %s(%d) at (%d+%d, %d+%d) - removing it", getName(psBlock->psStats->pName), psBlock->id, map_coord(psBlock->pos.x), psBlock->psStats->baseWidth, map_coord(psBlock->pos.y), psBlock->psStats->baseBreadth, getName(psFeature->psStats->pName), psFeature->id, mapX, psStats->baseWidth, mapY, psStats->baseBreadth); removeFeature(psBlock); } psTile->psObject = (BASE_OBJECT*)psFeature; // if it's a tall feature then flag it in the map. if (psFeature->sDisplay.imd->max.y > TALLOBJECT_YMAX) { auxSetBlocking(mapX + width, mapY + breadth, AIR_BLOCKED); } if (psStats->subType != FEAT_GEN_ARTE && psStats->subType != FEAT_OIL_DRUM && psStats->subType != FEAT_BUILD_WRECK) { auxSetBlocking(mapX + width, mapY + breadth, FEATURE_BLOCKED); } } if( (!psStats->tileDraw) && (FromSave == false) ) { psTile->height = height; } } } psFeature->pos.z = map_TileHeight(mapX,mapY);//jps 18july97 // // set up the imd for the feature // if(psFeature->psStats->subType==FEAT_BUILD_WRECK) // { // psFeature->sDisplay.imd = wreckageImds[rand()%MAX_WRECKAGE]; // } // else // { // psFeature->sDisplay.imd = psStats->psImd; // } return psFeature; }
/* Create a feature on the map */ FEATURE * buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y,bool FromSave) { //try and create the Feature FEATURE *psFeature = new FEATURE(generateSynchronisedObjectId(), psStats); if (psFeature == NULL) { debug(LOG_WARNING, "Feature couldn't be built."); return NULL; } // features are not in the cluster system // this will cause an assert when they still end up there psFeature->cluster = ~0; //add the feature to the list - this enables it to be drawn whilst being built addFeature(psFeature); // snap the coords to a tile if (!FromSave) { x = (x & ~TILE_MASK) + psStats->baseWidth %2 * TILE_UNITS/2; y = (y & ~TILE_MASK) + psStats->baseBreadth%2 * TILE_UNITS/2; } else { if ((x & TILE_MASK) != psStats->baseWidth %2 * TILE_UNITS/2 || (y & TILE_MASK) != psStats->baseBreadth%2 * TILE_UNITS/2) { debug(LOG_WARNING, "Feature not aligned. position (%d,%d), size (%d,%d)", x, y, psStats->baseWidth, psStats->baseBreadth); } } psFeature->pos.x = x; psFeature->pos.y = y; StructureBounds b = getStructureBounds(psFeature); // get the terrain average height int foundationMin = INT32_MAX; int foundationMax = INT32_MIN; for (int breadth = 0; breadth <= b.size.y; ++breadth) { for (int width = 0; width <= b.size.x; ++width) { int h = map_TileHeight(b.map.x + width, b.map.y + breadth); foundationMin = std::min(foundationMin, h); foundationMax = std::max(foundationMax, h); } } //return the average of max/min height int height = (foundationMin + foundationMax) / 2; if (psStats->subType == FEAT_TREE) { psFeature->rot.direction = gameRand(DEG_360); } else { psFeature->rot.direction = 0; } psFeature->body = psStats->body; psFeature->periodicalDamageStart = 0; psFeature->periodicalDamage = 0; // it has never been drawn psFeature->sDisplay.frameNumber = 0; memset(psFeature->seenThisTick, 0, sizeof(psFeature->seenThisTick)); memset(psFeature->visible, 0, sizeof(psFeature->visible)); // set up the imd for the feature psFeature->sDisplay.imd = psStats->psImd; ASSERT_OR_RETURN(NULL, psFeature->sDisplay.imd, "No IMD for feature"); // make sure we have an imd. for (int breadth = 0; breadth < b.size.y; ++breadth) { for (int width = 0; width < b.size.x; ++width) { MAPTILE *psTile = mapTile(b.map.x + width, b.map.y + breadth); //check not outside of map - for load save game ASSERT_OR_RETURN(NULL, b.map.x + width < mapWidth, "x coord bigger than map width - %s, id = %d", getName(psFeature->psStats), psFeature->id); ASSERT_OR_RETURN(NULL, b.map.y + breadth < mapHeight, "y coord bigger than map height - %s, id = %d", getName(psFeature->psStats), psFeature->id); if (width != psStats->baseWidth && breadth != psStats->baseBreadth) { if (TileHasFeature(psTile)) { FEATURE *psBlock = (FEATURE *)psTile->psObject; debug(LOG_ERROR, "%s(%d) already placed at (%d+%d, %d+%d) when trying to place %s(%d) at (%d+%d, %d+%d) - removing it", getName(psBlock->psStats), psBlock->id, map_coord(psBlock->pos.x), psBlock->psStats->baseWidth, map_coord(psBlock->pos.y), psBlock->psStats->baseBreadth, getName(psFeature->psStats), psFeature->id, b.map.x, b.size.x, b.map.y, b.size.y); removeFeature(psBlock); } psTile->psObject = (BASE_OBJECT*)psFeature; // if it's a tall feature then flag it in the map. if (psFeature->sDisplay.imd->max.y > TALLOBJECT_YMAX) { auxSetBlocking(b.map.x + width, b.map.y + breadth, AIR_BLOCKED); } if (psStats->subType != FEAT_GEN_ARTE && psStats->subType != FEAT_OIL_DRUM) { auxSetBlocking(b.map.x + width, b.map.y + breadth, FEATURE_BLOCKED); } } if( (!psStats->tileDraw) && (FromSave == false) ) { psTile->height = height; } } } psFeature->pos.z = map_TileHeight(b.map.x, b.map.y);//jps 18july97 return psFeature; }