Skip to content

Commit d4b2cfb

Browse files
Merge pull request #46 from justindujardin/test/feature-components
Test/feature components
2 parents ec89b52 + f5b0caf commit d4b2cfb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+6700
-316
lines changed

src/app/components/notification/notification.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ export class NotificationService implements IWorldObject, IProcessObject {
9494
};
9595
}
9696

97+
getFirst(): INotifyItem | null {
98+
return this._current || this._queue[0] || null;
99+
}
100+
97101
show(message: string, done?: () => void, duration?: number): INotifyItem {
98102
const obj: INotifyItem = {
99103
message,

src/app/models/combat/combat.reducer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,6 @@ export const sliceCombatLoading = (state: CombatStateRecord) => state.loading;
180180
/** @internal {@see sliceCombatState} */
181181
export const sliceCombatEncounterEnemies = (state: CombatStateRecord) => state.enemies;
182182
/** @internal {@see sliceCombatState} */
183+
export const sliceCombatType = (state: CombatStateRecord) => state.type;
184+
/** @internal {@see sliceCombatState} */
183185
export const sliceCombatEncounterParty = (state: CombatStateRecord) => state.party;

src/app/models/entity/entity.reducer.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { addEntityToCollection, EntityCollectionRecord } from '../entity-collect
44
import {
55
GameStateEquipItemAction,
66
GameStateHealPartyAction,
7+
GameStateHurtPartyAction,
78
GameStateUnequipItemAction,
89
} from '../game-state/game-state.actions';
910
import { Item } from '../item';
@@ -273,6 +274,39 @@ describe('Entity', () => {
273274
expect(secondHealed.mp).toBe(secondHealed.maxmp);
274275
});
275276
});
277+
describe('GameStateHurtPartyAction', () => {
278+
it('should restore all entities in partyIds hp and mp to their maximum', () => {
279+
const secondId: string = 'MotTon';
280+
const first = entityFactory({
281+
eid: testId,
282+
hp: 25,
283+
maxhp: 25,
284+
mp: 0,
285+
maxmp: 25,
286+
});
287+
const second = entityFactory({
288+
eid: secondId,
289+
hp: 20,
290+
maxhp: 20,
291+
mp: 0,
292+
maxmp: 25,
293+
});
294+
const initial: EntityStateRecord = defaultState('beings', [first, second]);
295+
const damage = 10;
296+
const actual = entityReducer(
297+
initial,
298+
new GameStateHurtPartyAction({
299+
damage,
300+
partyIds: [testId, secondId],
301+
})
302+
);
303+
const firstHurt: IPartyMember = actual.beings.byId.get(testId);
304+
expect(firstHurt.hp).toBe(first.hp - damage);
305+
306+
const secondHurt: IPartyMember = actual.beings.byId.get(secondId);
307+
expect(secondHurt.hp).toBe(second.hp - damage);
308+
});
309+
});
276310

277311
describe('CombatVictoryAction', () => {
278312
function summaryData(

src/app/models/entity/entity.reducer.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import {
1414
GameStateEquipItemAction,
1515
GameStateHealPartyAction,
16+
GameStateHurtPartyAction,
1617
GameStateUnequipItemAction,
1718
} from '../game-state/game-state.actions';
1819
import { Armor, Item, Magic, Weapon } from '../item';
@@ -101,6 +102,7 @@ type EntityReducerTypes =
101102
| GameStateEquipItemAction
102103
| GameStateUnequipItemAction
103104
| GameStateHealPartyAction
105+
| GameStateHurtPartyAction
104106
| CombatVictoryAction;
105107

106108
export function entityReducer(
@@ -152,6 +154,23 @@ export function entityReducer(
152154
return updateBeingsResult;
153155
});
154156
}
157+
case GameStateHurtPartyAction.typeId: {
158+
const result: EntityStateRecord = state;
159+
const partyAction: GameStateHurtPartyAction = action;
160+
return result.updateIn(['beings'], (beings: EntityCollectionRecord) => {
161+
let updateBeingsResult = beings;
162+
const damage = action.payload.damage;
163+
partyAction.payload.partyIds.forEach((partyMemberId: string) => {
164+
const newHp = state.beings.byId.get(partyMemberId).hp - damage;
165+
updateBeingsResult = mergeEntityInCollection(
166+
updateBeingsResult,
167+
{ hp: newHp },
168+
partyMemberId
169+
);
170+
});
171+
return updateBeingsResult;
172+
});
173+
}
155174
case GameStateEquipItemAction.typeId: {
156175
let result: EntityStateRecord = state;
157176
const current: Entity = state.beings.byId.get(action.payload.entityId);

src/app/models/game-state/game-state.actions.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,18 @@ export class GameStateHealPartyAction implements Action {
194194
) {}
195195
}
196196

197+
export class GameStateHurtPartyAction implements Action {
198+
static typeId: 'GAME_HURT_PARTY' = type('GAME_HURT_PARTY');
199+
type = GameStateHurtPartyAction.typeId;
200+
201+
constructor(
202+
public payload: {
203+
damage: number;
204+
partyIds: string[];
205+
}
206+
) {}
207+
}
208+
197209
export class GameStateSetBattleCounterAction implements Action {
198210
static typeId: 'GAME_SET_BATTLE_COUNTER' = type('GAME_SET_BATTLE_COUNTER');
199211
type = GameStateSetBattleCounterAction.typeId;
@@ -265,6 +277,7 @@ export type GameStateActions =
265277
| GameStateBoardShipAction
266278
| GameStateAddGoldAction
267279
| GameStateHealPartyAction
280+
| GameStateHurtPartyAction
268281
| GameStateEquipItemAction
269282
| GameStateUnequipItemAction
270283
| GameStateAddInventoryAction

src/app/models/game-state/game-state.reducer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
GameStateDeleteSuccessAction,
1414
GameStateEquipItemAction,
1515
GameStateHealPartyAction,
16+
GameStateHurtPartyAction,
1617
GameStateLoadAction,
1718
GameStateLoadFailAction,
1819
GameStateLoadSuccessAction,
@@ -127,6 +128,7 @@ export function gameStateReducer(
127128
case GameStateSaveAction.typeId:
128129
case GameStateSaveSuccessAction.typeId:
129130
case GameStateSaveFailAction.typeId:
131+
case GameStateHurtPartyAction.typeId:
130132
return state;
131133
case GameStateMoveAction.typeId: {
132134
if (state.boardedShip) {

src/app/models/selectors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
sliceCombatEncounterEnemies,
77
sliceCombatEncounterParty,
88
sliceCombatLoading,
9+
sliceCombatType,
910
} from './combat/combat.reducer';
1011
import { Entity, EntityWithEquipment } from './entity/entity.model';
1112
import {
@@ -54,6 +55,7 @@ import { assertTrue } from './util';
5455
*/
5556
export const sliceCombatState = (state: AppState) => state.combat;
5657

58+
export const getCombatType = createSelector(sliceCombatState, sliceCombatType);
5759
export const getCombatLoading = createSelector(sliceCombatState, sliceCombatLoading);
5860
export const getCombatEncounterParty = createSelector(
5961
sliceCombatState,

src/app/routes/combat/combat-player.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class CombatPlayerComponent
4141
@Input() model: IPartyMember;
4242
// @ts-ignore
4343
@Input() icon: string;
44-
@Input() scene: Scene;
44+
@Input() scene: Scene | null;
4545
@Input() combat: any; // CombatComponent - flirts with circular imports
4646

4747
_elapsed: number = 0;
@@ -258,14 +258,14 @@ export class CombatPlayerComponent
258258
}
259259

260260
ngAfterViewInit(): void {
261-
this.scene.addObject(this);
261+
this.scene?.addObject(this);
262262
this.behaviors.forEach((c: SceneObjectBehavior) => {
263263
this.addBehavior(c);
264264
});
265265
}
266266

267267
ngOnDestroy(): void {
268-
this.scene.removeObject(this);
268+
this.scene?.removeObject(this);
269269
this.behaviors.forEach((c: SceneObjectBehavior) => {
270270
this.removeBehavior(c);
271271
});

src/app/routes/combat/combat.component.ts

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -316,36 +316,24 @@ export class CombatComponent
316316
this._tileRenderer.render(this.map, this);
317317
this.party.forEach((component: CombatPlayerComponent) => {
318318
this.objectRenderer.render(
319-
component,
319+
component as TileRenderable,
320320
component.renderPoint || component.point,
321-
this,
322-
component.meta
321+
this
323322
);
324323
const sprites = component.findBehaviors(SpriteComponent) as SpriteComponent[];
325324
sprites.forEach((sprite: SpriteComponent) => {
326-
this.objectRenderer.render(
327-
sprite as TileRenderable,
328-
sprite.host.point,
329-
this,
330-
sprite.meta
331-
);
325+
this.objectRenderer.render(sprite as TileRenderable, sprite.host.point, this);
332326
});
333327
});
334328
this.enemies.forEach((component: CombatEnemyComponent) => {
335329
this.objectRenderer.render(
336-
component,
330+
component as TileRenderable,
337331
component.renderPoint || component.point,
338-
this,
339-
component.meta
332+
this
340333
);
341334
const sprites: SpriteComponent[] = component.findBehaviors(SpriteComponent);
342335
sprites.forEach((sprite: SpriteComponent) => {
343-
this.objectRenderer.render(
344-
sprite as TileRenderable,
345-
sprite.host.point,
346-
this,
347-
sprite.meta
348-
);
336+
this.objectRenderer.render(sprite as TileRenderable, sprite.host.point, this);
349337
});
350338
});
351339
return this;

src/app/routes/combat/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export const COMBAT_PROVIDERS = [CanActivateCombat];
6767
@NgModule({
6868
declarations: COMBAT_EXPORTS,
6969
exports: COMBAT_EXPORTS,
70+
providers: COMBAT_PROVIDERS,
7071
imports: [CommonModule, BehaviorsModule, AppComponentsModule, ServicesModule],
7172
})
7273
export class CombatModule {

0 commit comments

Comments
 (0)