Hovers can't be transported - Page 3

Hovers can't be transported

Discuss game development here, from a distinct game project to an accessible third-party mutator, down to the interaction and design of individual units if you like.

Moderator: Moderators

Taipan
Posts: 7
Joined: 06 Mar 2007, 21:55

Post by Taipan »

Hovercrafts are actually faster on calm water then on land.
manored
Posts: 3179
Joined: 15 Nov 2006, 00:37

Post by manored »

Taipan wrote:Hovercrafts are actually faster on calm water then on land.
In fact. but hovercrafts are not common amphibious vehicles since they hover instead of floating on water.
User avatar
yuritch
Spring 1944 Developer
Posts: 1018
Joined: 11 Oct 2005, 07:18

Post by yuritch »

"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:
Image
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.
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6241
Joined: 29 Apr 2005, 01:14

Post by FLOZi »

Speed on water can be controlled via script now anyway. :-)


p.s. yay for PT-76
j5mello
Posts: 1189
Joined: 26 Aug 2005, 05:40

Post by j5mello »

thats how all of GD's amphib tanks are gonna function once fang can set it up no more sit on the bottom of the sea :P

so hurrah for... this thread and more control over shit!!
User avatar
yuritch
Spring 1944 Developer
Posts: 1018
Joined: 11 Oct 2005, 07:18

A new patch

Post by yuritch »

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).

Code: Select all

[TRANSPORTABILITY]
{
transportGround=1;
transportHover=1;
transportShip=1;
transportAir=1;
}
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

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);
User avatar
Pxtl
Posts: 6112
Joined: 23 Oct 2004, 01:43

Post by Pxtl »

While I appreciate the effort, I have to say it's an unnecessary complication. The "canbetransported" tag is really all that's needed.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

Why does the code needs to treat ships, land units, air units differently?

Can't you just use MaxWaterDepth, MaxSlope, MinWaterDepth, without having to know what kind of unit it is?

Why should planes be allowed to be unloaded but not land on vertical cliffs?
User avatar
yuritch
Spring 1944 Developer
Posts: 1018
Joined: 11 Oct 2005, 07:18

Post by yuritch »

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):

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);
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?
Post Reply

Return to “Game Development”