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 #ifndef __UNIT_H__
00029 #define __UNIT_H__
00030
00032
00033
00034
00035
00036
00340
00341
00342
00343
00344 #include <vector>
00345 #include "SDL.h"
00346 #include "upgrade_structs.h"
00347
00348
00349
00350
00351
00352 class CUnit;
00353 class CUnitType;
00354 class CUnitStats;
00355 class CPlayer;
00356 class SpellType;
00357 class CUnitColors;
00358 class CConstructionFrame;
00359 class CVariable;
00360 class CBuildRestrictionOnTop;
00361 class CFile;
00362 struct lua_State;
00363 class CViewport;
00364 class CAnimation;
00365
00367 extern void SelectedUnitChanged(void);
00368
00372 typedef unsigned short UnitRef;
00373
00381 typedef enum _unit_action_ {
00382 UnitActionNone,
00383
00384 UnitActionStill,
00385 UnitActionStandGround,
00386 UnitActionFollow,
00387 UnitActionMove,
00388 UnitActionAttack,
00389 UnitActionAttackGround,
00390 UnitActionDie,
00391
00392 UnitActionSpellCast,
00393
00394 UnitActionTrain,
00395 UnitActionBuilt,
00396
00397
00398 UnitActionBoard,
00399 UnitActionUnload,
00400 UnitActionPatrol,
00401 UnitActionBuild,
00402
00403 UnitActionRepair,
00404 UnitActionResource,
00405 } UnitAction;
00406
00410 class COrder {
00411 public:
00412 COrder() : Action(UnitActionNone), Range(0), MinRange(0), Width(0),
00413 Height(0), Goal(NULL), X(-1), Y(-1), Type(NULL)
00414 {
00415 memset(&Arg1, 0, sizeof(Arg1));
00416 };
00417
00418 void Init() {
00419 Action = UnitActionNone;
00420 Range = 0;
00421 MinRange = 0;
00422 Width = 0;
00423 Height = 0;
00424 Assert(!Goal);
00425 X = -1; Y = -1;
00426 Type = NULL;
00427 memset(&Arg1, 0, sizeof(Arg1));
00428 };
00429
00430 unsigned char Action;
00431 int Range;
00432 unsigned int MinRange;
00433 unsigned char Width;
00434 unsigned char Height;
00435
00436 CUnit *Goal;
00437 int X;
00438 int Y;
00439 CUnitType *Type;
00440
00441 union {
00442 struct {
00443 int X;
00444 int Y;
00445 } Patrol;
00446 SpellType *Spell;
00447 } Arg1;
00448 };
00449
00453 enum UnitVoiceGroup {
00454 VoiceSelected,
00455 VoiceAcknowledging,
00456 VoiceReady,
00457 VoiceHelpMe,
00458 VoiceDying,
00459 VoiceWorkCompleted,
00460 VoiceBuilding,
00461 VoiceDocking,
00462 VoiceRepairing,
00463 VoiceHarvesting,
00464 };
00465
00474 enum _directions_ {
00475 LookingN = 0 * 32,
00476 LookingNE = 1 * 32,
00477 LookingE = 2 * 32,
00478 LookingSE = 3 * 32,
00479 LookingS = 4 * 32,
00480 LookingSW = 5 * 32,
00481 LookingW = 6 * 32,
00482 LookingNW = 7 * 32,
00483 };
00484
00485 #define NextDirection 32
00486 #define UnitNotSeen 0x7fffffff
00487
00489 class CUnit {
00490 public:
00491 CUnit() { Init(); }
00492
00493 void Init() {
00494 Refs = 0;
00495 Slot = 0;
00496 UnitSlot = NULL;
00497 PlayerSlot = NULL;
00498 Next = NULL;
00499 InsideCount = 0;
00500 BoardCount = 0;
00501 UnitInside = NULL;
00502 Container = NULL;
00503 NextContained = NULL;
00504 PrevContained = NULL;
00505 X = 0;
00506 Y = 0;
00507 Type = NULL;
00508 Player = NULL;
00509 Stats = NULL;
00510 CurrentSightRange = 0;
00511 Colors = NULL;
00512 IX = 0;
00513 IY = 0;
00514 Frame = 0;
00515 Direction = 0;
00516 Attacked = 0;
00517 Burning = 0;
00518 Destroyed = 0;
00519 Removed = 0;
00520 Selected = 0;
00521 TeamSelected = 0;
00522 Constructed = 0;
00523 Boarded = 0;
00524 RescuedFrom = NULL;
00525 memset(VisCount, 0, sizeof(VisCount));
00526 memset(&Seen, 0, sizeof(Seen));
00527 Variable = NULL;
00528 TTL = 0;
00529 GroupId = 0;
00530 LastGroup = 0;
00531 memset(ResourcesHeld, 0, sizeof(ResourcesHeld));
00532 ProductionEfficiency = 100;
00533 SubAction = 0;
00534 Wait = 0;
00535 State = 0;
00536 Blink = 0;
00537 Moving = 0;
00538 ReCast = 0;
00539 memset(&Anim, 0, sizeof(Anim));
00540 OrderCount = 0;
00541 OrderFlush = 0;
00542 Orders.clear();
00543 SavedOrder.Init();
00544 NewOrder.Init();
00545 AutoCastSpell = NULL;
00546 AutoRepair = 0;
00547 memset(&Data, 0, sizeof(Data));
00548 Goal = NULL;
00549 }
00550
00551
00552 unsigned long Refs;
00553 int Slot;
00554 CUnit **UnitSlot;
00555 CUnit **PlayerSlot;
00556
00557 CUnit *Next;
00558
00559 int InsideCount;
00560 int BoardCount;
00561 CUnit *UnitInside;
00562 CUnit *Container;
00563 CUnit *NextContained;
00564 CUnit *PrevContained;
00565
00566 int X;
00567 int Y;
00568
00569 CUnitType *Type;
00570 CPlayer *Player;
00571 CUnitStats *Stats;
00572 int CurrentSightRange;
00573
00574
00575 CUnitColors *Colors;
00576 signed char IX;
00577 signed char IY;
00578 int Frame;
00579
00580 unsigned Direction : 8;
00581
00582 unsigned long Attacked;
00583
00584 unsigned Burning : 1;
00585 unsigned Destroyed : 1;
00586 unsigned Removed : 1;
00587 unsigned Selected : 1;
00588
00589 unsigned Constructed : 1;
00590 unsigned Boarded : 1;
00591 unsigned TeamSelected;
00592 CPlayer *RescuedFrom;
00593
00594
00595 int VisCount[PlayerMax];
00596 struct _unit_seen_ {
00597 unsigned ByPlayer : PlayerMax;
00598 int Frame;
00599 CUnitType *Type;
00600 int X;
00601 int Y;
00602 signed char IX;
00603 signed char IY;
00604 unsigned Constructed : 1;
00605 unsigned State : 3;
00606 unsigned Destroyed : PlayerMax;
00607 CConstructionFrame *CFrame;
00608 } Seen;
00609
00610 CVariable *Variable;
00611
00612 unsigned long TTL;
00613
00614 int GroupId;
00615 int LastGroup;
00616
00617 int ResourcesHeld[MaxCosts];
00618 unsigned ProductionEfficiency : 8;
00619
00620 unsigned SubAction : 8;
00621 unsigned Wait;
00622 unsigned State : 8;
00623 unsigned Blink : 3;
00624 unsigned Moving : 1;
00625 unsigned ReCast : 1;
00626
00627 struct _unit_anim_ {
00628 const CAnimation *Anim;
00629 const CAnimation *CurrAnim;
00630 int Wait;
00631 int Unbreakable;
00632 } Anim;
00633
00634 char OrderCount;
00635 char OrderFlush;
00636 std::vector<COrder *> Orders;
00637 COrder SavedOrder;
00638 COrder NewOrder;
00639 char *AutoCastSpell;
00640 unsigned AutoRepair : 1;
00641
00642 union _order_data_ {
00643 struct _order_move_ {
00644 char Fast;
00645 char Length;
00646 #define MAX_PATH_LENGTH 28
00647 char Path[MAX_PATH_LENGTH];
00648 } Move;
00649 struct _order_built_ {
00650 CUnit *Worker;
00651 int Progress;
00652 int Cancel;
00653 CConstructionFrame *Frame;
00654 } Built;
00655 struct _order_harvest_ {
00656 int CurrentProduction[MaxCosts];
00657 } Harvest;
00658 struct _order_train_ {
00659 int Ticks;
00660 } Train;
00661 struct _order_repair_ {
00662 int Progress;
00663 } Repair;
00664 } Data;
00665
00666 CUnit *Goal;
00667
00668
00669 inline bool IsIdle() const {
00670 return Orders[0]->Action == UnitActionStill && OrderCount == 1;
00671 }
00672
00673 inline void ClearAction() {
00674 Orders[0]->Action = UnitActionStill;
00675 SubAction = 0;
00676 if (Selected) {
00677 SelectedUnitChanged();
00678 }
00679 }
00680
00682 void RefsIncrease();
00684 void RefsDecrease();
00685
00687 void Init(CUnitType *type);
00689 void AssignToPlayer(CPlayer *player);
00690
00692 void Draw() const;
00694 void Place(int x, int y);
00695
00697 void MoveToXY(int x, int y);
00699 void AddInContainer(CUnit *host);
00701 void ChangeOwner(CPlayer *newplayer);
00702
00704 void Remove(CUnit *host);
00706 void Release();
00707
00709 bool IsVisible(const CPlayer *player) const;
00711 bool IsVisibleAsGoal(const CPlayer *player) const;
00713 bool IsAliveOnMap() const;
00715 bool IsVisibleOnMap(const CPlayer *player) const;
00717 bool IsVisibleOnMinimap() const;
00719 bool IsVisibleInViewport(const CViewport *vp) const;
00721 bool IsVisibleOnScreen() const;
00722
00724 void GetMapArea(int *sx, int *sy, int *ex, int *ey) const;
00725
00726 bool IsEnemy(const CPlayer *x) const;
00727 bool IsEnemy(const CUnit *x) const;
00728 bool IsAllied(const CPlayer *x) const;
00729 bool IsAllied(const CUnit *x) const;
00730 bool IsSharedVision(const CPlayer *x) const;
00731 bool IsSharedVision(const CUnit *x) const;
00732 bool IsBothSharedVision(const CPlayer *x) const;
00733 bool IsBothSharedVision(const CUnit *x) const;
00734 bool IsTeamed(const CPlayer *x) const;
00735 bool IsTeamed(const CUnit *x) const;
00736
00737 bool IsUnusable() const;
00738 };
00739
00740 #define NoUnitP (CUnit *)0
00741 #define InfiniteDistance INT_MAX
00742
00743 #define FlushCommands 1
00744
00745 #define MAX_UNIT_SLOTS 65535
00746
00747
00750 #define UnitNumber(unit) ((unit)->Slot)
00751
00755 #define NUM_GROUPS 10
00756
00760 class CPreference {
00761 public:
00762 CPreference() : ShowSightRange(false), ShowReactionRange(false),
00763 ShowAttackRange(false), ShowOrders(0) {};
00764
00765 bool ShowSightRange;
00766 bool ShowReactionRange;
00767 bool ShowAttackRange;
00768 int ShowOrders;
00769 };
00770
00771 extern CPreference Preference;
00772
00773
00774
00775
00776
00777 extern CUnit *Units[MAX_UNIT_SLOTS];
00778 extern int NumUnits;
00779
00780
00782 extern unsigned long ShowOrdersCount;
00783 extern bool EnableBuildingCapture;
00784 extern const CViewport *CurrentViewport;
00785 extern void DrawUnitSelection(const CUnit *);
00786 extern void DrawSelection(Uint32 color, int x1, int y1, int x2, int y2);
00787 extern int MaxSelectable;
00788
00789 extern CUnit **Selected;
00790 extern CUnit **TeamSelected[PlayerMax];
00791 extern int NumSelected;
00792 extern int TeamNumSelected[PlayerMax];
00793
00794
00795
00796
00797
00799 void MarkUnitFieldFlags(const CUnit *unit);
00801 void UnmarkUnitFieldFlags(const CUnit *unit);
00803 void UpdateUnitSightRange(CUnit *unit);
00805 extern CUnit *MakeUnit(CUnitType *type, CPlayer *player);
00807 extern CUnit *MakeUnitAndPlace(int x, int y, CUnitType *type, CPlayer *player);
00809 extern void UnitLost(CUnit *unit);
00811 extern void UnitClearOrders(CUnit *unit);
00813 extern void UpdateForNewUnit(const CUnit *unit, int upgrade);
00815 extern void NearestOfUnit(const CUnit *unit, int tx, int ty, int *dx, int *dy);
00816
00818 extern void UnitGoesUnderFog(CUnit *unit, const CPlayer *player);
00820 extern void UnitGoesOutOfFog(CUnit *unit, const CPlayer *player);
00822 extern void UnitsOnTileMarkSeen(const CPlayer *player, int x, int y);
00824 extern void UnitsOnTileUnmarkSeen(const CPlayer *player, int x, int y);
00826 extern void UnitCountSeen(CUnit *unit);
00827
00829 extern void RescueUnits(void);
00830
00832 extern int DirectionToHeading(int, int);
00834 extern void UnitUpdateHeading(CUnit *unit);
00836 extern void UnitHeadingFromDeltaXY(CUnit *unit, int x, int y);
00837
00839 extern void DropOutOnSide(CUnit *unit, int heading, int addx, int addy);
00841 extern void DropOutNearest(CUnit *unit, int x, int y, int addx, int addy);
00843 extern void DropOutAll(const CUnit *unit);
00844
00846 extern CBuildRestrictionOnTop *OnTopDetails(const CUnit *unit, const CUnitType *parent);
00848 extern CUnit *CanBuildHere(const CUnit *unit, const CUnitType *type, int x, int y);
00850 extern bool CanBuildOn(int x, int y, int mask);
00852 extern CUnit *CanBuildUnitType(const CUnit *unit, const CUnitType *type, int x, int y, int real);
00853
00855 extern bool UnitHoldsResources(const CUnit *unit);
00857 extern CUnit *UnitFindResource(const CUnit *unit, int x, int y, int range, int resource = -1);
00859 extern CUnit *FindIdleWorker(const CPlayer *player);
00860
00862 extern CUnit *UnitOnScreen(int x, int y);
00864 extern void UnitRemoveConsumingResources(CUnit *unit);
00865
00867 extern void LetUnitDie(CUnit *unit);
00869 extern void DestroyAllInside(CUnit *source);
00871 extern void HitUnit(CUnit *attacker, CUnit *target, int damage);
00872
00874 extern int MapDistance(int x1, int y1, int x2, int y2);
00876 extern int MapDistanceToType(int x1, int y1, const CUnitType *type, int x2, int y2);
00878 extern int MapDistanceToUnit(int x, int y, const CUnit *dest);
00880 extern int MapDistanceBetweenTypes(const CUnitType *src, int x1, int y1, const CUnitType *dst, int x2, int y2);
00882 extern int MapDistanceBetweenUnits(const CUnit *src, const CUnit *dst);
00883
00885 extern int ViewPointDistance(int x, int y);
00887 extern int ViewPointDistanceToUnit(const CUnit *dest);
00888
00890 extern int CanTarget(const CUnitType *type, const CUnitType *dest);
00892 extern int CanTransport(const CUnit *transporter, const CUnit *unit);
00893
00895 extern bool CanMove(const CUnit *unit);
00896
00898 extern std::string UnitReference(const CUnit *unit);
00900 extern void SaveOrder(const COrder *order, CFile *file);
00902 extern void SaveUnit(const CUnit *unit, CFile *file);
00904 extern void SaveUnits(CFile *file);
00905
00907 extern void InitUnits(void);
00909 extern void CleanUnits(void);
00910
00911
00913 extern void DecorationCclRegister(void);
00915 extern void LoadDecorations(void);
00917 extern void CleanDecorations(void);
00918
00920 extern void DrawShadow(const CUnit *unit, const CUnitType *type,
00921 int frame, int x, int y);
00923 extern int FindAndSortUnits(const CViewport *vp, CUnit **table, int tablesize);
00925 extern void ShowOrder(const CUnit *unit);
00926
00927
00929 extern int FindUnitsByType(const CUnitType *type, CUnit **table, int tablesize);
00931 extern int FindPlayerUnitsByType(const CPlayer *, const CUnitType *, CUnit **, int);
00933 extern CUnit *UnitOnMapTile(int tx, int ty, unsigned type = (unsigned)-1);
00935 extern CUnit *TargetOnMap(const CUnit *unit, int x1, int y1, int x2, int y2);
00936
00938 extern CUnit *ResourceOnMap(int tx, int ty, int resource = -1);
00939
00941 extern CUnit *AttackUnitsInDistance(const CUnit *unit, int range);
00943 extern CUnit *AttackUnitsInRange(const CUnit *unit);
00945 extern CUnit *AttackUnitsInReactRange(const CUnit *unit);
00946
00947
00949 extern void InitGroups(void);
00951 extern void SaveGroups(CFile *file);
00953 extern void CleanGroups(void);
00954
00955
00957 extern int GetNumberUnitsOfGroup(int num);
00959 extern CUnit **GetUnitsOfGroup(int num);
00960
00962 extern void ClearGroup(int num);
00964 extern void AddToGroup(CUnit **units, int nunits, int num);
00966 extern void SetGroup(CUnit **units, int nunits, int num);
00968 extern void RemoveUnitFromGroups(CUnit *unit);
00970 extern void GroupCclRegister(void);
00971
00972
00974 #define IsOnlySelected(unit) (NumSelected == 1 && Selected[0] == (unit))
00975
00977 extern void SaveSelection(void);
00979 extern void RestoreSelection(void);
00981 extern void UnSelectAll(void);
00983 extern void ChangeSelectedUnits(CUnit **units, int num_units);
00985 extern void ChangeTeamSelectedUnits(CPlayer *player, CUnit **units, int adjust, int count);
00987 extern int SelectUnit(CUnit *unit);
00989 extern void SelectSingleUnit(CUnit *unit);
00991 extern void UnSelectUnit(CUnit *unit);
00993 extern int ToggleSelectUnit(CUnit *unit);
00995 extern int SelectUnitsByType(CUnit *base);
00997 extern int ToggleUnitsByType(CUnit *base);
00999 extern int SelectGroup(int group_number);
01001 extern int AddGroupFromUnitToSelection(CUnit *unit);
01003 extern int SelectGroupFromUnit(CUnit *unit);
01005 extern int SelectUnitsInRectangle(int tx, int ty, int w, int h);
01007 extern int SelectGroundUnitsInRectangle(int tx, int ty, int w, int h);
01009 extern int SelectAirUnitsInRectangle(int tx, int ty, int w, int h);
01011 extern int AddSelectedUnitsInRectangle(int tx, int ty, int w, int h);
01013 extern int AddSelectedGroundUnitsInRectangle(int tx, int ty, int w, int h);
01015 extern int AddSelectedAirUnitsInRectangle(int tx, int ty, int w, int h);
01016
01018 extern void InitSelections(void);
01020 extern void SaveSelections(CFile *file);
01022 extern void CleanSelections(void);
01024 extern void SelectionCclRegister(void);
01025
01026
01028 extern void CclParseOrder(lua_State *l, COrder *order);
01030 extern void UnitCclRegister(void);
01031
01033
01034 #endif // !__UNIT_H__