00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032
00033
00034
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039
00040 #include "stratagus.h"
00041 #include "unit.h"
00042 #include "unit_manager.h"
00043 #include "unittype.h"
00044 #include "script.h"
00045 #include "player.h"
00046 #include "iolib.h"
00047
00048
00049
00050
00051
00055 struct CUnitGroup {
00056 CUnit **Units;
00057 int NumUnits;
00058 };
00059
00060 static CUnitGroup Groups[NUM_GROUPS];
00061
00062
00063
00064
00065
00071 void InitGroups(void)
00072 {
00073 for (int i = 0; i < NUM_GROUPS; ++i) {
00074 if (!Groups[i].Units) {
00075 Groups[i].Units = new CUnit *[MaxSelectable];
00076 }
00077 }
00078 }
00079
00085 void SaveGroups(CFile *file)
00086 {
00087 file->printf("\n--- -----------------------------------------\n");
00088 file->printf("--- MODULE: groups\n\n");
00089
00090 for (int g = 0; g < NUM_GROUPS; ++g) {
00091 file->printf("Group(%d, %d, {", g, Groups[g].NumUnits);
00092 for (int i = 0; i < Groups[g].NumUnits; ++i) {
00093 file->printf("\"%s\", ", UnitReference(Groups[g].Units[i]).c_str());
00094 }
00095 file->printf("})\n");
00096 }
00097 }
00098
00102 void CleanGroups(void)
00103 {
00104 for (int i = 0; i < NUM_GROUPS; ++i) {
00105 delete[] Groups[i].Units;
00106 Groups[i].Units = NULL;
00107 Groups[i].NumUnits = 0;
00108 }
00109 }
00110
00118 int GetNumberUnitsOfGroup(int num)
00119 {
00120 return Groups[num].NumUnits;
00121 }
00122
00130 CUnit **GetUnitsOfGroup(int num)
00131 {
00132 return Groups[num].Units;
00133 }
00134
00140 void ClearGroup(int num)
00141 {
00142 CUnitGroup *group;
00143 int i;
00144
00145 group = &Groups[num];
00146 for (i = 0; i < group->NumUnits; ++i) {
00147 group->Units[i]->GroupId &= ~(1 << num);
00148 Assert(!group->Units[i]->Destroyed);
00149 }
00150 group->NumUnits = 0;
00151 }
00152
00160 void AddToGroup(CUnit **units, int nunits, int num)
00161 {
00162 CUnitGroup *group;
00163 int i;
00164
00165 Assert(num <= NUM_GROUPS);
00166
00167 group = &Groups[num];
00168
00169
00170 if (group->NumUnits == 1 && !group->Units[0]->Type->SelectableByRectangle) {
00171 return;
00172 }
00173 for (i = 0; group->NumUnits < MaxSelectable && i < nunits; ++i) {
00174
00175
00176
00177
00178 if (ThisPlayer->IsTeamed(units[i]) &&
00179 (units[i]->Type->SelectableByRectangle ||
00180 (nunits == 1 && group->NumUnits == 0))) {
00181 group->Units[group->NumUnits++] = units[i];
00182 units[i]->GroupId |= (1 << num);
00183 }
00184 }
00185 }
00186
00194 void SetGroup(CUnit **units, int nunits, int num)
00195 {
00196 Assert(num <= NUM_GROUPS && nunits <= MaxSelectable);
00197
00198 ClearGroup(num);
00199 AddToGroup(units, nunits, num);
00200 }
00201
00207 void RemoveUnitFromGroups(CUnit *unit)
00208 {
00209 CUnitGroup *group;
00210 int num;
00211 int i;
00212
00213 Assert(unit->GroupId != 0);
00214
00215 for (num = 0; unit->GroupId; ++num, unit->GroupId >>= 1) {
00216 if ((unit->GroupId & 1) != 1) {
00217 continue;
00218 }
00219
00220 group = &Groups[num];
00221 for (i = 0; group->Units[i] != unit; ++i) {
00222 ;
00223 }
00224
00225 Assert(i < group->NumUnits);
00226
00227
00228
00229 if (i < --group->NumUnits) {
00230 group->Units[i] = group->Units[group->NumUnits];
00231 }
00232 }
00233 }
00234
00235
00236
00242 static int CclGroup(lua_State *l)
00243 {
00244 int i;
00245 CUnitGroup *grp;
00246 int args;
00247 int j;
00248
00249 LuaCheckArgs(l, 3);
00250
00251 InitGroups();
00252 grp = &Groups[(int)LuaToNumber(l, 1)];
00253 grp->NumUnits = LuaToNumber(l, 2);
00254 i = 0;
00255 args = lua_objlen(l, 3);
00256 for (j = 0; j < args; ++j) {
00257 const char *str;
00258
00259 lua_rawgeti(l, 3, j + 1);
00260 str = LuaToString(l, -1);
00261 lua_pop(l, 1);
00262 grp->Units[i++] = UnitSlots[strtol(str + 1, NULL, 16)];
00263 }
00264
00265 return 0;
00266 }
00267
00271 void GroupCclRegister(void)
00272 {
00273 lua_register(Lua, "Group", CclGroup);
00274 }
00275