1. // basic array to hold information about your buildings
  2. // the client is interested in the images only
  3.  
  4. // $Gui::imagePath is the path from ~ leading to your images. In stock RTS SK, it should
  5. // be set to:
  6. // $Gui::imagePath = "./";
  7. // the rest of the paths are self-generating
  8.  
  9.    $Gui::imagePath = "starter.RTS/client/ui/";
  10.    $Gui::markerPath = "starter.RTS/data/shapes/";
  11.  
  12.  
  13.    $Gui::unitImagePath = $Gui::imagePath @ "buildingDisplay/";
  14.    $Gui::buildingImagePath = $Gui::imagePath @ "buildingDisplay/";
  15.    $Gui::resourceImagePath = $Gui::imagePath @ "resourceDisplay/";
  16.    
  17.    $Gui::BuildingActionCount = 3;
  18.    $Gui::TotalNumberBuildings = 12; // <-- JY - may need to modify this
  19. // this is a simple way to keep track of all your building information in one place. It's not the -best- way
  20.  
  21. // Factory: this building produces wood
  22.    $BD_buildingName[0]     = "Factory";
  23.    $BD_ActionType[0]       = "Harvest";
  24.    $BD_buildingIcon[0]     = $Gui::buildingImagePath @ "icon_factory";
  25.    $BD_ActionIcon[0,0]    = $Gui::resourceImagePath @ "icon_wood";
  26.    $BD_ActionIcon[1,0]   = $Gui::resourceImagePath @ "not_used";
  27.    $BD_ActionIcon[2,0]   = $Gui::resourceImagePath @ "not_used";
  28.    $BD_Marker_scale[0,0]        = "1 1 1";
  29.    $BD_Marker_thedatablock[0,0] = "factoryBlock";
  30.    $BD_Marker_shapeName[0,0]    = $Gui::markerPath @ "animated/human/snow/human1.dts";
  31.    $BD_Marker_TweakZAxis[0,0] = "0";
  32.  
  33.    
  34. // Barracks: this unit hires troops
  35.    $BD_buildingName[1]     = "Barracks";
  36.    $BD_ActionType[1]       = "Hire warrior knightress archer";
  37.    $BD_buildingIcon[1]     = $Gui::buildingImagePath @ "icon_barracks";
  38.    $BD_ActionIcon[0,1]      = $Gui::unitImagePath @ "train_0";
  39.    $BD_ActionIcon[1,1]      = $Gui::unitImagePath @ "train_1";
  40.    $BD_ActionIcon[2,1]      = $Gui::unitImagePath @ "train_2";
  41.    $BD_Marker_scale[0,1]        = "1 1 1";
  42.    $BD_Marker_thedatablock[0,1] = "barracksBlock";
  43.    $BD_Marker_shapeName[0,1]    = $Gui::markerPath @ "animated/human/snow/human4.dts";
  44.    $BD_Marker_TweakZAxis[0,1] = "0.0";
  45.  
  46. //Shop: this unit mines. Mines mines MINES! (ok, actually it generates gold)
  47.    $BD_buildingName[2]     = "Shop";
  48.    $BD_ActionType[2]       = "Harvest";
  49.    $BD_buildingIcon[2]     = $Gui::buildingImagePath @ "icon_shop";
  50.    $BD_ActionIcon[0,2]      = $Gui::resourceImagePath @ "icon_gold";
  51.    $BD_ActionIcon[1,2]      = $Gui::resourceImagePath @ "not_used";
  52.    $BD_ActionIcon[2,2]      = $Gui::resourceImagePath @ "not_used";
  53.    $BD_Marker_scale[0,2]        = "1 1 1";
  54.    $BD_Marker_thedatablock[0,2] = "shopBlock";
  55.    $BD_Marker_shapeName[0,2]    = $Gui::markerPath @ "animated/human/snow/human1.dts";
  56.    $BD_Marker_TweakZAxis[0,2] = "4.0";
  57.  
  58.  
  59. // Farm: this unit produces food
  60.    $BD_buildingName[3]     = "Farm";
  61.    $BD_ActionType[3]       = "Harvest";
  62.    $BD_buildingIcon[3]     = $Gui::buildingImagePath @ "icon_farm";
  63.    $BD_ActionIcon[0,3]      = $Gui::resourceImagePath @ "icon_food";
  64.    $BD_ActionIcon[1,3]      = $Gui::resourceImagePath @ "not_used";
  65.    $BD_ActionIcon[2,3]      = $Gui::resourceImagePath @ "not_used";
  66.    $BD_Marker_scale[0,3]        = "1 1 1";
  67.    $BD_Marker_thedatablock[0,3] = "farmBlock";
  68.    $BD_Marker_shapeName[0,3]    = $Gui::markerPath @ "animated/human/snow/human2.dts";
  69.    $BD_Marker_TweakZAxis[0,3] = "0";
  70.  
  71. // Foundry: this unit mines. Mines mines MINES! -- stone
  72.    $BD_buildingName[4]     = "Foundry";
  73.    $BD_ActionType[4]       = "Harvest";
  74.    $BD_buildingIcon[4]     = $Gui::buildingImagePath @ "icon_foundry";
  75.    $BD_ActionIcon[0,4]      = $Gui::resourceImagePath @ "icon_stone";
  76.    $BD_ActionIcon[1,4]      = $Gui::resourceImagePath @ "not_used";
  77.    $BD_ActionIcon[2,4]      = $Gui::resourceImagePath @ "not_used";
  78.    $BD_Marker_scale[0,4]        = "1 1 1";
  79.    $BD_Marker_thedatablock[0,4] = "foundryBlock";
  80.    $BD_Marker_shapeName[0,4]    = $Gui::markerPath @ "animated/human/snow/human3.dts";
  81.    $BD_Marker_TweakZAxis[0,4] = "0";
  82.  
  83. // Town Center: train peons, drop off point for resources
  84.    $BD_buildingName[5]   = "TownCenter";
  85.    $BD_ActionType[5]     = "Hire villager";
  86.    $BD_buildingIcon[5]   = $Gui::buildingImagePath @ "icon_towncenter";
  87.    $BD_ActionIcon[0,5]   = $Gui::unitImagePath @ "villager";
  88.    $BD_ActionIcon[1,5]   = $Gui::unitImagePath @ "not_used";
  89.    $BD_ActionIcon[2,5]   = $Gui::unitImagePath @ "not_used";
  90.    $BD_Marker_scale[0,5]   = "1 1 1";
  91.    $BD_Marker_thedatablock[0,5] = "townCenterBlock";
  92.    $BD_Marker_shapeName[0,5]    = $Gui::markerPath @ "animated/human/snow/human5.dts";
  93.    $BD_Marker_TweakZAxis[0,5] = "0";
  94. // ---------------------------------//
  95. // ORC buildings
  96. // ---------------------------------//
  97. // Factory: this building produces wood
  98.    $BD_buildingName[6]     = "Factory";
  99.    $BD_ActionType[6]       = "Harvest";
  100.    $BD_buildingIcon[6]     = $Gui::buildingImagePath @ "icon_factory";
  101.    $BD_ActionIcon[0,6]    = $Gui::resourceImagePath @ "icon_wood";
  102.    $BD_ActionIcon[1,6]   = $Gui::resourceImagePath @ "not_used";
  103.    $BD_ActionIcon[2,6]   = $Gui::resourceImagePath @ "not_used";
  104.    $BD_Marker_scale[0,6]        = "1 1 1";
  105.    $BD_Marker_thedatablock[0,6] = "orcFactoryBlock";
  106.    $BD_Marker_shapeName[0,6]    = $Gui::markerPath @ "animated/orc/snow/orc1.dts";
  107.    $BD_Marker_TweakZAxis[0,6] = "0";
  108.  
  109.    
  110. // Barracks: this unit hires troops
  111.    $BD_buildingName[7]     = "Barracks";
  112.    $BD_ActionType[7]       = "Hire warrior knightress archer";
  113.    $BD_buildingIcon[7]     = $Gui::buildingImagePath @ "icon_barracks";
  114.    $BD_ActionIcon[0,7]      = $Gui::unitImagePath @ "train_0";
  115.    $BD_ActionIcon[1,7]      = $Gui::unitImagePath @ "train_1";
  116.    $BD_ActionIcon[2,7]      = $Gui::unitImagePath @ "train_2";
  117.    $BD_Marker_scale[0,7]        = "1 1 1";
  118.    $BD_Marker_thedatablock[0,7] = "orcBarracksBlock";
  119.    $BD_Marker_shapeName[0,7]    = $Gui::markerPath @ "animated/orc/snow/orc4.dts";
  120.    $BD_Marker_TweakZAxis[0,7] = "0.0";
  121.  
  122. //Shop: this unit mines. Mines mines MINES! (ok, actually it generates gold)
  123.    $BD_buildingName[8]     = "Shop";
  124.    $BD_ActionType[8]       = "Harvest";
  125.    $BD_buildingIcon[8]     = $Gui::buildingImagePath @ "icon_shop";
  126.    $BD_ActionIcon[0,8]      = $Gui::resourceImagePath @ "icon_gold";
  127.    $BD_ActionIcon[1,8]      = $Gui::resourceImagePath @ "not_used";
  128.    $BD_ActionIcon[2,8]      = $Gui::resourceImagePath @ "not_used";
  129.    $BD_Marker_scale[0,8]        = "1 1 1";
  130.    $BD_Marker_thedatablock[0,8] = "orcShopBlock";
  131.    $BD_Marker_shapeName[0,8]    = $Gui::markerPath @ "animated/orc/snow/orc1.dts";
  132.    $BD_Marker_TweakZAxis[0,8] = "4.0";
  133.  
  134.  
  135. // Farm: this unit produces food
  136.    $BD_buildingName[9]     = "Farm";
  137.    $BD_ActionType[9]       = "Harvest";
  138.    $BD_buildingIcon[9]     = $Gui::buildingImagePath @ "icon_farm";
  139.    $BD_ActionIcon[0,9]      = $Gui::resourceImagePath @ "icon_food";
  140.    $BD_ActionIcon[1,9]      = $Gui::resourceImagePath @ "not_used";
  141.    $BD_ActionIcon[2,9]      = $Gui::resourceImagePath @ "not_used";
  142.    $BD_Marker_scale[0,9]        = "1 1 1";
  143.    $BD_Marker_thedatablock[0,9] = "orcFarmBlock";
  144.    $BD_Marker_shapeName[0,9]    = $Gui::markerPath @ "animated/orc/snow/orc2.dts";
  145.    $BD_Marker_TweakZAxis[0,9] = "0";
  146.  
  147. // Foundry: this unit mines. Mines mines MINES! -- stone
  148.    $BD_buildingName[10]     = "Foundry";
  149.    $BD_ActionType[10]       = "Harvest";
  150.    $BD_buildingIcon[10]     = $Gui::buildingImagePath @ "icon_foundry";
  151.    $BD_ActionIcon[0,10]      = $Gui::resourceImagePath @ "icon_stone";
  152.    $BD_ActionIcon[1,10]      = $Gui::resourceImagePath @ "not_used";
  153.    $BD_ActionIcon[2,10]      = $Gui::resourceImagePath @ "not_used";
  154.    $BD_Marker_scale[0,10]        = "1 1 1";
  155.    $BD_Marker_thedatablock[0,10] = "orcFoundryBlock";
  156.    $BD_Marker_shapeName[0,10]    = $Gui::markerPath @ "animated/orc/snow/orc3.dts";
  157.    $BD_Marker_TweakZAxis[0,10] = "0";
  158.  
  159. // Town Center: train peons, drop off point for resources
  160.    $BD_buildingName[11]     = "TownCenter";
  161.    $BD_ActionType[11]       = "Hire orc";
  162.    $BD_buildingIcon[11]     = $Gui::buildingImagePath @ "icon_towncenter";
  163.    $BD_ActionIcon[0,11]      = $Gui::unitImagePath @ "orc";
  164.    $BD_ActionIcon[1,11]      = $Gui::unitImagePath @ "not_used";
  165.    $BD_ActionIcon[2,11]      = $Gui::unitImagePath @ "not_used";
  166.    $BD_Marker_scale[0,11]        = "1 1 1";
  167.    $BD_Marker_thedatablock[0,11] = "orcTownCenterBlock";
  168.    $BD_Marker_shapeName[0,11]    = $Gui::markerPath @ "animated/orc/snow/orc5.dts";
  169.    $BD_Marker_TweakZAxis[0,11] = "0";
  170. // -------------
  171. // NOTE: You must also match the datablock's declared RTSUnitTypeName to an index
  172. //       in playGui.cs, function GuiRTSTSCtrl::getTypeID
  173.  
  174. // we use the technique the RTS SK demonstrates regarding "dynamic" gui controls,
  175. // and build ourselves a BuildingDisplay and BuildingMenu dynamically refreshed
  176. // set of gui controls for displaying and interacting with buildings.
  177.  
  178.  
  179. function GuiRTSTSCtrl::initBD_ActionIcons(%this)
  180. {
  181.      $BDActionCount = 0;
  182.      while(isObject(%idx = %this.getBDAction($BDActionCount)))
  183.      {
  184.         $BDActionsArray[$BDActionCount] = %idx;
  185.  echo("initBD_Actions--$BDActionsArray[" @ $BDActionCount @ "] is" SPC %idx);        
  186.         $BDActionCount++;
  187.      }
  188. // echo("   GuiRTSTSCtrl::initBD_ActionIcons--leaving, $BDActionCount is (" @ $BDActionCount++ @ ")");
  189. }
  190.  
  191. function GuiRTSTSCtrl::getBDAction(%this, %Num)
  192. {
  193.    %ret = "BM_Action_" @ %Num;
  194.    return %ret;
  195. }
  196.    
  197. // The following 3 methods are used to index our data with various input and output variables
  198. // This is a very hard to maintain implementation, and a good suggestion would be to re-factor
  199. // so that all of the data is stored in the building information arrays above. What I suggest is
  200. // a very basic abstraction of array access, but this does work for the purposes of the demo resource.
  201.  
  202. // NOTE: As mentioned elsewhere, the example SelectionDisplay provided by the RTS SK makes a bad assumption:
  203. // dataBlocks (specifically dataBlock names) are NOT actually accessable to the client in a remote situation.
  204. // dataBlocks are actually only stored in the server's process(es), and the most proper implementation for
  205. // indexing dataBlocks via their "name" requires code changes. We use the technique the RTS SK does, and
  206. // make the (faulty) assumption that we can always access the server's dataBlock for a particular object
  207. // via %objID.getDataBlock().getName() to keep our "script only" implementation
  208.    
  209. function getBuildingTypeIDFromUnitName(%unitName)
  210. {
  211.    switch$(%unitName)
  212.    {
  213.       case "factory":
  214.          return 0;
  215.       case "testbuilding":
  216.          return 0;
  217.       case "barracks":
  218.          return 1;
  219.       case "shop":
  220.          return 2;
  221.       case "farm":
  222.          return 3;
  223.       case "foundry":
  224.          return 4;
  225.       case "townCenter":
  226.          return 5;
  227.       // ORCs
  228.        case "orcFactory":
  229.          return 6;
  230.        case "orcShop":
  231.          return 7;
  232.        case "orcBarracks":
  233.          return 8;
  234.        case "orcFarm":
  235.          return 9;
  236.        case "orcFoundry":
  237.          return 10;
  238.        case "orcTownCenter":
  239.          return 11;    
  240.    }
  241. }  
  242.  
  243. function getBuildingTypeIDFromDataBlock(%unitDB)
  244. {
  245.    switch$(%unitDB)
  246.    {
  247.       case "factoryBlock":
  248.          return 0;
  249.       case "testbuildingBlock":
  250.          return 0;
  251.       case "barracksBlock":
  252.          return 1;
  253.       case "shopBlock":
  254.          return 2;
  255.       case "farmBlock":
  256.          return 3;
  257.       case "foundryBlock":
  258.          return 4;
  259.       case "townCenterBlock":
  260.          return 5;
  261.       // ORCs
  262.        case "orcFactory":
  263.          return "orcFactoryBlock";
  264.        case "orcShop":
  265.          return "orcShopBlock";
  266.        case "orcBarracks":
  267.          return "orcBarracksBlock";
  268.        case "orcFarm":
  269.          return "orcFarmBlock";
  270.        case "orcFoundry":
  271.          return "orcFoundryBlock";
  272.        case "orcTownCenter":
  273.          return "orcTownCenterBlock";        
  274.    }
  275. }  
  276. function getBuildingTypeID(%objID)      
  277. {
  278.    if (! isObject(%objID))
  279.    {
  280.       echo("getBuildingTypeID called by invalid object");
  281.       return false;
  282.    }
  283.      
  284.   return (getBuildingTypeIDFromDataBlock(%objID.getDataBlock().getName() ) );
  285. }  
  286.  
  287. function GuiRTSTSCtrl::setBuildCommandState(%this, %state )
  288. {
  289.    %building = $BuildingMenu::CurrentSelectedBuilding;
  290.    if (!isObject(%building))
  291.    {
  292.      echo("GuiRTSTSCtrl::setBuildCommandState--$BuildingMenu::CurrentSelectedBuilding NOT set. Fix this in selection.cs");
  293.      return;
  294.    }
  295.    
  296.    if ((%building.currentCommand $= "None") ||
  297.        (%building.currentCommand $= ""    ) )
  298.    {
  299.      echo("GuiRTSTSCtrl::setBuildCommandState--Changing building (" @ %building @ ") command state to: " @ %state);
  300.      switch$(%state)
  301.      {
  302.        case "warrior":
  303.          %building.currentCommand = "Train warrior";
  304.          commandToServer('QueueTrainUnit', LOCAL,
  305.                          0);
  306.        case "knightress":
  307.          %building.currentCommand = "Train knightress";
  308.          commandToServer('QueueTrainUnit', LOCAL,
  309.                          1);
  310.        case "archer":
  311.          %building.currentCommand = "Train archer";
  312.          commandToServer('QueueTrainUnit', LOCAL,
  313.                          2);
  314.        case "villager":
  315.          %building.currentCommand = "Train villager";
  316.          commandToServer('QueueTrainUnit', LOCAL,
  317.                          3);
  318.      }
  319.    }
  320.    else
  321.    {
  322.      echo("GuiRTSTSCtrl::setBuildCommandState--currently ignoring new build order: processing" SPC
  323.          %building.currentCommand SPC "at this time.");
  324.    }
  325.      
  326.      
  327. }
  328. function clientCmdInitBuildMenuStatusBar( %building, %actionDuration )
  329. {
  330.   // this -may- not be the best way, but we want to know
  331.   // how long the total current action's total time will be,
  332.   // and that information is always stored server side. Have them
  333.   // tell us to init the bar, and we'll process from there
  334.  
  335.   %activeBuilding = ServerConnection.resolveGhostID(%building);
  336.   %activeBuilding.startActionTime = getSimTime();
  337.   %activeBuilding.actionDuration = %actionDuration;
  338.   %activeBuilding.actionApproved = "true";
  339. }
  340.  
  341.  
  342. function GuiRTSTSCtrl::refreshBuildingDisplay(%this, %repeat)
  343. {
  344.   %activeBuilding = $BuildingMenu::CurrentSelectedBuilding;
  345.    if( (%repeat) &&
  346.        ( isObject(%activeBuilding) ) )
  347.  
  348.       %this.schedule(100,"refreshBuildingDisplay",true);      
  349.   %activeBuilding = $BuildingMenu::CurrentSelectedBuilding;
  350.   %buildingIndex = getBuildingTypeID(%activeBuilding);
  351.  
  352.    // Show all portraits
  353.    BD_Selected_Image.setBitMap($BD_BuildingIcon[%buildingIndex]);
  354.    BD_Selected_Image.visible = "1";
  355.    Building_Background.visible = "1";
  356. }
  357. function GuiRTSTSCtrl::updateBuildingStatusBar(%building)
  358. {
  359.   %statusPercent = (getSimTime() - %building.startActionTime) / %building.actionDuration;
  360. // echo("GuiRTSTSCtrl::updateBuildingStatusBar--progress for (" @ %building @ ") is (" @ %statusPercent @ ")");
  361.   return %statusPercent;
  362.  
  363. }
  364. function GuiRTSTSCtrl::refreshBuildingMenu(%this, %repeat)
  365. {
  366. // need to make sure this is called when it should be repeated, and not when it's not
  367. // probably just cancel the schedule on shutdown of PlayGui
  368. // the current resource's implentation works, but is probably not the most performance
  369. // efficient implementation. In a "perfect" implementation, instead of scheduling a refresh
  370. // every 10th of a second, we would have an event driven refresh. In keeping with the technique the
  371. // RTS-SK uses, we stick with a scheduled refresh implementation
  372.  
  373. // echo("CurrentSelectedBuilding = (" @ $BuildingMenu::CurrentSelectedBuilding @ ")");
  374.   %activeBuilding = $BuildingMenu::CurrentSelectedBuilding;
  375.  
  376.    if( (%repeat) &&
  377.        ( isObject(%activeBuilding) ) )
  378.    {
  379.       %this.schedule(100,"refreshBuildingMenu",true);      
  380.    }
  381.    else
  382.    {
  383.     return;
  384.    }
  385. // echo("CurrentSelectedBuilding = (" @ $BuildingMenu::CurrentSelectedBuilding @ ")");
  386.   %buildingIndex = getBuildingTypeID(%activeBuilding);
  387.  
  388.   if (!isObject(%activeBuilding) )
  389.   {
  390.     // what are we doing here? turn everything off
  391.    echo("GuiRTSTSCtrl::refreshBuildingMenu==no selected building!");    
  392.    BuildingMenu.visible = "0";
  393.    BuildingDisplay.visible = "0";
  394. //   %this.cancel();
  395.    return;
  396.   }
  397.  
  398. // spin in our action icons
  399.   for (%i = 0; %i < $Gui::BuildingActionCount; %i++)
  400.   {
  401.     $BDActionsArray[%i].setBitMap($BD_ActionIcon[%i,%buildingIndex]);
  402.     // until we have upgradeable buildings, turn 'em all on
  403.     $BDActionsArray[%i].visible = "1";
  404.     if (getWord($BD_ActionType[%buildingIndex],0) $= "Hire")
  405.     {
  406.       // hack to only show 3 icons if we're training. Different state checks here
  407.       // can be applied for different building types, including upgrade status/level
  408.       // to turn off a particular action icon as appropriate
  409.       if ($BD_ActionIcon[%i,%buildingIndex] $= ($Gui::unitImagePath @ "not_used"))
  410.       {
  411.         $BDActionsArray[%i].visible = "0";
  412.       }
  413.       else
  414.       {
  415.         $BDActionsArray[%i].visible = "1";
  416.       }
  417.     }
  418.     else
  419.     {
  420.       $BDActionsArray[%i].visible = ( (%i == 0) ? "1" : "0");
  421.     }
  422.   }
  423.    // Show all portraits
  424.    BM_Background.visible = "1";
  425.  
  426.   if ( ( getWord(%activeBuilding.currentCommand,0) $= "Train" )&&
  427.        ( %activeBuilding.actionApproved $= "true")  )
  428.   {
  429. //    echo("GuiRTSTSCtrl::refreshBuildingMenu--current command is (" @ %activeBuilding.currentCommand @ ") for (" @ %activeBuilding @ ")");
  430. //    echo( "-----Unit index is (" @ getWord(%activeBuilding.currentCommand, 1) @ ")");
  431.    
  432.     // current command (Train Villager)
  433.     // JY - get correct bitmap for unit you are building
  434.     %unit =  getWord(%activeBuilding.currentCommand, 1);    
  435.    
  436.     BM_CurActionPortrait.setBitmap( %this.getBitmapFromUnitName(%unit) );
  437. //    echo("------bitmap is " @ %this.getBitmapFromUnitName(%unit) );
  438.     // JY - fixed it was bug in the above function
  439.    
  440.     BM_CurActionPortrait.visible = "1";
  441.     %curStatus = GuiRTSTSCtrl::updateBuildingStatusBar(%activeBuilding);
  442.     BM_CurActionStatus.visible = "1";
  443.     // here is where we update the value for our visual status bar
  444.     BM_CurActionStatus.setValue(%curStatus);
  445.   }
  446.   else
  447.   {
  448.     // we're not hiring any units at this time, so no need to display the Action Icon
  449.     // or progress bar. Of course, if you implement new building actions (such as upgrade, or
  450.     // research), you'll want to be able to display the progress. Do it here, as well as
  451.     // implement the required support functions both server side and client side for upgrade/train
  452.     // initialization and progress
  453.     BM_CurActionPortrait.visible = "0";
  454.     BM_CurActionPortrait.setBitMap("");
  455.     BM_CurActionStatus.visible = "0";
  456.     BM_CurActionStatus.setValue("");
  457.   }
  458. }
  459. function clientCmdBuildUnitDenied( %building )
  460. {
  461.   %activeBuilding = ServerConnection.resolveGhostID(%building);
  462.   %activeBuilding.currentCommand = "None";
  463.   %activeBuilding.actionDuration = "0";
  464.   %activeBuilding.curActionStartTime = "0";
  465.  
  466. }
  467. function clientCmdBuildUnitComplete( %building )
  468. {
  469. //echo("clientCmdBuildUnitComplete-- server said we are done with current command for (" @ %building @ ")");
  470.  // we're done with that action, look for any pending trains (not implemented)
  471.   // otherwise set state to None
  472.   %activeBuilding = ServerConnection.resolveGhostID(%building);
  473. //echo("clientCmdBuildUnitComplete-- resolved that id to local ghostID (" @ %activeBuilding @ ")");
  474.  
  475.   %activeBuilding.currentCommand = "None";
  476.   %activeBuilding.actionApproved = "false";
  477.   BM_CurACtionStatus.setValue(0);
  478.   BM_CurActionStatus.visible = "0";
  479.   BM_CurActionPortrait.visible = "0";
  480. }
  481.  
  482. function startPlaceBuilding(%buildingName)
  483. {
  484.    // Building is already being placed
  485.    if( isObject( $NewBuilding ) )
  486.       return;
  487.    %buildingIndex = getBuildingTypeIDFromUnitName(%buildingName);
  488.    echo("startPlaceBuilding--building name is (" @ %buildingName @ ") building index is (" @ %buildingIndex @ ")");
  489.    $NewBuilding = new RTSBuildingMarker()
  490.    {
  491.       scale = $BD_Marker_scale[0,%buildingIndex];
  492.       thedatablock = $BD_Marker_thedatablock[0,%buildingIndex];
  493.       shapeName = $BD_Marker_shapeName[0,%buildingIndex];
  494.    };
  495.    // Starting position = (0,0,0)
  496.    $NewBuilding.setTransform( "0 0 0 0 0 1 3.14159" );
  497.    $NewBuilding.setOverrideTexture("starter.RTS/data/shapes/green");
  498.    PlayGui.startBuildingPlacement($NewBuilding);
  499. }
  500.  
  501. function GuiRTSTSCtrl::placeBuilding(%this)
  502. {
  503. // right now, buildings can be placed by villagers basically anywhere, regardless of
  504. // where the villager is. A good task here would be to track where the selected building position
  505. // is, and make sure that the villager assigned to do the build moves to that spot before
  506. // we actually cause the building to be placed. Not currently implemented
  507.  
  508.    echo("Client sending building notify!" SPC $NewBuilding.getTransform() SPC $NewBuilding.thedatablock);
  509.    commandToServer('PlaceBuilding', "LOCAL", $NewBuilding.getTransform(),
  510.                     $NewBuilding.thedatablock);
  511.    $NewBuilding.delete();
  512. }