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
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <stdarg.h>
00039 #include <algorithm>
00040
00041 #include "stratagus.h"
00042 #include "video.h"
00043 #include "sound.h"
00044 #include "unitsound.h"
00045 #include "unittype.h"
00046 #include "player.h"
00047 #include "unit.h"
00048 #include "map.h"
00049 #include "ai.h"
00050 #include "network.h"
00051 #include "netconnect.h"
00052 #include "interface.h"
00053 #include "iolib.h"
00054 #include "ui.h"
00055
00056
00057
00058
00059
00060 int NumPlayers;
00061 CPlayer Players[PlayerMax];
00062 CPlayer *ThisPlayer;
00063
00064 int NoRescueCheck;
00065
00069 SDL_Color *PlayerColorsRGB[PlayerMax];
00070 Uint32 *PlayerColors[PlayerMax];
00071
00072 std::string PlayerColorNames[PlayerMax];
00073
00077 int PlayerColorIndexStart;
00078 int PlayerColorIndexCount;
00079
00080
00081
00082
00083
00087 void InitPlayers(void)
00088 {
00089 for (int p = 0; p < PlayerMax; ++p) {
00090 Players[p].Index = p;
00091 if (!Players[p].Type) {
00092 Players[p].Type = PlayerNobody;
00093 }
00094 for (int x = 0; x < PlayerColorIndexCount; ++x) {
00095 PlayerColors[p][x] = Video.MapRGB(TheScreen->format,
00096 PlayerColorsRGB[p][x].r,
00097 PlayerColorsRGB[p][x].g, PlayerColorsRGB[p][x].b);
00098 }
00099 }
00100 }
00101
00105 void CleanPlayers(void)
00106 {
00107 ThisPlayer = NULL;
00108 for (int i = 0; i < PlayerMax; ++i) {
00109 Players[i].Clear();
00110 }
00111 NumPlayers = 0;
00112
00113 NoRescueCheck = 0;
00114 }
00115
00116 #ifdef DEBUG
00117 void FreePlayerColors()
00118 {
00119 for (int i = 0; i < PlayerMax; ++i) {
00120 delete[] Players[i].UnitColors.Colors;
00121 delete[] PlayerColorsRGB[i];
00122 PlayerColorsRGB[i] = NULL;
00123 delete[] PlayerColors[i];
00124 PlayerColors[i] = NULL;
00125 }
00126 }
00127 #endif
00128
00132 void CPlayer::AddToUnitsConsumingResources(CUnit *unit, int costs[MaxCosts])
00133 {
00134 Assert(UnitsConsumingResourcesActual[unit] == NULL);
00135 Assert(UnitsConsumingResourcesRequested[unit] == NULL);
00136
00137 int *c;
00138
00139 c = new int[MaxCosts];
00140 memset(c, 0, MaxCosts * sizeof(int));
00141 UnitsConsumingResourcesActual[unit] = c;
00142
00143
00144 c = new int[MaxCosts];
00145 memcpy(c, costs, MaxCosts * sizeof(int));
00146 UnitsConsumingResourcesRequested[unit] = c;
00147 for (int i = 0; i < MaxCosts; ++i) {
00148 RequestedUtilizationRate[i] += costs[i];
00149 }
00150 }
00151
00155 void CPlayer::RemoveFromUnitsConsumingResources(CUnit *unit)
00156 {
00157 int *cactual = UnitsConsumingResourcesActual[unit];
00158 int *crequested = UnitsConsumingResourcesRequested[unit];
00159
00160 for (int i = 0; i < MaxCosts; ++i) {
00161 ActualUtilizationRate[i] -= cactual[i];
00162 RequestedUtilizationRate[i] -= crequested[i];
00163 }
00164
00165 delete[] cactual;
00166 UnitsConsumingResourcesActual.erase(unit);
00167 delete[] crequested;
00168 UnitsConsumingResourcesRequested.erase(unit);
00169 }
00170
00174 void CPlayer::UpdateUnitsConsumingResources(CUnit *unit, int costs[MaxCosts])
00175 {
00176 int *c = UnitsConsumingResourcesActual[unit];
00177
00178 for (int i = 0; i < MaxCosts; ++i) {
00179 ActualUtilizationRate[i] -= c[i];
00180 c[i] = costs[i];
00181 ActualUtilizationRate[i] += c[i];
00182 }
00183 }
00184
00192 void CalculateRequestedAmount(CUnitType *utype, int bcosts[MaxCosts], int costs[MaxCosts])
00193 {
00194 if (bcosts[EnergyCost] == 0) {
00195 costs[EnergyCost] = 0;
00196 costs[MagmaCost] = utype->MaxUtilizationRate[MagmaCost];
00197 } else if (bcosts[MagmaCost] == 0) {
00198 costs[EnergyCost] = utype->MaxUtilizationRate[EnergyCost];
00199 costs[MagmaCost] = 0;
00200 } else {
00201 int f = 100 * bcosts[EnergyCost] * utype->MaxUtilizationRate[MagmaCost] /
00202 (bcosts[MagmaCost] * utype->MaxUtilizationRate[EnergyCost]);
00203 if (f > 100) {
00204 costs[EnergyCost] = utype->MaxUtilizationRate[EnergyCost];
00205 costs[MagmaCost] = (utype->MaxUtilizationRate[MagmaCost] * 100 + f / 2) / f;
00206 } else if (f < 100) {
00207 costs[EnergyCost] = (utype->MaxUtilizationRate[EnergyCost] * f + 50) / 100;
00208 costs[MagmaCost] = utype->MaxUtilizationRate[MagmaCost];
00209 } else {
00210 costs[EnergyCost] = utype->MaxUtilizationRate[EnergyCost];
00211 costs[MagmaCost] = utype->MaxUtilizationRate[MagmaCost];
00212 }
00213 }
00214
00215 for (int i = 0; i < MaxCosts; ++i) {
00216 if (costs[i] > bcosts[i]) {
00217 costs[i] = bcosts[i];
00218 }
00219 }
00220 }
00221
00226 void CPlayer::RebuildUnitsConsumingResourcesList()
00227 {
00228 for (int i = 0; i < TotalNumUnits; ++i) {
00229 int costs[MaxCosts];
00230 CUnit *unit = Units[i];
00231
00232 if (unit->Orders[0]->Action == UnitActionTrain && unit->SubAction != 0) {
00233 CalculateRequestedAmount(unit->Type, unit->Orders[0]->Type->ProductionCosts, costs);
00234 AddToUnitsConsumingResources(unit, costs);
00235 } else if (unit->Orders[0]->Action == UnitActionBuilt && !unit->Type->BuilderOutside) {
00236 CalculateRequestedAmount(unit->Type, unit->Type->ProductionCosts, costs);
00237 unit->Player->AddToUnitsConsumingResources(unit, costs);
00238 } else if (unit->Orders[0]->Action == UnitActionRepair && unit->SubAction == 20) {
00239 CalculateRequestedAmount(unit->Type, unit->Orders[0]->Goal->Type->ProductionCosts, costs);
00240 AddToUnitsConsumingResources(unit, costs);
00241 }
00242 }
00243 }
00244
00248 void CPlayer::ClearResourceVariables()
00249 {
00250 std::map<CUnit *, int *>::iterator i;
00251 for (i = UnitsConsumingResourcesActual.begin();
00252 i != UnitsConsumingResourcesActual.end(); ++i) {
00253 delete[] (*i).second;
00254 }
00255 for (i = UnitsConsumingResourcesRequested.begin();
00256 i != UnitsConsumingResourcesRequested.end(); ++i) {
00257 delete[] (*i).second;
00258 }
00259
00260 UnitsConsumingResourcesActual.clear();
00261 UnitsConsumingResourcesRequested.clear();
00262 memset(ProductionRate, 0, sizeof(ProductionRate));
00263 memset(ActualUtilizationRate, 0, sizeof(ActualUtilizationRate));
00264 memset(RequestedUtilizationRate, 0, sizeof(RequestedUtilizationRate));
00265 memset(StoredResources, 0, sizeof(StoredResources));
00266 memset(StorageCapacity, 0, sizeof(StorageCapacity));
00267
00268 }
00269
00270
00271 static int AvailableResourcesRate(int type, CPlayer *p)
00272 {
00273
00274 int RateFromStorage = 50;
00275 return p->ProductionRate[type] + std::min<int>(p->StoredResources[type], RateFromStorage);
00276 }
00277
00278
00279 static int SpecificEfficiency(int type, CPlayer *p)
00280 {
00281 if (p->RequestedUtilizationRate[type] == 0) {
00282 return 100;
00283 }
00284 return std::min((100 * AvailableResourcesRate(type, p) +
00285 p->RequestedUtilizationRate[type] / 2) / p->RequestedUtilizationRate[type], 100);
00286 }
00287
00288
00289 static int BaseEfficiency(CPlayer *p)
00290 {
00291 return std::min(SpecificEfficiency(EnergyCost, p), SpecificEfficiency(MagmaCost, p));
00292 }
00293
00294
00295 static int ExtraProduction(int type, CPlayer *p, int be)
00296 {
00297 return 100 * AvailableResourcesRate(type, p) - p->RequestedUtilizationRate[type] * be;
00298 }
00299
00300
00301 static int UniqueNeeds(int type, CPlayer *p)
00302 {
00303
00304 std::map<CUnit *, int *>::iterator i = p->UnitsConsumingResourcesRequested.begin();
00305 std::map<CUnit *, int *>::iterator end = p->UnitsConsumingResourcesRequested.end();
00306 int type2 = (type == EnergyCost ? MagmaCost : EnergyCost);
00307 int needs = 0;
00308
00309 for (; i != end; ++i) {
00310 if ((*i).second[type] != 0 && (*i).second[type2] == 0) {
00311 needs += (*i).second[type];
00312 }
00313 }
00314 return needs;
00315 }
00316
00317
00318 static int UniqueEfficiency(int type, CPlayer *p)
00319 {
00320 int be = BaseEfficiency(p);
00321 return std::min(ExtraProduction(type, p, be) / UniqueNeeds(type, p) + be, 100);
00322 }
00323
00324 static int MaxRate(CUnit *unit, int res)
00325 {
00326 int *costs = unit->Player->UnitsConsumingResourcesRequested[unit];
00327 return costs[res];
00328 }
00329
00330 static void CalculateCosts(CUnit *unit, int costs[MaxCosts])
00331 {
00332 int i;
00333 int usedtypes = 0;
00334 int type = -1;
00335 int *c = unit->Player->UnitsConsumingResourcesRequested[unit];
00336
00337 for (i = 0; i < MaxCosts; ++i) {
00338 if (c[i] != 0) {
00339 ++usedtypes;
00340 type = i;
00341 }
00342 }
00343 Assert(usedtypes > 0);
00344
00345
00346 if (usedtypes > 1) {
00347
00348 int be = BaseEfficiency(unit->Player);
00349 for (i = 0; i < MaxCosts; ++i) {
00350 costs[i] = MaxRate(unit, i) * be / 100;
00351 }
00352 } else {
00353
00354 int ue = UniqueEfficiency(type, unit->Player);
00355 for (i = 0; i < MaxCosts; ++i) {
00356 costs[i] = MaxRate(unit, i) * ue / 100;
00357 }
00358 }
00359 }
00360
00368 void SavePlayers(CFile *file)
00369 {
00370 int j;
00371 Uint8 r, g, b;
00372 CPlayer *p;
00373
00374 file->printf("\n--------------------------------------------\n");
00375 file->printf("--- MODULE: players\n\n");
00376
00377
00378
00379
00380 for (int i = 0; i < NumPlayers; ++i) {
00381 p = &Players[i];
00382 file->printf("Player(%d,\n", i);
00383 file->printf(" \"name\", \"%s\",\n", p->Name.c_str());
00384 file->printf(" \"type\", ");
00385 switch (p->Type) {
00386 case PlayerNeutral: file->printf("\"neutral\","); break;
00387 case PlayerNobody: file->printf("\"nobody\","); break;
00388 case PlayerComputer: file->printf("\"computer\","); break;
00389 case PlayerPerson: file->printf("\"person\","); break;
00390 case PlayerRescuePassive: file->printf("\"rescue-passive\",");break;
00391 case PlayerRescueActive: file->printf("\"rescue-active\","); break;
00392 default: file->printf("%d,",p->Type);break;
00393 }
00394 file->printf(" \"ai-name\", \"%s\",\n", p->AiName.c_str());
00395 file->printf(" \"team\", %d,", p->Team);
00396
00397 file->printf(" \"enemy\", \"");
00398 for (j = 0; j < PlayerMax; ++j) {
00399 file->printf("%c",(p->Enemy & (1 << j)) ? 'X' : '_');
00400 }
00401 file->printf("\", \"allied\", \"");
00402 for (j = 0; j < PlayerMax; ++j) {
00403 file->printf("%c", (p->Allied & (1 << j)) ? 'X' : '_');
00404 }
00405 file->printf("\", \"shared-vision\", \"");
00406 for (j = 0; j < PlayerMax; ++j) {
00407 file->printf("%c", (p->SharedVision & (1 << j)) ? 'X' : '_');
00408 }
00409 file->printf("\",\n \"start\", {%d, %d},\n", p->StartX,
00410 p->StartY);
00411
00412
00413 file->printf(" \"production-rate\", {");
00414 for (j = 0; j < MaxCosts; ++j) {
00415 if (j) {
00416 file->printf(" ");
00417 }
00418 file->printf("\"%s\", %d,", DefaultResourceNames[j].c_str(),
00419 p->ProductionRate[j]);
00420 }
00421
00422 file->printf("},\n \"stored-resources\", {");
00423 for (j = 0; j < MaxCosts; ++j) {
00424 if (j) {
00425 file->printf(" ");
00426 }
00427 file->printf("\"%s\", %d,", DefaultResourceNames[j].c_str(),
00428 p->StoredResources[j]);
00429 }
00430
00431 file->printf("},\n \"storage-capacity\", {");
00432 for (j = 0; j < MaxCosts; ++j) {
00433 if (j) {
00434 file->printf(" ");
00435 }
00436 file->printf("\"%s\", %d,", DefaultResourceNames[j].c_str(),
00437 p->StorageCapacity[j]);
00438 }
00439
00440
00441
00442 file->printf("},\n \"%s\",\n", p->AiEnabled ?
00443 "ai-enabled" : "ai-disabled");
00444
00445
00446
00447
00448
00449
00450 file->printf(" \"unit-limit\", %d,", p->UnitLimit);
00451 file->printf(" \"building-limit\", %d,", p->BuildingLimit);
00452 file->printf(" \"total-unit-limit\", %d,", p->TotalUnitLimit);
00453
00454 file->printf("\n \"score\", %d,", p->Score);
00455 file->printf("\n \"total-units\", %d,", p->TotalUnits);
00456 file->printf("\n \"total-buildings\", %d,", p->TotalBuildings);
00457 file->printf("\n \"total-resources\", {");
00458 for (j = 0; j < MaxCosts; ++j) {
00459 if (j) {
00460 file->printf(" ");
00461 }
00462 file->printf("%d,", p->TotalResources[j]);
00463 }
00464 file->printf("},");
00465 file->printf("\n \"total-razings\", %d,", p->TotalRazings);
00466 file->printf("\n \"total-kills\", %d,", p->TotalKills);
00467
00468 SDL_GetRGB(p->Color, TheScreen->format, &r, &g, &b);
00469 file->printf("\n \"color\", { %d, %d, %d }", r, g, b);
00470
00471
00472
00473
00474 file->printf(")\n\n");
00475 }
00476
00477 DebugPrint("FIXME: must save unit-stats?\n");
00478
00479
00480
00481
00482 file->printf("ThisPlayer = Players[%d]\n\n", ThisPlayer->Index);
00483 }
00484
00490 void CreatePlayer(int type)
00491 {
00492 int team;
00493 int i;
00494 CPlayer *player;
00495
00496 if (NumPlayers == PlayerMax) {
00497 return;
00498 }
00499 player = &Players[NumPlayers];
00500 player->Index = NumPlayers;
00501
00502
00503
00504
00505
00506 memset(player->Units, 0, sizeof(player->Units));
00507
00508
00509
00510
00511
00512 if (type == PlayerPerson && !NetPlayers) {
00513 if (!ThisPlayer) {
00514 ThisPlayer = player;
00515 } else {
00516 type = PlayerComputer;
00517 }
00518 }
00519 if (NetPlayers && NumPlayers == NetLocalPlayerNumber) {
00520 ThisPlayer = &Players[NetLocalPlayerNumber];
00521 }
00522
00523 if (NumPlayers == PlayerMax) {
00524 static int already_warned;
00525
00526 if (!already_warned) {
00527 DebugPrint("Too many players\n");
00528 already_warned = 1;
00529 }
00530 return;
00531 }
00532
00533
00534
00535
00536
00537 switch (type) {
00538 case PlayerNeutral:
00539 case PlayerNobody:
00540 default:
00541 team = 0;
00542 player->SetName("Neutral");
00543 break;
00544 case PlayerComputer:
00545 team = 1;
00546 player->SetName("Computer");
00547 break;
00548 case PlayerPerson:
00549 team = 2 + NumPlayers;
00550 player->SetName("Person");
00551 break;
00552 case PlayerRescuePassive:
00553 case PlayerRescueActive:
00554
00555 player->SetName("Computer");
00556 team = 2 + NumPlayers;
00557 break;
00558 }
00559 DebugPrint("CreatePlayer name %s\n" _C_ player->Name.c_str());
00560
00561 player->Type = type;
00562 player->Team = team;
00563 player->Enemy = 0;
00564 player->Allied = 0;
00565 player->AiName = "ai-passive";
00566
00567
00568
00569
00570 for (i = 0; i < NumPlayers; ++i) {
00571 switch (type) {
00572 case PlayerNeutral:
00573 case PlayerNobody:
00574 default:
00575 break;
00576 case PlayerComputer:
00577
00578 if (Players[i].Type == PlayerComputer) {
00579 player->Allied |= (1 << i);
00580 Players[i].Allied |= (1 << NumPlayers);
00581 } else if (Players[i].Type == PlayerPerson ||
00582 Players[i].Type == PlayerRescueActive) {
00583 player->Enemy |= (1 << i);
00584 Players[i].Enemy |= (1 << NumPlayers);
00585 }
00586 break;
00587 case PlayerPerson:
00588
00589 if (Players[i].Type == PlayerComputer ||
00590 Players[i].Type == PlayerPerson) {
00591 player->Enemy |= (1 << i);
00592 Players[i].Enemy |= (1 << NumPlayers);
00593 } else if (Players[i].Type == PlayerRescueActive ||
00594 Players[i].Type == PlayerRescuePassive) {
00595 player->Allied |= (1 << i);
00596 Players[i].Allied |= (1 << NumPlayers);
00597 }
00598 break;
00599 case PlayerRescuePassive:
00600
00601 if (Players[i].Type == PlayerPerson) {
00602 player->Allied |= (1 << i);
00603 Players[i].Allied |= (1 << NumPlayers);
00604 }
00605 break;
00606 case PlayerRescueActive:
00607
00608 if (Players[i].Type == PlayerComputer) {
00609 player->Enemy |= (1 << i);
00610 Players[i].Enemy |= (1 << NumPlayers);
00611 } else if (Players[i].Type == PlayerPerson) {
00612 player->Allied |= (1 << i);
00613 Players[i].Allied |= (1 << NumPlayers);
00614 }
00615 break;
00616 }
00617 }
00618
00619 memset(player->UnitTypesCount, 0, sizeof(player->UnitTypesCount));
00620
00621 player->NumBuildings = 0;
00622 player->TotalNumUnits = 0;
00623 player->Score = 0;
00624
00625 player->Color = PlayerColors[NumPlayers][0];
00626
00627 if (Players[NumPlayers].Type == PlayerComputer ||
00628 Players[NumPlayers].Type == PlayerRescueActive) {
00629 player->AiEnabled = 1;
00630 } else {
00631 player->AiEnabled = 0;
00632 }
00633
00634 ++NumPlayers;
00635 }
00636
00642 void CPlayer::SetName(const std::string &name)
00643 {
00644 Name = name;
00645 }
00646
00653 void CPlayer::Clear()
00654 {
00655 Index = 0;
00656 Name.clear();
00657 Type = 0;
00658 AiName.clear();
00659 Team = 0;
00660 Enemy = 0;
00661 Allied = 0;
00662 SharedVision = 0;
00663 StartX = 0;
00664 StartY = 0;
00665 memset(UnitTypesCount, 0, sizeof(UnitTypesCount));
00666 AiEnabled = 0;
00667 Ai = 0;
00668 memset(Units, 0, sizeof(Units));
00669 TotalNumUnits = 0;
00670 NumBuildings = 0;
00671
00672
00673
00674
00675 Score = 0;
00676 TotalUnits = 0;
00677 TotalBuildings = 0;
00678 memset(TotalResources, 0, sizeof(TotalResources));
00679 TotalRazings = 0;
00680 TotalKills = 0;
00681 Color = 0;
00682 ClearResourceVariables();
00683 }
00684
00685
00686
00687
00688
00698 int CPlayer::CheckLimits(const CUnitType *type) const
00699 {
00700
00701
00702
00703 if (NumUnits < UnitMax) {
00704 if (type->Building && NumBuildings >= BuildingLimit) {
00705 Notify(NotifyYellow, -1, -1, _("Building Limit Reached"));
00706 return -1;
00707 }
00708 if (!type->Building && (TotalNumUnits - NumBuildings) >= UnitLimit) {
00709 Notify(NotifyYellow, -1, -1, _("Unit Limit Reached"));
00710 return -2;
00711 }
00712 if (TotalNumUnits >= TotalUnitLimit) {
00713 Notify(NotifyYellow, -1, -1, _("Total Unit Limit Reached"));
00714 return -4;
00715 }
00716 if (UnitTypesCount[type->Slot] >= Allow.Units[type->Slot]) {
00717 Notify(NotifyYellow, -1, -1, _("Limit of %d reached for this unit type"),
00718 Allow.Units[type->Slot]);
00719 return -6;
00720 }
00721 return 1;
00722 } else {
00723 Notify(NotifyYellow, -1, -1, _("Cannot create more units."));
00724 if (AiEnabled) {
00725
00726 }
00727 return -5;
00728 }
00729 }
00730
00738 int CPlayer::HaveUnitTypeByType(const CUnitType *type) const
00739 {
00740 return UnitTypesCount[type->Slot];
00741 }
00742
00752 int CPlayer::HaveUnitTypeByIdent(const std::string &ident) const
00753 {
00754 return UnitTypesCount[UnitTypeByIdent(ident)->Slot];
00755 }
00756
00760 void PlayersInitAi(void)
00761 {
00762 for (int player = 0; player < NumPlayers; ++player) {
00763 if (Players[player].AiEnabled) {
00764 AiInit(&Players[player]);
00765 }
00766 }
00767 }
00768
00772 void PlayersEachCycle(void)
00773 {
00774 for (int player = 0; player < NumPlayers; ++player) {
00775 CPlayer *p = &Players[player];
00776
00777
00778 for (int res = 0; res < MaxCosts; ++res) {
00779 int rate = p->ProductionRate[res] - p->ActualUtilizationRate[res];
00780 if (rate > 0) {
00781 if (p->StoredResources[res] < p->StorageCapacity[res]) {
00782 p->StoredResources[res] += rate;
00783 if (p->StoredResources[res] > p->StorageCapacity[res]) {
00784 p->StoredResources[res] = p->StorageCapacity[res];
00785 }
00786 }
00787 } else if (rate < 0) {
00788 rate = -rate;
00789
00790 p->StoredResources[res] -= rate;
00791 if (p->StoredResources[res] < 0) {
00792 p->StoredResources[res] = 0;
00793 }
00794 }
00795 p->TotalResources[res] += p->ProductionRate[res];
00796 }
00797
00798
00799 std::map<CUnit *, int *>::iterator it;
00800 for (it = p->UnitsConsumingResourcesActual.begin(); it != p->UnitsConsumingResourcesActual.end(); ++it) {
00801 int costs[MaxCosts];
00802 CalculateCosts((*it).first, costs);
00803 p->UpdateUnitsConsumingResources((*it).first, costs);
00804 }
00805
00806
00807 if (p->AiEnabled) {
00808 AiEachCycle(p);
00809 }
00810 }
00811 }
00812
00818 void PlayersEachSecond(int player)
00819 {
00820 if (Players[player].AiEnabled) {
00821 AiEachSecond(&Players[player]);
00822 }
00823 }
00824
00833 void GraphicPlayerPixels(CPlayer *player, const CGraphic *sprite)
00834 {
00835 Assert(PlayerColorIndexCount);
00836
00837 SDL_LockSurface(sprite->Surface);
00838 SDL_SetColors(sprite->Surface, player->UnitColors.Colors,
00839 PlayerColorIndexStart, PlayerColorIndexCount);
00840 if (sprite->SurfaceFlip) {
00841 SDL_SetColors(sprite->SurfaceFlip,
00842 player->UnitColors.Colors, PlayerColorIndexStart, PlayerColorIndexCount);
00843 }
00844 SDL_UnlockSurface(sprite->Surface);
00845 }
00846
00852 void SetPlayersPalette(void)
00853 {
00854 for (int i = 0; i < PlayerMax; ++i) {
00855 delete[] Players[i].UnitColors.Colors;
00856 Players[i].UnitColors.Colors = new SDL_Color[PlayerColorIndexCount];
00857 memcpy(Players[i].UnitColors.Colors, PlayerColorsRGB[i],
00858 sizeof(SDL_Color) * PlayerColorIndexCount);
00859 }
00860 }
00861
00865 void DebugPlayers(void)
00866 {
00867 #ifdef DEBUG
00868 int i;
00869 const char *playertype;
00870
00871 DebugPrint("Nr Color I Name Type Ai\n");
00872 DebugPrint("-- -------- - -------- ------------ -----\n");
00873 for (i = 0; i < PlayerMax; ++i) {
00874 if (Players[i].Type == PlayerNobody) {
00875 continue;
00876 }
00877 switch (Players[i].Type) {
00878 case 0: playertype = "Don't know 0"; break;
00879 case 1: playertype = "Don't know 1"; break;
00880 case 2: playertype = "neutral "; break;
00881 case 3: playertype = "nobody "; break;
00882 case 4: playertype = "computer "; break;
00883 case 5: playertype = "person "; break;
00884 case 6: playertype = "rescue pas. "; break;
00885 case 7: playertype = "rescue akt. "; break;
00886 default : playertype = "?unknown? "; break;
00887 }
00888 DebugPrint("%2d: %8.8s %c %-8.8s %s %s\n" _C_ i _C_ PlayerColorNames[i].c_str() _C_
00889 ThisPlayer == &Players[i] ? '*' :
00890 Players[i].AiEnabled ? '+' : ' ' _C_
00891 Players[i].Name.c_str() _C_ playertype _C_
00892 Players[i].AiName.c_str());
00893 }
00894 #endif
00895 }
00896
00909 void CPlayer::Notify(int type, int x, int y, const char *fmt, ...) const
00910 {
00911 char temp[128];
00912 va_list va;
00913
00914
00915 if (this != ThisPlayer && !IsTeamed(ThisPlayer)) {
00916 return;
00917 }
00918
00919 va_start(va, fmt);
00920 temp[sizeof(temp) - 1] = '\0';
00921 vsnprintf(temp, sizeof(temp) - 1, fmt, va);
00922 va_end(va);
00923
00924 if (x != -1) {
00925 UI.Minimap.AddEvent(x, y);
00926 }
00927 if (this == ThisPlayer) {
00928 SetMessageEvent(x, y, "%s", temp);
00929 } else {
00930 SetMessageEvent(x, y, "(%s): %s", Name.c_str(), temp);
00931 }
00932
00933 }
00934
00938 bool CPlayer::IsEnemy(const CPlayer *x) const
00939 {
00940 return (Enemy & (1 << x->Index)) != 0;
00941 }
00942
00946 bool CPlayer::IsEnemy(const CUnit *x) const
00947 {
00948 return IsEnemy(x->Player);
00949 }
00950
00954 bool CPlayer::IsAllied(const CPlayer *x) const
00955 {
00956 return (Allied & (1 << x->Index)) != 0;
00957 }
00958
00962 bool CPlayer::IsAllied(const CUnit *x) const
00963 {
00964 return IsAllied(x->Player);
00965 }
00966
00970 bool CPlayer::IsSharedVision(const CPlayer *x) const
00971 {
00972 return (SharedVision & (1 << x->Index)) != 0;
00973 }
00974
00978 bool CPlayer::IsSharedVision(const CUnit *x) const
00979 {
00980 return IsSharedVision(x->Player);
00981 }
00982
00986 bool CPlayer::IsBothSharedVision(const CPlayer *x) const
00987 {
00988 return (SharedVision & (1 << x->Index)) != 0 &&
00989 (x->SharedVision & (1 << Index)) != 0;
00990 }
00991
00995 bool CPlayer::IsBothSharedVision(const CUnit *x) const
00996 {
00997 return IsBothSharedVision(x->Player);
00998 }
00999
01003 bool CPlayer::IsTeamed(const CPlayer *x) const
01004 {
01005 return Team == x->Team;
01006 }
01007
01011 bool CPlayer::IsTeamed(const CUnit *x) const
01012 {
01013 return IsTeamed(x->Player);
01014 }
01015