____ _ __
/ __ )____ _____ | | / /___ ___________
/ __ / __ \/ ___/ | | /| / / __ `/ ___/ ___/
/ /_/ / /_/ (__ ) | |/ |/ / /_/ / / (__ )
/_____/\____/____/ |__/|__/\__,_/_/ /____/
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 2001-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 #include <string.h> 00038 00039 #include "stratagus.h" 00040 #include "unit.h" 00041 #include "unittype.h" 00042 #include "pathfinder.h" 00043 #include "map.h" 00044 #include "interface.h" 00045 #include "actions.h" 00046 00047 /*---------------------------------------------------------------------------- 00048 -- Variables 00049 ----------------------------------------------------------------------------*/ 00050 00051 /*---------------------------------------------------------------------------- 00052 -- Function 00053 ----------------------------------------------------------------------------*/ 00054 00060 void HandleActionFollow(CUnit *unit) 00061 { 00062 CUnit *goal; 00063 00064 if (unit->Wait) { 00065 unit->Wait--; 00066 return; 00067 } 00068 00069 // 00070 // Reached target 00071 // 00072 if (unit->SubAction == 128) { 00073 goal = unit->Orders[0]->Goal; 00074 if (!goal || !goal->IsVisibleAsGoal(unit->Player)) { 00075 DebugPrint("Goal gone\n"); 00076 if (goal) { 00077 goal->RefsDecrease(); 00078 } 00079 unit->Orders[0]->Goal = NoUnitP; 00080 unit->ClearAction(); 00081 return; 00082 } 00083 00084 if (goal->X == unit->Orders[0]->X && goal->Y == unit->Orders[0]->Y) { 00085 // Move to the next order 00086 if (unit->OrderCount > 1) { 00087 goal->RefsDecrease(); 00088 unit->Orders[0]->Goal = NoUnitP; 00089 unit->ClearAction(); 00090 return; 00091 } 00092 00093 // Reset frame to still frame while we wait 00094 // FIXME: Unit doesn't animate. 00095 unit->Frame = unit->Type->StillFrame; 00096 UnitUpdateHeading(unit); 00097 unit->Wait = 10; 00098 if (unit->Orders[0]->Range > 1) { 00099 unit->Orders[0]->Range = 1; 00100 unit->SubAction = 0; 00101 } 00102 return; 00103 } 00104 00105 unit->SubAction = 0; 00106 } 00107 00108 if (!unit->SubAction) { // first entry 00109 unit->SubAction = 1; 00110 NewResetPath(unit); 00111 Assert(unit->State == 0); 00112 } 00113 00114 switch (DoActionMove(unit)) { // reached end-point? 00115 case PF_UNREACHABLE: 00116 // 00117 // Some tries to reach the goal 00118 // 00119 if (unit->Orders[0]->Range <= Map.Info.MapWidth || 00120 unit->Orders[0]->Range <= Map.Info.MapHeight) { 00121 unit->Orders[0]->Range++; 00122 break; 00123 } 00124 // FALL THROUGH 00125 case PF_REACHED: 00126 if (!(goal = unit->Orders[0]->Goal)) { // goal has died 00127 unit->ClearAction(); 00128 return; 00129 } 00130 unit->Orders[0]->X = goal->X; 00131 unit->Orders[0]->Y = goal->Y; 00132 unit->SubAction = 128; 00133 00134 // FALL THROUGH 00135 default: 00136 break; 00137 } 00138 00139 // 00140 // Target destroyed? 00141 // 00142 if ((goal = unit->Orders[0]->Goal) && !goal->IsVisibleAsGoal(unit->Player)) { 00143 DebugPrint("Goal gone\n"); 00144 unit->Orders[0]->X = goal->X + goal->Type->TileWidth / 2; 00145 unit->Orders[0]->Y = goal->Y + goal->Type->TileHeight / 2; 00146 unit->Orders[0]->Goal = NoUnitP; 00147 goal->RefsDecrease(); 00148 goal = NoUnitP; 00149 NewResetPath(unit); 00150 } 00151 00152 if (!unit->Anim.Unbreakable) { 00153 // 00154 // If our leader is dead or stops or attacks: 00155 // Attack any enemy in reaction range. 00156 // If don't set the goal, the unit can than choose a 00157 // better goal if moving nearer to enemy. 00158 // 00159 if (unit->Type->CanAttack && 00160 (!goal || goal->Orders[0]->Action == UnitActionAttack || 00161 goal->Orders[0]->Action == UnitActionStill)) { 00162 goal = AttackUnitsInReactRange(unit); 00163 if (goal) { 00164 CommandAttack(unit, goal->X, goal->Y, NULL, FlushCommands); 00165 // Save current command to come back. 00166 unit->SavedOrder = *unit->Orders[0]; 00167 // This stops the follow command and the attack is executed 00168 unit->ClearAction(); 00169 unit->Orders[0]->Goal = NoUnitP; 00170 } 00171 } 00172 } 00173 } 00174
1.5.6