/** ** Unit trains unit! ** ** @param unit Unit that trains. */ global void HandleActionTrain(Unit* unit) { Unit* nunit; UnitType* type; Player* player; #if 0 // JOHNS: should be checked by the user-interface if( &Players[unit->Player]==ThisPlayer ) { // FIXME: If so used you get millions of messages. if( ThisPlayer->Food<=ThisPlayer->Units && unit->Command.Data.Train.Ticks ) { SetMessage( "You need more farms!" ); } else { AiNeedMoreFarms(unit); } } #endif player=unit->Player; unit->Command.Data.Train.Ticks+=SpeedTrain; // FIXME: Should count down if( unit->Command.Data.Train.Ticks >=unit->Command.Data.Train.What[0] ->Stats[player->Player].Costs[TimeCost] ) { // // Check if enough food available. // if( player->Food<=player->NumUnits ) { // FIXME: GameMessage if( player==ThisPlayer ) { // FIXME: PlayVoice :), see task.txt SetMessage("You need more farms!"); } else { // FIXME: Callback for AI! // AiNeedMoreFarms(unit); } unit->Command.Data.Train.Ticks-=SpeedTrain; unit->Reset=1; unit->Wait=FRAMES_PER_SECOND/6; return; } nunit=MakeUnit(&UnitTypes[unit->Command.Data.Train.What[0]->Type] ,player); nunit->X=unit->X; nunit->Y=unit->Y; type=unit->Type; DropOutOnSide(nunit,HeadingW,type->TileWidth,type->TileHeight); // FIXME: GameMessage if( player==ThisPlayer ) { SetMessage("Training complete"); PlayUnitSound(nunit,VoiceReady); } else { AiTrainingComplete(unit,nunit); } unit->Reset=1; unit->Wait=1; if ( --unit->Command.Data.Train.Count ) { int z; for( z = 0; z < MAX_UNIT_TRAIN-1; z++ ) { unit->Command.Data.Train.What[z] = unit->Command.Data.Train.What[z+1]; } unit->Command.Data.Train.Ticks=0; } else { unit->Command.Action=UnitActionStill; } nunit->Command=unit->PendCommand; if( IsSelected(unit) ) { UpdateBottomPanel(); MustRedraw|=RedrawPanels; } return; } if( IsSelected(unit) ) { MustRedraw|=RedrawTopPanel; } unit->Reset=1; unit->Wait=FRAMES_PER_SECOND/6; }
/* virtual */ void COrder_Train::Execute(CUnit &unit) { AnimateActionTrain(unit); if (unit.Wait) { unit.Wait--; return ; } CPlayer &player = *unit.Player; const CUnitType &nType = *this->Type; const int cost = nType.Stats[player.Index].Costs[TimeCost]; this->Ticks += std::max(1, player.SpeedTrain / SPEEDUP_FACTOR); if (this->Ticks < cost) { unit.Wait = CYCLES_PER_SECOND / 6; return ; } this->Ticks = std::min(this->Ticks, cost); // Check if enough supply available. const int food = player.CheckLimits(nType); if (food < 0) { if (food == -3 && unit.Player->AiEnabled) { AiNeedMoreSupply(*unit.Player); } unit.Wait = CYCLES_PER_SECOND / 6; return ; } CUnit *newUnit = MakeUnit(nType, &player); if (newUnit == NULL) { // No more memory :/ player.Notify(NotifyYellow, unit.tilePos, _("Unable to train %s"), nType.Name.c_str()); unit.Wait = CYCLES_PER_SECOND / 6; return ; } // New unit might supply food UpdateForNewUnit(*newUnit, 0); // Set life span if (unit.Type->DecayRate) { newUnit->TTL = GameCycle + unit.Type->DecayRate * 6 * CYCLES_PER_SECOND; } /* Auto Group Add */ if (!unit.Player->AiEnabled && unit.GroupId) { int num = 0; while (!(unit.GroupId & (1 << num))) { ++num; } AddToGroup(&newUnit, 1, num); } DropOutOnSide(*newUnit, LookingW, &unit); player.Notify(NotifyGreen, newUnit->tilePos, _("New %s ready"), nType.Name.c_str()); if (&player == ThisPlayer) { PlayUnitSound(*newUnit, VoiceReady); } if (unit.Player->AiEnabled) { AiTrainingComplete(unit, *newUnit); } if (unit.NewOrder && unit.NewOrder->HasGoal() && unit.NewOrder->GetGoal()->Destroyed) { delete unit.NewOrder; unit.NewOrder = NULL; } if (CanHandleOrder(*newUnit, unit.NewOrder) == true) { delete newUnit->Orders[0]; newUnit->Orders[0] = unit.NewOrder->Clone(); } else { #if 0 // Tell the unit to rigth-click ? #endif } this->Finished = true; if (IsOnlySelected(unit)) { UI.ButtonPanel.Update(); } }