// ----------------------------------------------------------------------------- void renderParticle( ATPART *psPart ) { Vector3i dv; SDWORD x, y, z, rx, rz; x = psPart->position.x; y = psPart->position.y; z = psPart->position.z; /* Transform it */ dv.x = ((UDWORD)x - player.p.x) - terrainMidX * TILE_UNITS; dv.y = (UDWORD)y; dv.z = terrainMidY * TILE_UNITS - ((UDWORD)z - player.p.z); pie_MatBegin(); /* Push the identity matrix */ pie_TRANSLATE(dv.x,dv.y,dv.z); rx = map_round(player.p.x); /* Get the x,z translation components */ rz = map_round(player.p.z); pie_TRANSLATE(rx,0,-rz); /* Translate */ /* Make it face camera */ pie_MatRotY(-player.r.y); pie_MatRotY(-player.r.x); /* Scale it... */ pie_MatScale(psPart->size / 100.f); /* Draw it... */ pie_Draw3DShape(psPart->imd, 0, 0, WZCOL_WHITE, 0, 0); pie_MatEnd(); }
// Render a composite droid given a DROID_TEMPLATE structure. // void displayComponentButtonTemplate(DROID_TEMPLATE *psTemplate, Vector3i *Rotation, Vector3i *Position, BOOL RotXYZ, SDWORD scale) { static DROID Droid; // Made static to reduce stack usage. SDWORD difference; /* init to NULL */ memset( &Droid, 0, sizeof(DROID) ); setMatrix(Position, Rotation, RotXYZ); pie_MatScale(scale / 100.f); // Decide how to sort it. difference = Rotation->y%360; if((difference>0 && difference <180) || difference<-180) { leftFirst = false; } else { leftFirst = true; } droidSetBits(psTemplate,&Droid); Droid.player = (UBYTE)selectedPlayer; Droid.pos.x = Droid.pos.y = Droid.pos.z = 0; //draw multi component object as a button object displayCompObj(&Droid, true); unsetMatrix(); }
void displayIMDButton(iIMDShape *IMDShape, Vector3i *Rotation, Vector3i *Position, bool RotXYZ, SDWORD scale) { setMatrix(Position, Rotation, RotXYZ); pie_MatScale(scale / 100.f); pie_SetFogStatus(false); pie_Draw3DShape(IMDShape, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); unsetMatrix(); }
static void setMatrix(const Vector3i *Position, const Vector3i *Rotation, int scale) { pie_PerspectiveBegin(); pie_MatBegin(); pie_TRANSLATE(Position->x, Position->y, Position->z); pie_MatRotX(DEG(Rotation->x)); pie_MatRotY(DEG(Rotation->y)); pie_MatRotZ(DEG(Rotation->z)); pie_MatScale(scale / 100.f); }
// Render a component given a BASE_STATS structure. // void displayComponentButton(BASE_STATS *Stat, Vector3i *Rotation, Vector3i *Position, bool RotXYZ, SDWORD scale) { iIMDShape *ComponentIMD = NULL; iIMDShape *MountIMD = NULL; SDWORD compID; setMatrix(Position, Rotation, RotXYZ); pie_MatScale(scale / 100.f); compID = StatIsComponent(Stat); if (compID > 0) { StatGetComponentIMD(Stat, compID,&ComponentIMD, &MountIMD); } else { unsetMatrix(); return; } /* VTOL bombs are only stats allowed to have NULL ComponentIMD */ if (StatIsComponent(Stat) != COMP_WEAPON || (((WEAPON_STATS *)Stat)->weaponSubClass != WSC_BOMB && ((WEAPON_STATS *)Stat)->weaponSubClass != WSC_EMP)) { ASSERT(ComponentIMD, "No ComponentIMD"); } if (MountIMD) { pie_Draw3DShape(MountIMD, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); /* translate for weapon mount point */ if (MountIMD->nconnectors) { pie_TRANSLATE(MountIMD->connectors->x, MountIMD->connectors->z, MountIMD->connectors->y); } } if (ComponentIMD) { pie_Draw3DShape(ComponentIMD, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); } unsetMatrix(); }
// Render a composite droid given a DROID structure. // void displayComponentButtonObject(DROID *psDroid, Vector3i *Rotation, Vector3i *Position, bool RotXYZ, SDWORD scale) { SDWORD difference; setMatrix(Position, Rotation, RotXYZ); pie_MatScale(scale / 100.f); // Decide how to sort it. difference = Rotation->y%360; leftFirst = !((difference > 0 && difference < 180) || difference < -180); // And render the composite object. //draw multi component object as a button object displayCompObj(psDroid, true); unsetMatrix(); }
static void setMatrix(Vector3i *Position, Vector3i *Rotation, bool RotXYZ, int scale) { pie_PerspectiveBegin(); pie_MatBegin(); pie_TRANSLATE(Position->x,Position->y,Position->z); if(RotXYZ) { pie_MatRotX(DEG(Rotation->x)); pie_MatRotY(DEG(Rotation->y)); pie_MatRotZ(DEG(Rotation->z)); } else { pie_MatRotY(DEG(Rotation->y)); pie_MatRotX(DEG(Rotation->x)); pie_MatRotZ(DEG(Rotation->z)); } pie_MatScale(scale / 100.f); }
void renderParticle(ATPART *psPart) { Vector3i dv; /* Transform it */ dv.x = psPart->position.x - player.p.x; dv.y = psPart->position.y; dv.z = -(psPart->position.z - player.p.z); pie_MatBegin(); /* Push the current matrix */ pie_TRANSLATE(dv.x, dv.y, dv.z); /* Make it face camera */ pie_MatRotY(-player.r.y); pie_MatRotY(-player.r.x); /* Scale it... */ pie_MatScale(psPart->size / 100.f); /* Draw it... */ pie_Draw3DShape(psPart->imd, 0, 0, WZCOL_WHITE, 0, 0); pie_MatEnd(); }
// Render a composite droid given a DROID_TEMPLATE structure. // void displayComponentButtonTemplate(DROID_TEMPLATE *psTemplate, Vector3i *Rotation, Vector3i *Position, bool RotXYZ, SDWORD scale) { setMatrix(Position, Rotation, RotXYZ); pie_MatScale(scale / 100.f); // Decide how to sort it. leftFirst = angleDelta(DEG(Rotation->y)) < 0; DROID Droid(0, selectedPlayer); memset(Droid.asBits, 0, sizeof(Droid.asBits)); droidSetBits(psTemplate,&Droid); Droid.pos = Vector3i(0, 0, 0); //draw multi component object as a button object displayCompObj(&Droid, true); unsetMatrix(); }
// Render a research item given a BASE_STATS structure. // void displayResearchButton(BASE_STATS *Stat, Vector3i *Rotation, Vector3i *Position, bool RotXYZ, SDWORD scale) { iIMDShape *ResearchIMD = ((RESEARCH *)Stat)->pIMD; iIMDShape *MountIMD = ((RESEARCH *)Stat)->pIMD2; if(ResearchIMD) { setMatrix(Position, Rotation, RotXYZ); pie_MatScale(scale / 100.f); if(MountIMD) { pie_Draw3DShape(MountIMD, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); } pie_Draw3DShape(ResearchIMD, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); unsetMatrix(); } else { debug(LOG_ERROR, "ResearchIMD == NULL"); } }
// this is able to handle multiple weapon graphics now // removed mountRotation,they get such stuff from psObj directly now static void displayCompObj(DROID *psDroid, bool bButton) { iIMDShape *psShape, *psMoveAnim, *psStillAnim, *psShapeTemp = NULL, *psMountShape; SDWORD iConnector; PROPULSION_STATS *psPropStats; SDWORD pieFlag, iPieData; PIELIGHT brightness; UDWORD colour; UBYTE i; if (graphicsTime - psDroid->timeLastHit < GAME_TICKS_PER_SEC / 4 && psDroid->lastHitWeapon == WSC_ELECTRONIC && !gamePaused()) { colour = getPlayerColour(rand() % MAX_PLAYERS); } else { colour = getPlayerColour(psDroid->player); } /* get propulsion stats */ psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION]; ASSERT_OR_RETURN(, psPropStats != NULL, "invalid propulsion stats pointer"); //set pieflag for button object or ingame object if (bButton) { pieFlag = pie_BUTTON; brightness = WZCOL_WHITE; } else { pieFlag = pie_SHADOW; brightness = pal_SetBrightness(psDroid->illumination); // NOTE: Beware of transporters that are offscreen, on a mission! We should *not* be checking tiles at this point in time! if (!isTransporter(psDroid) && !missionIsOffworld()) { MAPTILE *psTile = worldTile(psDroid->pos.x, psDroid->pos.y); if (psTile->jammerBits & alliancebits[psDroid->player]) { pieFlag |= pie_ECM; } } } /* set default components transparent */ if (psDroid->asBits[COMP_PROPULSION] == 0) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { iPieData = 0; } if (!bButton && psPropStats->propulsionType == PROPULSION_TYPE_PROPELLOR) { // FIXME: change when adding submarines to the game pie_TRANSLATE(0, -world_coord(1) / 2.3f, 0); } //uses psShapeTemp too separate it from turret's psShape psShapeTemp = (leftFirst ? getLeftPropulsionIMD(psDroid) : getRightPropulsionIMD(psDroid)); if (psShapeTemp != NULL) { pie_Draw3DShape(psShapeTemp, 0, colour, brightness, pieFlag, iPieData); } /* set default components transparent */ if (psDroid->asBits[COMP_BODY] == 0) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { pieFlag &= ~pie_TRANSLUCENT; iPieData = 0; } /* Get the body graphic now*/ //uses psShapeTemp too separate it from turret's psShape psShapeTemp = BODY_IMD(psDroid, psDroid->player); if (psShapeTemp != NULL) { // FIXME if (psDroid->droidType == DROID_PERSON) { /* draw body if not animating */ if (psDroid->psCurAnim == NULL || psDroid->psCurAnim->bVisible == false) { // FIXME - hideous....!!!! pie_MatScale(.75f); pie_Draw3DShape(psShapeTemp, 0, psDroid->player - 6, brightness, pieFlag, iPieData); } } else if (cyborgDroid(psDroid)) { /* draw body if cyborg not animating */ if (psDroid->psCurAnim == NULL || psDroid->psCurAnim->bVisible == false) { pie_Draw3DShape(psShapeTemp, 0, colour, brightness, pieFlag, iPieData); } } else { pie_Draw3DShape(psShapeTemp, 0, colour, brightness, pieFlag, iPieData); } } /* Render animation effects based on movement or lack thereof, if any */ psMoveAnim = asBodyStats[psDroid->asBits[COMP_BODY]].ppMoveIMDList[psDroid->asBits[COMP_PROPULSION]]; psStillAnim = asBodyStats[psDroid->asBits[COMP_BODY]].ppStillIMDList[psDroid->asBits[COMP_PROPULSION]]; if (!bButton && psMoveAnim && psDroid->sMove.Status != MOVEINACTIVE) { pie_Draw3DShape(psMoveAnim, getModularScaledGraphicsTime(psMoveAnim->animInterval, psMoveAnim->numFrames), colour, brightness, pie_ADDITIVE, 200); } else if (!bButton && psStillAnim) // standing still { pie_Draw3DShape(psStillAnim, getModularScaledGraphicsTime(psStillAnim->animInterval, psStillAnim->numFrames), colour, brightness, 0, 0); } //don't change the screen coords of an object if drawing it in a button if (!bButton) { /* set up all the screen coords stuff - need to REMOVE FROM THIS LOOP */ calcScreenCoords(psDroid); } /* set default components transparent */ if (psDroid->asWeaps[0].nStat == 0 && psDroid->asBits[COMP_SENSOR] == 0 && psDroid->asBits[COMP_ECM] == 0 && psDroid->asBits[COMP_BRAIN] == 0 && psDroid->asBits[COMP_REPAIRUNIT] == 0 && psDroid->asBits[COMP_CONSTRUCT] == 0) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { pieFlag &= ~pie_TRANSLUCENT; iPieData = 0; } psShapeTemp = BODY_IMD(psDroid, psDroid->player); if (psShapeTemp->nconnectors) { /* vtol weapons attach to connector 2 (underneath); * all others to connector 1 */ /* VTOL's now skip the first 5 connectors(0 to 4), VTOL's use 5,6,7,8 etc now */ if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT && psDroid->droidType == DROID_WEAPON) { iConnector = VTOL_CONNECTOR_START; } else { iConnector = 0; } switch (psDroid->droidType) { case DROID_DEFAULT: case DROID_TRANSPORTER: case DROID_SUPERTRANSPORTER: case DROID_CYBORG: case DROID_CYBORG_SUPER: case DROID_WEAPON: case DROID_COMMAND: // command droids have a weapon to store all the graphics /* Get the mounting graphic - we've already moved to the right position Allegedly - all droids will have a mount graphic so this shouldn't fall on it's arse......*/ /* Double check that the weapon droid actually has any */ for (i = 0; i < psDroid->numWeaps; i++) { if ((psDroid->asWeaps[i].nStat > 0 || psDroid->droidType == DROID_DEFAULT) && psShapeTemp->connectors) { Rotation rot = getInterpolatedWeaponRotation(psDroid, i, graphicsTime); pie_MatBegin(!bButton); //to skip number of VTOL_CONNECTOR_START ground unit connectors if (iConnector < VTOL_CONNECTOR_START) { pie_TRANSLATE(psShapeTemp->connectors[i].x, psShapeTemp->connectors[i].z, psShapeTemp->connectors[i].y); } else { pie_TRANSLATE(psShapeTemp->connectors[iConnector + i].x, psShapeTemp->connectors[iConnector + i].z, psShapeTemp->connectors[iConnector + i].y); } pie_MatRotY(-rot.direction); /* vtol weapons inverted */ if (iConnector >= VTOL_CONNECTOR_START) { pie_MatRotZ(65536 / 2); //this might affect gun rotation } /* Get the mount graphic */ psShape = WEAPON_MOUNT_IMD(psDroid, i); int recoilValue = getRecoil(psDroid->asWeaps[i]); pie_TRANSLATE(0, 0, recoilValue / 3); /* Draw it */ if (psShape) { pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData); } pie_TRANSLATE(0, 0, recoilValue); /* translate for weapon mount point */ if (psShape && psShape->nconnectors) { pie_TRANSLATE(psShape->connectors->x, psShape->connectors->z, psShape->connectors->y); } /* vtol weapons inverted */ if (iConnector >= VTOL_CONNECTOR_START) { //pitch the barrel down pie_MatRotX(-rot.pitch); } else { //pitch the barrel up pie_MatRotX(rot.pitch); } /* Get the weapon (gun?) graphic */ psShape = WEAPON_IMD(psDroid, i); // We have a weapon so we draw it and a muzzle flash from weapon connector if (psShape) { pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData); drawMuzzleFlash(psDroid->asWeaps[i], psShape, MUZZLE_FLASH_PIE(psDroid, i), brightness, pieFlag, iPieData); } /* Pop Matrix */ pie_MatEnd(); } } break; case DROID_SENSOR: case DROID_CONSTRUCT: case DROID_CYBORG_CONSTRUCT: case DROID_ECM: case DROID_REPAIR: case DROID_CYBORG_REPAIR: { Rotation rot = getInterpolatedWeaponRotation(psDroid, 0, graphicsTime); switch (psDroid->droidType) { default: ASSERT(false, "..."); case DROID_SENSOR: psMountShape = SENSOR_MOUNT_IMD(psDroid, psDroid->player); /* Get the sensor graphic, assuming it's there */ psShape = SENSOR_IMD(psDroid, psDroid->player); break; case DROID_CONSTRUCT: case DROID_CYBORG_CONSTRUCT: psMountShape = CONSTRUCT_MOUNT_IMD(psDroid, psDroid->player); /* Get the construct graphic assuming it's there */ psShape = CONSTRUCT_IMD(psDroid, psDroid->player); break; case DROID_ECM: psMountShape = ECM_MOUNT_IMD(psDroid, psDroid->player); /* Get the ECM graphic assuming it's there.... */ psShape = ECM_IMD(psDroid, psDroid->player); break; case DROID_REPAIR: case DROID_CYBORG_REPAIR: psMountShape = REPAIR_MOUNT_IMD(psDroid, psDroid->player); /* Get the Repair graphic assuming it's there.... */ psShape = REPAIR_IMD(psDroid, psDroid->player); break; } /* Get the mounting graphic - we've already moved to the right position Allegedly - all droids will have a mount graphic so this shouldn't fall on it's arse......*/ //sensor and cyborg and ecm uses connectors[0] pie_MatBegin(!bButton); /* vtol weapons inverted */ if (iConnector >= VTOL_CONNECTOR_START) { pie_MatRotZ(65536 / 2); //this might affect gun rotation } pie_TRANSLATE(psShapeTemp->connectors[0].x, psShapeTemp->connectors[0].z, psShapeTemp->connectors[0].y); pie_MatRotY(-rot.direction); /* Draw it */ if (psMountShape) { pie_Draw3DShape(psMountShape, 0, colour, brightness, pieFlag, iPieData); } /* translate for construct mount point if cyborg */ if (cyborgDroid(psDroid) && psMountShape && psMountShape->nconnectors) { pie_TRANSLATE(psMountShape->connectors[0].x, psMountShape->connectors[0].z, psMountShape->connectors[0].y); } /* Draw it */ if (psShape) { pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData); // In repair droid case only: if ((psDroid->droidType == DROID_REPAIR || psDroid->droidType == DROID_CYBORG_REPAIR) && psShape->nconnectors && psDroid->action == DACTION_DROIDREPAIR) { Spacetime st = interpolateObjectSpacetime(psDroid, graphicsTime); pie_TRANSLATE(psShape->connectors[0].x, psShape->connectors[0].z, psShape->connectors[0].y); pie_TRANSLATE(0, -20, 0); psShape = getImdFromIndex(MI_FLAME); /* Rotate for droid */ pie_MatRotY(st.rot.direction); pie_MatRotX(-st.rot.pitch); pie_MatRotZ(-st.rot.roll); //rotate Y pie_MatRotY(rot.direction); pie_MatRotY(-player.r.y); pie_MatRotX(-player.r.x); pie_Draw3DShape(psShape, getModularScaledGraphicsTime(psShape->animInterval, psShape->numFrames), 0, brightness, pie_ADDITIVE, 140); pie_MatRotX(player.r.x); pie_MatRotY(player.r.y); } } /* Pop Matrix */ pie_MatEnd(); break; } case DROID_PERSON: // no extra mounts for people break; default: ASSERT(!"invalid droid type", "Whoa! Weirdy type of droid found in drawComponentObject!!!"); break; } } /* We've also got a handle on the psShape here for the weapon which has a connector to point to muzzle flash attachment points - just grab it from psShape->connectors->[x|y|z] */ /* set default components transparent */ if (psDroid->asBits[COMP_PROPULSION] == 0) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { pieFlag &= ~pie_TRANSLUCENT; iPieData = 0; } psShape = (leftFirst ? getRightPropulsionIMD(psDroid) : getLeftPropulsionIMD(psDroid)); if (psShape != NULL) { pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData); } }
void displayStructureStatButton(STRUCTURE_STATS *Stats, Vector3i *Rotation, Vector3i *Position, bool RotXYZ, SDWORD scale) { iIMDShape *baseImd,*strImd;//*mountImd,*weaponImd; iIMDShape *mountImd[STRUCT_MAXWEAPS]; iIMDShape *weaponImd[STRUCT_MAXWEAPS]; UBYTE i; /*HACK HACK HACK! if its a 'tall thin (ie tower)' structure stat with something on the top - offset the position to show the object on top*/ if (Stats->pIMD[0]->nconnectors && scale == SMALL_STRUCT_SCALE && getStructureStatHeight(Stats) > TOWER_HEIGHT) { Position->y -= 20; } setMatrix(Position, Rotation, RotXYZ); pie_MatScale(scale / 100.f); /* Draw the building's base first */ baseImd = Stats->pBaseIMD; if (baseImd != NULL) { pie_Draw3DShape(baseImd, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); } pie_Draw3DShape(Stats->pIMD[0], 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); //and draw the turret if(Stats->pIMD[0]->nconnectors) { if (Stats->numWeaps > 0) { for (i = 0;i < Stats->numWeaps;i++) { weaponImd[i] = NULL;//weapon is gun ecm or sensor mountImd[i] = NULL; } } else { weaponImd[0] = NULL; mountImd[0] = NULL; } strImd = Stats->pIMD[0]; //get an imd to draw on the connector priority is weapon, ECM, sensor //check for weapon //can only have the STRUCT_MAXWEAPS for (i = 0; i < MAX(1, Stats->numWeaps); i++) { //can only have the one if (Stats->psWeapStat[i] != NULL) { weaponImd[i] = Stats->psWeapStat[i]->pIMD; mountImd[i] = Stats->psWeapStat[i]->pMountGraphic; } if (weaponImd[i] == NULL) { //check for ECM if (Stats->pECM != NULL) { weaponImd[i] = Stats->pECM->pIMD; mountImd[i] = Stats->pECM->pMountGraphic; } } if (weaponImd[i] == NULL) { //check for sensor if (Stats->pSensor != NULL) { weaponImd[i] = Stats->pSensor->pIMD; mountImd[i] = Stats->pSensor->pMountGraphic; } } } //draw Weapon/ECM/Sensor for structure if (weaponImd[0] != NULL) { for (i = 0; i < MAX(1, Stats->numWeaps); i++) { pie_MatBegin(); pie_TRANSLATE(strImd->connectors[i].x,strImd->connectors[i].z,strImd->connectors[i].y); if (mountImd[i] != NULL) { pie_Draw3DShape(mountImd[i], 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); if(mountImd[i]->nconnectors) { pie_TRANSLATE(mountImd[i]->connectors->x,mountImd[i]->connectors->z,mountImd[i]->connectors->y); } } pie_Draw3DShape(weaponImd[i], 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); //we have a droid weapon so do we draw a muzzle flash pie_MatEnd(); } } } unsetMatrix(); }
//changed it to loop thru and draw all weapons void displayStructureButton(STRUCTURE *psStructure, Vector3i *rotation, Vector3i *Position, bool RotXYZ, SDWORD scale) { iIMDShape *baseImd,*strImd;//*mountImd,*weaponImd; iIMDShape *mountImd[STRUCT_MAXWEAPS]; iIMDShape *weaponImd[STRUCT_MAXWEAPS]; UDWORD nWeaponStat; int i; /*HACK HACK HACK! if its a 'tall thin (ie tower)' structure with something on the top - offset the position to show the object on top*/ if (psStructure->pStructureType->pIMD[0]->nconnectors && scale == SMALL_STRUCT_SCALE && getStructureHeight(psStructure) > TOWER_HEIGHT) { Position->y -= 20; } setMatrix(Position, rotation, RotXYZ); pie_MatScale(scale / 100.f); /* Draw the building's base first */ baseImd = psStructure->pStructureType->pBaseIMD; if(baseImd!=NULL) { pie_Draw3DShape(baseImd, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); } pie_Draw3DShape(psStructure->sDisplay.imd, 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); //and draw the turret if(psStructure->sDisplay.imd->nconnectors) { for (i = 0;i < STRUCT_MAXWEAPS;i++) { weaponImd[i] = NULL;//weapon is gun ecm or sensor mountImd[i] = NULL; } strImd = psStructure->sDisplay.imd; //get an imd to draw on the connector priority is weapon, ECM, sensor //check for weapon for (i = 0; i < MAX(1, psStructure->numWeaps); i++) { if (psStructure->asWeaps[i].nStat > 0) { nWeaponStat = psStructure->asWeaps[i].nStat; weaponImd[i] = asWeaponStats[nWeaponStat].pIMD; mountImd[i] = asWeaponStats[nWeaponStat].pMountGraphic; } if (weaponImd[i] == NULL) { //check for ECM if (psStructure->pStructureType->pECM != NULL) { weaponImd[i] = psStructure->pStructureType->pECM->pIMD; mountImd[i] = psStructure->pStructureType->pECM->pMountGraphic; } } if (weaponImd[i] == NULL) { //check for sensor if (psStructure->pStructureType->pSensor != NULL) { weaponImd[i] = psStructure->pStructureType->pSensor->pIMD; mountImd[i] = psStructure->pStructureType->pSensor->pMountGraphic; } } } //draw Weapon/ECM/Sensor for structure //uses 0 if (weaponImd[0] != NULL) { for (i = 0; i < MAX(1, psStructure->numWeaps); i++) { Rotation rot = structureGetInterpolatedWeaponRotation(psStructure, i, graphicsTime); pie_MatBegin(); pie_TRANSLATE(strImd->connectors[i].x,strImd->connectors[i].z,strImd->connectors[i].y); pie_MatRotY(-rot.direction); if (mountImd[i] != NULL) { pie_Draw3DShape(mountImd[i], 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); if(mountImd[i]->nconnectors) { pie_TRANSLATE(mountImd[i]->connectors->x,mountImd[i]->connectors->z,mountImd[i]->connectors->y); } } pie_MatRotX(rot.pitch); pie_Draw3DShape(weaponImd[i], 0, getPlayerColour(selectedPlayer), WZCOL_WHITE, pie_BUTTON, 0); //we have a droid weapon so do we draw a muzzle flash pie_MatEnd(); } } } unsetMatrix(); }
// this is able to handle multiple weapon graphics now // removed mountRotation,they get such stuff from psObj directly now static void displayCompObj(DROID *psDroid, BOOL bButton) { iIMDShape *psShape, *psJet, *psShapeTemp = NULL, *psMountShape; Vector3i zero = {0, 0, 0}; Vector2i screenCoords; SDWORD dummyZ, iConnector; PROPULSION_STATS *psPropStats; SDWORD frame; SDWORD pieFlag, iPieData; PIELIGHT brightness; const PIELIGHT specular = WZCOL_BLACK; UDWORD colour; UBYTE i; if( (gameTime-psDroid->timeLastHit < GAME_TICKS_PER_SEC/4 ) && psDroid->lastHitWeapon == WSC_ELECTRONIC && !gamePaused()) { colour = getPlayerColour(rand()%MAX_PLAYERS); } else { colour = getPlayerColour(psDroid->player); } /* get propulsion stats */ psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; ASSERT_OR_RETURN( , psPropStats != NULL, "invalid propulsion stats pointer"); //set pieflag for button object or ingame object if ( bButton ) { pieFlag = pie_BUTTON; } else { pieFlag = 0; } if(!bButton) { brightness = pal_SetBrightness(psDroid->illumination); pieFlag = pie_SHADOW; } else { brightness = WZCOL_WHITE; } /* We've got a z value here _and_ screen coords of origin */ dummyZ = pie_RotateProject(&zero, &screenCoords); /* set default components transparent */ if ( psDroid->asBits[COMP_PROPULSION].nStat == 0 ) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { iPieData = 0; } if (!bButton && psPropStats->propulsionType == PROPULSION_TYPE_PROPELLOR) { // FIXME: change when adding submarines to the game pie_TRANSLATE(0, -world_coord(1)/2.3f, 0); } //uses psShapeTemp too separate it from turret's psShape psShapeTemp = (leftFirst ? getLeftPropulsionIMD(psDroid) : getRightPropulsionIMD(psDroid)); if(psShapeTemp!=NULL) { pie_Draw3DShape(psShapeTemp, 0, colour, brightness, specular, pieFlag, iPieData); } /* set default components transparent */ if ( psDroid->asBits[COMP_BODY].nStat == 0 ) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { pieFlag &= ~pie_TRANSLUCENT; iPieData = 0; } /* Get the body graphic now*/ //uses psShapeTemp too separate it from turret's psShape psShapeTemp = BODY_IMD(psDroid,psDroid->player); if(psShapeTemp!=NULL) { // FIXME if ( psDroid->droidType == DROID_PERSON) { /* draw body if not animating */ if ( psDroid->psCurAnim == NULL || psDroid->psCurAnim->bVisible == false ) { // FIXME - hideous....!!!! pie_MatScale(.75f); pie_Draw3DShape(psShapeTemp, 0, psDroid->player-6, brightness, specular, pieFlag, iPieData); } } else if (cyborgDroid(psDroid)) { /* draw body if cyborg not animating */ if ( psDroid->psCurAnim == NULL || psDroid->psCurAnim->bVisible == false ) { pie_Draw3DShape(psShapeTemp, 0, colour, brightness, specular, pieFlag, iPieData); } } else { pie_Draw3DShape(psShapeTemp, 0, colour, brightness, specular, pieFlag, iPieData); } } /* render vtol jet if flying - horrible hack - GJ */ if (((psPropStats->propulsionType == PROPULSION_TYPE_LIFT) && //(psDroid->droidType != DROID_CYBORG)) && (!bButton)) (!cyborgDroid(psDroid))) && (!bButton)) { /* show flame if above ground */ if ( psDroid->sMove.Status != MOVEINACTIVE ) { /* draw flame if found */ /* GJ TODO: add flame-finding code here */ psJet = asBodyStats[psDroid->asBits[COMP_BODY].nStat].pFlameIMD; if ( psJet != NULL ) { pie_Draw3DShape(psJet, getModularScaledGraphicsTime(100, psJet->numFrames), colour, brightness, specular, pie_ADDITIVE, 200); } } } //don't change the screen coords of an object if drawing it in a button if (!bButton) { /* set up all the screen coords stuff - need to REMOVE FROM THIS LOOP */ calcScreenCoords(psDroid); } /* set default components transparent */ if (psDroid->asWeaps[0].nStat == 0 && psDroid->asBits[COMP_SENSOR].nStat == 0 && psDroid->asBits[COMP_ECM].nStat == 0 && psDroid->asBits[COMP_BRAIN].nStat == 0 && psDroid->asBits[COMP_REPAIRUNIT].nStat == 0 && psDroid->asBits[COMP_CONSTRUCT].nStat == 0) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { pieFlag &= ~pie_TRANSLUCENT; iPieData = 0; } /* Indenting here is only to show new matrix context */ { psShapeTemp = BODY_IMD(psDroid,psDroid->player); if( psShapeTemp->nconnectors ) { /* vtol weapons attach to connector 2 (underneath); * all others to connector 1 */ /* VTOL's now skip the first 5 connectors(0 to 4), VTOL's use 5,6,7,8 etc now */ if ( (psPropStats->propulsionType == PROPULSION_TYPE_LIFT) && psDroid->droidType == DROID_WEAPON ) { iConnector = VTOL_CONNECTOR_START; } else { iConnector = 0; } switch(psDroid->droidType) { case DROID_DEFAULT: case DROID_TRANSPORTER: case DROID_CYBORG: case DROID_CYBORG_SUPER: case DROID_WEAPON: case DROID_COMMAND: // command droids have a weapon to store all the graphics /* Get the mounting graphic - we've already moved to the right position Allegedly - all droids will have a mount graphic so this shouldn't fall on it's arse......*/ /* Double check that the weapon droid actually has any */ for (i = 0;i < psDroid->numWeaps;i++) { if (psDroid->asWeaps[i].nStat > 0 || psDroid->droidType == DROID_DEFAULT) { if ( psShapeTemp->connectors ) { Rotation rot = getInterpolatedWeaponRotation(psDroid, i, graphicsTime); pie_MatBegin(); //reset Z? dummyZ = pie_RotateProject(&zero, &screenCoords); //to skip number of VTOL_CONNECTOR_START ground unit connectors if ( iConnector < VTOL_CONNECTOR_START ) { pie_TRANSLATE(psShapeTemp->connectors[i].x, psShapeTemp->connectors[i].z, psShapeTemp->connectors[i].y); } else { pie_TRANSLATE( psShapeTemp->connectors[iConnector + i].x, psShapeTemp->connectors[iConnector + i].z, psShapeTemp->connectors[iConnector + i].y ); } pie_MatRotY(-rot.direction); /* vtol weapons inverted */ if ( iConnector >= VTOL_CONNECTOR_START ) { pie_MatRotZ(65536/2); //this might affect gun rotation } /* Get the mount graphic */ psShape = WEAPON_MOUNT_IMD(psDroid, i); pie_TRANSLATE(0,0,psDroid->asWeaps[i].recoilValue/3); /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0, colour, brightness, specular, pieFlag, iPieData); } pie_TRANSLATE(0,0,psDroid->asWeaps[i].recoilValue); /* translate for weapon mount point */ if (psShape && psShape->nconnectors) { pie_TRANSLATE(psShape->connectors->x, psShape->connectors->z, psShape->connectors->y); } /* vtol weapons inverted */ if ( iConnector >= VTOL_CONNECTOR_START ) { //pitch the barrel down pie_MatRotX(-rot.pitch); } else { //pitch the barrel up pie_MatRotX(rot.pitch); } /* Get the weapon (gun?) graphic */ psShape = WEAPON_IMD(psDroid, i); // We have a weapon so we draw it and a muzzle flash from weapon connector if (psShape) { pie_Draw3DShape(psShape, 0, colour, brightness, specular, pieFlag, iPieData); if (psShape->nconnectors) { unsigned int connector_num = 0; // which barrel is firing if model have multiple muzzle connectors? if (psDroid->asWeaps[i].shotsFired && (psShape->nconnectors > 1)) { // shoot first, draw later - substract one shot to get correct results connector_num = (psDroid->asWeaps[i].shotsFired - 1) % (psShape->nconnectors); } /* Now we need to move to the end of the firing barrel (there maybe multiple barrels) */ pie_TRANSLATE( psShape->connectors[connector_num].x, psShape->connectors[connector_num].z, psShape->connectors[connector_num].y); //and draw the muzzle flash psShape = MUZZLE_FLASH_PIE(psDroid, i); if (psShape) { //assume no clan colours for muzzle effects if ((psShape->numFrames == 0) || (psShape->animInterval <= 0)) { //no anim so display one frame for a fixed time if (gameTime < (psDroid->asWeaps[i].lastFired + BASE_MUZZLE_FLASH_DURATION)) { pie_Draw3DShape(psShape, 0, 0, brightness, WZCOL_BLACK, pieFlag | pie_ADDITIVE, EFFECT_MUZZLE_ADDITIVE); } } else { // animated muzzle frame = (gameTime - psDroid->asWeaps[i].lastFired) / psShape->animInterval; if (frame < psShape->numFrames) { pie_Draw3DShape(psShape, frame, 0, brightness, WZCOL_BLACK, pieFlag | pie_ADDITIVE, EFFECT_MUZZLE_ADDITIVE); } } } } } } /* Pop Matrix */ pie_MatEnd(); } } break; case DROID_SENSOR: case DROID_CONSTRUCT: case DROID_CYBORG_CONSTRUCT: case DROID_ECM: case DROID_REPAIR: case DROID_CYBORG_REPAIR: { Rotation rot = getInterpolatedWeaponRotation(psDroid, 0, graphicsTime); switch (psDroid->droidType) { default: ASSERT(false, "..."); case DROID_SENSOR: psMountShape = SENSOR_MOUNT_IMD(psDroid, psDroid->player); /* Get the sensor graphic, assuming it's there */ psShape = SENSOR_IMD(psDroid, psDroid->player); break; case DROID_CONSTRUCT: case DROID_CYBORG_CONSTRUCT: psMountShape = CONSTRUCT_MOUNT_IMD(psDroid, psDroid->player); /* Get the construct graphic assuming it's there */ psShape = CONSTRUCT_IMD(psDroid, psDroid->player); break; case DROID_ECM: psMountShape = ECM_MOUNT_IMD(psDroid, psDroid->player); /* Get the ECM graphic assuming it's there.... */ psShape = ECM_IMD(psDroid, psDroid->player); break; case DROID_REPAIR: case DROID_CYBORG_REPAIR: psMountShape = REPAIR_MOUNT_IMD(psDroid, psDroid->player); /* Get the Repair graphic assuming it's there.... */ psShape = REPAIR_IMD(psDroid, psDroid->player); break; } /* Get the mounting graphic - we've already moved to the right position Allegedly - all droids will have a mount graphic so this shouldn't fall on it's arse......*/ //sensor and cyborg and ecm uses connectors[0] pie_MatBegin(); //reset Z? dummyZ = pie_RotateProject(&zero, &screenCoords); /* vtol weapons inverted */ if ( iConnector >= VTOL_CONNECTOR_START ) { pie_MatRotZ(65536/2); //this might affect gun rotation } pie_TRANSLATE( psShapeTemp->connectors[0].x, psShapeTemp->connectors[0].z, psShapeTemp->connectors[0].y ); pie_MatRotY(-rot.direction); /* Draw it */ if (psMountShape) { pie_Draw3DShape(psMountShape, 0, colour, brightness, specular, pieFlag, iPieData); } /* translate for construct mount point if cyborg */ if (cyborgDroid(psDroid) && psMountShape && psMountShape->nconnectors) { pie_TRANSLATE(psMountShape->connectors[0].x, psMountShape->connectors[0].z, psMountShape->connectors[0].y); } /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0, colour, brightness, specular, pieFlag, iPieData); // In repair droid case only: if ((psDroid->droidType == DROID_REPAIR || psDroid->droidType == DROID_CYBORG_REPAIR) && psShape->nconnectors && psDroid->action == DACTION_DROIDREPAIR) { SPACETIME st = interpolateObjectSpacetime((SIMPLE_OBJECT *)psDroid, graphicsTime); Rotation rot = getInterpolatedWeaponRotation(psDroid, 0, graphicsTime); pie_TRANSLATE( psShape->connectors[0].x, psShape->connectors[0].z, psShape->connectors[0].y ); pie_TRANSLATE(0,-20,0); psShape = getImdFromIndex(MI_FLAME); /* Rotate for droid */ pie_MatRotY(st.rot.direction); pie_MatRotX(-st.rot.pitch); pie_MatRotZ(-st.rot.roll); //rotate Y pie_MatRotY(rot.direction); pie_MatRotY(-player.r.y); pie_MatRotX(-player.r.x); /* Dither on software */ pie_Draw3DShape(psShape, getModularScaledGraphicsTime(100, psShape->numFrames), 0, brightness, WZCOL_BLACK, pie_ADDITIVE, 140); /* Dither off software */ pie_MatRotX(player.r.x); pie_MatRotY(player.r.y); } } /* Pop Matrix */ pie_MatEnd(); break; } case DROID_PERSON: // no extra mounts for people break; default: ASSERT(!"invalid droid type", "Whoa! Weirdy type of droid found in drawComponentObject!!!"); break; } } /* We've also got a handle on the psShape here for the weapon which has a connector to point to muzzle flash attachment points - just grab it from psShape->connectors->[x|y|z] */ } // end of illustrative indentation - see above /* set default components transparent */ if ( psDroid->asBits[COMP_PROPULSION].nStat == 0 ) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { pieFlag &= ~pie_TRANSLUCENT; iPieData = 0; } psShape = (leftFirst ? getRightPropulsionIMD(psDroid) : getLeftPropulsionIMD(psDroid)); if(psShape!=NULL) { pie_Draw3DShape(psShape, 0, colour, brightness, specular, pieFlag, iPieData); } }