1 // _________ __ __
2 // / _____// |_____________ _/ |______ ____ __ __ ______
3 // \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
4 // / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
5 // /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
6 // \/ \/ \//_____/ \/
7 // ______________________ ______________________
8 // T H E W A R B E G I N S
9 // Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name commands.cpp - Global command handler - network support. */
12 //
13 // (c) Copyright 2000-2007 by Lutz Sammer, Andreas Arens, and Jimmy Salmon.
14 //
15 // This program is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation; only version 2 of the License.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with this program; if not, write to the Free Software
26 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 // 02111-1307, USA.
28 //
29
30 //@{
31
32 /*----------------------------------------------------------------------------
33 -- Includes
34 ----------------------------------------------------------------------------*/
35
36 #include "stratagus.h"
37
38 #include "commands.h"
39
40 #include "actions.h"
41 //Wyrmgus start
42 #include "map/map.h" //it contains map width and height
43 //Wyrmgus end
44 #include "net_message.h"
45 #include "network.h"
46 //Wyrmgus start
47 #include "quest.h"
48 //Wyrmgus end
49 #include "replay.h"
50 #include "spells.h"
51 #include "unit/unit.h"
52 #include "unit/unit_manager.h"
53 #include "unit/unittype.h"
54
55 /*----------------------------------------------------------------------------
56 -- Functions
57 ----------------------------------------------------------------------------*/
58
59 /**
60 ** Send command: Unit stop.
61 **
62 ** @param unit pointer to unit.
63 */
SendCommandStopUnit(CUnit & unit)64 void SendCommandStopUnit(CUnit &unit)
65 {
66 if (!IsNetworkGame()) {
67 CommandLog("stop", &unit, FlushCommands, -1, -1, NoUnitP, nullptr, -1);
68 CommandStopUnit(unit);
69 } else {
70 NetworkSendCommand(MessageCommandStop, unit, 0, 0, NoUnitP, 0, FlushCommands);
71 }
72 }
73
74 /**
75 ** Send command: Unit stand ground.
76 **
77 ** @param unit pointer to unit.
78 ** @param flush Flag flush all pending commands.
79 */
SendCommandStandGround(CUnit & unit,int flush)80 void SendCommandStandGround(CUnit &unit, int flush)
81 {
82 if (!IsNetworkGame()) {
83 CommandLog("stand-ground", &unit, flush, -1, -1, NoUnitP, nullptr, -1);
84 CommandStandGround(unit, flush);
85 } else {
86 NetworkSendCommand(MessageCommandStand, unit, 0, 0, NoUnitP, 0, flush);
87 }
88 }
89
90 /**
91 ** Send command: Defend some unit.
92 **
93 ** @param unit pointer to unit.
94 ** @param dest defend this unit.
95 ** @param flush Flag flush all pending commands.
96 */
SendCommandDefend(CUnit & unit,CUnit & dest,int flush)97 void SendCommandDefend(CUnit &unit, CUnit &dest, int flush)
98 {
99 if (!IsNetworkGame()) {
100 CommandLog("defend", &unit, flush, -1, -1, &dest, nullptr, -1);
101 CommandDefend(unit, dest, flush);
102 } else {
103 NetworkSendCommand(MessageCommandDefend, unit, 0, 0, &dest, 0, flush);
104 }
105 }
106
107 /**
108 ** Send command: Follow unit to position.
109 **
110 ** @param unit pointer to unit.
111 ** @param dest follow this unit.
112 ** @param flush Flag flush all pending commands.
113 */
SendCommandFollow(CUnit & unit,CUnit & dest,int flush)114 void SendCommandFollow(CUnit &unit, CUnit &dest, int flush)
115 {
116 if (!IsNetworkGame()) {
117 CommandLog("follow", &unit, flush, -1, -1, &dest, nullptr, -1);
118 CommandFollow(unit, dest, flush);
119 } else {
120 NetworkSendCommand(MessageCommandFollow, unit, 0, 0, &dest, 0, flush);
121 }
122 }
123
124 /**
125 ** Send command: Move unit to position.
126 **
127 ** @param unit pointer to unit.
128 ** @param pos map tile position to move to.
129 ** @param flush Flag flush all pending commands.
130 */
131 //Wyrmgus start
132 //void SendCommandMove(CUnit &unit, const Vec2i &pos, int flush)
SendCommandMove(CUnit & unit,const Vec2i & pos,int flush,int z)133 void SendCommandMove(CUnit &unit, const Vec2i &pos, int flush, int z)
134 //Wyrmgus end
135 {
136 if (!IsNetworkGame()) {
137 CommandLog("move", &unit, flush, pos.x, pos.y, NoUnitP, nullptr, -1);
138 //Wyrmgus start
139 // CommandMove(unit, pos, flush);
140 CommandMove(unit, pos, flush, z);
141 //Wyrmgus end
142 } else {
143 NetworkSendCommand(MessageCommandMove, unit, pos.x, pos.y, NoUnitP, 0, flush);
144 }
145 }
146
147 //Wyrmgus start
148 /**
149 ** Send command: Set new rally point for unit.
150 **
151 ** @param unit pointer to unit.
152 ** @param pos map tile position to move to.
153 */
SendCommandRallyPoint(CUnit & unit,const Vec2i & pos,int z)154 void SendCommandRallyPoint(CUnit &unit, const Vec2i &pos, int z)
155 {
156 if (!IsNetworkGame()) {
157 CommandLog("rally-point", &unit, 0, pos.x, pos.y, NoUnitP, nullptr, -1);
158 CommandRallyPoint(unit, pos, z);
159 } else {
160 NetworkSendCommand(MessageCommandMove, unit, pos.x, pos.y, NoUnitP, 0, 0);
161 }
162 }
163
164 /**
165 ** Send command: Accept new quest for the unit's player.
166 **
167 ** @param unit pointer to unit.
168 ** @param pos map tile position to move to.
169 */
SendCommandQuest(CUnit & unit,CQuest * quest)170 void SendCommandQuest(CUnit &unit, CQuest *quest)
171 {
172 if (!IsNetworkGame()) {
173 CommandLog("quest", &unit, 0, 0, 0, NoUnitP, quest->Ident.c_str(), -1);
174 CommandQuest(unit, quest);
175 } else {
176 NetworkSendCommand(MessageCommandQuest, unit, quest->ID, 0, NoUnitP, nullptr, 0);
177 }
178 }
179
180 /**
181 ** Send command: Buy an item from a building.
182 **
183 ** @param unit pointer to unit.
184 ** @param pos map tile position to move to.
185 */
SendCommandBuy(CUnit & unit,CUnit * sold_unit,int player)186 void SendCommandBuy(CUnit &unit, CUnit *sold_unit, int player)
187 {
188 if (!IsNetworkGame()) {
189 CommandLog("buy", &unit, 0, -1, -1, sold_unit, nullptr, player);
190 CommandBuy(unit, sold_unit, player);
191 } else {
192 NetworkSendCommand(MessageCommandBuy, unit, player, 0, sold_unit, 0, 0);
193 }
194 }
195
196 /**
197 ** Send command: Produce a resource.
198 */
SendCommandProduceResource(CUnit & unit,int resource)199 void SendCommandProduceResource(CUnit &unit, int resource)
200 {
201 if (!IsNetworkGame()) {
202 CommandLog("produce-resource", &unit, 0, 0, -1, NoUnitP, nullptr, resource);
203 CommandProduceResource(unit, resource);
204 } else {
205 NetworkSendCommand(MessageCommandProduceResource, unit, resource, 0, NoUnitP, nullptr, 0);
206 }
207 }
208
209 /**
210 ** Send command: Sell a resource for copper.
211 */
SendCommandSellResource(CUnit & unit,int resource,int player)212 void SendCommandSellResource(CUnit &unit, int resource, int player)
213 {
214 if (!IsNetworkGame()) {
215 CommandLog("sell-resource", &unit, 0, resource, -1, NoUnitP, nullptr, player);
216 CommandSellResource(unit, resource, player);
217 } else {
218 NetworkSendCommand(MessageCommandSellResource, unit, resource, player, NoUnitP, nullptr, 0);
219 }
220 }
221
222 /**
223 ** Send command: Buy a resource with copper.
224 */
SendCommandBuyResource(CUnit & unit,int resource,int player)225 void SendCommandBuyResource(CUnit &unit, int resource, int player)
226 {
227 if (!IsNetworkGame()) {
228 CommandLog("buy-resource", &unit, 0, resource, -1, NoUnitP, nullptr, player);
229 CommandBuyResource(unit, resource, player);
230 } else {
231 NetworkSendCommand(MessageCommandBuyResource, unit, resource, player, NoUnitP, nullptr, 0);
232 }
233 }
234
235 /**
236 ** Send command: Pick up item.
237 **
238 ** @param unit pointer to unit.
239 ** @param dest pick up this item.
240 ** @param flush Flag flush all pending commands.
241 */
SendCommandPickUp(CUnit & unit,CUnit & dest,int flush)242 void SendCommandPickUp(CUnit &unit, CUnit &dest, int flush)
243 {
244 if (!IsNetworkGame()) {
245 CommandLog("pick-up", &unit, flush, -1, -1, &dest, nullptr, -1);
246 CommandPickUp(unit, dest, flush);
247 } else {
248 NetworkSendCommand(MessageCommandPickUp, unit, 0, 0, &dest, 0, flush);
249 }
250 }
251 //Wyrmgus end
252
253 /**
254 ** Send command: Unit repair.
255 **
256 ** @param unit Pointer to unit.
257 ** @param pos map tile position to repair.
258 ** @param dest Unit to be repaired.
259 ** @param flush Flag flush all pending commands.
260 */
261 //Wyrmgus start
262 //void SendCommandRepair(CUnit &unit, const Vec2i &pos, CUnit *dest, int flush)
SendCommandRepair(CUnit & unit,const Vec2i & pos,CUnit * dest,int flush,int z)263 void SendCommandRepair(CUnit &unit, const Vec2i &pos, CUnit *dest, int flush, int z)
264 //Wyrmgus end
265 {
266 if (!IsNetworkGame()) {
267 CommandLog("repair", &unit, flush, pos.x, pos.y, dest, nullptr, -1);
268 //Wyrmgus start
269 // CommandRepair(unit, pos, dest, flush);
270 CommandRepair(unit, pos, dest, flush, z);
271 //Wyrmgus end
272 } else {
273 NetworkSendCommand(MessageCommandRepair, unit, pos.x, pos.y, dest, 0, flush);
274 }
275 }
276
277 /**
278 ** Send command: Unit auto repair.
279 **
280 ** @param unit pointer to unit.
281 ** @param on 1 for auto repair on, 0 for off.
282 */
SendCommandAutoRepair(CUnit & unit,int on)283 void SendCommandAutoRepair(CUnit &unit, int on)
284 {
285 if (!IsNetworkGame()) {
286 CommandLog("auto-repair", &unit, FlushCommands, on, -1, NoUnitP, nullptr, 0);
287 CommandAutoRepair(unit, on);
288 } else {
289 NetworkSendCommand(MessageCommandAutoRepair, unit, on, -1, NoUnitP, nullptr, FlushCommands);
290 }
291 }
292
293 /**
294 ** Send command: Unit attack unit or at position.
295 **
296 ** @param unit pointer to unit.
297 ** @param pos map tile position to attack.
298 ** @param attack or !=NoUnitP unit to be attacked.
299 ** @param flush Flag flush all pending commands.
300 */
301 //Wyrmgus start
302 //void SendCommandAttack(CUnit &unit, const Vec2i &pos, CUnit *attack, int flush)
SendCommandAttack(CUnit & unit,const Vec2i & pos,CUnit * attack,int flush,int z)303 void SendCommandAttack(CUnit &unit, const Vec2i &pos, CUnit *attack, int flush, int z)
304 //Wyrmgus end
305 {
306 if (!IsNetworkGame()) {
307 CommandLog("attack", &unit, flush, pos.x, pos.y, attack, nullptr, -1);
308 //Wyrmgus start
309 // CommandAttack(unit, pos, attack, flush);
310 CommandAttack(unit, pos, attack, flush, z);
311 //Wyrmgus end
312 } else {
313 NetworkSendCommand(MessageCommandAttack, unit, pos.x, pos.y, attack, 0, flush);
314 }
315 }
316
317 /**
318 ** Send command: Unit attack ground.
319 **
320 ** @param unit pointer to unit.
321 ** @param pos map tile position to fire on.
322 ** @param flush Flag flush all pending commands.
323 */
324 //Wyrmgus start
325 //void SendCommandAttackGround(CUnit &unit, const Vec2i &pos, int flush)
SendCommandAttackGround(CUnit & unit,const Vec2i & pos,int flush,int z)326 void SendCommandAttackGround(CUnit &unit, const Vec2i &pos, int flush, int z)
327 //Wyrmgus end
328 {
329 if (!IsNetworkGame()) {
330 CommandLog("attack-ground", &unit, flush, pos.x, pos.y, NoUnitP, nullptr, -1);
331 //Wyrmgus start
332 // CommandAttackGround(unit, pos, flush);
333 CommandAttackGround(unit, pos, flush, z);
334 //Wyrmgus end
335 } else {
336 NetworkSendCommand(MessageCommandGround, unit, pos.x, pos.y, NoUnitP, 0, flush);
337 }
338 }
339
340 //Wyrmgus start
341 /**
342 ** Send command: Use a unit.
343 **
344 ** @param unit pointer to unit.
345 ** @param dest use this unit.
346 ** @param flush Flag flush all pending commands.
347 */
SendCommandUse(CUnit & unit,CUnit & dest,int flush)348 void SendCommandUse(CUnit &unit, CUnit &dest, int flush)
349 {
350 if (!IsNetworkGame()) {
351 CommandLog("use", &unit, flush, -1, -1, &dest, nullptr, -1);
352 CommandUse(unit, dest, flush);
353 } else {
354 NetworkSendCommand(MessageCommandUse, unit, 0, 0, &dest, 0, flush);
355 }
356 }
357
358 /**
359 ** Send command: Trade with a unit.
360 **
361 ** @param unit pointer to unit.
362 ** @param dest trade with this unit.
363 ** @param flush Flag flush all pending commands.
364 */
SendCommandTrade(CUnit & unit,CUnit & dest,int flush)365 void SendCommandTrade(CUnit &unit, CUnit &dest, int flush)
366 {
367 if (!IsNetworkGame()) {
368 CommandLog("use", &unit, flush, -1, -1, &dest, nullptr, -1);
369 CommandTrade(unit, dest, flush);
370 } else {
371 NetworkSendCommand(MessageCommandTrade, unit, 0, 0, &dest, 0, flush);
372 }
373 }
374 //Wyrmgus end
375
376 /**
377 ** Send command: Unit patrol between current and position.
378 **
379 ** @param unit pointer to unit.
380 ** @param pos map tile position to patrol between.
381 ** @param flush Flag flush all pending commands.
382 */
383 //Wyrmgus start
384 //void SendCommandPatrol(CUnit &unit, const Vec2i &pos, int flush)
SendCommandPatrol(CUnit & unit,const Vec2i & pos,int flush,int z)385 void SendCommandPatrol(CUnit &unit, const Vec2i &pos, int flush, int z)
386 //Wyrmgus end
387 {
388 if (!IsNetworkGame()) {
389 CommandLog("patrol", &unit, flush, pos.x, pos.y, NoUnitP, nullptr, -1);
390 //Wyrmgus start
391 // CommandPatrolUnit(unit, pos, flush);
392 CommandPatrolUnit(unit, pos, flush, z);
393 //Wyrmgus end
394 } else {
395 NetworkSendCommand(MessageCommandPatrol, unit, pos.x, pos.y, NoUnitP, 0, flush);
396 }
397 }
398
399 /**
400 ** Send command: Unit board unit.
401 **
402 ** @param unit pointer to unit.
403 ** @param dest Destination to be boarded.
404 ** @param flush Flag flush all pending commands.
405 */
SendCommandBoard(CUnit & unit,CUnit & dest,int flush)406 void SendCommandBoard(CUnit &unit, CUnit &dest, int flush)
407 {
408 if (!IsNetworkGame()) {
409 CommandLog("board", &unit, flush, -1, -1, &dest, nullptr, -1);
410 CommandBoard(unit, dest, flush);
411 } else {
412 NetworkSendCommand(MessageCommandBoard, unit, -1, -1, &dest, 0, flush);
413 }
414 }
415
416 /**
417 ** Send command: Unit unload unit.
418 **
419 ** @param unit pointer to unit.
420 ** @param pos map tile position of unload.
421 ** @param what Passagier to be unloaded.
422 ** @param flush Flag flush all pending commands.
423 */
424 //Wyrmgus start
425 //void SendCommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush)
SendCommandUnload(CUnit & unit,const Vec2i & pos,CUnit * what,int flush,int z)426 void SendCommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush, int z)
427 //Wyrmgus end
428 {
429 if (!IsNetworkGame()) {
430 CommandLog("unload", &unit, flush, pos.x, pos.y, what, nullptr, -1);
431 //Wyrmgus start
432 // CommandUnload(unit, pos, what, flush);
433 CommandUnload(unit, pos, what, flush, z);
434 //Wyrmgus end
435 } else {
436 NetworkSendCommand(MessageCommandUnload, unit, pos.x, pos.y, what, 0, flush);
437 }
438 }
439
440 /**
441 ** Send command: Unit builds building at position.
442 **
443 ** @param unit pointer to unit.
444 ** @param pos map tile position of construction.
445 ** @param what pointer to unit-type of the building.
446 ** @param flush Flag flush all pending commands.
447 */
448 //Wyrmgus start
449 //void SendCommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int flush)
SendCommandBuildBuilding(CUnit & unit,const Vec2i & pos,CUnitType & what,int flush,int z)450 void SendCommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int flush, int z)
451 //Wyrmgus end
452 {
453 if (!IsNetworkGame()) {
454 CommandLog("build", &unit, flush, pos.x, pos.y, NoUnitP, what.Ident.c_str(), -1);
455 //Wyrmgus start
456 // CommandBuildBuilding(unit, pos, what, flush);
457 CommandBuildBuilding(unit, pos, what, flush, z);
458 //Wyrmgus end
459 } else {
460 NetworkSendCommand(MessageCommandBuild, unit, pos.x, pos.y, NoUnitP, &what, flush);
461 }
462 }
463
464 /**
465 ** Send command: Cancel this building construction.
466 **
467 ** @param unit pointer to unit.
468 */
SendCommandDismiss(CUnit & unit,bool salvage)469 void SendCommandDismiss(CUnit &unit, bool salvage)
470 {
471 // FIXME: currently unit and worker are same?
472 if (!IsNetworkGame()) {
473 CommandLog("dismiss", &unit, FlushCommands, -1, -1, nullptr, nullptr, -1);
474 CommandDismiss(unit, salvage);
475 } else {
476 NetworkSendCommand(MessageCommandDismiss, unit, salvage, 0, nullptr, 0, FlushCommands);
477 }
478 }
479
480 /**
481 ** Send command: Unit harvests a location (wood for now).
482 **
483 ** @param unit pointer to unit.
484 ** @param pos map tile position where to harvest.
485 ** @param flush Flag flush all pending commands.
486 */
487 //Wyrmgus start
488 //void SendCommandResourceLoc(CUnit &unit, const Vec2i &pos, int flush)
SendCommandResourceLoc(CUnit & unit,const Vec2i & pos,int flush,int z)489 void SendCommandResourceLoc(CUnit &unit, const Vec2i &pos, int flush, int z)
490 //Wyrmgus end
491 {
492 if (!IsNetworkGame()) {
493 CommandLog("resource-loc", &unit, flush, pos.x, pos.y, NoUnitP, nullptr, -1);
494 //Wyrmgus start
495 // CommandResourceLoc(unit, pos, flush);
496 CommandResourceLoc(unit, pos, flush, z);
497 //Wyrmgus end
498 } else {
499 NetworkSendCommand(MessageCommandResourceLoc, unit, pos.x, pos.y, NoUnitP, 0, flush);
500 }
501 }
502
503 /**
504 ** Send command: Unit harvest resources
505 **
506 ** @param unit pointer to unit.
507 ** @param dest pointer to destination (oil-platform,gold mine).
508 ** @param flush Flag flush all pending commands.
509 */
SendCommandResource(CUnit & unit,CUnit & dest,int flush)510 void SendCommandResource(CUnit &unit, CUnit &dest, int flush)
511 {
512 if (!IsNetworkGame()) {
513 CommandLog("resource", &unit, flush, -1, -1, &dest, nullptr, -1);
514 CommandResource(unit, dest, flush);
515 } else {
516 NetworkSendCommand(MessageCommandResource, unit, 0, 0, &dest, 0, flush);
517 }
518 }
519
520 /**
521 ** Send command: Unit return goods.
522 **
523 ** @param unit pointer to unit.
524 ** @param goal pointer to destination of the goods. (null=search best)
525 ** @param flush Flag flush all pending commands.
526 */
SendCommandReturnGoods(CUnit & unit,CUnit * goal,int flush)527 void SendCommandReturnGoods(CUnit &unit, CUnit *goal, int flush)
528 {
529 if (!IsNetworkGame()) {
530 CommandLog("return", &unit, flush, -1, -1, goal, nullptr, -1);
531 CommandReturnGoods(unit, goal, flush);
532 } else {
533 NetworkSendCommand(MessageCommandReturn, unit, 0, 0, goal, 0, flush);
534 }
535 }
536
537 /**
538 ** Send command: Building/unit train new unit.
539 **
540 ** @param unit pointer to unit.
541 ** @param what pointer to unit-type of the unit to be trained.
542 ** @param flush Flag flush all pending commands.
543 */
544 //Wyrmgus start
545 //void SendCommandTrainUnit(CUnit &unit, CUnitType &what, int flush)
SendCommandTrainUnit(CUnit & unit,CUnitType & what,int player,int flush)546 void SendCommandTrainUnit(CUnit &unit, CUnitType &what, int player, int flush)
547 //Wyrmgus end
548 {
549 if (!IsNetworkGame()) {
550 //Wyrmgus start
551 // CommandLog("train", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), -1);
552 // CommandTrainUnit(unit, what, flush);
553 CommandLog("train", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), player);
554 CommandTrainUnit(unit, what, player, flush);
555 //Wyrmgus end
556 } else {
557 //Wyrmgus start
558 // NetworkSendCommand(MessageCommandTrain, unit, 0, 0, NoUnitP, &what, flush);
559 NetworkSendCommand(MessageCommandTrain, unit, player, 0, NoUnitP, &what, flush);
560 //Wyrmgus end
561 }
562 }
563
564 /**
565 ** Send command: Cancel training.
566 **
567 ** @param unit Pointer to unit.
568 ** @param slot Slot of training queue to cancel.
569 ** @param type Unit-type of unit to cancel.
570 */
SendCommandCancelTraining(CUnit & unit,int slot,const CUnitType * type)571 void SendCommandCancelTraining(CUnit &unit, int slot, const CUnitType *type)
572 {
573 if (!IsNetworkGame()) {
574 CommandLog("cancel-train", &unit, FlushCommands, -1, -1, NoUnitP,
575 type ? type->Ident.c_str() : nullptr, slot);
576 CommandCancelTraining(unit, slot, type);
577 } else {
578 NetworkSendCommand(MessageCommandCancelTrain, unit, slot, 0, NoUnitP,
579 type, FlushCommands);
580 }
581 }
582
583 /**
584 ** Send command: Building starts upgrading to.
585 **
586 ** @param unit pointer to unit.
587 ** @param what pointer to unit-type of the unit upgrade.
588 ** @param flush Flag flush all pending commands.
589 */
SendCommandUpgradeTo(CUnit & unit,CUnitType & what,int flush)590 void SendCommandUpgradeTo(CUnit &unit, CUnitType &what, int flush)
591 {
592 if (!IsNetworkGame()) {
593 CommandLog("upgrade-to", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), -1);
594 CommandUpgradeTo(unit, what, flush);
595 } else {
596 NetworkSendCommand(MessageCommandUpgrade, unit, 0, 0, NoUnitP, &what, flush);
597 }
598 }
599
600 /**
601 ** Send command: Cancel building upgrading to.
602 **
603 ** @param unit Pointer to unit.
604 */
SendCommandCancelUpgradeTo(CUnit & unit)605 void SendCommandCancelUpgradeTo(CUnit &unit)
606 {
607 if (!IsNetworkGame()) {
608 CommandLog("cancel-upgrade-to", &unit, FlushCommands, -1, -1, NoUnitP, nullptr, -1);
609 CommandCancelUpgradeTo(unit);
610 } else {
611 NetworkSendCommand(MessageCommandCancelUpgrade, unit,
612 0, 0, NoUnitP, nullptr, FlushCommands);
613 }
614 }
615
616 //Wyrmgus start
617 /**
618 ** Send command: Unit starts upgrading to.
619 **
620 ** @param unit pointer to unit.
621 ** @param what pointer to unit-type of the unit upgrade.
622 ** @param flush Flag flush all pending commands.
623 */
SendCommandTransformInto(CUnit & unit,CUnitType & what,int flush)624 void SendCommandTransformInto(CUnit &unit, CUnitType &what, int flush)
625 {
626 if (!IsNetworkGame()) {
627 CommandLog("transform-into", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), -1);
628 CommandTransformIntoType(unit, what);
629 } else {
630 NetworkSendCommand(MessageCommandUpgrade, unit, 2, 0, NoUnitP, &what, flush); //use X as a way to mark that this is a transformation and not an upgrade
631 }
632 }
633 //Wyrmgus end
634
635 /**
636 ** Send command: Building/unit research.
637 **
638 ** @param unit pointer to unit.
639 ** @param what research-type of the research.
640 ** @param flush Flag flush all pending commands.
641 */
642 //Wyrmgus start
643 //void SendCommandResearch(CUnit &unit, CUpgrade &what, int flush)
SendCommandResearch(CUnit & unit,CUpgrade & what,int player,int flush)644 void SendCommandResearch(CUnit &unit, CUpgrade &what, int player, int flush)
645 //Wyrmgus end
646 {
647 if (!IsNetworkGame()) {
648 //Wyrmgus start
649 // CommandLog("research", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), -1);
650 // CommandResearch(unit, what, flush);
651 CommandLog("research", &unit, flush, -1, -1, NoUnitP, what.Ident.c_str(), player);
652 CommandResearch(unit, what, player, flush);
653 //Wyrmgus end
654 } else {
655 NetworkSendCommand(MessageCommandResearch, unit,
656 //Wyrmgus start
657 // what.ID, 0, NoUnitP, nullptr, flush);
658 what.ID, player, NoUnitP, nullptr, flush);
659 //Wyrmgus end
660 }
661 }
662
663 /**
664 ** Send command: Cancel Building/unit research.
665 **
666 ** @param unit pointer to unit.
667 */
SendCommandCancelResearch(CUnit & unit)668 void SendCommandCancelResearch(CUnit &unit)
669 {
670 if (!IsNetworkGame()) {
671 CommandLog("cancel-research", &unit, FlushCommands, -1, -1, NoUnitP, nullptr, -1);
672 CommandCancelResearch(unit);
673 } else {
674 NetworkSendCommand(MessageCommandCancelResearch, unit,
675 0, 0, NoUnitP, nullptr, FlushCommands);
676 }
677 }
678
679 //Wyrmgus start
680 /**
681 ** Send command: Unit learn ability.
682 **
683 ** @param unit pointer to unit.
684 ** @param what upgrade-type of the ability.
685 */
SendCommandLearnAbility(CUnit & unit,CUpgrade & what)686 void SendCommandLearnAbility(CUnit &unit, CUpgrade &what)
687 {
688 if (!IsNetworkGame()) {
689 CommandLog("learn-ability", &unit, 0, -1, -1, NoUnitP, what.Ident.c_str(), -1);
690 CommandLearnAbility(unit, what);
691 } else {
692 NetworkSendCommand(MessageCommandLearnAbility, unit,
693 what.ID, 0, NoUnitP, nullptr, 0);
694 }
695 }
696 //Wyrmgus end
697
698 /**
699 ** Send command: Unit spell cast on position/unit.
700 **
701 ** @param unit pointer to unit.
702 ** @param pos map tile position where to cast spell.
703 ** @param dest Cast spell on unit (if exist).
704 ** @param spellid Spell type id.
705 ** @param flush Flag flush all pending commands.
706 */
SendCommandSpellCast(CUnit & unit,const Vec2i & pos,CUnit * dest,int spellid,int flush,int z)707 void SendCommandSpellCast(CUnit &unit, const Vec2i &pos, CUnit *dest, int spellid, int flush, int z)
708 {
709 if (!IsNetworkGame()) {
710 CommandLog("spell-cast", &unit, flush, pos.x, pos.y, dest, nullptr, spellid);
711 CommandSpellCast(unit, pos, dest, *CSpell::Spells[spellid], flush, z);
712 } else {
713 NetworkSendCommand(MessageCommandSpellCast + spellid,
714 unit, pos.x, pos.y, dest, nullptr, flush);
715 }
716 }
717
718 /**
719 ** Send command: Unit auto spell cast.
720 **
721 ** @param unit pointer to unit.
722 ** @param spellid Spell type id.
723 ** @param on 1 for auto cast on, 0 for off.
724 */
SendCommandAutoSpellCast(CUnit & unit,int spellid,int on)725 void SendCommandAutoSpellCast(CUnit &unit, int spellid, int on)
726 {
727 if (!IsNetworkGame()) {
728 CommandLog("auto-spell-cast", &unit, FlushCommands, on, -1, NoUnitP, nullptr, spellid);
729 CommandAutoSpellCast(unit, spellid, on);
730 } else {
731 NetworkSendCommand(MessageCommandSpellCast + spellid,
732 unit, on, -1, NoUnitP, nullptr, FlushCommands);
733 }
734 }
735
736 /**
737 ** Send command: Diplomacy changed.
738 **
739 ** @param player Player which changes his state.
740 ** @param state New diplomacy state.
741 ** @param opponent Opponent.
742 */
SendCommandDiplomacy(int player,int state,int opponent)743 void SendCommandDiplomacy(int player, int state, int opponent)
744 {
745 if (!IsNetworkGame()) {
746 switch (state) {
747 case DiplomacyNeutral:
748 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
749 NoUnitP, "neutral", -1);
750 break;
751 case DiplomacyAllied:
752 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
753 NoUnitP, "allied", -1);
754 break;
755 case DiplomacyEnemy:
756 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
757 NoUnitP, "enemy", -1);
758 break;
759 //Wyrmgus start
760 case DiplomacyOverlord:
761 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
762 NoUnitP, "overlord", -1);
763 break;
764 case DiplomacyVassal:
765 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
766 NoUnitP, "vassal", -1);
767 break;
768 //Wyrmgus end
769 case DiplomacyCrazy:
770 CommandLog("diplomacy", NoUnitP, 0, player, opponent,
771 NoUnitP, "crazy", -1);
772 break;
773 }
774 CommandDiplomacy(player, state, opponent);
775 } else {
776 NetworkSendExtendedCommand(ExtendedMessageDiplomacy,
777 -1, player, state, opponent, 0);
778 }
779 }
780
781 /**
782 ** Send command: Shared vision changed.
783 **
784 ** @param player Player which changes his state.
785 ** @param state New shared vision state.
786 ** @param opponent Opponent.
787 */
SendCommandSharedVision(int player,bool state,int opponent)788 void SendCommandSharedVision(int player, bool state, int opponent)
789 {
790 if (!IsNetworkGame()) {
791 if (state == false) {
792 CommandLog("shared-vision", NoUnitP, 0, player, opponent,
793 NoUnitP, "0", -1);
794 } else {
795 CommandLog("shared-vision", NoUnitP, 0, player, opponent,
796 NoUnitP, "1", -1);
797 }
798 CommandSharedVision(player, state, opponent);
799 } else {
800 NetworkSendExtendedCommand(ExtendedMessageSharedVision,
801 -1, player, state, opponent, 0);
802 }
803 }
804
805 //Wyrmgus start
806 /**
807 ** Send command: Faction changed.
808 **
809 ** @param player Player which changes his faction.
810 ** @param faction New faction.
811 */
SendCommandSetFaction(int player,int faction)812 void SendCommandSetFaction(int player, int faction)
813 {
814 if (!IsNetworkGame()) {
815 //FIXME: should add log of faction change here
816 if (faction != -1) {
817 Players[player].SetFaction(PlayerRaces.Factions[faction]);
818 } else {
819 Players[player].SetFaction(nullptr);
820 }
821 } else {
822 NetworkSendExtendedCommand(ExtendedMessageSetFaction, -1, player, faction, 0, 0);
823 }
824 }
825 //Wyrmgus end
826
827 /**
828 ** Send command: Toggle resource autosell.
829 **
830 ** @param player Player which toggles the resource autosell.
831 ** @param resource The resource.
832 */
SendCommandAutosellResource(int player,int resource)833 void SendCommandAutosellResource(int player, int resource)
834 {
835 if (!IsNetworkGame()) {
836 Players[player].AutosellResource(resource);
837 } else {
838 NetworkSendExtendedCommand(ExtendedMessageAutosellResource, -1, player, resource, 0, 0);
839 }
840 }
841
842 //@}
843
844 //----------------------------------------------------------------------------
845 // Parse the message, from the network.
846 //----------------------------------------------------------------------------
847
848 /**@name parse */
849 //@{
850
851 /**
852 ** Execute a command (from network).
853 **
854 ** @param msgnr Network message type
855 ** @param unum Unit number (slot) that receive the command.
856 ** @param x optional X map position.
857 ** @param y optional y map position.
858 ** @param dstnr optional destination unit.
859 */
ExecCommand(unsigned char msgnr,UnitRef unum,unsigned short x,unsigned short y,UnitRef dstnr)860 void ExecCommand(unsigned char msgnr, UnitRef unum,
861 unsigned short x, unsigned short y, UnitRef dstnr)
862 {
863 CUnit &unit = UnitManager.GetSlotUnit(unum);
864 const Vec2i pos(x, y);
865 const int arg1 = x;
866 const int arg2 = y;
867 //
868 // Check if unit is already killed?
869 //
870 if (unit.Destroyed) {
871 DebugPrint(" destroyed unit skipping %d\n" _C_ UnitNumber(unit));
872 return;
873 }
874 Assert(unit.Type);
875
876 const int status = (msgnr & 0x80) >> 7;
877 // Note: destroyed destination unit is handled by the action routines.
878
879 switch (msgnr & 0x7F) {
880 case MessageSync:
881 return;
882 case MessageQuit:
883 return;
884 case MessageChat:
885 return;
886
887 case MessageCommandStop:
888 CommandLog("stop", &unit, FlushCommands, -1, -1, NoUnitP, nullptr, -1);
889 CommandStopUnit(unit);
890 break;
891 case MessageCommandStand:
892 CommandLog("stand-ground", &unit, status, -1, -1, NoUnitP, nullptr, -1);
893 CommandStandGround(unit, status);
894 break;
895 case MessageCommandDefend: {
896 if (dstnr != (unsigned short)0xFFFF) {
897 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
898 Assert(dest.Type);
899 CommandLog("defend", &unit, status, -1, -1, &dest, nullptr, -1);
900 CommandDefend(unit, dest, status);
901 }
902 break;
903 }
904 case MessageCommandFollow: {
905 if (dstnr != (unsigned short)0xFFFF) {
906 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
907 Assert(dest.Type);
908 CommandLog("follow", &unit, status, -1, -1, &dest, nullptr, -1);
909 CommandFollow(unit, dest, status);
910 }
911 break;
912 }
913 case MessageCommandMove:
914 //Wyrmgus start
915 // CommandLog("move", &unit, status, pos.x, pos.y, NoUnitP, nullptr, -1);
916 // CommandMove(unit, pos, status);
917 if (!unit.CanMove()) { //FIXME: find better way to identify whether the unit should move or set a rally point
918 CommandLog("rally-point", &unit, status, pos.x, pos.y, NoUnitP, nullptr, -1);
919 CommandRallyPoint(unit, pos);
920 } else {
921 CommandLog("move", &unit, status, pos.x, pos.y, NoUnitP, nullptr, -1);
922 CommandMove(unit, pos, status);
923 }
924 //Wyrmgus end
925 break;
926 //Wyrmgus start
927 case MessageCommandPickUp: {
928 if (dstnr != (unsigned short)0xFFFF) {
929 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
930 Assert(dest.Type);
931 CommandLog("pick-up", &unit, status, -1, -1, &dest, nullptr, -1);
932 CommandPickUp(unit, dest, status);
933 }
934 break;
935 }
936 //Wyrmgus end
937 case MessageCommandRepair: {
938 CUnit *dest = NoUnitP;
939 if (dstnr != (unsigned short)0xFFFF) {
940 dest = &UnitManager.GetSlotUnit(dstnr);
941 Assert(dest && dest->Type);
942 }
943 CommandLog("repair", &unit, status, pos.x, pos.y, dest, nullptr, -1);
944 CommandRepair(unit, pos, dest, status);
945 break;
946 }
947 case MessageCommandAutoRepair:
948 CommandLog("auto-repair", &unit, status, arg1, arg2, NoUnitP, nullptr, 0);
949 CommandAutoRepair(unit, arg1);
950 break;
951 case MessageCommandAttack: {
952 CUnit *dest = NoUnitP;
953 if (dstnr != (unsigned short)0xFFFF) {
954 dest = &UnitManager.GetSlotUnit(dstnr);
955 Assert(dest && dest->Type);
956 }
957 CommandLog("attack", &unit, status, pos.x, pos.y, dest, nullptr, -1);
958 CommandAttack(unit, pos, dest, status);
959 break;
960 }
961 case MessageCommandGround:
962 CommandLog("attack-ground", &unit, status, pos.x, pos.y, NoUnitP, nullptr, -1);
963 CommandAttackGround(unit, pos, status);
964 break;
965 //Wyrmgus start
966 case MessageCommandUse: {
967 if (dstnr != (unsigned short)0xFFFF) {
968 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
969 Assert(dest.Type);
970 CommandLog("use", &unit, status, -1, -1, &dest, nullptr, -1);
971 CommandUse(unit, dest, status);
972 }
973 break;
974 }
975 case MessageCommandTrade: {
976 if (dstnr != (unsigned short)0xFFFF) {
977 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
978 Assert(dest.Type);
979 CommandLog("trade", &unit, status, -1, -1, &dest, nullptr, -1);
980 CommandTrade(unit, dest, status);
981 }
982 break;
983 }
984 //Wyrmgus end
985 case MessageCommandPatrol:
986 CommandLog("patrol", &unit, status, pos.x, pos.y, NoUnitP, nullptr, -1);
987 CommandPatrolUnit(unit, pos, status);
988 break;
989 case MessageCommandBoard: {
990 if (dstnr != (unsigned short)0xFFFF) {
991 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
992 Assert(dest.Type);
993 CommandLog("board", &unit, status, arg1, arg2, &dest, nullptr, -1);
994 CommandBoard(unit, dest, status);
995 }
996 break;
997 }
998 case MessageCommandUnload: {
999 CUnit *dest = nullptr;
1000 if (dstnr != (unsigned short)0xFFFF) {
1001 dest = &UnitManager.GetSlotUnit(dstnr);
1002 Assert(dest && dest->Type);
1003 }
1004 CommandLog("unload", &unit, status, pos.x, pos.y, dest, nullptr, -1);
1005 CommandUnload(unit, pos, dest, status);
1006 break;
1007 }
1008 case MessageCommandBuild:
1009 CommandLog("build", &unit, status, pos.x, pos.y, NoUnitP, UnitTypes[dstnr]->Ident.c_str(), -1);
1010 CommandBuildBuilding(unit, pos, *UnitTypes[dstnr], status);
1011 break;
1012 case MessageCommandDismiss:
1013 CommandLog("dismiss", &unit, FlushCommands, arg1, -1, nullptr, nullptr, -1);
1014 CommandDismiss(unit, arg1 > 0);
1015 break;
1016 case MessageCommandResourceLoc:
1017 CommandLog("resource-loc", &unit, status, pos.x, pos.y, NoUnitP, nullptr, -1);
1018 CommandResourceLoc(unit, pos, status);
1019 break;
1020 case MessageCommandResource: {
1021 if (dstnr != (unsigned short)0xFFFF) {
1022 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
1023 Assert(dest.Type);
1024 CommandLog("resource", &unit, status, -1, -1, &dest, nullptr, -1);
1025 CommandResource(unit, dest, status);
1026 }
1027 break;
1028 }
1029 case MessageCommandReturn: {
1030 CUnit *dest = (dstnr != (unsigned short)0xFFFF) ? &UnitManager.GetSlotUnit(dstnr) : nullptr;
1031 CommandLog("return", &unit, status, -1, -1, dest, nullptr, -1);
1032 CommandReturnGoods(unit, dest, status);
1033 break;
1034 }
1035 case MessageCommandTrain:
1036 //Wyrmgus start
1037 // CommandLog("train", &unit, status, -1, -1, NoUnitP, UnitTypes[dstnr]->Ident.c_str(), -1);
1038 // CommandTrainUnit(unit, *UnitTypes[dstnr], status);
1039 CommandLog("train", &unit, status, -1, -1, NoUnitP, UnitTypes[dstnr]->Ident.c_str(), arg1); // use X as a way to mark the player
1040 CommandTrainUnit(unit, *UnitTypes[dstnr], arg1, status);
1041 //Wyrmgus end
1042 break;
1043 case MessageCommandCancelTrain:
1044 // We need (short)x for the last slot -1
1045 if (dstnr != (unsigned short)0xFFFF) {
1046 CommandLog("cancel-train", &unit, FlushCommands, -1, -1, NoUnitP,
1047 UnitTypes[dstnr]->Ident.c_str(), (short)x);
1048 CommandCancelTraining(unit, (short)x, UnitTypes[dstnr]);
1049 } else {
1050 CommandLog("cancel-train", &unit, FlushCommands, -1, -1, NoUnitP, nullptr, (short)x);
1051 CommandCancelTraining(unit, (short)x, nullptr);
1052 }
1053 break;
1054 case MessageCommandUpgrade:
1055 //Wyrmgus start
1056 /*
1057 CommandLog("upgrade-to", &unit, status, -1, -1, NoUnitP,
1058 UnitTypes[dstnr]->Ident.c_str(), -1);
1059 CommandUpgradeTo(unit, *UnitTypes[dstnr], status);
1060 break;
1061 */
1062 if (arg1 == 2) { //use X as a way to mark whether this is an upgrade or a transformation
1063 CommandLog("transform-into", &unit, status, -1, -1, NoUnitP,
1064 UnitTypes[dstnr]->Ident.c_str(), -1);
1065 CommandTransformIntoType(unit, *UnitTypes[dstnr]);
1066 } else {
1067 CommandLog("upgrade-to", &unit, status, -1, -1, NoUnitP,
1068 UnitTypes[dstnr]->Ident.c_str(), -1);
1069 CommandUpgradeTo(unit, *UnitTypes[dstnr], status);
1070 }
1071 break;
1072 //Wyrmgus end
1073 case MessageCommandCancelUpgrade:
1074 CommandLog("cancel-upgrade-to", &unit, FlushCommands, -1, -1, NoUnitP, nullptr, -1);
1075 CommandCancelUpgradeTo(unit);
1076 break;
1077 case MessageCommandResearch:
1078 CommandLog("research", &unit, status, -1, -1, NoUnitP,
1079 //Wyrmgus start
1080 // AllUpgrades[arg1]->Ident.c_str(), -1);
1081 AllUpgrades[arg1]->Ident.c_str(), arg2);
1082 //Wyrmgus end
1083 //Wyrmgus start
1084 // CommandResearch(unit, *AllUpgrades[arg1], status);
1085 CommandResearch(unit, *AllUpgrades[arg1], arg2, status);
1086 //Wyrmgus end
1087 break;
1088 case MessageCommandCancelResearch:
1089 CommandLog("cancel-research", &unit, FlushCommands, -1, -1, NoUnitP, nullptr, -1);
1090 CommandCancelResearch(unit);
1091 break;
1092 //Wyrmgus start
1093 case MessageCommandLearnAbility:
1094 CommandLog("learn-ability", &unit, 0, -1, -1, NoUnitP,
1095 AllUpgrades[arg1]->Ident.c_str(), -1);
1096 CommandLearnAbility(unit, *AllUpgrades[arg1]);
1097 break;
1098 case MessageCommandQuest: {
1099 CommandLog("quest", &unit, 0, 0, 0, NoUnitP, Quests[arg1]->Ident.c_str(), -1);
1100 CommandQuest(unit, Quests[arg1]);
1101 break;
1102 }
1103 case MessageCommandBuy: {
1104 if (dstnr != (unsigned short)0xFFFF) {
1105 CUnit &dest = UnitManager.GetSlotUnit(dstnr);
1106 Assert(dest.Type);
1107 CommandLog("buy", &unit, 0, -1, -1, &dest, nullptr, arg1);
1108 CommandBuy(unit, &dest, arg1);
1109 }
1110 break;
1111 }
1112 case MessageCommandProduceResource: {
1113 CommandLog("produce-resource", &unit, 0, 0, -1, NoUnitP, nullptr, arg1);
1114 CommandProduceResource(unit, arg1);
1115 break;
1116 }
1117 case MessageCommandSellResource: {
1118 CommandLog("sell-resource", &unit, 0, arg1, -1, NoUnitP, nullptr, arg2);
1119 CommandSellResource(unit, arg1, arg2);
1120 break;
1121 }
1122 case MessageCommandBuyResource: {
1123 CommandLog("buy-resource", &unit, 0, arg1, -1, NoUnitP, nullptr, arg2);
1124 CommandBuyResource(unit, arg1, arg2);
1125 break;
1126 }
1127 //Wyrmgus end
1128 default: {
1129 int id = (msgnr & 0x7f) - MessageCommandSpellCast;
1130 if (arg2 != (unsigned short)0xFFFF) {
1131 CUnit *dest = nullptr;
1132 if (dstnr != (unsigned short)0xFFFF) {
1133 dest = &UnitManager.GetSlotUnit(dstnr);
1134 Assert(dest && dest->Type);
1135 }
1136 CommandLog("spell-cast", &unit, status, pos.x, pos.y, dest, nullptr, id);
1137 CommandSpellCast(unit, pos, dest, *CSpell::Spells[id], status);
1138 } else {
1139 CommandLog("auto-spell-cast", &unit, status, arg1, -1, NoUnitP, nullptr, id);
1140 CommandAutoSpellCast(unit, id, arg1);
1141 }
1142 break;
1143 }
1144 }
1145 }
1146
GetDiplomacyName(enum _diplomacy_ e)1147 static const char *GetDiplomacyName(enum _diplomacy_ e)
1148 {
1149 Assert(int(e) < 4);
1150 const char *diplomacyNames[] = {"allied", "neutral", "enemy", "crazy"};
1151
1152 return diplomacyNames[int(e)];
1153 }
1154
1155 /**
1156 ** Execute an extended command (from network).
1157 **
1158 ** @param type Network extended message type
1159 ** @param status Bit 7 of message type
1160 ** @param arg1 Messe argument 1
1161 ** @param arg2 Messe argument 2
1162 ** @param arg3 Messe argument 3
1163 ** @param arg4 Messe argument 4
1164 */
ExecExtendedCommand(unsigned char type,int status,unsigned char arg1,unsigned short arg2,unsigned short arg3,unsigned short arg4)1165 void ExecExtendedCommand(unsigned char type, int status,
1166 unsigned char arg1, unsigned short arg2, unsigned short arg3,
1167 unsigned short arg4)
1168 {
1169 // Note: destroyed units are handled by the action routines.
1170
1171 switch (type) {
1172 case ExtendedMessageDiplomacy: {
1173 const char *diplomacyName = GetDiplomacyName(_diplomacy_(arg3));
1174 CommandLog("diplomacy", NoUnitP, 0, arg2, arg4, NoUnitP, diplomacyName, -1);
1175 CommandDiplomacy(arg2, arg3, arg4);
1176 break;
1177 }
1178 case ExtendedMessageSharedVision:
1179 if (arg3 == 0) {
1180 CommandLog("shared-vision", NoUnitP, 0, arg2, arg4, NoUnitP, "0", -1);
1181 } else {
1182 CommandLog("shared-vision", NoUnitP, 0, arg2, arg4, NoUnitP, "1", -1);
1183 }
1184 CommandSharedVision(arg2, arg3 ? true : false, arg4);
1185 break;
1186 //Wyrmgus start
1187 case ExtendedMessageSetFaction: {
1188 //FIXME: should add log for faction change here
1189 Players[arg2].SetFaction(PlayerRaces.Factions[arg3]);
1190 break;
1191 }
1192 case ExtendedMessageAutosellResource: {
1193 Players[arg2].AutosellResource(arg3);
1194 break;
1195 }
1196 //Wyrmgus end
1197 default:
1198 DebugPrint("Unknown extended message %u/%s %u %u %u %u\n" _C_
1199 type _C_ status ? "flush" : "-" _C_
1200 arg1 _C_ arg2 _C_ arg3 _C_ arg4);
1201 break;
1202 }
1203 }
1204
1205 //@}
1206