____ _ __
/ __ )____ _____ | | / /___ ___________
/ __ / __ \/ ___/ | | /| / / __ `/ ___/ ___/
/ /_/ / /_/ (__ ) | |/ |/ / /_/ / / (__ )
/_____/\____/____/ |__/|__/\__,_/_/ /____/
A futuristic real-time strategy game.
This file is part of Bos Wars.
(C) Copyright 2001-2007 by the Bos Wars and Stratagus Project.
Distributed under the "GNU General Public License"00001 // ____ _ __ 00002 // / __ )____ _____ | | / /___ ___________ 00003 // / __ / __ \/ ___/ | | /| / / __ `/ ___/ ___/ 00004 // / /_/ / /_/ (__ ) | |/ |/ / /_/ / / (__ ) 00005 // /_____/\____/____/ |__/|__/\__,_/_/ /____/ 00006 // 00007 // A futuristic real-time strategy game. 00008 // This file is part of Bos Wars. 00009 // 00011 // 00012 // (c) Copyright 1998-2007 by Lutz Sammer and Jimmy Salmon 00013 // 00014 // This program is free software; you can redistribute it and/or modify 00015 // it under the terms of the GNU General Public License as published by 00016 // the Free Software Foundation; only version 2 of the License. 00017 // 00018 // This program is distributed in the hope that it will be useful, 00019 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 // GNU General Public License for more details. 00022 // 00023 // You should have received a copy of the GNU General Public License 00024 // along with this program; if not, write to the Free Software 00025 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00026 // 02111-1307, USA. 00027 // 00028 00030 00031 /*---------------------------------------------------------------------------- 00032 -- Includes 00033 ----------------------------------------------------------------------------*/ 00034 00035 #include <stdio.h> 00036 #include <stdlib.h> 00037 00038 #include "stratagus.h" 00039 #include "unittype.h" 00040 #include "animation.h" 00041 #include "player.h" 00042 #include "unit.h" 00043 #include "actions.h" 00044 #include "interface.h" 00045 #include "pathfinder.h" 00046 #include "map.h" 00047 00048 /*---------------------------------------------------------------------------- 00049 -- Functions 00050 ----------------------------------------------------------------------------*/ 00051 00060 static int MoveToTransporter(CUnit *unit) 00061 { 00062 int i; 00063 int x; 00064 int y; 00065 00066 x = unit->X; 00067 y = unit->Y; 00068 i = DoActionMove(unit); 00069 // We have to reset a lot, or else they will circle each other and stuff. 00070 if (x != unit->X || y != unit->Y) { 00071 unit->Orders[0]->Range = 1; 00072 NewResetPath(unit); 00073 } 00074 // New code has this as default. 00075 Assert(unit->Orders[0]->Action == UnitActionBoard); 00076 return i; 00077 } 00078 00086 static int WaitForTransporter(CUnit *unit) 00087 { 00088 CUnit *trans; 00089 00090 if (unit->Wait) { 00091 unit->Wait--; 00092 return 0; 00093 } 00094 00095 trans = unit->Orders[0]->Goal; 00096 00097 if (!trans || !CanTransport(trans, unit)) { 00098 // FIXME: destination destroyed?? 00099 unit->Wait = 6; 00100 return 0; 00101 } 00102 00103 if (!trans->IsVisibleAsGoal(unit->Player)) { 00104 DebugPrint("Transporter Gone\n"); 00105 trans->RefsDecrease(); 00106 unit->Orders[0]->Goal = NoUnitP; 00107 unit->Wait = 6; 00108 return 0; 00109 } 00110 00111 if (MapDistanceBetweenUnits(unit, trans) == 1) { 00112 // enter transporter 00113 return 1; 00114 } 00115 00116 // 00117 // FIXME: any enemies in range attack them, while waiting. 00118 // 00119 00120 // n0b0dy: This means we have to search with a smaller range. 00121 // It happens only when you reach the shore,and the transporter 00122 // is not there. The unit searches with a big range, so it thinks 00123 // it's there. This is why we reset the search. The transporter 00124 // should be a lot closer now, so it's not as bad as it seems. 00125 unit->SubAction = 0; 00126 unit->Orders[0]->Range = 1; 00127 // Uhh wait a bit. 00128 unit->Wait = 10; 00129 00130 return 0; 00131 } 00132 00138 static void EnterTransporter(CUnit *unit) 00139 { 00140 CUnit *transporter; 00141 00142 unit->ClearAction(); 00143 00144 transporter = unit->Orders[0]->Goal; 00145 if (!transporter->IsVisibleAsGoal(unit->Player)) { 00146 DebugPrint("Transporter gone\n"); 00147 transporter->RefsDecrease(); 00148 unit->Orders[0]->Goal = NoUnitP; 00149 return; 00150 } 00151 00152 transporter->RefsDecrease(); 00153 unit->Orders[0]->Goal = NoUnitP; 00154 00155 // 00156 // Place the unit inside the transporter. 00157 // 00158 00159 if (transporter->BoardCount < transporter->Type->MaxOnBoard) { 00160 unit->Remove(transporter); 00161 transporter->BoardCount++; 00162 unit->Boarded = 1; 00163 if (!unit->Player->AiEnabled) { 00164 // Don't make anything funny after going out of the transporter. 00165 // FIXME: This is probably wrong, but it works for me (n0b0dy) 00166 unit->OrderCount = 1; 00167 unit->ClearAction(); 00168 } 00169 00170 if (IsOnlySelected(transporter)) { 00171 SelectedUnitChanged(); 00172 } 00173 return; 00174 } 00175 DebugPrint("No free slot in transporter\n"); 00176 } 00177 00185 void HandleActionBoard(CUnit *unit) 00186 { 00187 int i; 00188 CUnit *goal; 00189 00190 switch (unit->SubAction) { 00191 // 00192 // Wait for transporter 00193 // 00194 case 201: 00195 if (WaitForTransporter(unit)) { 00196 unit->SubAction = 202; 00197 } else { 00198 UnitShowAnimation(unit, unit->Type->Animations->Still); 00199 } 00200 break; 00201 // 00202 // Enter transporter 00203 // 00204 case 202: 00205 EnterTransporter(unit); 00206 break; 00207 // 00208 // Move to transporter 00209 // 00210 case 0: 00211 if (unit->Wait) { 00212 unit->Wait--; 00213 return; 00214 } 00215 NewResetPath(unit); 00216 unit->SubAction = 1; 00217 // FALL THROUGH 00218 default: 00219 if (unit->SubAction <= 200) { 00220 // FIXME: if near transporter wait for enter 00221 if ((i = MoveToTransporter(unit))) { 00222 if (i == PF_UNREACHABLE) { 00223 if (++unit->SubAction == 200) { 00224 unit->ClearAction(); 00225 if ((goal = unit->Orders[0]->Goal)) { 00226 goal->RefsDecrease(); 00227 unit->Orders[0]->Goal = NoUnitP; 00228 } 00229 } else { 00230 // 00231 // Try with a bigger range. 00232 // 00233 if (unit->Orders[0]->Range <= Map.Info.MapWidth || 00234 unit->Orders[0]->Range <= Map.Info.MapHeight) { 00235 unit->Orders[0]->Range++; 00236 unit->SubAction--; 00237 } 00238 } 00239 } else if (i == PF_REACHED) { 00240 unit->SubAction = 201; 00241 } 00242 } 00243 } 00244 break; 00245 } 00246 } 00247
1.5.6