2025-08-03 21:55 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000853Spring engineGeneralpublic2008-04-08 16:30
ReporterLordMatt 
Assigned Totvo 
PrioritynormalSeveritycrashReproducibilityalways
StatusresolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000853: Give a transport an unload order on the edge of the map with .76b1 and spring crashes
DescriptionGive a transport an unload order on the edge of the map with .76b1 and spring crashes. No stacktrace is produced on Linux or Windows. Tested with arm atlas (BA 6.1) on the right side of comet catcher. You have to give the order exactly on the edge for it to work.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • ? file icon unnamed.sdf (19,275 bytes) 2008-02-23 21:23
  • patch file icon airunload.patch (2,964 bytes) 2008-04-02 06:21 -
    Index: rts/Sim/Units/CommandAI/CommandAI.h
    ===================================================================
    --- rts/Sim/Units/CommandAI/CommandAI.h	(revision 5634)
    +++ rts/Sim/Units/CommandAI/CommandAI.h	(working copy)
    @@ -81,7 +81,7 @@
     protected:
     	bool isTrackable(const CUnit* unit) const;
     	bool isAttackCapable() const;
    -	bool AllowedCommand(const Command &c);
    +	virtual bool AllowedCommand(const Command &c);
     	bool SkipParalyzeTarget(const CUnit* target);
     	void GiveAllowedCommand(const Command& c);
     	void GiveWaitCommand(const Command& c);
    Index: rts/Sim/Units/CommandAI/TransportCAI.cpp
    ===================================================================
    --- rts/Sim/Units/CommandAI/TransportCAI.cpp	(revision 5634)
    +++ rts/Sim/Units/CommandAI/TransportCAI.cpp	(working copy)
    @@ -297,6 +297,18 @@
     bool CTransportCAI::FindEmptySpot(float3 center, float radius, float emptyRadius, float3& found, CUnit* unitToUnload)
     {
     	if (dynamic_cast<CTAAirMoveType*>(owner->moveType)) {
    +		// If the command radius is less than the diameter of the unit we wish to drop
    +		if(radius < emptyRadius*2) {
    +			// Boundary checking.  If we are too close to the edge of the map, we will get stuck
    +			// in an infinite loop due to not finding any random positions that match a valid location.
    +			if	(	(center.x+1*radius < emptyRadius)
    +				||	(center.z+1*radius < emptyRadius)
    +				||	(center.x-1*radius >= gs->mapx * SQUARE_SIZE - emptyRadius)
    +				||	(center.z-1*radius >= gs->mapy * SQUARE_SIZE - emptyRadius)
    +				)
    +				return false;
    +		}
    +
     		// handle air transports differently
     		for (int a = 0; a < 100; ++a) {
     			float3 delta(1, 0, 1);
    @@ -970,3 +982,25 @@
     		&& unit->pos.distance2D(
     		float3(cmd.params[0], cmd.params[1], cmd.params[2])) > cmd.params[3]*2);
     }
    +
    +bool CTransportCAI::AllowedCommand(const Command& c)
    +{
    +	if(!CMobileCAI::AllowedCommand(c))
    +		return false;
    +
    +	switch (c.id) {
    +		case CMD_UNLOAD_UNIT:
    +		case CMD_UNLOAD_UNITS: {
    +			CUnit* u = ((CTransportUnit*) owner)->transported.front().unit;
    +			float3 pos(c.params[0],c.params[1],c.params[2]);
    +			float radius = c.params[3];
    +			float spread = u->radius * ((CTransportUnit*) owner)->unitDef->unloadSpread;
    +			float3 found;
    +			bool canUnload = FindEmptySpot(pos, max(16.0f, radius), spread, found, u);
    +
    +			if(!canUnload)	return false;	break;
    +		}
    +	}
    +
    +	return true;
    +}
    Index: rts/Sim/Units/CommandAI/TransportCAI.h
    ===================================================================
    --- rts/Sim/Units/CommandAI/TransportCAI.h	(revision 5634)
    +++ rts/Sim/Units/CommandAI/TransportCAI.h	(working copy)
    @@ -51,6 +51,7 @@
     	void UnloadLandFlood(Command& c); //land and dispatch units all at once
     	void UnloadCrashFlood(Command& c); //slam into landscape abruptly and dispatch units all at once (incomplete)
     	
    +	virtual bool AllowedCommand(const Command& c);
     	bool SpotIsClear(float3 pos, CUnit* u);
     	std::list<float3> dropSpots;		
     	bool isFirstIteration;
    
    patch file icon airunload.patch (2,964 bytes) 2008-04-02 06:21 +

-Relationships
+Relationships

-Notes

~0001980

Kloot (developer)

Unable to reproduce as of r5525, can you
upload a demo showing this crash with SVN
Spring?

~0001983

LordMatt (reporter)

Last edited: 2008-02-23 21:24

Uploaded a demo of crash with r5526. Dunno if it is corrupted or what, however. It can be somewhat hard to get to work. I had to spam unload commmands near the edge before the crash happened.

~0001984

Auswaschbar (reporter)

There seems to be an infinite loop in CTransportCAI::FindEmptySpot:

#1 0x086fecab in CTransportCAI::FindEmptySpot ()
#2 0x086ff896 in CTransportCAI::UnloadUnits_Land ()
0000003 0x086ffa2a in CTransportCAI::ExecuteUnloadUnits ()
0000004 0x08700e1d in CTransportCAI::SlowUpdate ()
0000005 0x087166a0 in CCommandAI::GiveAllowedCommand ()
#6 0x08708a9e in CMobileCAI::GiveCommandReal ()
#7 0x08714e85 in CCommandAI::GiveCommand ()

I continued and interrupted several times, it never goes past the FindEmptySpot (). Of course it didn't react to any user input.

~0002022

Flaamwing (reporter)

The loop checking for a random location within the drop radius cycles in an infinite loop as Auswaschbar mentioned. The following patch fixes it, and prevents the command from being queued if the location is invalid, so that the unit doesnt get loaded and sit there with the user thinking that it will eventually be unloaded.

Attaching the patch that fixes this.

~0002028

LordMatt (reporter)

Great! Now if only I knew enough C++ to be able to judge that it works I would apply it. :P

~0002033

Flaamwing (reporter)

Not actually that much C++ involved :)

But, np. Can wait for another dev to test it... It certainly worked for me :P

~0002036

tvo (reporter)

Committed in r5681, thank you Flaamwing!

I slightly modified it btw; multiplying stuff by 1 seemed a bit pointless (in the bounds check), and I added a check for if the transported list is empty in your CTransportCAI::AllowedCommand method, to prevent crash if ever the list is empty when that method is called (possibly that never happens atm though).
+Notes

-Issue History
Date Modified Username Field Change
2008-02-16 02:02 LordMatt New Issue
2008-02-23 20:51 Kloot Note Added: 0001980
2008-02-23 20:52 Kloot Status new => feedback
2008-02-23 21:23 LordMatt File Added: unnamed.sdf
2008-02-23 21:23 LordMatt Note Added: 0001983
2008-02-23 21:24 LordMatt Note Edited: 0001983
2008-02-24 11:11 Auswaschbar Note Added: 0001984
2008-04-02 06:20 Flaamwing Note Added: 0002022
2008-04-02 06:21 Flaamwing File Added: airunload.patch
2008-04-03 00:25 LordMatt Note Added: 0002028
2008-04-05 00:35 Flaamwing Note Added: 0002033
2008-04-08 16:26 tvo Status feedback => assigned
2008-04-08 16:26 tvo Assigned To => tvo
2008-04-08 16:30 tvo Status assigned => resolved
2008-04-08 16:30 tvo Resolution open => fixed
2008-04-08 16:30 tvo Note Added: 0002036
+Issue History