Skip to content

Commit 40e7bc3

Browse files
authored
新增快捷導入用事件json以及填充事件的完善...
添加了透過簡化json來配置所有事件的入口 完善透過事件動態調整填充延遲與填充方塊數的部分 添加Twitch小奇點的事件支持
1 parent dfcfeac commit 40e7bc3

18 files changed

Lines changed: 858 additions & 60 deletions

[BP]iiTNTC/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232
},
3333
{
3434
"module_name": "@minecraft/server",
35-
"version": "1.13.0"
35+
"version": "1.19.0"
3636
},
3737
{
3838
"module_name": "@minecraft/server-ui",
39-
"version": "1.1.0"
39+
"version": "1.3.0"
4040
}
4141
],
4242
"metadata": {

[BP]iiTNTC/scripts/core/EventActionForm.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ export class EventActionForm {
310310
return;
311311

312312
const fillOptions = action.fillOptions || {
313-
delay:20,
314-
amount:20,
313+
delay:1,
314+
amount:50,
315315
fillStop:false
316316
};
317317
let formTitle = `Fill Action: ${isEdit ? 'Edit' : 'Create'} Action`;

[BP]iiTNTC/scripts/game/TNTCoin.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,15 @@ export class TNTCoin {
3737
memberActionManager;
3838
likeActionManager;
3939
chatActionManager;
40+
rewardActionManager;
4041
_isPlayerInGame = false;
4142
_gameKey;
4243
_taskAutoSaveId;
4344
_taskCameraId;
4445
_taskFillCheckId;
4546
_useBarriers = false;
4647
_doesCameraRotate = true;
47-
_randomizeBlocks = true;
48+
_randomizeBlocks = false;
4849
_summonEntityFormSettings = {
4950
entityName: 'tnt_minecart',
5051
locationType: 'random',
@@ -78,6 +79,7 @@ export class TNTCoin {
7879
this.memberActionManager = new EventActionManager(player, 'MemberActions');
7980
this.likeActionManager = new EventActionManager(player, 'LikeActions');
8081
this.chatActionManager = new EventActionManager(player, 'ChatActions');
82+
this.rewardActionManager = new EventActionManager(player, 'RewardActions');
8183
this._taskAutoSaveId = `${player.name}:autosave`;
8284
this._taskFillCheckId = `${player.name}:fillcheck`;
8385
this._taskCameraId = `${player.name}:camera`;

[BP]iiTNTC/scripts/game/TNTCoinGui.js

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,59 @@ import { ShareActionForm } from "./actions/ShareAction";
1212
import { MemberActionForm } from "./actions/MemberAction";
1313
import { LikeActionForm } from "./actions/LikeAction";
1414
import { ChatActionForm } from "./actions/ChatAction";
15+
//給Twitch忠誠點數兌換觸發用的事件(依據花費點數量觸發)
16+
import { REActionForm } from "./actions/RewardAction";
1517
/**
1618
* A map of player names in-game with a TNTCoinGUI instance.
1719
*/
1820
export const INGAME_PLAYERS = new Map();
21+
22+
23+
24+
export class EventA {
25+
_player;
26+
_game;
27+
28+
constructor(player, game) {
29+
this._player = player;
30+
this._game = game
31+
this.showActionFormPage1 = this.showActionFormPage1.bind(this);
32+
this.showActionFormPage2 = this.showActionFormPage2.bind(this);
33+
}
34+
// Page 1
35+
showActionFormPage1() {
36+
37+
const giftAction = new GiftActionForm(this._player, this._game.giftActionManager);
38+
const likeAction = new LikeActionForm(this._player, this._game.likeActionManager);
39+
const memberAction = new MemberActionForm(this._player, this._game.memberActionManager);
40+
const followAction = new FollowActionForm(this._player, this._game.followActionManager);
41+
42+
43+
44+
new ActionForm(this._player, 'Event Actions - Page 1')
45+
.button('Gift Actions', giftAction.show.bind(giftAction), 'textures/tnt-coin/gui/buttons/gift.png') // 可以跳頁
46+
.button('Like Actions', likeAction.show.bind(likeAction), 'textures/tnt-coin/gui/buttons/heart.png')
47+
.button('Member Actions', memberAction.show.bind(memberAction), 'textures/tnt-coin/gui/buttons/member.png')
48+
.button('Follow Actions', followAction.show.bind(followAction), 'textures/tnt-coin/gui/buttons/follow.png')
49+
.button('Next Page', this.showActionFormPage2.bind(this) ) // 可以跳頁
50+
.show();
51+
}
52+
53+
// Page 2
54+
showActionFormPage2() {
55+
const shareAction = new ShareActionForm(this._player, this._game.shareActionManager);
56+
const chatAction = new ChatActionForm(this._player, this._game.chatActionManager);
57+
const rewardAction = new REActionForm(this._player, this._game.rewardActionManager);
58+
59+
new ActionForm(this._player, 'Event Actions - Page 2')
60+
.button('Chat Actions', chatAction.show.bind(chatAction), 'textures/tnt-coin/gui/buttons/chat.png')
61+
.button('Share Actions', shareAction.show.bind(shareAction), 'textures/tnt-coin/gui/buttons/share.png')
62+
.button('Reward Actions', rewardAction.show.bind(rewardAction), 'textures/tnt-coin/gui/buttons/reward.png')
63+
.button('Back', this.showActionFormPage1.bind(this) ) // 返回上一頁
64+
.show();
65+
}
66+
67+
}
1968
/**
2069
* Represents a TNTCoin game instance with a GUI.
2170
*/
@@ -185,7 +234,11 @@ export class TNTCoinGUI {
185234
/**
186235
* Shows the in-game form to the player.
187236
*/
237+
238+
239+
188240
showInGameForm() {
241+
const EGUI = new EventA(this._player, this._game);
189242
const wins = this._game.winManager.getCurrentWins();
190243
const maxWin = this._game.winManager.getMaxWins();
191244
let maxfillblock=this._structure.airBlockLocations.length + this._structure.filledBlockLocations.size
@@ -206,29 +259,17 @@ export class TNTCoinGUI {
206259
.button('Teleport', () => this._game.teleportPlayer(this._structure.structureHeight), 'textures/tnt-coin/gui/buttons/ender_pearl.png')
207260
.button('Timer', this.showTimerForm.bind(this), 'textures/tnt-coin/gui/buttons/clock.png')
208261
.button('Gift Goal', this.showGiftGoalForm.bind(this), 'textures/tnt-coin/gui/buttons/goals.png')
209-
.button('§2§kii§r§8Event Actions§2§kii§r', this.showEventActionsForm.bind(this), 'textures/tnt-coin/gui/buttons/events.png')
262+
.button('§2§kii§r§8Event Actions§2§kii§r', EGUI.showActionFormPage1.bind(this), 'textures/tnt-coin/gui/buttons/events.png')
210263
.button('§2§kii§r§8Events§2§kii§r', this.showEventsForm.bind(this), 'textures/tnt-coin/gui/buttons/bell.png')
211264
.button('Settings', this.showInGameSettingsForm.bind(this), 'textures/tnt-coin/gui/buttons/settings.png')
212265
.button('Reload', this._game.loadGame.bind(this._game), 'textures/tnt-coin/gui/buttons/reload.png')
213266
.button('Quit', this._game.quitGame.bind(this._game), 'textures/tnt-coin/gui/buttons/left.png')
214267
.show();
215268
}
216-
showEventActionsForm() {
217-
const giftAction = new GiftActionForm(this._player, this._game.giftActionManager);
218-
const followAction = new FollowActionForm(this._player, this._game.followActionManager);
219-
const shareAction = new ShareActionForm(this._player, this._game.shareActionManager);
220-
const memberAction = new MemberActionForm(this._player, this._game.memberActionManager);
221-
const likeAction = new LikeActionForm(this._player, this._game.likeActionManager);
222-
const chatAction = new ChatActionForm(this._player, this._game.chatActionManager);
223-
new ActionForm(this._player, 'Event Actions')
224-
.button('Gift Actions', giftAction.show.bind(giftAction), 'textures/tnt-coin/gui/buttons/gift.png')
225-
.button('Like Actions', likeAction.show.bind(likeAction), 'textures/tnt-coin/gui/buttons/heart.png')
226-
.button('Member Actions', memberAction.show.bind(memberAction), 'textures/tnt-coin/gui/buttons/member.png')
227-
.button('Follow Actions', followAction.show.bind(followAction), 'textures/tnt-coin/gui/buttons/follow.png')
228-
.button('Chat Actions', chatAction.show.bind(chatAction), 'textures/tnt-coin/gui/buttons/chat.png')
229-
.button('Share Actions', shareAction.show.bind(shareAction), 'textures/tnt-coin/gui/buttons/share.png')
230-
.show();
231-
}
269+
270+
271+
272+
232273
/**
233274
* Shows the form to set up or modify the gift goal.
234275
*/
@@ -309,7 +350,8 @@ export class TNTCoinGUI {
309350
.textField("number", "[§eFILL§r] Delay in Ticks:", "Enter the delay in ticks to fill blocks", oldSettings.fillSettings.tickInterval.toString(), (updatedValue) => newSettings.fillSettings.tickInterval = updatedValue)
310351
.textField("number", "[§eFILL§r] Amount of Blocks per tick:", 'Enter the amount of blocks to fill per tick', oldSettings.fillSettings.blocksPerTick.toString(), (updatedValue) => newSettings.fillSettings.blocksPerTick = updatedValue)
311352
.textField("number", "[§eFILL§r] 方塊容錯:", '允許方塊容錯數', this._game.structure.allowAmount.toString(), (updatedValue) => this._game.structure.allowAmount = updatedValue)
312-
353+
.textField("number", "[§eDetectTick§r] 框架方塊保護檢測間隔:", 'Tick延遲', this._game.structure.detectTick.toString(), (updatedValue) => this._game.structure.detectTick = updatedValue)
354+
313355
.submitButton('§2Update Settings§r')
314356
.show(() => {
315357
const isSettingsChanged = JSON.stringify(oldSettings) !== JSON.stringify(newSettings);

[BP]iiTNTC/scripts/game/TNTCoinStructure.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export class TNTCoinStructure {
2020
_fillTickInterval = 1;
2121
_fillBlocksPerTick = 50;
2222
_fillAllowAirAmount = 0;
23+
_detectTick=2;
24+
2325
_isFilling = false;
2426
_protectedBlockLocations = new Set();
2527
_airBlockLocations = new Set();
@@ -92,10 +94,18 @@ export class TNTCoinStructure {
9294
set allowAmount(allAmount){
9395
this._fillAllowAirAmount = allAmount;
9496
}
95-
set fillSettings({ blockName, tickInterval, blocksPerTick }) {
96-
this._fillBlockName = blockName;
97-
this._fillTickInterval = tickInterval;
98-
this._fillBlocksPerTick = blocksPerTick;
97+
98+
get detectTick(){
99+
return this._detectTick;
100+
}
101+
set detectTick(tick){
102+
this._detectTick = tick;
103+
}
104+
105+
set fillSettings({ tickInterval, blocksPerTick, blockName }) {
106+
if (blockName !== undefined) this._fillBlockName = blockName;
107+
if (tickInterval !== undefined) this._fillTickInterval = tickInterval;
108+
if (blocksPerTick !== undefined) this._fillBlocksPerTick = blocksPerTick;
99109
}
100110
/**
101111
* Gets a value indicating whether the structure is currently being filled.
@@ -226,7 +236,7 @@ export class TNTCoinStructure {
226236
* @returns {Promise<void>} a promise that resolves when all blocks have been generated.
227237
*/
228238
async generateProtectedBlocks(blocks) {
229-
const chunkSize = 1000;
239+
const chunkSize = 200;
230240

231241
// 先按 blockName 分組
232242
const blocksByName = {};
@@ -259,7 +269,7 @@ export class TNTCoinStructure {
259269
*/
260270

261271

262-
async iterateProtectedBlockLocations(startingPosition, handleBlock, batchSize = 1000) {
272+
async iterateProtectedBlockLocations(startingPosition, handleBlock, batchSize = 200) {
263273
this._airBlockLocations.clear();
264274
const { width, height, centerLocation, blockOptions } = this.structureProperties;
265275
const { baseBlockName, sideBlockName, floorBlockName } = blockOptions;
@@ -302,7 +312,7 @@ export class TNTCoinStructure {
302312
}
303313
}
304314
// 等待一個 tick,讓 event loop 先處理其他事情,避免 Watchdog
305-
await new Promise(resolve => system.runTimeout(resolve, 1));
315+
await new Promise(resolve => system.runTimeout(resolve, this._detectTick));
306316
}
307317
}
308318
/**
@@ -442,7 +452,11 @@ export class TNTCoinStructure {
442452

443453
const loc = floorVector3(location);
444454
const key = JSON.stringify(loc);
445-
455+
456+
457+
// ✅ 檢查是不是結構範圍內需要處理的位置
458+
if (!this._airBlockLocations.has(key)) return;
459+
446460
if (!isBlockAir(this._dimension, loc)) {
447461
this._filledBlockLocations.add(key);
448462
} else {

[BP]iiTNTC/scripts/game/actions/ChatAction.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ export class ChatActionForm extends EventActionFormBase {
2424
.show(response => {
2525
const chat = response[0];
2626
this._eventActionForm.showCreateActionForm({
27-
eventKey: chat,
28-
chat
27+
eventKey: chat
2928
}, this._actionOptions);
3029
});
3130
}

[BP]iiTNTC/scripts/game/actions/GiftAction.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { EventActionForm } from "../../core/EventActionForm";
44
import { EventActionFormBase } from "./EventActionFormBase";
55
export class GiftActionForm extends EventActionFormBase {
66
constructor(player, giftActionManager) {
7-
super(player, new EventActionForm(player, giftActionManager));
7+
super(player, new EventActionForm(player,giftActionManager));
88
}
99
show() {
1010
const giftEvents = this._eventActionForm.actionManager.getAllEvents();
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { EventActionForm } from "../../core/EventActionForm";
2+
import { ActionForm, ModalForm } from "../../core/Form";
3+
import { EventActionFormBase } from "./EventActionFormBase";
4+
export class REActionForm extends EventActionFormBase {
5+
constructor(player, rewardActionManager) {
6+
super(player, new EventActionForm(player, rewardActionManager));
7+
}
8+
show() {
9+
const chatEvents = this._eventActionForm.actionManager.getAllEvents();
10+
const form = new ActionForm(this._player, 'Reward Actions');
11+
chatEvents.forEach((actions, eventKey) => {
12+
form.button(`§2§kii§r§e${eventKey} §8Chat§2§kii§r\n§2Actions: [${actions.length}]`, () => {
13+
this.showRActionsForm(eventKey, `Actions for ${eventKey} Reward`, actions);
14+
});
15+
});
16+
form.button('Create New Chat Action', () => this.showCreateNewActionForm());
17+
form.button('Clear All Actions', () => this._eventActionForm.showClearAllActionsForm(chatEvents));
18+
form.show();
19+
}
20+
showCreateNewActionForm() {
21+
new ModalForm(this._player, 'Create New Reward Action')
22+
.textField('number', 'Enter the number for action', "50", "100")
23+
.submitButton('Continue')
24+
.show(response => {
25+
const chat = response[0];
26+
this._eventActionForm.showCreateActionForm({
27+
eventKey: chat,
28+
chat
29+
}, this._actionOptions);
30+
});
31+
}
32+
showRActionsForm(eventKey, formTitle, chatActions) {
33+
const form = new ActionForm(this._player, formTitle);
34+
form.body(`§2§kii§r§fTotal Actions: §d${chatActions.length}§2§kii§r\nUse Point: §e${eventKey}§f.`);
35+
chatActions.forEach((action, index) => {
36+
let text = '';
37+
if (action.actionType === 'Summon') {
38+
text += ` - ${action.summonOptions.entityName.toUpperCase()} x${action.summonOptions?.amount}`;
39+
}
40+
else if (action.actionType === 'Play Sound') {
41+
text += ` - ${action.playSound}`;
42+
}
43+
form.button(`§2§kii§r§8${index + 1}. ${action.actionType}${text}§2§kii§r`, () => {
44+
this._eventActionForm.showActionInfo(action, index);
45+
});
46+
});
47+
form.button('Clear All Actions', () => {
48+
this._eventActionForm.showClearAllActionsFromEvent(eventKey);
49+
});
50+
form.show();
51+
}
52+
}

[BP]iiTNTC/scripts/game/actions/executeAction.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ export function executeAction(game, action) {
2727
game.structure.fillStop()
2828
game.player.sendMessage("[Fill]Stop Fill Block Work")
2929
}else{
30+
game.structure.fillSettings = {
31+
tickInterval : action.fillOptions.delay,
32+
blocksPerTick : action.fillOptions.amount
33+
}
34+
game.player.sendMessage(`填充速度${action.fillOptions.delay}T 數量:${action.fillOptions.amount}`)
3035
game.structure.fill();
3136
game.player.sendMessage("[Fill]Start Fill Block Work")
3237
}

0 commit comments

Comments
 (0)