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 "stratagus.h"
00036 #include "commands.h"
00037 #include "unit.h"
00038 #include "unit_manager.h"
00039 #include "unittype.h"
00040 #include "actions.h"
00041 #include "network.h"
00042 #include "spells.h"
00043 #include "replay.h"
00044
00045
00046
00047
00048
00054 void SendCommandStopUnit(CUnit *unit)
00055 {
00056 if (!IsNetworkGame()) {
00057 CommandLog("stop", unit, FlushCommands, -1, -1, NoUnitP, NULL, -1);
00058 CommandStopUnit(unit);
00059 } else {
00060 NetworkSendCommand(MessageCommandStop, unit, 0, 0, NoUnitP, 0, FlushCommands);
00061 }
00062 }
00063
00070 void SendCommandStandGround(CUnit *unit, int flush)
00071 {
00072 if (!IsNetworkGame()) {
00073 CommandLog("stand-ground", unit, flush, -1, -1, NoUnitP, NULL, -1);
00074 CommandStandGround(unit, flush);
00075 } else {
00076 NetworkSendCommand(MessageCommandStand, unit, 0, 0, NoUnitP, 0, flush);
00077 }
00078 }
00079
00087 void SendCommandFollow(CUnit *unit, CUnit *dest, int flush)
00088 {
00089 if (!IsNetworkGame()) {
00090 CommandLog("follow", unit, flush, -1, -1, dest, NULL, -1);
00091 CommandFollow(unit, dest, flush);
00092 } else {
00093 NetworkSendCommand(MessageCommandFollow, unit, 0, 0, dest, 0, flush);
00094 }
00095 }
00096
00105 void SendCommandMove(CUnit *unit, int x, int y, int flush)
00106 {
00107 if (!IsNetworkGame()) {
00108 CommandLog("move", unit, flush, x, y, NoUnitP, NULL, -1);
00109 CommandMove(unit, x, y, flush);
00110 } else {
00111 NetworkSendCommand(MessageCommandMove, unit, x, y, NoUnitP, 0, flush);
00112 }
00113 }
00114
00124 void SendCommandRepair(CUnit *unit, int x, int y, CUnit *dest, int flush)
00125 {
00126 if (!IsNetworkGame()) {
00127 CommandLog("repair", unit, flush, x, y, dest, NULL, -1);
00128 CommandRepair(unit, x, y, dest, flush);
00129 } else {
00130 NetworkSendCommand(MessageCommandRepair, unit, x, y, dest, 0, flush);
00131 }
00132 }
00133
00140 void SendCommandAutoRepair(CUnit *unit, int on)
00141 {
00142 if (!IsNetworkGame()) {
00143 CommandLog("auto-repair", unit, FlushCommands, on, -1, NoUnitP,
00144 NULL, 0);
00145 CommandAutoRepair(unit, on);
00146 } else {
00147 NetworkSendCommand(MessageCommandAutoRepair,
00148 unit, on, -1, NoUnitP, NULL, FlushCommands);
00149 }
00150 }
00151
00161 void SendCommandAttack(CUnit *unit, int x, int y, CUnit *attack, int flush)
00162 {
00163 if (!IsNetworkGame()) {
00164 CommandLog("attack", unit, flush, x, y, attack, NULL, -1);
00165 CommandAttack(unit, x, y, attack, flush);
00166 } else {
00167 NetworkSendCommand(MessageCommandAttack, unit, x, y, attack, 0, flush);
00168 }
00169 }
00170
00179 void SendCommandAttackGround(CUnit *unit, int x, int y, int flush)
00180 {
00181 if (!IsNetworkGame()) {
00182 CommandLog("attack-ground", unit, flush, x, y, NoUnitP, NULL, -1);
00183 CommandAttackGround(unit, x, y, flush);
00184 } else {
00185 NetworkSendCommand(MessageCommandGround, unit, x, y, NoUnitP, 0, flush);
00186 }
00187 }
00188
00197 void SendCommandPatrol(CUnit *unit, int x, int y, int flush)
00198 {
00199 if (!IsNetworkGame()) {
00200 CommandLog("patrol", unit, flush, x, y, NoUnitP, NULL, -1);
00201 CommandPatrolUnit(unit, x, y, flush);
00202 } else {
00203 NetworkSendCommand(MessageCommandPatrol, unit, x, y, NoUnitP, 0, flush);
00204 }
00205 }
00206
00216 void SendCommandBoard(CUnit *unit, int x, int y, CUnit *dest, int flush)
00217 {
00218 if (!IsNetworkGame()) {
00219 CommandLog("board", unit, flush, x, y, dest, NULL, -1);
00220 CommandBoard(unit, dest, flush);
00221 } else {
00222 NetworkSendCommand(MessageCommandBoard, unit, x, y, dest, 0, flush);
00223 }
00224 }
00225
00235 void SendCommandUnload(CUnit *unit, int x, int y, CUnit *what, int flush)
00236 {
00237 if (!IsNetworkGame()) {
00238 CommandLog("unload", unit, flush, x, y, what, NULL, -1);
00239 CommandUnload(unit, x, y, what, flush);
00240 } else {
00241 NetworkSendCommand(MessageCommandUnload, unit, x, y, what, 0, flush);
00242 }
00243 }
00244
00254 void SendCommandBuildBuilding(CUnit *unit, int x, int y,
00255 CUnitType *what, int flush)
00256 {
00257 if (!IsNetworkGame()) {
00258 CommandLog("build", unit, flush, x, y, NoUnitP, what->Ident.c_str(), -1);
00259 CommandBuildBuilding(unit, x, y, what, flush);
00260 } else {
00261 NetworkSendCommand(MessageCommandBuild, unit, x, y, NoUnitP, what, flush);
00262 }
00263 }
00264
00270 void SendCommandDismiss(CUnit *unit)
00271 {
00272
00273 if (!IsNetworkGame()) {
00274 CommandLog("dismiss", unit, FlushCommands, -1, -1, NULL, NULL, -1);
00275 CommandDismiss(unit);
00276 } else {
00277 NetworkSendCommand(MessageCommandDismiss, unit, 0, 0, NULL, 0,
00278 FlushCommands);
00279 }
00280 }
00281
00289 void SendCommandResource(CUnit *unit, CUnit *dest, int flush)
00290 {
00291 if (!IsNetworkGame()) {
00292 CommandLog("resource", unit, flush, -1, -1, dest, NULL, -1);
00293 CommandResource(unit, dest, flush);
00294 } else {
00295 NetworkSendCommand(MessageCommandResource, unit, 0, 0, dest, 0, flush);
00296 }
00297 }
00298
00306 void SendCommandTrainUnit(CUnit *unit, CUnitType *what, int flush)
00307 {
00308 if (!IsNetworkGame()) {
00309 CommandLog("train", unit, flush, -1, -1, NoUnitP, what->Ident.c_str(), -1);
00310 CommandTrainUnit(unit, what, flush);
00311 } else {
00312 NetworkSendCommand(MessageCommandTrain, unit, 0, 0, NoUnitP, what, flush);
00313 }
00314 }
00315
00323 void SendCommandCancelTraining(CUnit *unit, int slot, const CUnitType *type)
00324 {
00325 if (!IsNetworkGame()) {
00326 CommandLog("cancel-train", unit, FlushCommands, -1, -1, NoUnitP,
00327 type ? type->Ident.c_str() : NULL, slot);
00328 CommandCancelTraining(unit, slot, type);
00329 } else {
00330 NetworkSendCommand(MessageCommandCancelTrain, unit, slot, 0, NoUnitP,
00331 type, FlushCommands);
00332 }
00333 }
00334
00345 void SendCommandSpellCast(CUnit *unit, int x, int y, CUnit *dest, int spellid,
00346 int flush)
00347 {
00348 if (!IsNetworkGame()) {
00349 CommandLog("spell-cast", unit, flush, x, y, dest, NULL, spellid);
00350 CommandSpellCast(unit, x, y, dest, SpellTypeTable[spellid], flush);
00351 } else {
00352 NetworkSendCommand(MessageCommandSpellCast + spellid,
00353 unit, x, y, dest, NULL, flush);
00354 }
00355 }
00356
00364 void SendCommandAutoSpellCast(CUnit *unit, int spellid, int on)
00365 {
00366 if (!IsNetworkGame()) {
00367 CommandLog("auto-spell-cast", unit, FlushCommands, on, -1, NoUnitP,
00368 NULL, spellid);
00369 CommandAutoSpellCast(unit, spellid, on);
00370 } else {
00371 NetworkSendCommand(MessageCommandSpellCast + spellid,
00372 unit, on, -1, NoUnitP, NULL, FlushCommands);
00373 }
00374 }
00375
00383 void SendCommandDiplomacy(int player, int state, int opponent)
00384 {
00385 if (!IsNetworkGame()) {
00386 switch (state) {
00387 case DiplomacyNeutral:
00388 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
00389 NoUnitP, "neutral", -1);
00390 break;
00391 case DiplomacyAllied:
00392 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
00393 NoUnitP, "allied", -1);
00394 break;
00395 case DiplomacyEnemy:
00396 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
00397 NoUnitP, "enemy", -1);
00398 break;
00399 case DiplomacyCrazy:
00400 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
00401 NoUnitP, "crazy", -1);
00402 break;
00403 }
00404 CommandDiplomacy(player, state, opponent);
00405 } else {
00406 NetworkSendExtendedCommand(ExtendedMessageDiplomacy,
00407 -1, player, state, opponent, 0);
00408 }
00409 }
00410
00418 void SendCommandSharedVision(int player, bool state, int opponent)
00419 {
00420 if (!IsNetworkGame()) {
00421 if (state == false) {
00422 CommandLog("shared-vision", NoUnitP, 0, player, opponent,
00423 NoUnitP, "0", -1);
00424 } else {
00425 CommandLog("shared-vision", NoUnitP, 0, player, opponent,
00426 NoUnitP, "1", -1);
00427 }
00428 CommandSharedVision(player, state, opponent);
00429 } else {
00430 NetworkSendExtendedCommand(ExtendedMessageSharedVision,
00431 -1, player, state, opponent, 0);
00432 }
00433 }
00434
00436
00437
00438
00439
00440
00443
00453 void ParseCommand(unsigned char msgnr, UnitRef unum,
00454 unsigned short x, unsigned short y, UnitRef dstnr)
00455 {
00456 CUnit *unit;
00457 CUnit *dest;
00458 int id;
00459 int status;
00460
00461 Assert(unum < UnitSlotFree);
00462 unit = UnitSlots[unum];
00463 Assert(unit);
00464
00465
00466
00467
00468 if (unit->Destroyed) {
00469 DebugPrint(" destroyed unit skipping %d\n" _C_ UnitNumber(unit));
00470 return;
00471 }
00472
00473 Assert(unit->Type);
00474
00475 status = (msgnr & 0x80) >> 7;
00476
00477
00478
00479 switch (msgnr & 0x7F) {
00480 case MessageSync:
00481 return;
00482 case MessageQuit:
00483 return;
00484 case MessageChat:
00485 return;
00486
00487 case MessageCommandStop:
00488 CommandLog("stop", unit, FlushCommands, -1, -1, NoUnitP, NULL, -1);
00489 CommandStopUnit(unit);
00490 break;
00491 case MessageCommandStand:
00492 CommandLog("stand-ground", unit, status, -1, -1, NoUnitP, NULL, -1);
00493 CommandStandGround(unit, status);
00494 break;
00495 case MessageCommandFollow:
00496 dest = NoUnitP;
00497 if (dstnr != (unsigned short)0xFFFF) {
00498 dest = UnitSlots[dstnr];
00499 Assert(dest && dest->Type);
00500 }
00501 CommandLog("follow", unit, status, -1, -1, dest, NULL, -1);
00502 CommandFollow(unit, dest, status);
00503 break;
00504 case MessageCommandMove:
00505 CommandLog("move", unit, status, x, y, NoUnitP, NULL, -1);
00506 CommandMove(unit, x, y, status);
00507 break;
00508 case MessageCommandRepair:
00509 dest = NoUnitP;
00510 if (dstnr != (unsigned short)0xFFFF) {
00511 dest = UnitSlots[dstnr];
00512 Assert(dest && dest->Type);
00513 }
00514 CommandLog("repair", unit, status, x, y, dest, NULL, -1);
00515 CommandRepair(unit, x, y, dest, status);
00516 break;
00517 case MessageCommandAutoRepair:
00518 CommandLog("auto-repair", unit, status, x, y, NoUnitP, NULL, 0);
00519 CommandAutoRepair(unit, x);
00520 break;
00521 case MessageCommandAttack:
00522 dest = NoUnitP;
00523 if (dstnr != (unsigned short)0xFFFF) {
00524 dest = UnitSlots[dstnr];
00525 Assert(dest && dest->Type);
00526 }
00527 CommandLog("attack", unit, status, x, y, dest, NULL, -1);
00528 CommandAttack(unit, x, y, dest, status);
00529 break;
00530 case MessageCommandGround:
00531 CommandLog("attack-ground", unit, status, x, y, NoUnitP, NULL, -1);
00532 CommandAttackGround(unit, x, y, status);
00533 break;
00534 case MessageCommandPatrol:
00535 CommandLog("patrol", unit, status, x, y, NoUnitP, NULL, -1);
00536 CommandPatrolUnit(unit, x, y, status);
00537 break;
00538 case MessageCommandBoard:
00539 dest = NoUnitP;
00540 if (dstnr != (unsigned short)0xFFFF) {
00541 dest = UnitSlots[dstnr];
00542 Assert(dest && dest->Type);
00543 }
00544 CommandLog("board", unit, status, x, y, dest, NULL, -1);
00545 CommandBoard(unit, dest, status);
00546 break;
00547 case MessageCommandUnload:
00548 dest = NoUnitP;
00549 if (dstnr != (unsigned short)0xFFFF) {
00550 dest = UnitSlots[dstnr];
00551 Assert(dest && dest->Type);
00552 }
00553 CommandLog("unload", unit, status, x, y, dest, NULL, -1);
00554 CommandUnload(unit, x, y, dest, status);
00555 break;
00556 case MessageCommandBuild:
00557 CommandLog("build", unit, status, x, y, NoUnitP, UnitTypes[dstnr]->Ident.c_str(),
00558 -1);
00559 CommandBuildBuilding(unit, x, y, UnitTypes[dstnr], status);
00560 break;
00561 case MessageCommandDismiss:
00562 CommandLog("dismiss", unit, FlushCommands, -1, -1, NULL, NULL, -1);
00563 CommandDismiss(unit);
00564 break;
00565 case MessageCommandResource:
00566 dest = NoUnitP;
00567 if (dstnr != (unsigned short)0xFFFF) {
00568 dest = UnitSlots[dstnr];
00569 Assert(dest && dest->Type);
00570 }
00571 CommandLog("resource", unit, status, -1, -1, dest, NULL, -1);
00572 CommandResource(unit, dest, status);
00573 break;
00574 case MessageCommandTrain:
00575 CommandLog("train", unit, status, -1, -1, NoUnitP,
00576 UnitTypes[dstnr]->Ident.c_str(), -1);
00577 CommandTrainUnit(unit, UnitTypes[dstnr], status);
00578 break;
00579 case MessageCommandCancelTrain:
00580
00581 if (dstnr != (unsigned short)0xFFFF) {
00582 CommandLog("cancel-train", unit, FlushCommands, -1, -1, NoUnitP,
00583 UnitTypes[dstnr]->Ident.c_str(), (short)x);
00584 CommandCancelTraining(unit, (short)x, UnitTypes[dstnr]);
00585 } else {
00586 CommandLog("cancel-train", unit, FlushCommands, -1, -1, NoUnitP,
00587 NULL, (short)x);
00588 CommandCancelTraining(unit, (short)x, NULL);
00589 }
00590 break;
00591 default:
00592 id = (msgnr&0x7f) - MessageCommandSpellCast;
00593 if (y != (unsigned short)0xFFFF) {
00594 dest = NoUnitP;
00595 if (dstnr != (unsigned short)0xFFFF) {
00596 dest = UnitSlots[dstnr];
00597 Assert(dest && dest->Type);
00598 }
00599 CommandLog("spell-cast", unit, status, x, y, dest, NULL, id);
00600 CommandSpellCast(unit, x, y, dest, SpellTypeTable[id], status);
00601 } else {
00602 CommandLog("auto-spell-cast", unit, status, x, -1, NoUnitP, NULL, id);
00603 CommandAutoSpellCast(unit, id, x);
00604 }
00605 break;
00606 }
00607 }
00608
00619 void ParseExtendedCommand(unsigned char type, int status,
00620 unsigned char arg1, unsigned short arg2, unsigned short arg3,
00621 unsigned short arg4)
00622 {
00623
00624
00625 switch (type) {
00626 case ExtendedMessageDiplomacy:
00627 switch (arg3) {
00628 case DiplomacyNeutral:
00629 CommandLog("diplomacy", NoUnitP, 0, arg2, arg4,
00630 NoUnitP, "neutral", -1);
00631 break;
00632 case DiplomacyAllied:
00633 CommandLog("diplomacy", NoUnitP, 0, arg2, arg4,
00634 NoUnitP, "allied", -1);
00635 break;
00636 case DiplomacyEnemy:
00637 CommandLog("diplomacy", NoUnitP, 0, arg2, arg4,
00638 NoUnitP, "enemy", -1);
00639 break;
00640 case DiplomacyCrazy:
00641 CommandLog("diplomacy", NoUnitP, 0, arg2, arg4,
00642 NoUnitP, "crazy", -1);
00643 break;
00644 }
00645 CommandDiplomacy(arg2, arg3, arg4);
00646 break;
00647 case ExtendedMessageSharedVision:
00648 if (arg3 == 0) {
00649 CommandLog("shared-vision", NoUnitP, 0, arg2, arg4,
00650 NoUnitP, "0", -1);
00651 } else {
00652 CommandLog("shared-vision", NoUnitP, 0, arg2, arg4,
00653 NoUnitP, "1", -1);
00654 }
00655 CommandSharedVision(arg2, arg3 ? true : false, arg4);
00656 break;
00657 default:
00658 DebugPrint("Unknown extended message %u/%s %u %u %u %u\n" _C_
00659 type _C_ status ? "flush" : "-" _C_
00660 arg1 _C_ arg2 _C_ arg3 _C_ arg4);
00661 break;
00662 }
00663 }
00664