Hovers can't be transported
Moderator: Moderators
"True" hovercraft are facter on water, yes (in fact they cannot go too far into the land anyway). But I use hover move type for completely different vehicles.
Look at this picture:

There are amphibious tanks, but not of the type used in TA. They don't drive on the sea bed, they float on the surface. To make such units in Spring, you have to use hover move type. And those are much slower on water than on land.
Look at this picture:

There are amphibious tanks, but not of the type used in TA. They don't drive on the sea bed, they float on the surface. To make such units in Spring, you have to use hover move type. And those are much slower on water than on land.
A new patch
I made a new patch. This one allows to control what unit types can/cannot be transported on a per-mod basis. Control tags are in modrules.tdf (where the reclaim rules are).
Defaults are 1 for ground units and 0 for everything else.
0 - unittype cannot be transported.
1 - unittype can be transported if unit's size and mass fit into the transport.
Also it is now possible to unload units into water if their minWaterDepth is more than water depth, so that ships can be transported properly. minWaterDepth check works both ways so that ships won't be unloaded on land, either.
Diffs:
Code: Select all
[TRANSPORTABILITY]
{
transportGround=1;
transportHover=1;
transportShip=1;
transportAir=1;
}
0 - unittype cannot be transported.
1 - unittype can be transported if unit's size and mass fit into the transport.
Also it is now possible to unload units into water if their minWaterDepth is more than water depth, so that ships can be transported properly. minWaterDepth check works both ways so that ships won't be unloaded on land, either.
Diffs:
Code: Select all
Index: ModInfo.cpp
===================================================================
--- ModInfo.cpp (revision 3465)
+++ ModInfo.cpp (working copy)
@@ -42,6 +42,25 @@
// We already set the defaults so we should be able to ignore this
// Other optional mod rules MUST set their defaults...
}
+ //Get the transportability options for the mod
+ transportGround = 1;
+ transportHover = 0;
+ transportShip = 0;
+ transportAir = 0;
+ // See if the mod overrides the defaults:
+ try
+ {
+ TdfParser transportOptions("gamedata/modrules.tdf");
+ transportGround = atoi(transportOptions.SGetValueDef("1", "TRANSPORTABILITY\\TransportGround").c_str());
+ transportHover = atoi(transportOptions.SGetValueDef("0", "TRANSPORTABILITY\\TransportHover").c_str());
+ transportShip = atoi(transportOptions.SGetValueDef("0", "TRANSPORTABILITY\\TransportShip").c_str());
+ transportAir = atoi(transportOptions.SGetValueDef("0", "TRANSPORTABILITY\\TransportAir").c_str());
+ }
+ catch(content_error) // If the modrules.tdf isnt found
+ {
+ // We already set the defaults so we should be able to ignore this
+ // Other optional mod rules MUST set their defaults...
+ }
}
Code: Select all
Index: ModInfo.h
===================================================================
--- ModInfo.h (revision 3465)
+++ ModInfo.h (working copy)
@@ -16,6 +16,12 @@
int multiReclaim; // 0 = 1 reclaimer per feature max, otherwise unlimited
int reclaimMethod; // 0 = gradual reclaim, 1 = all reclaimed at end, otherwise reclaim in reclaimMethod chunks
+ //Transportation behaviour
+ int transportGround; //0 = all ground units cannot be transported, 1 = all ground units can be transported (mass and size restrictions still apply). Defaults to 1.
+ int transportHover; //0 = all hover units cannot be transported, 1 = all hover units can be transported (mass and size restrictions still apply). Defaults to 0.
+ int transportShip; //0 = all naval units cannot be transported, 1 = all naval units can be transported (mass and size restrictions still apply). Defaults to 0.
+ int transportAir; //0 = all air units cannot be transported, 1 = all air units can be transported (mass and size restrictions still apply). Defaults to 0.
+
};
extern CModInfo *modInfo;
Code: Select all
Index: TransportCAI.cpp
===================================================================
--- TransportCAI.cpp (revision 3465)
+++ TransportCAI.cpp (working copy)
@@ -15,6 +15,7 @@
#include "Rendering/GL/glExtra.h"
#include "Game/GameHelper.h"
#include "Sim/MoveTypes/TAAirMoveType.h"
+#include "Sim/ModInfo.h"
#include "Rendering/UnitModels/3DOParser.h"
#include "mmgr.h"
@@ -197,7 +198,8 @@
float3 pos(c.params[0],c.params[1],c.params[2]);
float radius=c.params[3];
float3 found;
- bool canUnload=FindEmptySpot(pos,max(16.0f,radius),((CTransportUnit*)owner)->transported.front().unit->radius,found);
+ CUnit* unitToUnload=((CTransportUnit*)owner)->transported.front().unit;
+ bool canUnload=FindEmptySpot(pos,max(16.0f,radius),unitToUnload->radius,found,unitToUnload);
if(canUnload){
Command c2;
c2.id=CMD_UNLOAD_UNIT;
@@ -273,8 +275,15 @@
// don't transport cloaked enemies
if (unit->isCloaked && !gs->AlliedTeams(unit->team, owner->team))
return false;
- if(unit->unitDef->canhover || unit->unitDef->floater || unit->unitDef->canfly)
+ if(unit->unitDef->canhover && (modInfo->transportHover==0))
return false;
+ if(unit->unitDef->floater && (modInfo->transportShip==0))
+ return false;
+ if(unit->unitDef->canfly && (modInfo->transportAir==0))
+ return false;
+ // if not a hover, not a floater and not a flier, then it's probably ground unit
+ if(!unit->unitDef->canhover && !unit->unitDef->floater && !unit->unitDef->canfly && (modInfo->transportGround==0))
+ return false;
if(unit->xsize > owner->unitDef->transportSize*2)
return false;
if(!transport->CanTransport(unit))
@@ -285,7 +294,7 @@
return true;
}
-bool CTransportCAI::FindEmptySpot(float3 center, float radius,float emptyRadius, float3& found)
+bool CTransportCAI::FindEmptySpot(float3 center, float radius,float emptyRadius, float3& found, CUnit* unitToUnload)
{
// std::vector<CUnit*> units=qf->GetUnitsExact(center,radius);
if(CTAAirMoveType* am=dynamic_cast<CTAAirMoveType*>(owner->moveType)){ //handle air transports differently
@@ -298,10 +307,21 @@
float3 pos=center+delta*radius;
pos.y=ground->GetHeight(pos.x,pos.z);
- if(ground->GetApproximateHeight(pos.x,pos.z)<-5)
+ //Don't unload ground units to water
+ if(!unitToUnload->unitDef->canhover && !unitToUnload->unitDef->floater && !unitToUnload->unitDef->canfly)
+ {
+ if(ground->GetApproximateHeight(pos.x,pos.z)<(0-unitToUnload->unitDef->maxWaterDepth))
+ continue;
+ }
+ //Don't unload ships on land
+ if(unitToUnload->unitDef->floater)
+ {
+ if(ground->GetApproximateHeight(pos.x,pos.z)>-5)
+ continue;
+ }
+ //Don't unload non-flying units on slopes
+ if((ground->GetSlope(pos.x,pos.z)>0.05f) && !unitToUnload->unitDef->canfly)
continue;
- if(ground->GetSlope(pos.x,pos.z)>0.05f)
- continue;
if(!qf->GetUnitsExact(pos,emptyRadius+8).empty())
continue;
found=pos;
@@ -315,10 +335,21 @@
continue;
rx=sqrt(rx);
for(float x=max(0.0f,center.x-rx);x<min(float(gs->mapx*SQUARE_SIZE),center.x+rx);x+=SQUARE_SIZE){
- if(ground->GetApproximateHeight(x,y)<-5)
+ //Don't unload ground units to water
+ if(!unitToUnload->unitDef->canhover && !unitToUnload->unitDef->floater && !unitToUnload->unitDef->canfly)
+ {
+ if(ground->GetApproximateHeight(x,y)<(0-unitToUnload->unitDef->maxWaterDepth))
+ continue;
+ }
+ //Don't unload ships on land
+ if(unitToUnload->unitDef->floater)
+ {
+ if(ground->GetApproximateHeight(x,y)>-5)
+ continue;
+ }
+ //Don't unload non-flying units on slopes
+ if((ground->GetSlope(x,y)>0.05f) && !unitToUnload->unitDef->canfly)
continue;
- if(ground->GetSlope(x,y)>0.05f)
- continue;
float3 pos(x,ground->GetApproximateHeight(x,y),y);
if(!qf->GetUnitsExact(pos,emptyRadius+8).empty())
continue;
Code: Select all
Index: TransportCAI.h
===================================================================
--- TransportCAI.h (revision 3465)
+++ TransportCAI.h (working copy)
@@ -13,7 +13,7 @@
void ScriptReady(void);
bool CanTransport(CUnit* unit);
- bool FindEmptySpot(float3 center, float radius,float emptyRadius, float3& found);
+ bool FindEmptySpot(float3 center, float radius,float emptyRadius, float3& found, CUnit* unitToUnload);
CUnit* FindUnitToTransport(float3 center, float radius);
int GetDefaultCmd(CUnit* pointed,CFeature* feature);
void DrawCommands(void);
The checks for unit type are mainly there because I couldn't get the minWaterDepth check to work, it always allowed the ship to be unloaded to land (strangely enough maxWaterDepth worked).
I'll probably try to redo this part, but I'm not sure it will get any better.
Edit: I found what was wrong - my ship had no minWaterDepth in unit fbi (it was specified in movetype) and so the engine assigned some strange value to it. After I added minWaterDepth to the unit, the check started to work as intended.
So, here is the updated diff (only the TransportCAI.cpp, everything else in the same as in previous diff):
As for maxSlope, I cannot understand how to convert between maxSlope (found in the unitDef) and GetSlope, so I don't know how to check for that. Is is just that maxSlope is in degrees and GetSlope is in radians or is it something entirely different?
I'll probably try to redo this part, but I'm not sure it will get any better.
Edit: I found what was wrong - my ship had no minWaterDepth in unit fbi (it was specified in movetype) and so the engine assigned some strange value to it. After I added minWaterDepth to the unit, the check started to work as intended.
So, here is the updated diff (only the TransportCAI.cpp, everything else in the same as in previous diff):
Code: Select all
Index: TransportCAI.cpp
===================================================================
--- TransportCAI.cpp (revision 3465)
+++ TransportCAI.cpp (working copy)
@@ -15,6 +15,7 @@
#include "Rendering/GL/glExtra.h"
#include "Game/GameHelper.h"
#include "Sim/MoveTypes/TAAirMoveType.h"
+#include "Sim/ModInfo.h"
#include "Rendering/UnitModels/3DOParser.h"
#include "mmgr.h"
@@ -197,7 +198,8 @@
float3 pos(c.params[0],c.params[1],c.params[2]);
float radius=c.params[3];
float3 found;
- bool canUnload=FindEmptySpot(pos,max(16.0f,radius),((CTransportUnit*)owner)->transported.front().unit->radius,found);
+ CUnit* unitToUnload=((CTransportUnit*)owner)->transported.front().unit;
+ bool canUnload=FindEmptySpot(pos,max(16.0f,radius),unitToUnload->radius,found,unitToUnload);
if(canUnload){
Command c2;
c2.id=CMD_UNLOAD_UNIT;
@@ -273,8 +275,15 @@
// don't transport cloaked enemies
if (unit->isCloaked && !gs->AlliedTeams(unit->team, owner->team))
return false;
- if(unit->unitDef->canhover || unit->unitDef->floater || unit->unitDef->canfly)
+ if(unit->unitDef->canhover && (modInfo->transportHover==0))
return false;
+ if(unit->unitDef->floater && (modInfo->transportShip==0))
+ return false;
+ if(unit->unitDef->canfly && (modInfo->transportAir==0))
+ return false;
+ // if not a hover, not a floater and not a flier, then it's probably ground unit
+ if(!unit->unitDef->canhover && !unit->unitDef->floater && !unit->unitDef->canfly && (modInfo->transportGround==0))
+ return false;
if(unit->xsize > owner->unitDef->transportSize*2)
return false;
if(!transport->CanTransport(unit))
@@ -285,7 +294,7 @@
return true;
}
-bool CTransportCAI::FindEmptySpot(float3 center, float radius,float emptyRadius, float3& found)
+bool CTransportCAI::FindEmptySpot(float3 center, float radius,float emptyRadius, float3& found, CUnit* unitToUnload)
{
// std::vector<CUnit*> units=qf->GetUnitsExact(center,radius);
if(CTAAirMoveType* am=dynamic_cast<CTAAirMoveType*>(owner->moveType)){ //handle air transports differently
@@ -297,9 +306,12 @@
}
float3 pos=center+delta*radius;
pos.y=ground->GetHeight(pos.x,pos.z);
-
- if(ground->GetApproximateHeight(pos.x,pos.z)<-5)
+ float unloadPosHeight=ground->GetApproximateHeight(pos.x,pos.z);
+ if(unloadPosHeight<(0-unitToUnload->unitDef->maxWaterDepth))
continue;
+ if(unloadPosHeight>(0-unitToUnload->unitDef->minWaterDepth))
+ continue;
+ //Don't unload anything on slopes
if(ground->GetSlope(pos.x,pos.z)>0.05f)
continue;
if(!qf->GetUnitsExact(pos,emptyRadius+8).empty())
@@ -315,8 +327,12 @@
continue;
rx=sqrt(rx);
for(float x=max(0.0f,center.x-rx);x<min(float(gs->mapx*SQUARE_SIZE),center.x+rx);x+=SQUARE_SIZE){
- if(ground->GetApproximateHeight(x,y)<-5)
+ float unloadPosHeight=ground->GetApproximateHeight(x,y);
+ if(unloadPosHeight<(0-unitToUnload->unitDef->maxWaterDepth))
continue;
+ if(unloadPosHeight>(0-unitToUnload->unitDef->minWaterDepth))
+ continue;
+ //Don't unload anything on slopes
if(ground->GetSlope(x,y)>0.05f)
continue;
float3 pos(x,ground->GetApproximateHeight(x,y),y);