Page 3 of 3

Posted: 07 Mar 2007, 19:07
by Taipan
Hovercrafts are actually faster on calm water then on land.

Posted: 07 Mar 2007, 22:14
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.

Posted: 07 Mar 2007, 22:36
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.

Posted: 07 Mar 2007, 22:41
by FLOZi
Speed on water can be controlled via script now anyway. :-)


p.s. yay for PT-76

Posted: 08 Mar 2007, 05:13
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!!

A new patch

Posted: 08 Mar 2007, 18:48
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);

Posted: 08 Mar 2007, 19:30
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.

Posted: 09 Mar 2007, 09:31
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?

Posted: 09 Mar 2007, 10:19
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?