Skip to content

Commit

Permalink
インベントリからの複数選択と移動 ToDO:スマホ対応
Browse files Browse the repository at this point in the history
  • Loading branch information
Nanasu committed Oct 13, 2023
1 parent 2755ede commit b1aba28
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/app/component/game-character/game-character.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -815,20 +815,23 @@ export class GameCharacterComponent implements OnChanges, AfterViewInit, OnDestr
name: '共有インベントリ', action: () => {
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: this.gameCharacter.identifier });
this.gameCharacter.setLocation('common');
this.selectionService.remove(this.gameCharacter);
SoundEffect.play(PresetSound.piecePut);
}
},
{
name: '個人インベントリ', action: () => {
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: this.gameCharacter.identifier });
this.gameCharacter.setLocation(Network.peerId);
this.selectionService.remove(this.gameCharacter);
SoundEffect.play(PresetSound.piecePut);
}
},
{
name: '墓場', action: () => {
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: this.gameCharacter.identifier });
this.gameCharacter.setLocation('graveyard');
this.selectionService.remove(this.gameCharacter);
SoundEffect.play(PresetSound.sweep);
}
},
Expand Down Expand Up @@ -871,6 +874,7 @@ export class GameCharacterComponent implements OnChanges, AfterViewInit, OnDestr
name: '削除する(墓場へ移動)', action: () => {
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: this.gameCharacter.identifier });
this.gameCharacter.setLocation('graveyard');
this.selectionService.remove(this.gameCharacter);
SoundEffect.play(PresetSound.sweep);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,14 @@ button.link {

.url-link {
cursor: inherit;
}

.muluti-selected {
border-top: 2px dotted #666;
border-bottom: 2px dotted #666;
border-right: 5px solid hsla(200, 100%, 75%, 0.6);
}
.muluti-selected:not(.selected) {
padding-left: 6px;
border-left: 2px dotted #666;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<ng-container *ngTemplateOutlet="inventoryViewSetting"></ng-container>
<div *ngIf="getGameObjects(selectTab).length < 1">{{getTabTitle(selectTab)}}インベントリは空です</div>
<div (contextmenu)="onContextMenu($event, $any(gameObject))" *ngFor="let gameObject of getGameObjects(selectTab); trackBy: trackByGameObject" class="object-container"
(click)="selectGameObject(gameObject)" (dblclick)="focusGameObject($any(gameObject), $event)" [ngClass]="{'box': true, 'selected': (selectedIdentifier === gameObject.identifier), 'is-hide-in': $any(gameObject).isHideIn, 'is-inventory-no-indicate': !gameObject.isInventoryIndicate}">
(click)="selectGameObject(gameObject, $event)" (dblclick)="focusGameObject($any(gameObject), $event)"
[ngClass]="{'box': true, 'selected': (selectedIdentifier === gameObject.identifier), 'muluti-selected': checkSelected(gameObject), 'is-hide-in': $any(gameObject).isHideIn, 'is-inventory-no-indicate': !gameObject.isInventoryIndicate}">
<div *ngIf="$any(gameObject).isHideIn && $any(gameObject).ownerName != null" class="owner-tag" [style.background-color]="$any(gameObject).ownerColor">{{$any(gameObject).ownerName ? $any(gameObject).ownerName : '(無名のプレイヤー)'}}</div>
<ng-container *ngTemplateOutlet="gameObjectTags; context:{ gameObject: gameObject}"></ng-container>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { GameObjectInventoryService } from 'service/game-object-inventory.servic
import { ModalService } from 'service/modal.service';
import { PanelOption, PanelService } from 'service/panel.service';
import { PointerDeviceService } from 'service/pointer-device.service';
import { SelectionState, TabletopSelectionService } from 'service/tabletop-selection.service';

@Component({
selector: 'game-object-inventory',
Expand Down Expand Up @@ -56,13 +57,18 @@ export class GameObjectInventoryComponent implements OnInit, OnDestroy {

get isGMMode(): boolean{ return PeerCursor.myCursor ? PeerCursor.myCursor.isGMMode : false; }

selectionState(tabletopObject: TabletopObject): SelectionState { return this.selectionService.state(tabletopObject); }
checkSelected(tabletopObject: TabletopObject): boolean { return this.selectionState(tabletopObject) !== SelectionState.NONE; }
checkMagnetic(tabletopObject: TabletopObject): boolean { return this.selectionState(tabletopObject) === SelectionState.MAGNETIC; }

constructor(
private changeDetector: ChangeDetectorRef,
private panelService: PanelService,
private inventoryService: GameObjectInventoryService,
private contextMenuService: ContextMenuService,
private pointerDeviceService: PointerDeviceService,
private modalService: ModalService
private modalService: ModalService,
private selectionService: TabletopSelectionService
) { }

ngOnInit() {
Expand Down Expand Up @@ -142,14 +148,84 @@ export class GameObjectInventoryComponent implements OnInit, OnDestroy {
if (target && target.tagName === 'BUTTON') {
const clientRect = target.getBoundingClientRect();
position = {
x: window.pageXOffset + clientRect.left + target.clientWidth,
y: window.pageYOffset + clientRect.top
x: window.scrollX + clientRect.left + target.clientWidth,
y: window.scrollY + clientRect.top
};
} else {
position = this.pointerDeviceService.pointers[0];
}

let actions: ContextMenuAction[] = [];
if (this.checkSelected(gameObject)) {
let selectedCharacter = () => this.selectionService.objects.filter(object => object.aliasName === gameObject.aliasName) as GameCharacter[];
let subActions: ContextMenuAction[] = [];
if (this.selectTab != 'table') {
subActions.push({
name: 'すべてテーブルに移動', action: () => {
selectedCharacter().forEach(gameCharacter => {
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: gameCharacter.identifier });
let isStealthMode = GameCharacter.isStealthMode;
gameCharacter.setLocation('table');
this.selectionService.remove(gameCharacter);
if (gameCharacter.isHideIn && gameCharacter.isVisible && !isStealthMode && !PeerCursor.myCursor.isGMMode) {
this.modalService.open(ConfirmationComponent, {
title: 'ステルスモード',
text: 'ステルスモードになります。',
help: '位置を自分だけ見ているキャラクターが1つ以上テーブル上にある間、あなたのカーソル位置は他の参加者に伝わりません。',
type: ConfirmationType.OK,
materialIcon: 'disabled_visible'
});
}
});
SoundEffect.play(PresetSound.piecePut);
EventSystem.call('UPDATE_INVENTORY', true);
}
});
}
if (this.selectTab != 'common') {
subActions.push({
name: 'すべて共有イベントリに移動', action: () => {
selectedCharacter().forEach(gameCharacter => {
gameCharacter.setLocation('common');
this.selectionService.remove(gameCharacter);
});
SoundEffect.play(PresetSound.piecePut);
EventSystem.call('UPDATE_INVENTORY', true);
}
});
}
if (this.selectTab === 'table' || this.selectTab === 'common' || this.selectTab === 'graveyard') {
subActions.push({
name: 'すべて個人イベントリに移動', action: () => {
selectedCharacter().forEach(gameCharacter => {
gameCharacter.setLocation(Network.peerId);
this.selectionService.remove(gameCharacter);
});
SoundEffect.play(PresetSound.piecePut);
EventSystem.call('UPDATE_INVENTORY', true);
}
});
}
if (this.selectTab != 'graveyard') {
subActions.push({
name: 'すべて墓場に移動', action: () => {
selectedCharacter().forEach(gameCharacter => {
gameCharacter.setLocation('graveyard');
this.selectionService.remove(gameCharacter);
});
SoundEffect.play(PresetSound.sweep);
EventSystem.call('UPDATE_INVENTORY', true);
}
});
}
actions.push({
name: '選択したキャラクター',
action: null,
subActions: subActions
});
actions.push(ContextMenuSeparator);
}

if (gameObject.location.name === 'table' && (this.isGMMode || gameObject.isVisible)) {
actions.push({
name: 'テーブル上から探す',
Expand All @@ -161,6 +237,29 @@ export class GameObjectInventoryComponent implements OnInit, OnDestroy {
selfOnly: true
});
}
if (gameObject.location.name != 'table' && (this.isGMMode || gameObject.isVisible)) {
actions.push({
name: 'テーブルへ移動',
action: () => {
let isStealthMode = GameCharacter.isStealthMode;
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: gameObject.identifier });
gameObject.setLocation('table');
this.selectionService.remove(gameObject);
if (gameObject.isHideIn && gameObject.isVisible && !isStealthMode && !PeerCursor.myCursor.isGMMode) {
this.modalService.open(ConfirmationComponent, {
title: 'ステルスモード',
text: 'ステルスモードになります。',
help: '位置を自分だけ見ているキャラクターが1つ以上テーブル上にある間、あなたのカーソル位置は他の参加者に伝わりません。',
type: ConfirmationType.OK,
materialIcon: 'disabled_visible'
});
}
SoundEffect.play(PresetSound.piecePut);
EventSystem.call('UPDATE_INVENTORY', true);
}
});
}

if (gameObject.isHideIn) {
actions.push({
name: '位置を公開する',
Expand Down Expand Up @@ -397,6 +496,7 @@ export class GameObjectInventoryComponent implements OnInit, OnDestroy {
let isStealthMode = GameCharacter.isStealthMode;
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: gameObject.identifier });
gameObject.setLocation(location.name);
this.selectionService.remove(gameObject);
if (location.name === 'table' && gameObject.isHideIn && gameObject.isVisible && !isStealthMode && !PeerCursor.myCursor.isGMMode) {
this.modalService.open(ConfirmationComponent, {
title: 'ステルスモード',
Expand Down Expand Up @@ -462,6 +562,7 @@ export class GameObjectInventoryComponent implements OnInit, OnDestroy {
actions.push(ContextMenuSeparator);
actions.push({
name: '削除する(完全に削除)', action: () => {
this.selectionService.remove(gameObject);
this.deleteGameObject(gameObject);
SoundEffect.play(PresetSound.sweep);
}
Expand All @@ -471,6 +572,7 @@ export class GameObjectInventoryComponent implements OnInit, OnDestroy {
actions.push({
name: '削除する(墓場へ移動)', action: () => {
EventSystem.call('FAREWELL_STAND_IMAGE', { characterIdentifier: gameObject.identifier });
this.selectionService.remove(gameObject);
gameObject.setLocation('graveyard');
SoundEffect.play(PresetSound.sweep);
}
Expand Down Expand Up @@ -522,11 +624,25 @@ export class GameObjectInventoryComponent implements OnInit, OnDestroy {
component.character = gameObject;
}

selectGameObject(gameObject: GameObject) {
EventSystem.trigger('SELECT_TABLETOP_OBJECT', { identifier: gameObject.identifier, className: gameObject.aliasName, highlighting: true });
selectGameObject(gameObject: GameObject, e: Event=null) {
if (!(gameObject instanceof TabletopObject)) return;
if (e && e instanceof PointerEvent && e.ctrlKey) {
SoundEffect.playLocal(PresetSound.selectionStart);
if (this.checkSelected(gameObject)) {
this.selectionService.remove(gameObject);
} else {
EventSystem.trigger('SELECT_TABLETOP_OBJECT', { identifier: gameObject.identifier, className: gameObject.aliasName, highlighting: true });
this.selectionService.add(gameObject);
}
} else {
EventSystem.trigger('SELECT_TABLETOP_OBJECT', { identifier: gameObject.identifier, className: gameObject.aliasName, highlighting: true });
if (!this.checkSelected(gameObject)) {
this.selectionService.clear();
}
}
}

focusGameObject(gameObject: GameCharacter, e: Event, ) {
focusGameObject(gameObject: GameCharacter, e: Event) {
if (!(e.target instanceof HTMLElement)) return;
if (new Set(['input', 'button']).has(e.target.tagName.toLowerCase())) return;
if (gameObject.location.name !== 'table' || (!gameObject.isVisible && !this.isGMMode)) return;
Expand Down
1 change: 1 addition & 0 deletions src/app/service/tabletop-selection.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export class TabletopSelectionService {
for (let target of targets) {
EventSystem.trigger(`UPDATE_SELECTION/identifier/${target.identifier}`, { changed: targets });
}
EventSystem.trigger('UPDATE_INVENTORY', null);
});
this.isUdpateCssBatching = true;
}
Expand Down

0 comments on commit b1aba28

Please sign in to comment.