Skip to content

Commit 0c940f7

Browse files
authored
Merge branch 'master' into renovate/angular-monorepo
2 parents ce84527 + 80704bd commit 0c940f7

24 files changed

+751
-259
lines changed

apps/keira/src/assets/sqlite.db

0 Bytes
Binary file not shown.

libs/features/creature/src/creature-template-model/creature-template-model.integration.spec.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
22
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
3-
import { TestBed } from '@angular/core/testing';
43
import { provideZonelessChangeDetection } from '@angular/core';
4+
import { TestBed } from '@angular/core/testing';
5+
import { ReactiveFormsModule } from '@angular/forms';
56
import { provideNoopAnimations } from '@angular/platform-browser/animations';
67
import { CreatureTemplateModel } from '@keira/shared/acore-world-model';
78
import { KEIRA_APP_CONFIG_TOKEN, KEIRA_MOCK_CONFIG } from '@keira/shared/config';
89
import { MysqlQueryService, SqliteService } from '@keira/shared/db-layer';
10+
import { Model3DViewerService } from '@keira/shared/model-3d-viewer';
911
import { MultiRowEditorPageObject, TranslateTestingModule } from '@keira/shared/test-utils';
1012
import { ModalModule } from 'ngx-bootstrap/modal';
1113
import { ToastrModule } from 'ngx-toastr';
@@ -23,21 +25,20 @@ describe('CreatureTemplateModel integration tests', () => {
2325

2426
const id = 1234;
2527

26-
beforeEach(() => {
28+
function setup(creatingNew: boolean) {
2729
TestBed.configureTestingModule({
28-
imports: [ToastrModule.forRoot(), ModalModule.forRoot(), CreatureTemplateModelComponent, TranslateTestingModule],
30+
imports: [ToastrModule.forRoot(), ModalModule.forRoot(), CreatureTemplateModelComponent, TranslateTestingModule, ReactiveFormsModule],
2931
providers: [
3032
provideZonelessChangeDetection(),
3133
provideNoopAnimations(),
34+
{ provide: Model3DViewerService, useValue: { generateModels: () => new Promise((resolve) => resolve({ destroy: () => {} })) } },
3235
{ provide: SqliteService, useValue: instance(mock(SqliteService)) },
3336
{ provide: KEIRA_APP_CONFIG_TOKEN, useValue: KEIRA_MOCK_CONFIG },
3437
provideHttpClient(withInterceptorsFromDi()),
3538
provideHttpClientTesting(),
3639
],
3740
}).compileComponents();
38-
});
3941

40-
function setup(creatingNew: boolean) {
4142
const originalRow0 = new CreatureTemplateModel();
4243
const originalRow1 = new CreatureTemplateModel();
4344
const originalRow2 = new CreatureTemplateModel();
@@ -60,6 +61,7 @@ describe('CreatureTemplateModel integration tests', () => {
6061
const fixture = TestBed.createComponent(CreatureTemplateModelComponent);
6162
const component = fixture.componentInstance;
6263
const page = new CreatureTemplateModelPage(fixture);
64+
6365
fixture.autoDetectChanges(true);
6466
fixture.detectChanges();
6567

libs/features/gameobject/src/gameobject-template/gameobject-template.component.spec.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { ComponentFixture, TestBed } from '@angular/core/testing';
21
import { provideZonelessChangeDetection } from '@angular/core';
2+
import { ComponentFixture, TestBed } from '@angular/core/testing';
33
import { provideNoopAnimations } from '@angular/platform-browser/animations';
44
import { RouterTestingModule } from '@angular/router/testing';
5+
import { FieldDefinition } from '@keira/shared/constants';
56
import { MysqlQueryService } from '@keira/shared/db-layer';
7+
import { Model3DViewerService } from '@keira/shared/model-3d-viewer';
68
import { TranslateTestingModule } from '@keira/shared/test-utils';
7-
import { FieldDefinition } from '@keira/shared/constants';
89
import { ModalModule } from 'ngx-bootstrap/modal';
910
import { ToastrModule } from 'ngx-toastr';
1011
import { of } from 'rxjs';
@@ -20,6 +21,7 @@ describe('GameobjectComponent', () => {
2021
let queryService: MysqlQueryService;
2122
let gameobjectTemplateService: GameobjectTemplateService;
2223
let getFieldSpy: Spy;
24+
let model3DViewerService: Model3DViewerService;
2325

2426
beforeEach(() => {
2527
TestBed.configureTestingModule({
@@ -32,6 +34,9 @@ describe('GameobjectComponent', () => {
3234
queryService = TestBed.inject(MysqlQueryService);
3335
spyOn(queryService, 'query').and.returnValue(of());
3436

37+
model3DViewerService = TestBed.inject(Model3DViewerService);
38+
spyOn(model3DViewerService, 'generateModels').and.returnValue(new Promise((resolve) => resolve({ destroy: () => {} })));
39+
3540
fixture = TestBed.createComponent(GameobjectTemplateComponent);
3641
component = fixture.componentInstance;
3742
fixture.detectChanges();

libs/features/gameobject/src/gameobject-template/gameobject-template.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ import { GameobjectTemplateService } from './gameobject-template.service';
2929
],
3030
})
3131
export class GameobjectTemplateComponent extends SingleRowEditorComponent<GameobjectTemplate> {
32-
readonly GAMEOBJECT_TYPE = GAMEOBJECT_TYPE;
33-
readonly GAMEOBJECT_ICON = GAMEOBJECT_ICON;
34-
readonly OBJECT_VIEWER_TYPE = VIEWER_TYPE.OBJECT;
32+
protected readonly GAMEOBJECT_TYPE = GAMEOBJECT_TYPE;
33+
protected readonly GAMEOBJECT_ICON = GAMEOBJECT_ICON;
34+
protected readonly OBJECT_VIEWER_TYPE = VIEWER_TYPE.OBJECT;
3535

36-
showGameobjectPreview = true;
36+
protected showGameobjectPreview = true;
3737

3838
protected override readonly editorService = inject(GameobjectTemplateService);
3939
readonly handlerService = inject(GameobjectHandlerService);

libs/features/gameobject/src/gameobject-template/gameobject-template.integration.spec.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1+
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
12
import { provideHttpClientTesting } from '@angular/common/http/testing';
2-
import { ComponentFixture, TestBed } from '@angular/core/testing';
33
import { provideZonelessChangeDetection } from '@angular/core';
4+
import { ComponentFixture, TestBed } from '@angular/core/testing';
5+
import { ReactiveFormsModule } from '@angular/forms';
46
import { provideNoopAnimations } from '@angular/platform-browser/animations';
57
import { RouterTestingModule } from '@angular/router/testing';
8+
import { GameobjectTemplate } from '@keira/shared/acore-world-model';
9+
import { KEIRA_APP_CONFIG_TOKEN, KEIRA_MOCK_CONFIG } from '@keira/shared/config';
610
import { MysqlQueryService, SqliteService } from '@keira/shared/db-layer';
11+
import { Model3DViewerService } from '@keira/shared/model-3d-viewer';
712
import { EditorPageObject, TranslateTestingModule } from '@keira/shared/test-utils';
8-
import { GameobjectTemplate } from '@keira/shared/acore-world-model';
913
import { ModalModule } from 'ngx-bootstrap/modal';
1014
import { ToastrModule } from 'ngx-toastr';
1115
import { of } from 'rxjs';
16+
import { instance, mock } from 'ts-mockito';
1217
import { GameobjectHandlerService } from '../gameobject-handler.service';
1318
import { SaiGameobjectHandlerService } from '../sai-gameobject-handler.service';
1419
import { GameobjectTemplateComponent } from './gameobject-template.component';
1520
import Spy = jasmine.Spy;
16-
import { instance, mock } from 'ts-mockito';
17-
import { KEIRA_APP_CONFIG_TOKEN, KEIRA_MOCK_CONFIG } from '@keira/shared/config';
18-
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
1921

2022
class GameobjectTemplatePage extends EditorPageObject<GameobjectTemplateComponent> {}
2123

@@ -25,6 +27,7 @@ describe('GameobjectTemplate integration tests', () => {
2527
let querySpy: Spy;
2628
let handlerService: GameobjectHandlerService;
2729
let page: GameobjectTemplatePage;
30+
let model3DViewerService: Model3DViewerService;
2831

2932
const id = 1234;
3033
const expectedFullCreateQuery =
@@ -45,7 +48,14 @@ describe('GameobjectTemplate integration tests', () => {
4548

4649
beforeEach(() => {
4750
TestBed.configureTestingModule({
48-
imports: [ToastrModule.forRoot(), ModalModule.forRoot(), GameobjectTemplateComponent, RouterTestingModule, TranslateTestingModule],
51+
imports: [
52+
ToastrModule.forRoot(),
53+
ModalModule.forRoot(),
54+
GameobjectTemplateComponent,
55+
RouterTestingModule,
56+
TranslateTestingModule,
57+
ReactiveFormsModule,
58+
],
4959
providers: [
5060
provideZonelessChangeDetection(),
5161
provideNoopAnimations(),
@@ -67,6 +77,9 @@ describe('GameobjectTemplate integration tests', () => {
6777
queryService = TestBed.inject(MysqlQueryService);
6878
querySpy = spyOn(queryService, 'query').and.returnValue(of([]));
6979

80+
model3DViewerService = TestBed.inject(Model3DViewerService);
81+
spyOn(model3DViewerService, 'generateModels').and.returnValue(new Promise((resolve) => resolve({ destroy: () => {} })));
82+
7083
spyOn(queryService, 'selectAll').and.returnValue(of(creatingNew ? [] : [originalEntity]));
7184

7285
fixture = TestBed.createComponent(GameobjectTemplateComponent);

libs/features/item/src/item-template/item-preview.service.spec.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { TestBed } from '@angular/core/testing';
21
import { provideZonelessChangeDetection } from '@angular/core';
2+
import { TestBed } from '@angular/core/testing';
33
import { provideNoopAnimations } from '@angular/platform-browser/animations';
44
import { RouterTestingModule } from '@angular/router/testing';
55
import { ITEM_FLAG, ITEM_TYPE, ITEMS_QUALITY, ItemTemplate } from '@keira/shared/acore-world-model';
6+
import { TableRow } from '@keira/shared/constants';
67
import { MysqlQueryService, SqliteQueryService, SqliteService } from '@keira/shared/db-layer';
78
import { ToastrService } from 'ngx-toastr';
89
import { lastValueFrom, Observable, of } from 'rxjs';
910
import { instance, mock } from 'ts-mockito';
1011
import { ItemHandlerService } from '../item-handler.service';
1112
import { ItemPreviewService } from './item-preview.service';
12-
import { TableRow } from '@keira/shared/constants';
1313

1414
describe('ItemPreviewService', () => {
1515
interface Lock extends TableRow {
@@ -415,6 +415,19 @@ describe('ItemPreviewService', () => {
415415
expect(sqliteQueryService.query).toHaveBeenCalledWith(`SELECT * FROM item_enchantment_condition WHERE id = ${id}`);
416416
});
417417

418+
it('getCreatureEntryByItemSpellId', async () => {
419+
const getCreatureEntryByItemSpellIdSpy = spyOn(sqliteQueryService, 'getCreatureEntryByItemSpellId').and.returnValue(
420+
Promise.resolve(123),
421+
);
422+
const getCreatureDisplayIdByIdSpy = spyOn(mysqlQueryService, 'getCreatureDisplayIdById').and.returnValue(Promise.resolve(456));
423+
424+
const res = await service['getNpcDisplayIdBySpell'](id);
425+
426+
expect(getCreatureEntryByItemSpellIdSpy).toHaveBeenCalledOnceWith(id);
427+
expect(getCreatureDisplayIdByIdSpy).toHaveBeenCalledOnceWith(123);
428+
expect(res).toBe(456);
429+
});
430+
418431
const cases = [
419432
{ name: 'Empty variables', template: {}, output: '' },
420433
{

libs/features/item/src/item-template/item-preview.service.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// - comments should be added to document what the code is actually doing
44
// - type errors should be fixed and any usage of "@ts-ignore" or "any" should be removed
55

6-
import { Injectable, inject } from '@angular/core';
6+
import { inject, Injectable } from '@angular/core';
77
import {
88
FACTION_RANK,
99
ITEM_FLAG,
@@ -16,10 +16,10 @@ import {
1616
} from '@keira/shared/acore-world-model';
1717
import { CLASSES_TEXT, RACES_TEXT } from '@keira/shared/constants';
1818
import { MysqlQueryService, SqliteQueryService } from '@keira/shared/db-layer';
19-
import { ITEM_CONSTANTS } from './item-constants';
20-
import { gtCombatRatings, lvlIndepRating, MAX_LEVEL, resistanceFields } from './item-preview';
2119
import { PreviewHelperService } from '@keira/shared/preview';
2220
import { lastValueFrom } from 'rxjs';
21+
import { ITEM_CONSTANTS } from './item-constants';
22+
import { gtCombatRatings, lvlIndepRating, MAX_LEVEL, resistanceFields } from './item-preview';
2323

2424
@Injectable({
2525
providedIn: 'root',
@@ -1413,4 +1413,10 @@ export class ItemPreviewService {
14131413

14141414
return tmpItemPreview;
14151415
}
1416+
1417+
async getNpcDisplayIdBySpell(spellId: number): Promise<number> {
1418+
const creatureId = await this.sqliteQueryService.getCreatureEntryByItemSpellId(spellId);
1419+
const creatureDisplayId = await this.mysqlQueryService.getCreatureDisplayIdById(creatureId);
1420+
return creatureDisplayId;
1421+
}
14161422
}

libs/features/item/src/item-template/item-template.component.html

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -528,12 +528,7 @@
528528
<div class="col-12">
529529
<label class="control-label" for="stat_value{{ i }}">value{{ i }}</label>
530530
<i class="fas fa-info-circle ms-1" placement="auto" [tooltip]="'ITEM.TEMPLATE.STAT_VALUE' | translate"></i>
531-
<input
532-
[formControlName]="'stat_value' + i"
533-
id="stat_value{{ i }}"
534-
type="number"
535-
class="form-control form-control-sm"
536-
/>
531+
<input [formControlName]="'stat_value' + i" id="stat_value{{ i }}" type="number" class="form-control form-control-sm" />
537532
</div>
538533
</div>
539534
</div>
@@ -781,12 +776,16 @@
781776
<div class="item-stats">
782777
<div [innerHTML]="itemPreview"></div>
783778
<br />
784-
<keira-model-3d-viewer
785-
[viewerType]="ITEM_VIEWER_TYPE"
786-
[displayId]="editorService.form.controls.displayid.value"
787-
[itemClass]="editorService.form.controls.class.value"
788-
[itemInventoryType]="editorService.form.controls.InventoryType.value"
789-
/>
779+
@if (npcDisplayId) {
780+
<keira-model-3d-viewer [viewerType]="NPC_VIEWER_TYPE" [displayId]="npcDisplayId" />
781+
} @else {
782+
<keira-model-3d-viewer
783+
[viewerType]="ITEM_VIEWER_TYPE"
784+
[displayId]="editorService.form.controls.displayid.value"
785+
[itemClass]="editorService.form.controls.class.value"
786+
[itemInventoryType]="editorService.form.controls.InventoryType.value"
787+
/>
788+
}
790789
</div>
791790
</div>
792791
</div>

libs/features/item/src/item-template/item-template.component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ import {
4141
SkillSelectorBtnComponent,
4242
SpellSelectorBtnComponent,
4343
} from '@keira/shared/selectors';
44+
import { compareObjFn } from '@keira/shared/utils';
4445
import { TranslateModule } from '@ngx-translate/core';
4546
import { TooltipModule } from 'ngx-bootstrap/tooltip';
4647
import { debounceTime, distinctUntilChanged } from 'rxjs';
4748
import { ItemHandlerService } from '../item-handler.service';
4849
import { SPELL_TRIGGERS } from './item-constants';
4950
import { ItemPreviewService } from './item-preview.service';
5051
import { ItemTemplateService } from './item-template.service';
51-
import { compareObjFn } from '@keira/shared/utils';
5252

5353
@Component({
5454
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -105,16 +105,27 @@ export class ItemTemplateComponent extends SingleRowEditorComponent<ItemTemplate
105105
readonly STAT_TYPE = STAT_TYPE;
106106
readonly PVP_RANK = PVP_RANK;
107107
readonly ITEM_VIEWER_TYPE = VIEWER_TYPE.ITEM;
108+
readonly NPC_VIEWER_TYPE = VIEWER_TYPE.NPC;
108109
readonly SPELL_TRIGGERS = SPELL_TRIGGERS;
109110

110-
showItemPreview = true;
111+
protected showItemPreview = true;
112+
protected npcDisplayId: number | undefined;
111113

112114
public itemPreview: SafeHtml = this.sanitizer.bypassSecurityTrustHtml('loading...');
113115

114116
private async loadItemPreview(): Promise<void> {
115117
this.itemPreview = this.sanitizer.bypassSecurityTrustHtml(
116118
await this.itemPreviewService.calculatePreview(this.editorService.form.getRawValue()),
117119
);
120+
121+
const isNpc =
122+
this.editorService.form.controls.class.value === 15 &&
123+
(this.editorService.form.controls.subclass.value === 5 || this.editorService.form.controls.subclass.value === 2) &&
124+
this.editorService.form.controls.spellid_2.value;
125+
if (isNpc) {
126+
this.npcDisplayId = await this.itemPreviewService.getNpcDisplayIdBySpell(this.editorService.form.controls.spellid_2.value);
127+
}
128+
118129
this.changeDetectorRef.markForCheck();
119130
}
120131

0 commit comments

Comments
 (0)