use HeldObjectManager.get()

This commit is contained in:
Hendrik Brummermann 2026-02-28 02:30:16 +01:00
parent c9f865a894
commit 3a478f341d
5 changed files with 45 additions and 50 deletions

View file

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright © 2003-2024 - Faiumoni e. V. *
* Copyright © 2003-2026 - Faiumoni e. V. *
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
@ -19,8 +19,8 @@ import { FacingHandler } from "./util/FacingHandler";
import { KeyHandler } from "./util/KeyHandler";
import { SessionManager } from "./util/SessionManager";
import { CStatus } from "./data/CStatus";
import { CacheManager } from "./data/CacheManager";
import { CStatus } from "./data/CStatus";
import { EmojiStore } from "./data/EmojiStore";
import { GroupManager } from "./data/GroupManager";
import { Paths } from "./data/Paths";
@ -28,11 +28,10 @@ import { Paths } from "./data/Paths";
import { LoopedSoundSourceManager } from "./data/sound/LoopedSoundSourceManager";
import { SoundManager } from "./data/sound/SoundManager";
import { ui } from "./ui/UI";
import { UIComponentEnum } from "./ui/UIComponentEnum";
import { HeldObjectManager } from "./ui/HeldObject";
import { Inventory } from "./ui/Inventory";
import { SoftwareJoystickController } from "./ui/SoftwareJoystickController";
import { ui } from "./ui/UI";
import { UIComponentEnum } from "./ui/UIComponentEnum";
import { UIUpdateObserver } from "./ui/UIUpdateObserver";
import { ChatInputComponent } from "./ui/component/ChatInputComponent";
@ -82,10 +81,6 @@ export class SingletonRepo {
return GroupManager.get();
}
static getHeldObjectManager(): HeldObjectManager {
return HeldObjectManager.get();
}
static getInventory(): Inventory {
return Inventory.get();
}

View file

@ -37,11 +37,13 @@ export interface HeldObject {
*/
export class HeldObjectManager {
/** Singleton instance. */
private static instance: HeldObjectManager;
/** Image displayed when an object is "held". */
private image: HTMLCanvasElement|HTMLImageElement;
/** Singleton instance. */
private static instance: HeldObjectManager;
public heldObject?: HeldObject;
/**
@ -75,9 +77,7 @@ export class HeldObjectManager {
canvas.height = sprite.height!;
let ctx = canvas.getContext("2d")!;
ctx.clearRect(0, 0, sprite.width!, sprite.height!);
sprite.drawOntoWithZoom(ctx, 0, 0, 24, 24);
sprite.drawOntoWithZoom(ctx, 0, 0, 32, 32);
if (e instanceof DragEvent) {
e.dataTransfer?.setDragImage(canvas, 0, 0);
@ -108,7 +108,7 @@ export class HeldObjectManager {
* Initial position of displayed image.
*/
public set(obj: HeldObject, pos?: Point) {
stendhal.ui.heldObject = obj;
this.heldObject = obj;
this.onSet(pos);
}
@ -135,7 +135,7 @@ export class HeldObjectManager {
* Hides object image.
*/
public onRelease() {
// NOTE: should we unset `stendhal.ui.heldObject` here?
// NOTE: should we unset `heldObject` here?
this.setVisible(false);
}

View file

@ -12,7 +12,7 @@
import { marauroa } from "marauroa";
import { stendhal } from "../stendhal";
import { HeldObject } from "./HeldObject";
import { HeldObject, HeldObjectManager } from "./HeldObject";
import { ui } from "./UI";
import { UIComponentEnum } from "./UIComponentEnum";
@ -22,7 +22,6 @@ import { ActionContextMenu } from "./dialog/ActionContextMenu";
import { DropQuantitySelectorDialog } from "./dialog/DropQuantitySelectorDialog";
import { Client } from "../Client";
import { singletons } from "../SingletonRepo";
import { AchievementBanner } from "../sprite/AchievementBanner";
import { EmojiSprite } from "../sprite/EmojiSprite";
@ -30,10 +29,8 @@ import { NotificationBubble } from "../sprite/NotificationBubble";
import { SpeechBubble } from "../sprite/SpeechBubble";
import { TextBubble } from "../sprite/TextBubble";
import { htmlImageStore } from "data/HTMLImageStore";
import { TileMap } from "data/TileMap";
import { Zone } from "entity/Zone";
import { HTMLImageElementUtil } from "sprite/image/HTMLImageElementUtil";
import { Canvas, RenderingContext2D } from "util/Types";
import { WeatherRenderer } from "util/WeatherRenderer";
import { Debug } from "../util/Debug";
@ -664,7 +661,8 @@ export class ViewPort {
}
}
if (!draggedEntity || !singletons.getHeldObjectManager().prepare(draggedEntity, e)) {
if (!draggedEntity || !HeldObjectManager.get().prepare(draggedEntity, e)) {
e.preventDefault();
return;
}
@ -677,10 +675,10 @@ export class ViewPort {
let touchHandler = TouchHandler.get();
if (touchHandler.isTouchEvent(e)) {
singletons.getHeldObjectManager().set(heldObject, new Point(pos.pageX, pos.pageY));
HeldObjectManager.get().set(heldObject, new Point(pos.pageX, pos.pageY));
touchHandler.setHolding(true);
} else {
stendhal.ui.heldObject = heldObject;
HeldObjectManager.get().heldObject = heldObject;
}
}
@ -699,22 +697,23 @@ export class ViewPort {
* Handles releasing an item or corpse from drag event.
*/
onDrop(e: DragEvent|TouchEvent) {
if (stendhal.ui.heldObject) {
let heldObject = HeldObjectManager.get().heldObject;
if (heldObject) {
var pos = HTMLUtil.extractPosition(e);
const targetSlot = HTMLUtil.parseSlotName((pos.target as HTMLElement).id);
const action: any = {
"zone": stendhal.ui.heldObject.zone
"zone": heldObject.zone
};
if (targetSlot === "viewport") {
let viewPort = ViewPort.get();
action.x = Math.floor((pos.canvasRelativeX + viewPort.offsetX) / 32).toString();
action.y = Math.floor((pos.canvasRelativeY + viewPort.offsetY) / 32).toString();
var id = stendhal.ui.heldObject.path.substr(1, stendhal.ui.heldObject.path.length - 2);
var id = heldObject.path.substring(1, heldObject.path.length - 1);
var drop = /\t/.test(id);
if (drop) {
action["type"] = "drop";
action["source_path"] = stendhal.ui.heldObject.path;
action["source_path"] = heldObject.path;
} else {
action["type"] = "displace";
action["baseitem"] = id;
@ -729,22 +728,22 @@ export class ViewPort {
}
}
action["type"] = "equip";
action["source_path"] = stendhal.ui.heldObject.path;
action["source_path"] = heldObject.path;
action["target_path"] = "[" + objectId + "\t" + targetSlot + "]";
}
const quantity = stendhal.ui.heldObject.quantity;
const sourceSlot = stendhal.ui.heldObject.slot || "viewport";
const quantity = heldObject.quantity;
const sourceSlot = heldObject.slot || "viewport";
// item was dropped
stendhal.ui.heldObject = undefined;
heldObject = undefined;
const touch_held = TouchHandler.get().holding() && quantity > 1;
const touch_held = TouchHandler.get().holding() && (quantity||1) > 1;
// if ctrl is pressed or holding stackable item from touch event, we ask for the quantity
// NOTE: don't create selector if touch source is ground
if (e.ctrlKey || (touch_held && sourceSlot !== targetSlot)) {
ui.createSingletonFloatingWindow("Quantity", new DropQuantitySelectorDialog(action, touch_held), pos.pageX - 50, pos.pageY - 25);
} else {
singletons.getHeldObjectManager().onRelease();
HeldObjectManager.get().onRelease();
marauroa.clientFramework.sendAction(action);
}
}

View file

@ -21,7 +21,7 @@ import { DropQuantitySelectorDialog } from "../dialog/DropQuantitySelectorDialog
import { singletons } from "../../SingletonRepo";
import { htmlImageStore } from "data/HTMLImageStore";
import { HTMLImageElementUtil } from "sprite/image/HTMLImageElementUtil";
import { HeldObjectManager } from "ui/HeldObject";
import { HTMLUtil } from "ui/HTMLUtil";
import { TouchHandler } from "ui/TouchHandler";
import { ViewPort } from "ui/ViewPort";
@ -190,7 +190,7 @@ export class ItemContainerImplementation {
const slotNumber = target.id.slice(this.slot.length + this.suffix.length);
let item = myobject[this.slot].getByIndex(slotNumber);
if (item) {
if (!singletons.getHeldObjectManager().prepare(item, event)) {
if (!HeldObjectManager.get().prepare(item, event)) {
return;
}
@ -202,12 +202,12 @@ export class ItemContainerImplementation {
};
if (event instanceof DragEvent && event.dataTransfer) {
stendhal.ui.heldObject = heldObject;
HeldObjectManager.get().heldObject = heldObject;
} else if (this.touchHandler.isTouchEvent(event)) {
this.touchHandler.setHolding(true);
// TODO: move when supported by mouse events
const pos = HTMLUtil.extractPosition(event);
singletons.getHeldObjectManager().set(heldObject, new Point(pos.pageX, pos.pageY));
HeldObjectManager.get().set(heldObject, new Point(pos.pageX, pos.pageY));
}
} else {
event.preventDefault();
@ -218,7 +218,7 @@ export class ItemContainerImplementation {
* Handles displaying an icon for objects dragged with touch.
*/
private onTouchMove(event: TouchEvent) {
if (stendhal.ui.heldObject) {
if (HeldObjectManager.get().heldObject) {
return;
}
this.onDragStart(event);
@ -251,8 +251,9 @@ export class ItemContainerImplementation {
}
private onDrop(event: DragEvent|TouchEvent) {
let heldObject = HeldObjectManager.get().heldObject;
const myobject = this.object || marauroa.me;
if (stendhal.ui.heldObject) {
if (heldObject) {
const pos = HTMLUtil.extractPosition(event);
const id = (pos.target as HTMLElement).id;
const targetSlot = HTMLUtil.parseSlotName(id);
@ -278,20 +279,20 @@ export class ItemContainerImplementation {
}
const action = {
"source_path": stendhal.ui.heldObject.path
"source_path": heldObject.path
} as any;
const sameSlot = stendhal.ui.heldObject.slot === targetSlot;
const sameSlot = heldObject.slot === targetSlot;
if (sameSlot) {
action["type"] = "reorder";
action["new_position"] = this.parseIndex(id) || "" + (this.size - 1);
} else {
action["type"] = "equip";
action["target_path"] = "[" + objectId + "\t" + targetSlot + "]";
action["zone"] = stendhal.ui.heldObject.zone;
action["zone"] = heldObject.zone;
}
const quantity = stendhal.ui.heldObject.quantity;
stendhal.ui.heldObject = undefined;
const quantity = heldObject.quantity || 1;
HeldObjectManager.get().heldObject = undefined;
// if ctrl is pressed or holding stackable item from touch event, we ask for the quantity
const touch_held = this.touchHandler.holding() && quantity > 1;
@ -302,7 +303,7 @@ export class ItemContainerImplementation {
new DropQuantitySelectorDialog(action, touch_held),
pos.pageX - 50, pos.pageY - 25);
} else {
singletons.getHeldObjectManager().onRelease();
HeldObjectManager.get().onRelease();
marauroa.clientFramework.sendAction(action);
}
}
@ -381,7 +382,7 @@ export class ItemContainerImplementation {
stendhal.ui.actionContextMenu.set(ui.createSingletonFloatingWindow("Action",
new ActionContextMenu((event.target as any).dataItem, append),
event.pageX - 50, event.pageY - 5));
} else if (!stendhal.ui.heldObject) {
} else if (!HeldObjectManager.get().heldObject) {
if (!stendhal.config.getBoolean("inventory.double-click") || this.isDoubleClick(event)) {
marauroa.clientFramework.sendAction({
type: "use",

View file

@ -9,10 +9,10 @@
* *
***************************************************************************/
import { marauroa } from "marauroa"
import { marauroa } from "marauroa";
import { HeldObjectManager } from "ui/HeldObject";
import { Component } from "../toolkit/Component";
import { singletons } from "../../SingletonRepo";
export class DropQuantitySelectorDialog extends Component {
@ -49,7 +49,7 @@ export class DropQuantitySelectorDialog extends Component {
* Drops selected quantity from stack.
*/
private onDrop(event: Event) {
singletons.getHeldObjectManager().onRelease();
HeldObjectManager.get().onRelease();
let quantityStr = (this.child(".quantityselectorvalue") as HTMLInputElement).value;
let quantity = parseInt(quantityStr);
if (quantity > 0) {
@ -64,7 +64,7 @@ export class DropQuantitySelectorDialog extends Component {
* Drops entire stack.
*/
private onDropAll(event: Event) {
singletons.getHeldObjectManager().onRelease();
HeldObjectManager.get().onRelease();
marauroa.clientFramework.sendAction(this.action);
this.componentElement.dispatchEvent(new Event("close"));
event.preventDefault();