ScummVM API documentation
group.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22/*
23 * Based on the Reverse Engineering work of Christophe Fontanel,
24 * maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/)
25 */
26
27#ifndef DM_GROUP_H
28#define DM_GROUP_H
29
30#include "dm/dm.h"
31#include "dm/sounds.h"
32#include "dm/timeline.h"
33
34namespace DM {
35 class Champion;
36 class TimelineEvent;
37 class CreatureInfo;
38
39/* Creature types */
40enum CreatureType : uint16 {
41 kDMCreatureTypeGiantScorpion = 0, // @ C00_CREATURE_GIANT_SCORPION_SCORPION
42 kDMCreatureTypeSwampSlime = 1, // @ C01_CREATURE_SWAMP_SLIME_SLIME_DEVIL
43 kDMCreatureTypeGiggler = 2, // @ C02_CREATURE_GIGGLER
44 kDMCreatureTypeWizardEye = 3, // @ C03_CREATURE_WIZARD_EYE_FLYING_EYE
45 kDMCreatureTypePainRat = 4, // @ C04_CREATURE_PAIN_RAT_HELLHOUND
46 kDMCreatureTypeRuster = 5, // @ C05_CREATURE_RUSTER
47 kDMCreatureTypeScreamer = 6, // @ C06_CREATURE_SCREAMER
48 kDMCreatureTypeRockpile = 7, // @ C07_CREATURE_ROCK_ROCKPILE
49 kDMCreatureTypeGhostRive = 8, // @ C08_CREATURE_GHOST_RIVE
50 kDMCreatureTypeStoneGolem = 9, // @ C09_CREATURE_STONE_GOLEM
51 kDMCreatureTypeMummy = 10, // @ C10_CREATURE_MUMMY
52 kDMCreatureTypeBlackFlame = 11, // @ C11_CREATURE_BLACK_FLAME
53 kDMCreatureTypeSkeleton = 12, // @ C12_CREATURE_SKELETON
54 kDMCreatureTypeCouatl = 13, // @ C13_CREATURE_COUATL
55 kDMCreatureTypeVexirk = 14, // @ C14_CREATURE_VEXIRK
56 kDMCreatureTypeMagentaWorm = 15, // @ C15_CREATURE_MAGENTA_WORM_WORM
57 kDMCreatureTypeAntman = 16, // @ C16_CREATURE_TROLIN_ANTMAN
58 kDMCreatureTypeGiantWasp = 17, // @ C17_CREATURE_GIANT_WASP_MUNCHER
59 kDMCreatureTypeAnimatedArmour = 18, // @ C18_CREATURE_ANIMATED_ARMOUR_DETH_KNIGHT
60 kDMCreatureTypeMaterializerZytaz = 19, // @ C19_CREATURE_MATERIALIZER_ZYTAZ
61 kDMCreatureTypeWaterElemental = 20, // @ C20_CREATURE_WATER_ELEMENTAL
62 kDMCreatureTypeOitu = 21, // @ C21_CREATURE_OITU
63 kDMCreatureTypeDemon = 22, // @ C22_CREATURE_DEMON
64 kDMCreatureTypeLordChaos = 23, // @ C23_CREATURE_LORD_CHAOS
65 kDMCreatureTypeRedDragon = 24, // @ C24_CREATURE_RED_DRAGON
66 kDMCreatureTypeLordOrder = 25, // @ C25_CREATURE_LORD_ORDER
67 kDMCreatureTypeGreyLord = 26 // @ C26_CREATURE_GREY_LORD
68};
69
70enum CreatureSize {
71 kDMCreatureSizeQuarter = 0, // @ C0_SIZE_QUARTER_SQUARE
72 kDMCreatureSizeHalf = 1, // @ C1_SIZE_HALF_SQUARE
73 kDMCreatureSizeFull = 2 // @ C2_SIZE_FULL_SQUARE
74};
75
76enum Behavior {
77 kDMBehaviorWander = 0, // @ C0_BEHAVIOR_WANDER
78 kDMBehaviorUnknown2 = 2, // @ C2_BEHAVIOR_USELESS
79 kDMBehaviorUnknown3 = 3, // @ C3_BEHAVIOR_USELESS
80 kDMBehaviorUnknown4 = 4, // @ C4_BEHAVIOR_USELESS
81 kDMBehaviorFlee = 5, // @ C5_BEHAVIOR_FLEE
82 kDMBehaviorAttack = 6, // @ C6_BEHAVIOR_ATTACK
83 kDMBehaviorApproach = 7 // @ C7_BEHAVIOR_APPROACH
84};
85
86#define kDMImmuneToFear 15 // @ C15_IMMUNE_TO_FEAR
87#define kDMMovementTicksImmobile 255 // @ C255_IMMOBILE
88#define kDMWholeCreatureGroup -1 // @ CM1_WHOLE_CREATURE_GROUP
89#define kDMCreatureTypeSingleCenteredCreature 255 // @ C255_SINGLE_CENTERED_CREATURE
90
91enum CreatureMask {
92 kDMCreatureMaskSize = 0x0003, // @ MASK0x0003_SIZE
93 kDMCreatureMaskSideAttack = 0x0004, // @ MASK0x0004_SIDE_ATTACK
94 kDMCreatureMaskPreferBackRow = 0x0008, // @ MASK0x0008_PREFER_BACK_ROW
95 kDMCreatureMaskAttackAnyChamp = 0x0010, // @ MASK0x0010_ATTACK_ANY_CHAMPION
96 kDMCreatureMaskLevitation = 0x0020, // @ MASK0x0020_LEVITATION
97 kDMCreatureMaskNonMaterial = 0x0040, // @ MASK0x0040_NON_MATERIAL
98 kDMCreatureMaskDropFixedPoss = 0x0200, // @ MASK0x0200_DROP_FIXED_POSSESSIONS
99 kDMCreatureMaskKeepThrownSharpWeapon = 0x0400, // @ MASK0x0400_KEEP_THROWN_SHARP_WEAPONS
100 kDMCreatureMaskSeeInvisible = 0x0800, // @ MASK0x0800_SEE_INVISIBLE
101 kDMCreatureMaskNightVision = 0x1000, // @ MASK0x1000_NIGHT_VISION
102 kDMCreatureMaskArchenemy = 0x2000, // @ MASK0x2000_ARCHENEMY
103 kDMCreatureMaskMagicMap = 0x4000 // @ MASK0x4000_MAGICMAP
104};
105
106enum aspectMask {
107 kDMAspectMaskActiveGroupFlipBitmap = 0x0040, // @ MASK0x0040_FLIP_BITMAP
108 kDMAspectMaskActiveGroupIsAttacking = 0x0080 // @ MASK0x0080_IS_ATTACKING
109};
110
112public:
113 int16 _groupThingIndex;
114 uint16 _directions;
115 byte _cells;
116 byte _lastMoveTime;
117 byte _delayFleeingFromTarget;
118 byte _targetMapX;
119 byte _targetMapY;
120 byte _priorMapX;
121 byte _priorMapY;
122 byte _homeMapX;
123 byte _homeMapY;
124 byte _aspect[4];
125}; // @ ACTIVE_GROUP
126
127class Group {
128public:
129 Thing _nextThing;
130 Thing _slot;
131 CreatureType _type;
132 uint16 _cells;
133 uint16 _health[4];
134 uint16 _flags;
135 Group() : _nextThing(0xFFFF), _slot(0xFFFF), _type((CreatureType)0), _cells(0), _flags(0) {
136 _health[0] = _health[1] = _health[2] = _health[3] = 0;
137 }
138
139 uint16 &getActiveGroupIndex() { return _cells; }
140
141 uint16 getBehaviour() { return _flags & 0xF; }
142 uint16 setBehaviour(uint16 val) { _flags = (_flags & ~0xF) | (val & 0xF); return (val & 0xF); }
143 uint16 getCount() { return (_flags >> 5) & 0x3; }
144 void setCount(uint16 val) { _flags = (_flags & ~(0x3 << 5)) | ((val & 0x3) << 5); }
145 Direction getDir() { return (Direction)((_flags >> 8) & 0x3); }
146 void setDir(uint16 val) { _flags = (_flags & ~(0x3 << 8)) | ((val & 0x3) << 8); }
147 uint16 getDoNotDiscard() { return (_flags >> 10) & 0x1; }
148 void setDoNotDiscard(bool val) { _flags = (_flags & ~(1 << 10)) | ((val & 1) << 10); }
149}; // @ GROUP
150
151class GroupMan {
152 DMEngine *_vm;
153 byte _dropMovingCreatureFixedPossessionsCell[4]; // @ G0392_auc_DropMovingCreatureFixedPossessionsCells
154 uint16 _dropMovingCreatureFixedPossCellCount; // @ G0391_ui_DropMovingCreatureFixedPossessionsCellCount
155 uint16 _fluxCageCount; // @ G0386_ui_FluxCageCount
156 int16 _fluxCages[4]; // @ G0385_ac_FluxCages
157 int16 _currentGroupMapX; // @ G0378_i_CurrentGroupMapX
158 int16 _currentGroupMapY; // @ G0379_i_CurrentGroupMapY
159 Thing _currGroupThing; // @ G0380_T_CurrentGroupThing
160 int16 _groupMovementTestedDirections[4]; // @ G0384_auc_GroupMovementTestedDirections
161 uint16 _currGroupDistanceToParty; // @ G0381_ui_CurrentGroupDistanceToParty
162 int16 _currGroupPrimaryDirToParty; // @ G0382_i_CurrentGroupPrimaryDirectionToParty
163 int16 _currGroupSecondaryDirToParty; // @ G0383_i_CurrentGroupSecondaryDirectionToParty
164
165 Thing _groupMovementBlockedByGroupThing; // @ G0388_T_GroupMovementBlockedByGroupThing
166 bool _groupMovementBlockedByDoor; // @ G0389_B_GroupMovementBlockedByDoor
167 bool _groupMovementBlockedByParty; // @ G0390_B_GroupMovementBlockedByParty
168 bool _groupMovBlockedByWallStairsPitFakeWalFluxCageTeleporter; // @ G0387_B_GroupMovementBlockedByWallStairsPitFakeWallFluxcageTeleporter
169 int32 twoHalfSquareSizedCreaturesGroupLastDirectionSetTime; // @ G0395_l_TwoHalfSquareSizedCreaturesGroupLastDirectionSetTime
170 uint16 toggleFlag(uint16 &val, uint16 mask); // @ M10_TOGGLE
171 int32 setTime(int32 &map_time, int32 time); // @ M32_SET_TIME
172
173public:
174 uint16 _maxActiveGroupCount; // @ G0376_ui_MaximumActiveGroupCount
175 ActiveGroup *_activeGroups; // @ G0375_ps_ActiveGroups
176 uint16 _currActiveGroupCount; // @ G0377_ui_CurrentActiveGroupCount
177 explicit GroupMan(DMEngine *vm);
178 ~GroupMan();
179
180 void initActiveGroups(); // @ F0196_GROUP_InitializeActiveGroups
181 uint16 getGroupCells(Group *group, int16 mapIndex); // @ F0145_DUNGEON_GetGroupCells
182 uint16 getGroupDirections(Group *group, int16 mapIndex); // @ F0147_DUNGEON_GetGroupDirections
183 int16 getCreatureOrdinalInCell(Group *group, uint16 cell); // @ F0176_GROUP_GetCreatureOrdinalInCell
184 uint16 getCreatureValue(uint16 groupVal, uint16 creatureIndex); // @ M50_CREATURE_VALUE
185 void dropGroupPossessions(int16 mapX, int16 mapY, Thing groupThing, SoundMode mode); // @ F0188_GROUP_DropGroupPossessions
186 void dropCreatureFixedPossessions(CreatureType creatureType, int16 mapX, int16 mapY, uint16 cell,
187 SoundMode soundMode); // @ F0186_GROUP_DropCreatureFixedPossessions
188 int16 getDirsWhereDestIsVisibleFromSource(int16 srcMapX, int16 srcMapY,
189 int16 destMapX, int16 destMapY); // @ F0228_GROUP_GetDirectionsWhereDestinationIsVisibleFromSource
190 bool isDestVisibleFromSource(uint16 dir, int16 srcMapX, int16 srcMapY, int16 destMapX,
191 int16 destMapY); // @ F0227_GROUP_IsDestinationVisibleFromSource
192 bool groupIsDoorDestoryedByAttack(uint16 mapX, uint16 mapY, int16 attack,
193 bool magicAttack, int16 ticks); // @ F0232_GROUP_IsDoorDestroyedByAttack
194 Thing groupGetThing(int16 mapX, int16 mapY); // @ F0175_GROUP_GetThing
195 int16 groupGetDamageCreatureOutcome(Group *group, uint16 creatureIndex,
196 int16 mapX, int16 mapY, int16 damage, bool notMoving); // @ F0190_GROUP_GetDamageCreatureOutcome
197 void groupDelete(int16 mapX, int16 mapY); // @ F0189_GROUP_Delete
198 void groupDeleteEvents(int16 mapX, int16 mapY); // @ F0181_GROUP_DeleteEvents
199 uint16 getGroupValueUpdatedWithCreatureValue(uint16 groupVal, uint16 creatureIndex, uint16 creatureVal); // @ F0178_GROUP_GetGroupValueUpdatedWithCreatureValue
200 int16 getDamageAllCreaturesOutcome(Group *group, int16 mapX, int16 mapY, int16 attack, bool notMoving); // @ F0191_GROUP_GetDamageAllCreaturesOutcome
201 int16 groupGetResistanceAdjustedPoisonAttack(CreatureType creatureType, int16 poisonAttack); // @ F0192_GROUP_GetResistanceAdjustedPoisonAttack
202 void processEvents29to41(int16 eventMapX, int16 eventMapY, TimelineEventType eventType, uint16 ticks); // @ F0209_GROUP_ProcessEvents29to41
203 bool isMovementPossible(CreatureInfo *creatureInfo, int16 mapX, int16 mapY,
204 uint16 dir, bool allowMovementOverImaginaryPitsAndFakeWalls); // @ F0202_GROUP_IsMovementPossible
205 int16 getDistanceBetweenSquares(int16 srcMapX, int16 srcMapY, int16 destMapX,
206 int16 destMapY); // @ F0226_GROUP_GetDistanceBetweenSquares
207
208 int16 groupGetDistanceToVisibleParty(Group *group, int16 creatureIndex, int16 mapX, int16 mapY); // @ F0200_GROUP_GetDistanceToVisibleParty
209 int16 getDistanceBetweenUnblockedSquares(int16 srcMapX, int16 srcMapY,
210 int16 destMapX, int16 destMapY, bool (GroupMan::*isBlocked)(uint16, uint16)); // @ F0199_GROUP_GetDistanceBetweenUnblockedSquares
211 bool isViewPartyBlocked(uint16 mapX, uint16 mapY); // @ F0197_GROUP_IsViewPartyBlocked
212 int32 getCreatureAspectUpdateTime(ActiveGroup *activeGroup, int16 creatureIndex,
213 bool isAttacking); // @ F0179_GROUP_GetCreatureAspectUpdateTime
214 void setGroupDirection(ActiveGroup *activeGroup, int16 dir, int16 creatureIndex, bool twoHalfSquareSizedCreatures); // @ F0205_GROUP_SetDirection
215 void addGroupEvent(TimelineEvent *event, uint32 time); // @ F0208_GROUP_AddEvent
216 int16 getSmelledPartyPrimaryDirOrdinal(CreatureInfo *creatureInfo, int16 mapX, int16 mapY); // @ F0201_GROUP_GetSmelledPartyPrimaryDirectionOrdinal
217 bool isSmellPartyBlocked(uint16 mapX, uint16 mapY); // @ F0198_GROUP_IsSmellPartyBlocked
218 int16 getFirstPossibleMovementDirOrdinal(CreatureInfo *info, int16 mapX, int16 mapY,
219 bool allowMovementOverImaginaryPitsAndFakeWalls); // @ F0203_GROUP_GetFirstPossibleMovementDirectionOrdinal
220 void setDirGroup(ActiveGroup *activeGroup, int16 dir, int16 creatureIndex,
221 int16 creatureSize); // @ F0206_GROUP_SetDirectionGroup
222 void stopAttacking(ActiveGroup *group, int16 mapX, int16 mapY);// @ F0182_GROUP_StopAttacking
223 bool isArchenemyDoubleMovementPossible(CreatureInfo *info, int16 mapX, int16 mapY, uint16 dir); // @ F0204_GROUP_IsArchenemyDoubleMovementPossible
224 bool isCreatureAttacking(Group *group, int16 mapX, int16 mapY, uint16 creatureIndex); // @ F0207_GROUP_IsCreatureAttacking
225 void setOrderedCellsToAttack(signed char *orderedCellsToAttack, int16 targetMapX,
226 int16 targetMapY, int16 attackerMapX, int16 attackerMapY, uint16 cellSource); // @ F0229_GROUP_SetOrderedCellsToAttack
227 void stealFromChampion(Group *group, uint16 championIndex); // @ F0193_GROUP_StealFromChampion
228 int16 getChampionDamage(Group *group, uint16 champIndex); // @ F0230_GROUP_GetChampionDamage
229 void dropMovingCreatureFixedPossession(Thing thing, int16 mapX, int16 mapY); // @ F0187_GROUP_DropMovingCreatureFixedPossessions
230 void startWandering(int16 mapX, int16 mapY); // @ F0180_GROUP_StartWandering
231 void addActiveGroup(Thing thing, int16 mapX, int16 mapY); // @ F0183_GROUP_AddActiveGroup
232 void removeActiveGroup(uint16 activeGroupIndex); // @ F0184_GROUP_RemoveActiveGroup
233 void removeAllActiveGroups(); // @ F0194_GROUP_RemoveAllActiveGroups
234 void addAllActiveGroups(); // @ F0195_GROUP_AddAllActiveGroups
235 Thing groupGetGenerated(CreatureType creatureType, int16 healthMultiplier, uint16 creatureCount, Direction dir, int16 mapX, int16 mapY); // @ F0185_GROUP_GetGenerated
236 bool isSquareACorridorTeleporterPitOrDoor(int16 mapX, int16 mapY); // @ F0223_GROUP_IsSquareACorridorTeleporterPitOrDoor
237 int16 getMeleeTargetCreatureOrdinal(int16 groupX, int16 groupY, int16 partyX, int16 paryY,
238 uint16 champCell); // @ F0177_GROUP_GetMeleeTargetCreatureOrdinal
239 int16 getMeleeActionDamage(Champion *champ, int16 champIndex, Group *group, int16 creatureIndex,
240 int16 mapX, int16 mapY, uint16 actionHitProbability, uint16 actionDamageFactor, int16 skillIndex); // @ F0231_GROUP_GetMeleeActionDamage
241 void fluxCageAction(int16 mapX, int16 mapY); // @ F0224_GROUP_FluxCageAction
242 uint16 isLordChaosOnSquare(int16 mapX, int16 mapY); // @ F0222_GROUP_IsLordChaosOnSquare
243 bool isFluxcageOnSquare(int16 mapX, int16 mapY); // @ F0221_GROUP_IsFluxcageOnSquare
244 void fuseAction(uint16 mapX, uint16 mapY); // @ F0225_GROUP_FuseAction
245 void saveActiveGroupPart(Common::WriteStream *file);
246 void loadActiveGroupPart(Common::SeekableReadStream *file);
247};
248}
249
250#endif
Definition: stream.h:745
Definition: stream.h:77
Definition: group.h:111
Definition: champion.h:399
Definition: dungeonman.h:304
Definition: dm.h:169
Definition: group.h:127
Definition: group.h:151
Definition: dm.h:135
Definition: timeline.h:100