29 changes: 25 additions & 4 deletions src/intdisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -2280,11 +2280,19 @@ void CreateIMDButton(IMAGEFILE *ImageFile, UWORD ImageID, void *Object, UDWORD P

if(IMDType == IMDTYPE_DROID)
{
if(((DROID*)Object)->droidType == DROID_TRANSPORTER) {
if(((DROID*)Object)->droidType == DROID_TRANSPORTER)
{
Position.x = 0;
Position.y = 0;//BUT_TRANSPORTER_ALT;
Position.z = BUTTON_DEPTH;
scale = DROID_BUT_SCALE/2;
if ((!strcmp("Cyborg Transport",((DROID*)Object)->aName)))
{
scale = DROID_BUT_SCALE/2;
}
else
{
scale = DROID_BUT_SCALE/3;
}
}
else
{
Expand All @@ -2294,11 +2302,19 @@ void CreateIMDButton(IMAGEFILE *ImageFile, UWORD ImageID, void *Object, UDWORD P
}
else//(IMDType == IMDTYPE_DROIDTEMPLATE)
{
if(((DROID_TEMPLATE*)Object)->droidType == DROID_TRANSPORTER) {
if(((DROID_TEMPLATE*)Object)->droidType == DROID_TRANSPORTER)
{
Position.x = 0;
Position.y = 0;//BUT_TRANSPORTER_ALT;
Position.z = BUTTON_DEPTH;
scale = DROID_BUT_SCALE/2;
if ((!strcmp("Cyborg Transport",((DROID_TEMPLATE*)Object)->aName)))
{
scale = DROID_BUT_SCALE/2;
}
else
{
scale = DROID_BUT_SCALE/3;
}
}
else
{
Expand Down Expand Up @@ -2362,6 +2378,11 @@ void CreateIMDButton(IMAGEFILE *ImageFile, UWORD ImageID, void *Object, UDWORD P
//scale = COMP_BUT_SCALE;
//ASSERT( Radius <= OBJECT_RADIUS,"Object too big for button - %s",
// ((BASE_STATS*)Object)->pName );
// NOTE: The Super transport is huge, and is considered a component type, so refit it to inside the button.
if ((!strcmp("MP-SuperTransportBody",((BASE_STATS*)Object)->pName)))
{
scale /= 2;
}
}
else if(IMDType == IMDTYPE_RESEARCH)
{
Expand Down
139 changes: 76 additions & 63 deletions src/mapdisplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,60 +38,59 @@

/* renders the Research IMDs into the surface - used by message display in
Intelligence Map */
void renderResearchToBuffer(RESEARCH *psResearch,
UDWORD OriginX, UDWORD OriginY)
void renderResearchToBuffer(RESEARCH *psResearch, UDWORD OriginX, UDWORD OriginY)
{
UDWORD angle = 0;

BASE_STATS *psResGraphic;
UDWORD compID, IMDType;
BASE_STATS *psResGraphic;
UDWORD compID, IMDType;
Vector3i Rotation,Position;
UDWORD basePlateSize, Radius;
SDWORD scale = 0;
SDWORD scale = 0;

// Set identity (present) context
pie_MatBegin();

pie_SetGeometricOffset(OriginX+10,OriginY+10);
pie_SetGeometricOffset(OriginX+10, OriginY+10);

// Pitch down a bit
//pie_MatRotX(DEG(-30));

// Rotate round
// Rotate round
// full rotation once every 2 seconds..
angle = (gameTime2 % ROTATE_TIME) * 360 / ROTATE_TIME;

Position.x = 0;
Position.x = 0;
Position.y = 0;
Position.z = BUTTON_DEPTH;

// Rotate round
// Rotate round
Rotation.x = -30;
Rotation.y = angle;
Rotation.z = 0;

//draw the IMD for the research
if (psResearch->psStat)
{
//we have a Stat associated with this research topic
if (StatIsStructure(psResearch->psStat))
{
//this defines how the button is drawn
//draw the IMD for the research
if (psResearch->psStat)
{
//we have a Stat associated with this research topic
if (StatIsStructure(psResearch->psStat))
{
//this defines how the button is drawn
IMDType = IMDTYPE_STRUCTURESTAT;
psResGraphic = psResearch->psStat;
//set up the scale
psResGraphic = psResearch->psStat;
//set up the scale
basePlateSize= getStructureStatSize((STRUCTURE_STATS*)psResearch->psStat);
if(basePlateSize == 1)
{
scale = RESEARCH_COMPONENT_SCALE / 2;
/*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 (((STRUCTURE_STATS*)psResearch->psStat)->pIMD->nconnectors &&
getStructureStatHeight((STRUCTURE_STATS*)psResearch->psStat) > TOWER_HEIGHT)
{
Position.y -= 30;
}
/*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 (((STRUCTURE_STATS*)psResearch->psStat)->pIMD->nconnectors &&
getStructureStatHeight((STRUCTURE_STATS*)psResearch->psStat) > TOWER_HEIGHT)
{
Position.y -= 30;
}
}
else if(basePlateSize == 2)
{
Expand All @@ -101,36 +100,44 @@ void renderResearchToBuffer(RESEARCH *psResearch,
{
scale = RESEARCH_COMPONENT_SCALE / 5;
}
}
else
{
compID = StatIsComponent(psResearch->psStat);
}
else
{
compID = StatIsComponent(psResearch->psStat);
if (compID != COMP_UNKNOWN)
{
//this defines how the button is drawn
IMDType = IMDTYPE_COMPONENT;
psResGraphic = psResearch->psStat;
scale = RESEARCH_COMPONENT_SCALE;
}
else
{
ASSERT( false, "intDisplayMessageButton: invalid stat" );
IMDType = IMDTYPE_RESEARCH;
psResGraphic = (BASE_STATS *)psResearch;
}
}
}
else
{
//no Stat for this research topic so use the research topic to define what is drawn
psResGraphic = (BASE_STATS *)psResearch;
IMDType = IMDTYPE_RESEARCH;
}

//scale the research according to size of IMD
if (IMDType == IMDTYPE_RESEARCH)
{
Radius = getResearchRadius((BASE_STATS*)psResGraphic);
//this defines how the button is drawn
IMDType = IMDTYPE_COMPONENT;
psResGraphic = psResearch->psStat;
// NOTE: Another kludge to deal with the superTransport to make it "fit" the display.
if (!strcmp("MP-SuperTransport", psResearch->pName))
{
scale = RESEARCH_COMPONENT_SCALE / 3;
}
else
{
scale = RESEARCH_COMPONENT_SCALE;
}
}
else
{
ASSERT( false, "intDisplayMessageButton: invalid stat" );
IMDType = IMDTYPE_RESEARCH;
psResGraphic = (BASE_STATS *)psResearch;
}
}
}
else
{
//no Stat for this research topic so use the research topic to define what is drawn
psResGraphic = (BASE_STATS *)psResearch;
IMDType = IMDTYPE_RESEARCH;
}

//scale the research according to size of IMD
if (IMDType == IMDTYPE_RESEARCH)
{
Radius = getResearchRadius((BASE_STATS*)psResGraphic);
if(Radius <= 100)
{
scale = RESEARCH_COMPONENT_SCALE / 2;
Expand All @@ -147,18 +154,24 @@ void renderResearchToBuffer(RESEARCH *psResearch,
{
scale = RESEARCH_COMPONENT_SCALE / 5;
}
}

}

/* display the IMDs */
if(IMDType == IMDTYPE_COMPONENT) {
displayComponentButton(psResGraphic,&Rotation,&Position,true, scale);
} else if(IMDType == IMDTYPE_RESEARCH) {
displayResearchButton(psResGraphic,&Rotation,&Position,true, scale);
} else if(IMDType == IMDTYPE_STRUCTURESTAT) {
if(IMDType == IMDTYPE_COMPONENT)
{
displayComponentButton(psResGraphic, &Rotation, &Position, true, scale);
}
else if(IMDType == IMDTYPE_RESEARCH)
{
displayResearchButton(psResGraphic, &Rotation, &Position, true, scale);
}
else if(IMDType == IMDTYPE_STRUCTURESTAT)
{
displayStructureStatButton((STRUCTURE_STATS *)psResGraphic, &Rotation, &Position, true, scale);
} else {
ASSERT( false, "renderResearchToBuffer: Unknown PIEType" );
}
else
{
ASSERT( false, "Unknown PIEType" );
}

// close matrix context
Expand Down
82 changes: 46 additions & 36 deletions src/order.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include "fpath.h"
#include "display3d.h"
#include "combat.h"
#include "console.h"

// how long to run for
#define RUN_TIME 8000
Expand Down Expand Up @@ -847,57 +848,66 @@ void orderUpdateDroid(DROID *psDroid)
}
break;
case DORDER_EMBARK:
// only place it can be trapped - in multiPlayer can only put cyborgs onto a Transporter
if (bMultiPlayer && !cyborgDroid(psDroid))
{
psDroid->order = DORDER_NONE;
actionDroid(psDroid, DACTION_NONE);
}
else
{
// don't want the droids to go into a formation for this order
if (psDroid->sMove.psFormation != NULL)
{
formationLeave(psDroid->sMove.psFormation, psDroid);
psDroid->sMove.psFormation = NULL;
}
// only place it can be trapped - in multiPlayer can only put cyborgs onto a Cyborg Transporter
DROID *temp = NULL;

// Wait for the action to finish then assign to Transporter (if not already flying)
if (psDroid->psTarget == NULL || transporterFlying((DROID *)psDroid->psTarget))
temp = (DROID*)psDroid->psTarget;
if (!strcmp("Cyborg Transport", temp->aName) && !cyborgDroid(psDroid))
{
// NOTE: since we only have one type of transport (DROID_TRANSPORT), it isn't worth changing tons of code
// to have two types available (DROID_TRANSPORT_SUPER), so we just check the name which can never be
// renamed anyway, so we should be safe with this kludge.
psDroid->order = DORDER_NONE;
actionDroid(psDroid, DACTION_NONE);
audio_PlayTrack( ID_SOUND_BUILD_FAIL );
addConsoleMessage(_("We can't do that! We must be a Cyborg unit to use a Cyborg Transport!"), DEFAULT_JUSTIFY, selectedPlayer);
}
else if (abs((SDWORD)psDroid->pos.x - (SDWORD)psDroid->psTarget->pos.x) < TILE_UNITS
&& abs((SDWORD)psDroid->pos.y - (SDWORD)psDroid->psTarget->pos.y) < TILE_UNITS)
else
{
// if in multiPlayer, only want to process if this player's droid
if (!bMultiPlayer || psDroid->player == selectedPlayer)
// don't want the droids to go into a formation for this order
if (psDroid->sMove.psFormation != NULL)
{
// save the target of current droid (the transporter)
DROID * transporter = (DROID *)psDroid->psTarget;
formationLeave(psDroid->sMove.psFormation, psDroid);
psDroid->sMove.psFormation = NULL;
}

// Make sure that it really is a valid droid
CHECK_DROID(transporter);
// Wait for the action to finish then assign to Transporter (if not already flying)
if (psDroid->psTarget == NULL || transporterFlying((DROID *)psDroid->psTarget))
{
psDroid->order = DORDER_NONE;
actionDroid(psDroid, DACTION_NONE);
}
else if (abs((SDWORD)psDroid->pos.x - (SDWORD)psDroid->psTarget->pos.x) < TILE_UNITS
&& abs((SDWORD)psDroid->pos.y - (SDWORD)psDroid->psTarget->pos.y) < TILE_UNITS)
{
// if in multiPlayer, only want to process if this player's droid
if (!bMultiPlayer || psDroid->player == selectedPlayer)
{
// save the target of current droid (the transporter)
DROID * transporter = (DROID *)psDroid->psTarget;

// order the droid to stop so moveUpdateDroid does not process this unit
orderDroid(psDroid, DORDER_STOP);
setDroidTarget(psDroid, NULL);
psDroid->psTarStats = NULL;
secondarySetState(psDroid, DSO_RETURN_TO_LOC, DSS_NONE);
// Make sure that it really is a valid droid
CHECK_DROID(transporter);

// order the droid to stop so moveUpdateDroid does not process this unit
orderDroid(psDroid, DORDER_STOP);
setDroidTarget(psDroid, NULL);
psDroid->psTarStats = NULL;
secondarySetState(psDroid, DSO_RETURN_TO_LOC, DSS_NONE);

/* We must add the droid to the transporter only *after*
* processing changing its orders (see above).
/* We must add the droid to the transporter only *after*
* processing changing its orders (see above).
*/
transporterAddDroid(transporter, psDroid);
transporterAddDroid(transporter, psDroid);
}
}
else if (psDroid->action == DACTION_NONE)
{
actionDroidLoc(psDroid, DACTION_MOVE, psDroid->psTarget->pos.x,psDroid->psTarget->pos.y);
}
}
else if (psDroid->action == DACTION_NONE)
{
actionDroidLoc(psDroid, DACTION_MOVE, psDroid->psTarget->pos.x,psDroid->psTarget->pos.y);
}
}

// Do we need to clear the secondary order "DSO_EMBARK" here? (PD)
break;
case DORDER_DISEMBARK:
Expand Down
68 changes: 46 additions & 22 deletions src/transporter.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@
//They all take up the same amount of space now - AB 30/10/98
//defines how much space each sized droid takes up on the Transporter
#define LIGHT_DROID 1
#define MEDIUM_DROID 1//2
#define HEAVY_DROID 1//3
#define MEDIUM_DROID 2
#define HEAVY_DROID 3

//max that can be available from home

Expand Down Expand Up @@ -271,9 +271,6 @@ static BOOL _intAddTransporter(DROID *psSelected, BOOL offWorld)
return false;
}




/* Add the close button */
memset(&sButInit, 0, sizeof(W_BUTINIT));
sButInit.formID = IDTRANS_FORM;
Expand Down Expand Up @@ -322,6 +319,7 @@ BOOL intAddTransporterContents(void)
W_FORMINIT sFormInit;
W_BUTINIT sButInit;
W_FORMINIT sButFInit;
W_LABINIT sLabInit;
BOOL Animate = true;
BOOL AlreadyUp = false;

Expand Down Expand Up @@ -380,7 +378,25 @@ BOOL intAddTransporterContents(void)
{
return false;
}

if (bMultiPlayer)
{
//add the capacity label
memset(&sLabInit,0,sizeof(W_LABINIT));
sLabInit.formID = IDTRANS_CONTENTFORM;
sLabInit.id = IDTRANS_CAPACITY;
sLabInit.style = WLAB_PLAIN;
sLabInit.x = (SWORD)sButInit.x -40;
sLabInit.y = 0;
sLabInit.width = 16;
sLabInit.height = 16;
sLabInit.pText = "00/10";
sLabInit.FontID = font_regular;
sLabInit.pCallback = intUpdateTransCapacity;
if (!widgAddLabel(psWScreen, &sLabInit))
{
return false;
}
}
//add the Launch button if on a mission
if (onMission)
{
Expand Down Expand Up @@ -1504,6 +1520,8 @@ void transporterAddDroid(DROID *psTransporter, DROID *psDroidToAdd)
/* check for space */
if (!checkTransporterSpace(psTransporter, psDroidToAdd))
{
audio_PlayTrack( ID_SOUND_BUILD_FAIL );
addConsoleMessage(_("There is not enough room in the Transport!"), DEFAULT_JUSTIFY, selectedPlayer);
return;
}
if (onMission)
Expand Down Expand Up @@ -1588,24 +1606,30 @@ UDWORD transporterSpaceRequired(DROID *psDroid)
{
UDWORD size;

switch ((asBodyStats + psDroid->asBits[COMP_BODY].nStat)->size)
if (!bMultiPlayer)
{
case SIZE_LIGHT:
size = LIGHT_DROID;
break;
case SIZE_MEDIUM:
size = MEDIUM_DROID;
break;
case SIZE_HEAVY:
case SIZE_SUPER_HEAVY:
size = HEAVY_DROID;
break;
default:
ASSERT( false, "transporterSpaceRequired: Unknown Droid size" );
size = 0;
break;
size = LIGHT_DROID; // all droids are the same weight for SP games.
}
else
{
switch ((asBodyStats + psDroid->asBits[COMP_BODY].nStat)->size)
{
case SIZE_LIGHT:
size = LIGHT_DROID;
break;
case SIZE_MEDIUM:
size = MEDIUM_DROID;
break;
case SIZE_HEAVY:
case SIZE_SUPER_HEAVY:
size = HEAVY_DROID;
break;
default:
ASSERT( false, "transporterSpaceRequired: Unknown Droid size" );
size = 0;
break;
}
}

return size;
}

Expand Down