diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 477927af2c..87b5921cc4 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -3604,6 +3604,9 @@ _miWorld: bodyMat: "コップの素材" liquidMat: "液体の素材" mikan: "みかん" + bolt: "ボルト" + _bolt: + mat: "素材" _miRoom: snapToGrid: "グリッドにスナップ" diff --git a/packages/frontend-misskey-world-engine/src/avatars/accessories/bolt.ts b/packages/frontend-misskey-world-engine/src/avatars/accessories/bolt.ts new file mode 100644 index 0000000000..afe2144064 --- /dev/null +++ b/packages/frontend-misskey-world-engine/src/avatars/accessories/bolt.ts @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import * as BABYLON from '@babylonjs/core/pure.js'; +import { bolt_schema } from 'misskey-world/src/avatars/accessories/bolt.schema.js'; +import { defineAccessory } from '../accessory.js'; + +export const bolt = defineAccessory(bolt_schema, { + createInstance: ({ model, options }) => { + const material = model.findMaterial('__X_BOLT__'); + + const applyMat = () => { + material.albedoColor = new BABYLON.Color3(options.mat.color[0], options.mat.color[1], options.mat.color[2]); + material.roughness = options.mat.roughness; + material.metallic = options.mat.metallic; + }; + + applyMat(); + + return { + onOptionsUpdated: ([k, v]) => { + switch (k) { + case 'mat': applyMat(); break; + } + }, + dispose: () => { + }, + }; + }, +}); diff --git a/packages/frontend-misskey-world-engine/src/avatars/accessory-defs.ts b/packages/frontend-misskey-world-engine/src/avatars/accessory-defs.ts index 7eb70a1d3c..e5f08c2112 100644 --- a/packages/frontend-misskey-world-engine/src/avatars/accessory-defs.ts +++ b/packages/frontend-misskey-world-engine/src/avatars/accessory-defs.ts @@ -5,11 +5,13 @@ import { mug } from './accessories/mug.js'; import { mikan } from './accessories/mikan.js'; +import { bolt } from './accessories/bolt.js'; import type { AvatarAccessoryDef } from './accessory.js'; export const AVATAR_ACCESSORY_DEFS = [ mug, mikan, + bolt, ] as AvatarAccessoryDef[]; export function getAccessoryDef(type: string): AvatarAccessoryDef { diff --git a/packages/frontend/assets/world/objects/bolt/bolt.blend b/packages/frontend/assets/world/objects/bolt/bolt.blend new file mode 100644 index 0000000000..5acc3a3eae Binary files /dev/null and b/packages/frontend/assets/world/objects/bolt/bolt.blend differ diff --git a/packages/frontend/assets/world/objects/bolt/bolt.glb b/packages/frontend/assets/world/objects/bolt/bolt.glb new file mode 100644 index 0000000000..f8bd96366b Binary files /dev/null and b/packages/frontend/assets/world/objects/bolt/bolt.glb differ diff --git a/packages/frontend/src/world/avatars/accessories/bolt.ui.ts b/packages/frontend/src/world/avatars/accessories/bolt.ui.ts new file mode 100644 index 0000000000..06529f815a --- /dev/null +++ b/packages/frontend/src/world/avatars/accessories/bolt.ui.ts @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { defineAccessoryUi } from '../defineAccessoryUi.js'; +import type { bolt_schema } from 'misskey-world/src/avatars/accessories/bolt.schema.js'; +import { i18n } from '@/i18n.js'; + +export const bolt_ui = defineAccessoryUi({ + name: i18n.ts._miWorld._avatarAccessories.bolt, + options: { + mat: { + label: i18n.ts._miWorld._avatarAccessories._bolt.mat, + }, + }, +}); diff --git a/packages/frontend/src/world/avatars/accessory-ui-defs.ts b/packages/frontend/src/world/avatars/accessory-ui-defs.ts index 587f415789..2e8a90d4a6 100644 --- a/packages/frontend/src/world/avatars/accessory-ui-defs.ts +++ b/packages/frontend/src/world/avatars/accessory-ui-defs.ts @@ -5,11 +5,13 @@ import { mug_ui } from './accessories/mug.ui.js'; import { mikan_ui } from './accessories/mikan.ui.js'; +import { bolt_ui } from './accessories/bolt.ui.js'; import type { AccessoryUiDef } from './defineAccessoryUi.js'; export const AVATAR_ACCESSORY_UI_DEFS = { mug: mug_ui, mikan: mikan_ui, + bolt: bolt_ui, } as Record; export function getAccessoryUiDef(type: string): AccessoryUiDef { diff --git a/packages/i18n/src/autogen/locale.ts b/packages/i18n/src/autogen/locale.ts index a5f4eeff12..e60e9088ab 100644 --- a/packages/i18n/src/autogen/locale.ts +++ b/packages/i18n/src/autogen/locale.ts @@ -13438,6 +13438,16 @@ export interface Locale extends ILocale { * みかん */ "mikan": string; + /** + * ボルト + */ + "bolt": string; + "_bolt": { + /** + * 素材 + */ + "mat": string; + }; }; }; "_miRoom": { diff --git a/packages/misskey-world/src/avatars/accessories/bolt.schema.ts b/packages/misskey-world/src/avatars/accessories/bolt.schema.ts new file mode 100644 index 0000000000..2d61abefd1 --- /dev/null +++ b/packages/misskey-world/src/avatars/accessories/bolt.schema.ts @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { defineAccessorySchema } from '../accessory.js'; +export const bolt_schema = defineAccessorySchema({ + id: 'bolt', + options: { + schema: { + mat: { + type: 'material', + }, + }, + default: { + mat: { color: [0.8, 0.8, 0.8], roughness: 0.3, metallic: 1 }, + }, + }, +}); diff --git a/packages/misskey-world/src/avatars/accessory-schema-defs.ts b/packages/misskey-world/src/avatars/accessory-schema-defs.ts index d3bc034043..643d85270e 100644 --- a/packages/misskey-world/src/avatars/accessory-schema-defs.ts +++ b/packages/misskey-world/src/avatars/accessory-schema-defs.ts @@ -5,11 +5,13 @@ import { mug_schema } from './accessories/mug.schema.js'; import { mikan_schema } from './accessories/mikan.schema.js'; +import { bolt_schema } from './accessories/bolt.schema.js'; import type { AccessorySchemaDef } from './accessory.js'; export const ACCESSORY_SCHEMA_DEFS = { mug: mug_schema, mikan: mikan_schema, + bolt: bolt_schema, } as Record>; export function getAccessorySchemaDef(type: string): AccessorySchemaDef {