/* Component.c Draws component objects - oh yes indeed. Alex M, Pumpkin Studios, EIDOS Interactive, 1997. */ #include "lib/framework/frame.h" #include "base.h" #include "droid.h" #include "action.h" #include "order.h" #include "component.h" #include "lib/ivis_common/ivisdef.h" //ivis matrix code #include "lib/ivis_common/geo.h" //ivis matrix code #include "lib/ivis_common/piedef.h" //ivis matrix code #include "lib/ivis_common/piestate.h" //ivis render code #include "lighting.h" #include "lib/ivis_common/bspfunc.h" #include "loop.h" #define TESTLOWPOLY #define GAME2PSX(x) (((x)*4096)/360) #define GetRadius(x) ((x)->sradius) #include "stats.h" #include "lib/ivis_common/piemode.h" #include "objects.h" #include "display.h" #include "geometry.h" #include "display3d.h" #include "map.h" #include "lib/gamelib/gtime.h" #include "intdisplay.h" #include "miscimd.h" #include "effects.h" #include "e3demo.h" #include "transporter.h" #include "projectile.h" void unsetMatrix(void); void setMatrix(iVector *Position,iVector *Rotation,iVector *CameraPos,BOOL RotXYZ); #define MAX_GROUP_SIZE 10 #define NUM_GIBLETS 5 #define BLIP_ANIM_DURATION 200 #define DEFAULT_COMPONENT_TRANSLUCENCY 128 #define DROID_EMP_SPREAD (20 - rand()%40) UDWORD droidScale = 100; void displayComponentTemplate(DROID_TEMPLATE *psTemplate); //void displayComponentObject(BASE_OBJECT *psObj); //Watermelon:updated protocol for displayCompObj static void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], BOOL bButton); static iIMDShape *getLeftPropulsionIMD(DROID *psDroid); static iIMDShape *getRightPropulsionIMD(DROID *psDroid); static UDWORD getStructureHeight(STRUCTURE *psStructure); BOOL leftFirst; SDWORD droidLightLevel = 224; UDWORD lightInterval=15; UDWORD lightLastChanged; SDWORD lightSpeed=2; extern UDWORD selectedPlayer; UBYTE PlayerColour[MAX_PLAYERS];// = {0,1,2,3,4,5,6,7} // Colour Lookups // use col = MAX_PLAYERS for anycolour (see multiint.c) BOOL setPlayerColour(UDWORD player, UDWORD col) { if(player >MAX_PLAYERS || col >MAX_PLAYERS) { debug( LOG_ERROR, "setplayercolour: wrong values" ); abort(); return FALSE; } PlayerColour[(UBYTE)player] = (UBYTE)col; return TRUE; } UBYTE getPlayerColour(UDWORD pl) { return PlayerColour[pl]; } void initPlayerColours(void) { UBYTE i; for(i=0;i(lightLastChanged+lightInterval)) { droidLightLevel+=lightSpeed; lightLastChanged = gameTime; if(droidLightLevel>255 OR droidLightLevel<128) { if(lightSpeed>0) { lightSpeed = -lightSpeed; } else { lightSpeed = -lightSpeed; } } } } void setMatrix(iVector *Position,iVector *Rotation,iVector *CameraPos,BOOL RotXYZ) { iVector BSPCameraPos; OBJPOS Camera = {0,0,0}; Camera.pitch=-45; Camera.yaw=0; // Rotation->y=0; GetRealCameraPos(&Camera,Position->z,&BSPCameraPos); // SetBSPCameraPos(BSPCameraPos.x,BSPCameraPos.y,BSPCameraPos.z); // Fixes BSP drawing in buttons. eg Player HQ. SetBSPCameraPos(BSPCameraPos.x,500,BSPCameraPos.z); SetBSPObjectPos(0,0,0); // For imd button the bsp is sourced at 0,0,0 SetBSPObjectRot(DEG(-Rotation->y),0); // Droid rotation 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)); } } void unsetMatrix(void) { pie_MatEnd(); pie_PerspectiveEnd(); } UDWORD getComponentDroidRadius(DROID *psDroid) { return 100; } UDWORD getComponentDroidTemplateRadius(DROID_TEMPLATE *psDroid) { return 100; } UDWORD getComponentRadius(BASE_STATS *psComponent) { iIMDShape *ComponentIMD = NULL; iIMDShape *MountIMD = NULL; SDWORD compID; compID = StatIsComponent(psComponent); if (compID > 0) { StatGetComponentIMD(psComponent, compID,&ComponentIMD, &MountIMD); // ComponentIMD = StatGetComponentIMD(psComponent, compID); if(ComponentIMD) { return GetRadius(ComponentIMD); } else { // NULL component,should this be an error? } } // DBERROR(("Not a valid component")); /* VTOL bombs are only stats allowed to have NULL ComponentIMD */ if ( (StatIsComponent(psComponent) != COMP_WEAPON) || ((WEAPON_STATS *)psComponent)->weaponSubClass != WSC_BOMB ) { debug( LOG_NEVER, "ComponentPIE == NULL : File : %s Line : %d\n", __FILE__, __LINE__ ); } return COMPONENT_RADIUS; } UDWORD getResearchRadius(BASE_STATS *Stat) { iIMDShape *ResearchIMD = ((RESEARCH *)Stat)->pIMD; if(ResearchIMD) { return GetRadius(ResearchIMD); } // DBERROR(("Null IMD in getResearchRadius()")); debug( LOG_NEVER, "ResearchPIE == NULL : File : %s Line : %d\n", __FILE__, __LINE__ ); return 100; } UDWORD getStructureSize(STRUCTURE *psStructure) { UDWORD size; //radius based on base plate size size = psStructure->pStructureType->baseWidth; if (psStructure->pStructureType->baseBreadth > size) { size = psStructure->pStructureType->baseBreadth; } return (size); } static UDWORD getStructureRadius(STRUCTURE *psStructure) { iIMDShape *baseImd; SDWORD Radius = GetRadius(psStructure->sDisplay.imd); baseImd = psStructure->pStructureType->pBaseIMD; if(baseImd!=NULL) { if(GetRadius(baseImd) > Radius) { Radius = GetRadius(baseImd); } } return Radius; } UDWORD getStructureStatSize(STRUCTURE_STATS *Stats) { UDWORD size; //radius based on base plate size size = Stats->baseWidth; if (Stats->baseBreadth > size) { size = Stats->baseBreadth; } return (size); } static UDWORD getStructureStatRadius(STRUCTURE_STATS *Stats,UDWORD Player) { iIMDShape *baseImd; SDWORD Radius = GetRadius(Stats->pIMD); baseImd = Stats->pBaseIMD; if(baseImd!=NULL) { if(GetRadius(baseImd) > Radius) { Radius = GetRadius(baseImd); } } return Radius; } UDWORD getStructureHeight(STRUCTURE *psStructure) { return (getStructureStatHeight(psStructure->pStructureType)); } UDWORD getStructureStatHeight(STRUCTURE_STATS *psStat) { if (psStat->pIMD) { return (psStat->pIMD->ymax - psStat->pIMD->ymin); } return 0; } void displayIMDButton(iIMDShape *IMDShape, iVector *Rotation,iVector *Position,BOOL RotXYZ, SDWORD scale) { iVector TmpCamPos = {0,0,0}; setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); pie_SetFogStatus(FALSE); pie_Draw3DShape(IMDShape, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); // ajl changed 0 to selectedPlayer unsetMatrix(); } void displayStructureButton(STRUCTURE *psStructure, iVector *Rotation,iVector *Position,BOOL RotXYZ, SDWORD scale) { iIMDShape *baseImd,*strImd,*mountImd,*weaponImd; UDWORD nWeaponStat; iVector TmpCamPos = {0,0,0}; /*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->nconnectors AND scale == SMALL_STRUCT_SCALE AND getStructureHeight(psStructure) > TOWER_HEIGHT) { Position->y -= 20; } SetBSPObjectPos(0,0,0); setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); /* Draw the building's base first */ baseImd = psStructure->pStructureType->pBaseIMD; if(baseImd!=NULL) { pie_Draw3DShape(baseImd, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); // ajl changed 0 to selectedPlayer } pie_Draw3DShape(psStructure->sDisplay.imd, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); // ajl changed 0 to selectedPlayer //and draw the turret if(psStructure->sDisplay.imd->nconnectors) { weaponImd = NULL;//weapon is gun ecm or sensor mountImd = NULL; strImd = psStructure->sDisplay.imd; //get an imd to draw on the connector priority is weapon, ECM, sensor //check for weapon //if (psStructure->numWeaps > 0) if (psStructure->asWeaps[0].nStat > 0) { nWeaponStat = psStructure->asWeaps[0].nStat; weaponImd = asWeaponStats[nWeaponStat].pIMD; mountImd = asWeaponStats[nWeaponStat].pMountGraphic; } if (weaponImd == NULL) { //check for ECM if (psStructure->pStructureType->pECM != NULL) { weaponImd = psStructure->pStructureType->pECM->pIMD; mountImd = psStructure->pStructureType->pECM->pMountGraphic; } } if (weaponImd == NULL) { //check for sensor if (psStructure->pStructureType->pSensor != NULL) { weaponImd = psStructure->pStructureType->pSensor->pIMD; mountImd = psStructure->pStructureType->pSensor->pMountGraphic; } } //draw Weapon/ECM/Sensor for structure if(weaponImd != NULL) { iV_MatrixBegin(); iV_TRANSLATE(strImd->connectors->x,strImd->connectors->z,strImd->connectors->y); pie_MatRotY(DEG(-((SDWORD)psStructure->turretRotation))); if (mountImd != NULL) { pie_Draw3DShape(mountImd, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); if(mountImd->nconnectors) { iV_TRANSLATE(mountImd->connectors->x,mountImd->connectors->z,mountImd->connectors->y); } } iV_MatrixRotateX(DEG(psStructure->turretPitch)); pie_Draw3DShape(weaponImd, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); //we have a droid weapon so do we draw a muzzle flash iV_MatrixEnd(); } } unsetMatrix(); } void displayStructureStatButton(STRUCTURE_STATS *Stats,UDWORD Player, iVector *Rotation,iVector *Position,BOOL RotXYZ, SDWORD scale) { iIMDShape *baseImd,*strImd,*mountImd,*weaponImd; iVector TmpCamPos = {0,0,0}; //UDWORD nWeaponStat; /*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->nconnectors AND scale == SMALL_STRUCT_SCALE AND getStructureStatHeight(Stats) > TOWER_HEIGHT) { Position->y -= 20; } setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); /* Draw the building's base first */ baseImd = Stats->pBaseIMD; if(baseImd!=NULL) { pie_Draw3DShape(baseImd, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0);// ajl changed 0 to selectedPlayer } pie_Draw3DShape(Stats->pIMD, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0);// ajl changed 0 to selectedPlayer //and draw the turret if(Stats->pIMD->nconnectors) { weaponImd = NULL;//weapon is gun ecm or sensor mountImd = NULL; strImd = Stats->pIMD; //get an imd to draw on the connector priority is weapon, ECM, sensor //check for weapon //if (Stats->numWeaps > 0) //can only have the one if (Stats->psWeapStat != NULL) { /*nWeaponStat = Stats->defaultWeap; weaponImd = Stats->asWeapList[nWeaponStat]->pIMD; mountImd = Stats->asWeapList[nWeaponStat]->pMountGraphic;*/ weaponImd = Stats->psWeapStat->pIMD; mountImd = Stats->psWeapStat->pMountGraphic; } if (weaponImd == NULL) { //check for ECM if (Stats->pECM != NULL) { weaponImd = Stats->pECM->pIMD; mountImd = Stats->pECM->pMountGraphic; } } if (weaponImd == NULL) { //check for sensor if (Stats->pSensor != NULL) { weaponImd = Stats->pSensor->pIMD; mountImd = Stats->pSensor->pMountGraphic; } } //draw Weapon/ECM/Sensor for structure if(weaponImd != NULL) { iV_MatrixBegin(); iV_TRANSLATE(strImd->connectors->x,strImd->connectors->z,strImd->connectors->y); pie_MatRotY(DEG(0)); if (mountImd != NULL) { pie_Draw3DShape(mountImd, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); if(mountImd->nconnectors) { iV_TRANSLATE(mountImd->connectors->x,mountImd->connectors->z,mountImd->connectors->y); } } iV_MatrixRotateX(DEG(0)); pie_Draw3DShape(weaponImd, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); //we have a droid weapon so do we draw a muzzle flash iV_MatrixEnd(); } } unsetMatrix(); } // Render a component given a BASE_STATS structure. // void displayComponentButton(BASE_STATS *Stat, iVector *Rotation,iVector *Position, BOOL RotXYZ, SDWORD scale) { iIMDShape *ComponentIMD = NULL; iIMDShape *MountIMD = NULL; SDWORD compID; iVector TmpCamPos = {0,0,0}; setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); compID = StatIsComponent(Stat); if (compID > 0) { StatGetComponentIMD(Stat, compID,&ComponentIMD, &MountIMD); // ComponentIMD = StatGetComponentIMD(Stat, compID); } else { unsetMatrix(); return; } /* VTOL bombs are only stats allowed to have NULL ComponentIMD */ if ( (ComponentIMD == NULL) && ((StatIsComponent(Stat) != COMP_WEAPON) || ((WEAPON_STATS *)Stat)->weaponSubClass != WSC_BOMB) ) { debug( LOG_NEVER, "ComponentPIE == NULL : File : %s Line : %d\n", __FILE__, __LINE__ ); // DBERROR(("ComponentIMD == NULL")); } if(MountIMD) { pie_Draw3DShape(MountIMD, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0);// ajl changed 0 to selectedPlayer } if(ComponentIMD) { pie_Draw3DShape(ComponentIMD, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0);// ajl changed 0 to selectedPlayer } unsetMatrix(); } // Render a research item given a BASE_STATS structure. // void displayResearchButton(BASE_STATS *Stat, iVector *Rotation,iVector *Position,BOOL RotXYZ, SDWORD scale) { iIMDShape *ResearchIMD = ((RESEARCH *)Stat)->pIMD; iIMDShape *MountIMD = ((RESEARCH *)Stat)->pIMD2; iVector TmpCamPos = {0,0,0}; if(ResearchIMD) { setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); if(MountIMD) { pie_Draw3DShape(MountIMD, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); // ajl, added colourthing using selectedPlayer } pie_Draw3DShape(ResearchIMD, 0, getPlayerColour(selectedPlayer), pie_MAX_BRIGHT_LEVEL, 0, pie_BUTTON, 0); //ajl, added colourthing using selectedPlayer unsetMatrix(); } // DBERROR(("Null IMD in displayResearchButton()")); } // Render a composite droid given a DROID_TEMPLATE structure. // void displayComponentButtonTemplate(DROID_TEMPLATE *psTemplate, iVector *Rotation,iVector *Position,BOOL RotXYZ, SDWORD scale) { static DROID Droid; // Made static to reduce stack usage. SDWORD difference; //Watermelon:make it contain DROID_MAXWEAPS Vector info iVector mountRotation[DROID_MAXWEAPS]; iVector TmpCamPos = {0,0,0}; int i; //Watermelon:I need to initialise the values of this,since DROID_MAXWEAPS is not a 'constant' for(i = 0;i < psTemplate->numWeaps;i++) { mountRotation[i].x = 0; mountRotation[i].y = 0; mountRotation[i].z = 0; } /* init to NULL */ memset( &Droid, 0, sizeof(DROID) ); setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); // Decide how to sort it. difference = Rotation->y%360; if((difference>0 AND difference <180) OR difference<-180) { leftFirst = FALSE; } else { leftFirst = TRUE; } droidSetBits(psTemplate,&Droid); Droid.player = (UBYTE)selectedPlayer; Droid.x=Droid.y=Droid.z=0; // important for psx stuff ... //draw multi component object as a button object displayCompObj((BASE_OBJECT*)&Droid,&mountRotation,TRUE); unsetMatrix(); } // Render a composite droid given a DROID structure. // void displayComponentButtonObject(DROID *psDroid, iVector *Rotation,iVector *Position,BOOL RotXYZ, SDWORD scale) { SDWORD difference; //Watermelon:make it contain DROID_MAXWEAPS Vector info iVector mountRotation[DROID_MAXWEAPS]; iVector TmpCamPos = {0,0,0}; int i; //Watermelon:I need to initialise the values of this,since DROID_MAXWEAPS is not a 'constant' for(i = 0;i < psDroid->numWeaps;i++) { mountRotation[i].x = 0; mountRotation[i].y = 0; mountRotation[i].z = 0; } setMatrix(Position,Rotation,&TmpCamPos,RotXYZ); pie_MatScale(scale); // Decide how to sort it. difference = Rotation->y%360; if((difference>0 AND difference <180) OR difference<-180) { leftFirst = FALSE; } else { leftFirst = TRUE; } // And render the composite object. //draw multi component object as a button object displayCompObj((BASE_OBJECT*)psDroid,&mountRotation,TRUE); unsetMatrix(); } /* Assumes matrix context is already set */ // Watermelon:multiple turrets display void displayComponentObject(BASE_OBJECT *psObj) { DROID *psDroid; //iIMDShape *psShape; //Watermelon:mountRotation is array now iVector position,rotation; //,null; iVector mountRotation[DROID_MAXWEAPS]; //iPoint screenCoords; //SDWORD dummyZ; int32 xShift,zShift; UDWORD worldAngle; SDWORD difference; SDWORD frame; PROPULSION_STATS *psPropStats; UDWORD tileX,tileY; MAPTILE *psTile; //Watermelon:added int iWeapons,i; int iWeapons = 0; int i = 0; psDroid = (DROID *)psObj; psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; for(i = 0;i < psDroid->numWeaps;i++) { mountRotation[i].x = 0; mountRotation[i].y = 0; mountRotation[i].z = 0; } worldAngle = (UDWORD) ((UDWORD)player.r.y/DEG_1)%360; difference = (worldAngle-psObj->direction); if((difference>0 AND difference <180) OR difference<-180) { leftFirst = FALSE; } else { leftFirst = TRUE; } /* Push the matrix */ pie_MatBegin(); /* Get internal tile units coordinates */ xShift = player.p.x & (TILE_UNITS-1); zShift = player.p.z & (TILE_UNITS-1); /* Mask out to tile_units resolution */ pie_TRANSLATE(xShift,0,-zShift); /* Get the real position */ position.x = (psDroid->x - player.p.x) - terrainMidX*TILE_UNITS; position.z = terrainMidY*TILE_UNITS - (psDroid->y - player.p.z); position.y = psDroid->z; //{ // position.y += bobTransporterHeight(); //} //if(psPropStats->propulsionType == LIFT) if(psDroid->droidType == DROID_TRANSPORTER) { position.y += bobTransporterHeight(); } /* Get all the pitch,roll,yaw info */ rotation.y = -(SDWORD)psDroid->direction; rotation.x = psDroid->pitch; rotation.z = psDroid->roll; /* Get rotation info for the mounting too (holds the gun */ // Watermelon:added check against droid type if ( psDroid->type == OBJ_DROID ) { if ( psDroid->droidType == DROID_WEAPON ) { for(iWeapons = 0;iWeapons < psDroid->numWeaps;iWeapons++) { mountRotation[iWeapons].y = -(SDWORD)psDroid->turretRotation[iWeapons]; mountRotation[iWeapons].x = psDroid->turretPitch[iWeapons]; mountRotation[iWeapons].z = 0; } } else { mountRotation[0].y = -(SDWORD)((DROID *)psObj)->turretRotation[0]; mountRotation[0].x = ((DROID *)psObj)->turretPitch[0]; mountRotation[0].z = 0; } } else { mountRotation[0].y = -(SDWORD)((DROID *)psObj)->turretRotation[0]; mountRotation[0].x = ((DROID *)psObj)->turretPitch[0]; mountRotation[0].z = 0; } /* Translate origin */ pie_TRANSLATE(position.x,position.y,position.z); /* Rotate for droid */ pie_MatRotY(DEG(rotation.y)); pie_MatRotX(DEG(rotation.x)); pie_MatRotZ(DEG(rotation.z)); if( (gameTime-psDroid->timeLastHit < GAME_TICKS_PER_SEC) AND psDroid->lastHitWeapon == WSC_ELECTRONIC) { objectShimmy( (BASE_OBJECT*) psDroid ); } if (psDroid->lastHitWeapon == WSC_EMP AND (gameTime - psDroid->timeLastHit < EMP_DISABLE_TIME)) { iVector position; //add an effect on the droid position.x = psDroid->x + DROID_EMP_SPREAD; position.y = psDroid->z + rand()%8;; position.z = psDroid->y + DROID_EMP_SPREAD; effectGiveAuxVar(90+rand()%20); addEffect(&position,EFFECT_EXPLOSION,EXPLOSION_TYPE_PLASMA,FALSE,NULL,0); } if (godMode || (psDroid->visible[selectedPlayer] == UBYTE_MAX) OR demoGetStatus()) { //ingame not button object //Watermelon:should render 3 mounted weapons now displayCompObj(psObj,&mountRotation,FALSE); } else { // make sure it's not over water. tileX = psDroid->x/TILE_UNITS; tileY = psDroid->y/TILE_UNITS; // double check it's on map if( (tileX>=0) AND (tileY>=0) AND (tileXid; //visible[selectedPlayer]; pie_Draw3DShape(getImdFromIndex(MI_BLIP), frame, 0, pie_MAX_BRIGHT_LEVEL, 0, pie_ADDITIVE, (psDroid->visible[selectedPlayer]/2)); // pie_Draw3DShape(blipImd, frame, 0, pie_MAX_BRIGHT_LEVEL, 0, pie_TRANSLUCENT, 128); /* set up all the screen coords stuff - need to REMOVE FROM THIS LOOP */ } } } pie_MatEnd(); } /* Assumes matrix context is already set */ // Watermelon:this is able to handle multiple weapon graphics now // mountRotation is iVector array contains mountRotation from all weapons now!!! void displayCompObj(BASE_OBJECT *psObj,iVector (*mountRotation)[DROID_MAXWEAPS], BOOL bButton) { DROID *psDroid; //Watermelon:I need another temp pointer to Shape iIMDShape *psShape, *psJet, *psShapeTemp = NULL; iVector null; iPoint screenCoords; SDWORD dummyZ, iConnector; PROPULSION_STATS *psPropStats; SDWORD frame; SDWORD pieFlag, iPieData; UDWORD brightness, specular; // SDWORD centreX,centreZ; UDWORD colour; UDWORD bDarkSide = FALSE; //Watermelon:i int i; /* Cast the droid pointer */ psDroid = (DROID *)psObj; if( (gameTime-psDroid->timeLastHit < GAME_TICKS_PER_SEC/4 ) AND psDroid->lastHitWeapon == WSC_ELECTRONIC AND !gamePaused()) { colour = getPlayerColour(rand()%MAX_PLAYERS); bDarkSide = TRUE; } else { colour = getPlayerColour(psDroid->player); } //set pieflag for button object or ingame object if ( bButton ) { pieFlag = pie_BUTTON; } else { pieFlag = 0; } if(!pieFlag) { // centreX = ( player.p.x + ((visibleXTiles/2)<illumination,getCentreX() - psDroid->x,getCentreZ() - psDroid->y, &specular); } else { brightness = pie_MAX_BRIGHT_LEVEL; specular = 0; } // /* No auxilliary rotation */ null.x = null.y = null.z = 0; /* We've got a z value here _and_ screen coords of origin */ dummyZ = pie_RotProj(&null,&screenCoords); /* Draw the propulsion and body imds here */ /* Establish the propulsion - this is more complex if two parts */ /* if(leftFirst) { psShape = getLeftPropulsionIMD(psDroid); if(psShape!=NULL) { iV_PIEDraw(psShape,psDroid->player); } } else { psShape = getRightPropulsionIMD(psDroid); if(psShape!=NULL) { iV_PIEDraw(psShape,psDroid->player); } } */ if (droidScale != 100) { pie_MatScale(droidScale); } /* set default components transparent */ if ( psDroid->asBits[COMP_PROPULSION].nStat == 0 ) { pieFlag |= pie_TRANSLUCENT; iPieData = DEFAULT_COMPONENT_TRANSLUCENCY; } else { iPieData = 0; } //Watermelon:uses psShapeTemp too separate it from turret's psShape psShapeTemp = (leftFirst ? getLeftPropulsionIMD(psDroid) : getRightPropulsionIMD(psDroid)); if(psShapeTemp!=NULL) { pie_Draw3DShape(psShapeTemp, 0, colour/*getPlayerColour(psDroid->player)*/, 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*/ //Watermelon: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(75); pie_Draw3DShape(psShapeTemp, 0, psDroid->player-6, brightness, specular, pieFlag, iPieData); } } //else if( psDroid->droidType == DROID_CYBORG) else if (cyborgDroid(psDroid)) { /* draw body if cyborg not animating */ if ( psDroid->psCurAnim == NULL || psDroid->psCurAnim->bVisible == FALSE ) { pie_Draw3DShape(psShapeTemp, 0, colour/*getPlayerColour(psDroid->player)*/, brightness, specular, pieFlag, iPieData); } } else { pie_Draw3DShape(psShapeTemp, 0, colour/*getPlayerColour(psDroid->player)*/, brightness, specular, pieFlag, iPieData ); } } /* get propulsion stats */ psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; ASSERT( PTRVALID(psPropStats, sizeof(PROPULSION_STATS)), "moveUpdateUnit: invalid propulsion stats pointer" ); /* render vtol jet if flying - horrible hack - GJ */ if (((psPropStats->propulsionType == 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, getStaticTimeValueRange(100,psJet->numFrames), colour /*getPlayerColour(psDroid->player)*/, 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); //Watermelon:I moved it to 'for' loop //pie_MatBegin(); if( psShapeTemp->nconnectors ) { /* vtol weapons attach to connector 2 (underneath); * all others to connector 1 */ if ( (psPropStats->propulsionType == LIFT) && psDroid->droidType == DROID_WEAPON ) { iConnector = 1; } else { iConnector = 0; } /* Now we need to move for the mount point */ //Watermelon:I moved it to switch,this is called __inline__ j/k /* pie_TRANSLATE( psShape->connectors[iConnector].x, psShape->connectors[iConnector].z, psShape->connectors[iConnector].y ); */ /* Rotate the turret */ /* if(&mountRotation[i]) { pie_MatRotY(DEG(&mountRotation[i].y)); } */ //dont pitch the turret // pie_MatRotZ(DEG(mountRotation->z)); //I moved it to 'for' loop /* vtol weapons inverted */ /* if ( iConnector == 1 ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } */ //SEPERATE Mount IMDs now... /* 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......*/ //psShape = MOUNT_IMD(psDroid,psDroid->player); /* Draw it */ 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 */ //Watermelon:uses numWeaps //if(psDroid->numWeaps) for (i = 0;i < psDroid->numWeaps;i++) { if (psDroid->asWeaps[i].nStat > 0 OR psDroid->droidType == DROID_DEFAULT) { if ( psShapeTemp->connectors ) { pie_MatBegin(); //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); //Watermelon:to skip connectors[1](VOTL hardpoint) if ( i == 0 ) { pie_TRANSLATE( psShapeTemp->connectors[iConnector].x, psShapeTemp->connectors[iConnector].z, psShapeTemp->connectors[iConnector].y ); } else if ( i > 0 ) { if ( iConnector == 1 ) { pie_TRANSLATE( psShapeTemp->connectors[iConnector].x, psShapeTemp->connectors[iConnector].z, psShapeTemp->connectors[iConnector].y ); } else { pie_TRANSLATE( psShapeTemp->connectors[i+1].x, psShapeTemp->connectors[i+1].z, psShapeTemp->connectors[i+1].y ); } } if ( psDroid->turretRotation[i] ) { pie_MatRotY(DEG( (-(SDWORD)psDroid->turretRotation[i])) ); } /* vtol weapons inverted */ if ( iConnector == 1 ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } //psShape = WEAPON_MOUNT_IMD(psDroid,psDroid->player); psShape = (asWeaponStats[psDroid->asWeaps[i].nStat]).pMountGraphic; /* Draw it */ //if(psDroid->numWeaps) already done this check above?! { pie_TRANSLATE(0,0,psDroid->asWeaps[i].recoilValue/3); } if(psShape) { pie_Draw3DShape(psShape, 0, colour/*getPlayerColour(psDroid->player)*/, brightness, specular, pieFlag, iPieData); } //if(psDroid->numWeaps) already done this check above?! { pie_TRANSLATE(0,0,psDroid->asWeaps[i].recoilValue); } /* translate for weapon mount point if cyborg */ //if( psDroid->droidType == DROID_CYBORG && if (cyborgDroid(psDroid) && psShape && psShape->nconnectors) { pie_TRANSLATE( psShape->connectors[0].x, psShape->connectors[0].z, psShape->connectors[0].y ); } /* vtol weapons inverted */ if ( iConnector == 1 ) { //pitch the barrel down pie_MatRotX(DEG( (-(psDroid->turretPitch[i])) )); } else { //pitch the barrel up pie_MatRotX(DEG(psDroid->turretPitch[i])); } /* Get the weapon (gun?) graphic */ //psShape = WEAPON_IMD(psDroid,psDroid->player); psShape = (asWeaponStats[psDroid->asWeaps[i].nStat]).pIMD; /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0, colour/*getPlayerColour(psDroid->player)*/, brightness, specular, pieFlag, iPieData); } //we have a droid weapon so do we draw a muzzle flash if( psShape && psShape->nconnectors ) { /* Now we need to move to the end fo the barrel */ //Watermelon:to skip connectors[1](VOTL hardpoint) if ( i == 0 ) { pie_TRANSLATE( psShape->connectors[0].x, psShape->connectors[0].z, psShape->connectors[0].y ); } else if ( i > 0 ) { //Watermelon:to skip VTOL connector 1 if ( iConnector == 1) { //Watermelon:VTOL untouched pie_TRANSLATE( psShape->connectors[iConnector].x, psShape->connectors[iConnector].z, psShape->connectors[iConnector].y ); } else { //Watermelon:MUZZLE_FLASH_PIE for all weapons pie_TRANSLATE( psShape->connectors[i+1].x, psShape->connectors[i+1].z, psShape->connectors[i+1].y ); } } //and draw the muzzle flash //animate for the duration of the flash only //Watermelon:change macro to actual accessor for each turret effect //psShape = MUZZLE_FLASH_PIE(psDroid,psDroid->player); psShape = (asWeaponStats[psDroid->asWeaps[i].nStat]).pMuzzleGraphic; if(psShape) { //assume no clan colours formuzzle 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, 0, pieFlag | pie_ADDITIVE, EFFECT_MUZZLE_ADDITIVE);//muzzle flash // pie_Draw3DShape(psShape, 0, 0, brightness, 0, pieFlag, 0);//muzzle flash } } else { frame = (gameTime - psDroid->asWeaps[i].lastFired)/psShape->animInterval; if (frame < psShape->numFrames) { pie_Draw3DShape(psShape, frame, 0, brightness, 0, pieFlag | pie_ADDITIVE, EFFECT_MUZZLE_ADDITIVE);//muzzle flash // pie_Draw3DShape(psShape, frame, 0, brightness, 0, pieFlag, 0);//muzzle flash } } } } } /* Pop Matrix */ pie_MatEnd(); } } break; case DROID_SENSOR: /* 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......*/ //Watermelon:sensor uses connectors[0] pie_MatBegin(); //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ if ( iConnector == 1 ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } pie_TRANSLATE( psShapeTemp->connectors[0].x, psShapeTemp->connectors[0].z, psShapeTemp->connectors[0].y ); if(psDroid->turretRotation[0]) { pie_MatRotY(DEG( (-(SDWORD)(psDroid->turretRotation[0])) )); } psShape = SENSOR_MOUNT_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { // pie_MatRotY(DEG(getStaticTimeValueRange(7920,360))); // pie_MatRotY(DEG(psDroid->turretRotation)); pie_Draw3DShape(psShape, 0,colour/*getPlayerColour( psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* Get the sensor graphic, assuming it's there */ psShape = SENSOR_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { // pie_MatRotY(DEG(getStaticTimeValueRange(7920,360))); // pie_MatRotY(DEG(psDroid->turretRotation)); pie_Draw3DShape(psShape, 0,colour/*getPlayerColour( psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* Pop Matrix */ pie_MatEnd(); break; case DROID_CONSTRUCT: case DROID_CYBORG_CONSTRUCT: /* 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......*/ //Watermelon:cyborg uses connectors[0] pie_MatBegin(); //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ if ( iConnector == 1 ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } pie_TRANSLATE( psShapeTemp->connectors[0].x, psShapeTemp->connectors[0].z, psShapeTemp->connectors[0].y ); if(psDroid->turretRotation[0]) { pie_MatRotY(DEG( (-(SDWORD)(psDroid->turretRotation[0])) )); } psShape = CONSTRUCT_MOUNT_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0,colour/*getPlayerColour( psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* translate for construct mount point if cyborg */ if (cyborgDroid(psDroid) && psShape && psShape->nconnectors) { pie_TRANSLATE( psShape->connectors[0].x, psShape->connectors[0].z, psShape->connectors[0].y ); } /* Get the construct graphic assuming it's there */ psShape = CONSTRUCT_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0,colour/*getPlayerColour( psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* Pop Matrix */ pie_MatEnd(); break; case DROID_ECM: /* 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......*/ //Watermelon:ecm uses connectors[0] pie_MatBegin(); //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ if ( iConnector == 1 ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } pie_TRANSLATE( psShapeTemp->connectors[0].x, psShapeTemp->connectors[0].z, psShapeTemp->connectors[0].y ); if(psDroid->turretRotation[0]) { pie_MatRotY(DEG( (-(SDWORD)(psDroid->turretRotation[0])) )); } psShape = ECM_MOUNT_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0, colour/*getPlayerColour(psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* Get the ECM graphic assuming it's there.... */ psShape = ECM_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0, colour/*getPlayerColour(psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* Pop Matrix */ pie_MatEnd(); break; case DROID_REPAIR: case DROID_CYBORG_REPAIR: /* 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......*/ //Watermelon:cyborg uses connectors[0] pie_MatBegin(); //Watermelon:reset Z? dummyZ = pie_RotProj(&null,&screenCoords); /* vtol weapons inverted */ if ( iConnector == 1 ) { pie_MatRotZ( DEG_360/2 );//this might affect gun rotation } pie_TRANSLATE( psShapeTemp->connectors[0].x, psShapeTemp->connectors[0].z, psShapeTemp->connectors[0].y ); if(psDroid->turretRotation[0]) { pie_MatRotY(DEG( (-(SDWORD)(psDroid->turretRotation[0])) )); } psShape = REPAIR_MOUNT_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0,colour /*getPlayerColour( psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* translate for construct mount point if cyborg */ if (cyborgDroid(psDroid) && psShape && psShape->nconnectors) { pie_TRANSLATE( psShape->connectors[0].x, psShape->connectors[0].z, psShape->connectors[0].y ); } /* Get the Repair graphic assuming it's there.... */ psShape = REPAIR_IMD(psDroid,psDroid->player); /* Draw it */ if(psShape) { pie_Draw3DShape(psShape, 0,colour /*getPlayerColour( psDroid->player)*/, brightness, specular, pieFlag, iPieData); if(psShape->nconnectors AND psDroid->action == DACTION_DROIDREPAIR) { 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(DEG((SDWORD)psDroid->direction)); pie_MatRotX(DEG(-psDroid->pitch)); pie_MatRotZ(DEG(-psDroid->roll)); //Watermelon:rotate Y pie_MatRotY(DEG( -( (-(SDWORD)(psDroid->turretRotation[0])) ) )); iV_MatrixRotateY(-player.r.y); iV_MatrixRotateX(-player.r.x); /* Dither on software */ pie_Draw3DShape(psShape, getStaticTimeValueRange(100,psShape->numFrames), 0, brightness, 0, pie_ADDITIVE, 140); /* Dither off software */ iV_MatrixRotateX(player.r.x); iV_MatrixRotateY(player.r.y); } } /* Pop Matrix */ pie_MatEnd(); break; case DROID_PERSON: // no extra mounts for people break; default: ASSERT( FALSE, "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] */ //Watermelon:I moved it to 'for' loop /* Pop Matrix */ //pie_MatEnd(); } // 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 /*getPlayerColour( psDroid->player)*/, brightness, specular, pieFlag, iPieData); } /* if(leftFirst) { psShape = getRightPropulsionIMD(psDroid); if(psShape!=NULL) { iV_PIEDraw(psShape,psDroid->player); } } else { psShape = getLeftPropulsionIMD(psDroid); if(psShape!=NULL) { iV_PIEDraw(psShape,psDroid->player); } } */ } void destroyFXDroid(DROID *psDroid) { UDWORD i; iIMDShape *psImd = NULL; SDWORD widthScatter,breadthScatter,heightScatter; iVector pos; widthScatter = TILE_UNITS/4; breadthScatter = TILE_UNITS/4; heightScatter = TILE_UNITS/5; for(i=0; i<5; i++) { pos.x = psDroid->x + widthScatter - rand()%(2*widthScatter); pos.z = psDroid->y + breadthScatter - rand()%(2*breadthScatter); pos.y = psDroid->z + 16 +heightScatter; switch(i) { case 0: switch(psDroid->droidType) { case DROID_DEFAULT: case DROID_CYBORG: case DROID_CYBORG_SUPER: case DROID_CYBORG_CONSTRUCT: case DROID_CYBORG_REPAIR: case DROID_WEAPON: case DROID_COMMAND: //Watermelon:another commented-out crash... //Re-added the safety check //if(psDroid->numWeaps) if (psDroid->numWeaps > 0) { if(psDroid->asWeaps[0].nStat > 0) { psImd = WEAPON_MOUNT_IMD(psDroid,psDroid->player); } } else { // psImd = debrisImds[rand()%MAX_DEBRIS]; psImd = getRandomDebrisImd(); } break; default: // psImd = debrisImds[rand()%MAX_DEBRIS]; psImd = getRandomDebrisImd(); break; } break; case 1: switch(psDroid->droidType) { case DROID_DEFAULT: case DROID_CYBORG: case DROID_CYBORG_SUPER: case DROID_CYBORG_CONSTRUCT: case DROID_CYBORG_REPAIR: case DROID_WEAPON: case DROID_COMMAND: //if(psDroid->numWeaps) if(psDroid->asWeaps[0].nStat > 0) { psImd = WEAPON_IMD(psDroid,psDroid->player); } else { // psImd = debrisImds[rand()%MAX_DEBRIS]; psImd = getRandomDebrisImd(); } break; default: // psImd = debrisImds[rand()%MAX_DEBRIS]; psImd = getRandomDebrisImd(); break; } break; case 2: case 3: case 4: // psImd = debrisImds[rand()%MAX_DEBRIS]; psImd = getRandomDebrisImd(); break; } if(psImd) { addEffect(&pos,EFFECT_GRAVITON,GRAVITON_TYPE_EMITTING_DR,TRUE,psImd,getPlayerColour(psDroid->player)); } else { // addEffect(&pos,EFFECT_GRAVITON,GRAVITON_TYPE_EMITTING_DR,TRUE,debrisImds[rand()%MAX_DEBRIS],0); addEffect(&pos,EFFECT_GRAVITON,GRAVITON_TYPE_EMITTING_DR,TRUE,getRandomDebrisImd(),0); } } } //void addBodyPartEffect(iVector *position,iIMDShape *psShape) //{ // velocity.x = 1-rand()%3; // velocity.z = 1-rand()%3; // velocity.y = 4+rand()%7; // addEffect(position,EFFECT_GRAVITON,GRAVITON_TYPE_GIBLET,TRUE,psShape,0); //} void compPersonToBits(DROID *psDroid) { iVector position; //,rotation,velocity; iIMDShape *headImd, *legsImd, *armImd, *bodyImd; UDWORD groundHeight; UDWORD col; if(!psDroid->visible[selectedPlayer]) { /* We can't see the person or cyborg - so get out */ return; } /* get bits pointers according to whether baba or cyborg*/ //if ( psDroid->droidType == DROID_CYBORG ) if (cyborgDroid(psDroid)) { headImd = getImdFromIndex(MI_CYBORG_HEAD); legsImd = getImdFromIndex(MI_CYBORG_LEGS); armImd = getImdFromIndex(MI_CYBORG_ARM); bodyImd = getImdFromIndex(MI_CYBORG_BODY); } else { headImd = getImdFromIndex(MI_BABA_HEAD); legsImd = getImdFromIndex(MI_BABA_LEGS); armImd = getImdFromIndex(MI_BABA_ARM); bodyImd = getImdFromIndex(MI_BABA_BODY); } /* Get where he's at */ position.x = psDroid->x; position.y = psDroid->z+1; groundHeight = psDroid->z; position.z = psDroid->y; /* Tell about player colour */ col = getPlayerColour(psDroid->player); addEffect(&position,EFFECT_GRAVITON,GRAVITON_TYPE_GIBLET,TRUE,headImd,col); addEffect(&position,EFFECT_GRAVITON,GRAVITON_TYPE_GIBLET,TRUE,legsImd,col); addEffect(&position,EFFECT_GRAVITON,GRAVITON_TYPE_GIBLET,TRUE,armImd,col); addEffect(&position,EFFECT_GRAVITON,GRAVITON_TYPE_GIBLET,TRUE,bodyImd,col); } iIMDShape *getLeftPropulsionIMD(DROID *psDroid) { UDWORD bodyStat, propStat; iIMDShape **imd; bodyStat = psDroid->asBits[COMP_BODY].nStat; propStat = psDroid->asBits[COMP_PROPULSION].nStat; imd = asBodyStats[bodyStat].ppIMDList; imd += (propStat * NUM_PROP_SIDES + LEFT_PROP); return *imd; } iIMDShape *getRightPropulsionIMD(DROID *psDroid) { UDWORD bodyStat, propStat; iIMDShape **imd; bodyStat = psDroid->asBits[COMP_BODY].nStat; propStat = psDroid->asBits[COMP_PROPULSION].nStat; imd = asBodyStats[bodyStat].ppIMDList; imd += (propStat * NUM_PROP_SIDES + RIGHT_PROP); return *imd; } SDWORD rescaleButtonObject(SDWORD radius, SDWORD baseScale,SDWORD baseRadius) { SDWORD newScale; newScale = 100 * baseRadius; newScale /= radius; if(baseScale > 0) { newScale += baseScale; newScale /= 2; } return newScale; }