Game Development Community

Consolidated formation movement example

by Stephen Zepp · in RTS Starter Kit · 11/16/2004 (6:47 pm) · 14 replies

I've condensed the appropriate information into this thread from this one.

This small set of script mods allows you to set a formation that your selected group of units will march into when you set a move destination.

Currently, the formation itself is not capable of being "oriented", meaning that they all line up to the right/down of the destination point. My next goal (which I will probably need some assistance on for the target formation decal) is to have the player able to right click and hold on the destination point, which displays a grid of destination points (one for each unit). While the mouse is held, the player can rotate the formation in the X-Y plane to change the orientation of the formation when they reach the destination. The move will commence when the mouse is released.

Anyway, here's the code:

in file /client/scripts/inputHandler.cs:

Replace the entire function "function GuiRTSTSCtrl::onRightMouseDownTerrain(%this, %x, %y, %z)" with

function GuiRTSTSCtrl::onRightMouseDownTerrain(%this, %x, %y, %z)
{
   if(%this.selectionIncludesTeam)
      commandToServer('IssueMove', $Player::CurSquadFormation, %x, %y, %z);
}
in file /client/scripts/mapHud.cs, scroll down to the bottom and replace the entire function GuiMapHud::onRightMouseDown with:
function GuiMapHud::onRightMouseDown(%this, %worldPos)
{
   commandToServer('IssueMove', $Player::CurSquadFormation, "true",
                                getWord(%worldPos, 0),
                                getWord(%worldPos, 1),
                                getWord(%worldPos, 2));
}
(con't next message)

#1
11/16/2004 (6:47 pm)
In file /server/scripts/core/commands.cs:

Replace the entire function "function serverCmdIssueMove(%client, %x, %y, %z) with

function serverCmdIssueMove(%client, %formation, %x, %y, %z)
{
   if (%client.selection.getObject(0).getTeam() != %client.getTeam())
      return;
   %numUnitsSelected = %client.selection.getCount();
   for (%i = 0; %i < ClientGroup.getCount(); %i++)
   {
      %cl = ClientGroup.getObject(%i);
      %cl.sendMoveEvent(%client.selection, %x SPC %y);
   }
   
   %center = "0 0 0";
   // finding the center of the selected group
   for (%i = 0; %i < %numUnitsSelected; %i++)
   {
      %center = VectorAdd(%center, %client.selection.getObject(%i).getPosition());
   }
   %center = VectorScale(%center, 1.0 / %numUnitsSelected);
   
   for(%i = 0; %i < %numUnitsSelected; %i++)
   {
      %obj = %client.selection.getObject(%i);
      %dest = %x SPC %y SPC %z;
      
      switch$(%formation)
      {
      	case "FormDoubleLine":
      	  // calculate number of columns. 
      	  %numColumns = mFloor(%numUnitsSelected / 2);
      	  // find out if this count is even or odd
      	  if ( %i % 2 > 0 )
      	    %rowOffset = 0;
      	  else
      	    %rowOffset = 1;
      	  // set column spacing
      	  %ColSpacing = 5;
      	  %rowSpacing = 5;
      	  // right now we will treat the destination position as the top left corner of the formation
      	  // so rows are always to the positive. when we add in formation orientation, this will rotate
      	  // about the destination
      	  %offset = ( mFloor(%i / 2) * %ColSpacing ) SPC
      	                ( %RowOffset * %RowSpacing ) SPC
      	                0;
      	  echo("Set FormDoubleLine Destination: Unit Count " @ %i @ " form offset " @ %offset);
      	case "FormSquare":
      	  // calculate number of columns/rows. 
      	  %numColumns = mFloor(mSqrt(%numUnitsSelected) );
      	  if (%numColumns * %numColumns < %numUnitsSelected)
      	    %numColumns++;
      	  echo("FormSquare: numColumns is " @ %numColumns);
      	  // set column spacing
      	  %ColSpacing = 5;
      	  %RowSpacing = 5;
      	  // right now we will treat the destination position as the top left corner of the formation
      	  // so rows are always to the positive. when we add in formation orientation, this will rotate
      	  // about the destination
      	  %offset = ( %i % %numColumns) * %ColSpacing SPC
      	                ( mFloor( %i / %numColumns) * %RowSpacing ) SPC
      	                0;
      	  echo("Set FormSquare Destination: Unit Count " @ %i @ " form offset " @ %offset);
      	default :
      	// default to maintain relative position
      	%offset = VectorSub(%obj.getPosition(), %center);

      }
      %dest = VectorAdd(%dest, %offset);
      %obj.clearAim();
      
      %obj.setMoveGoal(%dest);
   }
}
(cont)
#2
11/16/2004 (6:50 pm)
To make buttons in your playGui to select formation type:


First, you must grab the new buttons that John McGlamory made, you can get them Here.

Unzip the buttons into your /starter.RTS/client/ui/commands directory.

Next, open up playGui.gui in a text editor, and add the following two new guis, after the current set of 4 CM_ buttons (right after the CM_HOLD one):

new GuiBitmapButtonCtrl(CM_FormSquare) {
         profile = "GuiDefaultProfile";
         horizSizing = "left";
         vertSizing = "top";
         position = "77 7";
         extent = "32 32";
         minExtent = "8 2";
         visible = "1";
         command = "CommandMenu::onFormSquareClick();";
         text = "Hold";
         groupNum = "-1";
         buttonType = "RadioButton";
         bitmap = "./commands/boxform";
      };
      new GuiBitmapButtonCtrl(CM_FormDblLine) {
         profile = "GuiDefaultProfile";
         horizSizing = "left";
         vertSizing = "top";
         position = "77 42";
         extent = "32 32";
         minExtent = "8 2";
         visible = "1";
         command = "CommandMenu::onFormDoubleLineClick();";
         text = "Hold";
         groupNum = "-1";
         buttonType = "RadioButton";
         bitmap = "./commands/lineform";
      };

NOTE: They should be in the same grouping space as the other 4 CM_ buttons, and should (but don't have to be) at the end of that block.

at the bottom of the same file, add in:
function CommandMenu::onFormSquareClick()
{
  $Player::CurSquadFormation = "FormSquare";
}

function CommandMenu::onFormDoubleLineClick()
{
  $Player::CurSquadFormation = "FormDoubleLine";
}

Save the file, and fire up the demo!
#3
11/17/2004 (3:26 pm)
Stephen:

Thanks a lot for your Resource. I made the changes on the scripts and runs without any problem.
#4
12/28/2004 (12:19 pm)
Thanks for starting this!

Is this resource based on some other fix? When I try this on a fresh install of the pack my guys act somewhat retarded, i.e. sometimes walk the opposite direction of what I clicked for, etc. Or is that "WAD"?
#5
12/28/2004 (2:41 pm)
I had the same thing happen when I first implemented it. I believe it was a change that I missed making but unforetunately can't remember what. Recheck your edits and make sure you're not getting any script errors in the console.
#6
12/28/2004 (5:13 pm)
Thanks Jeff, I found it. :) For future users: When you copy/paste the code, check the single quotes. They are supposed to be like this ' but they are pasted as the right-slanted variety.
#7
12/29/2004 (2:36 pm)
That was it!
#8
12/31/2004 (6:27 pm)
Hopefully in the near future we'll have private resources up and running, so you guys won't have to copy outstanding resources like this from forum text. :) For now, search and replace is all of our friend. :)
#9
12/31/2004 (6:35 pm)
@Josh: Hope so, because Jeff and I are hopefully going to finish up the cool new RTS SK terrain digging resource this next week! I can of course host it at my server until you guys do get something up and running, but would be good to get it passed over to you guys.
#10
06/20/2005 (5:05 pm)
I followed the instructions, but it didn't work. the right click gave an error. namely: Remote Server Error: command must be a tag - i was weary for the mentioned single parenthesis copy/paste thing, but couldn't find any whatsoever. i'm not sure why, but both the lines in the code sniplets of the first post don't have any here - and they should:

CommandToServer(IssueMove, $Player::CurSquadFormation, %x, %y, %z);

should be changed to:

CommandToServer('IssueMove', $Player::CurSquadFormation, %x, %y, %z);

Single parenthesis around the IssueMove. Took me a while to figure out, just in case some of you get stuck! =)
#11
06/27/2005 (7:31 am)
Good catch--unfortunately that's an artifact of the code/code block for the web site--it tends to remove those types of characters.
#12
07/26/2005 (12:56 pm)
Hello community, the link for the buttons is dead. There is a way to got it ? Thanks in advance :)
#13
10/13/2005 (11:08 pm)
Hi there everyone,

The link to the buttons is still dead, does anyone know if the link has been changed or updated?

Thanks

Brad
#14
10/14/2005 (7:52 am)
John McGlamory appears to have had real life take over, but the buttons you are speaking of are simply two little 32x32 icons. Not to hard to mock something up in photoshop, gimp, or even ms paint :)