quake2ts 0.0.113 → 0.0.115

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4596,6 +4596,300 @@ var ClientConfigStrings = class {
4596
4596
  }
4597
4597
  };
4598
4598
 
4599
+ // src/ui/menu/main.ts
4600
+ var MainMenuFactory = class {
4601
+ constructor(menuSystem, saveLoadFactory, options) {
4602
+ this.menuSystem = menuSystem;
4603
+ this.saveLoadFactory = saveLoadFactory;
4604
+ this.options = options;
4605
+ }
4606
+ createMainMenu() {
4607
+ const items = [
4608
+ {
4609
+ label: "New Game",
4610
+ action: () => {
4611
+ this.options.onNewGame();
4612
+ }
4613
+ },
4614
+ {
4615
+ label: "Load Game",
4616
+ action: () => {
4617
+ void this.saveLoadFactory.createLoadMenu().then((menu) => {
4618
+ this.menuSystem.pushMenu(menu);
4619
+ });
4620
+ }
4621
+ },
4622
+ {
4623
+ label: "Save Game",
4624
+ action: () => {
4625
+ void this.saveLoadFactory.createSaveMenu().then((menu) => {
4626
+ this.menuSystem.pushMenu(menu);
4627
+ });
4628
+ }
4629
+ },
4630
+ {
4631
+ label: "Options",
4632
+ action: () => {
4633
+ console.log("Options clicked");
4634
+ }
4635
+ },
4636
+ {
4637
+ label: "Quit",
4638
+ action: () => {
4639
+ this.options.onQuit();
4640
+ }
4641
+ }
4642
+ ];
4643
+ return {
4644
+ title: "Main Menu",
4645
+ items
4646
+ };
4647
+ }
4648
+ };
4649
+
4650
+ // src/ui/menu/saveLoad.ts
4651
+ var SaveLoadMenuFactory = class {
4652
+ constructor(menuSystem, storage, onSave, onLoad, onDelete) {
4653
+ this.menuSystem = menuSystem;
4654
+ this.storage = storage;
4655
+ this.onSave = onSave;
4656
+ this.onLoad = onLoad;
4657
+ this.onDelete = onDelete;
4658
+ }
4659
+ async createSaveMenu() {
4660
+ const saves = await this.storage.list();
4661
+ const items = [];
4662
+ items.push({
4663
+ label: "New Save...",
4664
+ action: () => {
4665
+ this.menuSystem.pushMenu(this.createNewSaveInputMenu());
4666
+ }
4667
+ });
4668
+ saves.forEach((save) => {
4669
+ items.push({
4670
+ label: `${save.name} - ${save.map} (${formatTime(save.playtimeSeconds)})`,
4671
+ action: () => {
4672
+ this.menuSystem.pushMenu(this.createConfirmOverwriteMenu(save));
4673
+ }
4674
+ });
4675
+ });
4676
+ items.push({
4677
+ label: "Back",
4678
+ action: () => this.menuSystem.popMenu()
4679
+ });
4680
+ return {
4681
+ title: "Save Game",
4682
+ items
4683
+ };
4684
+ }
4685
+ async createLoadMenu() {
4686
+ const saves = await this.storage.list();
4687
+ const items = [];
4688
+ saves.forEach((save) => {
4689
+ items.push({
4690
+ label: `${save.name} - ${save.map} (${formatTime(save.playtimeSeconds)})`,
4691
+ action: () => {
4692
+ this.menuSystem.pushMenu(this.createLoadActionMenu(save));
4693
+ }
4694
+ });
4695
+ });
4696
+ if (saves.length === 0) {
4697
+ items.push({
4698
+ label: "No saves found",
4699
+ action: () => {
4700
+ }
4701
+ });
4702
+ }
4703
+ items.push({
4704
+ label: "Back",
4705
+ action: () => this.menuSystem.popMenu()
4706
+ });
4707
+ return {
4708
+ title: "Load Game",
4709
+ items
4710
+ };
4711
+ }
4712
+ createLoadActionMenu(save) {
4713
+ return {
4714
+ title: `Slot: ${save.name}`,
4715
+ items: [
4716
+ {
4717
+ label: "Load Game",
4718
+ action: () => {
4719
+ void this.onLoad(save.id).then(() => {
4720
+ this.menuSystem.closeAll();
4721
+ });
4722
+ }
4723
+ },
4724
+ {
4725
+ label: "Delete Save",
4726
+ action: () => {
4727
+ this.menuSystem.pushMenu(this.createConfirmDeleteMenu(save));
4728
+ }
4729
+ },
4730
+ {
4731
+ label: "Back",
4732
+ action: () => this.menuSystem.popMenu()
4733
+ }
4734
+ ]
4735
+ };
4736
+ }
4737
+ createConfirmDeleteMenu(save) {
4738
+ return {
4739
+ title: `Delete ${save.name}?`,
4740
+ items: [
4741
+ {
4742
+ label: "Yes, Delete",
4743
+ action: () => {
4744
+ void this.onDelete(save.id).then(() => {
4745
+ this.menuSystem.popMenu();
4746
+ this.menuSystem.popMenu();
4747
+ this.menuSystem.popMenu();
4748
+ });
4749
+ }
4750
+ },
4751
+ {
4752
+ label: "No, Cancel",
4753
+ action: () => this.menuSystem.popMenu()
4754
+ }
4755
+ ]
4756
+ };
4757
+ }
4758
+ createNewSaveInputMenu() {
4759
+ const state = {
4760
+ name: `Save ${(/* @__PURE__ */ new Date()).toLocaleString()}`
4761
+ };
4762
+ return {
4763
+ title: "Enter Save Name",
4764
+ items: [
4765
+ {
4766
+ label: "Name",
4767
+ type: "input",
4768
+ getValue: () => state.name,
4769
+ onUpdate: (val) => {
4770
+ state.name = val;
4771
+ }
4772
+ },
4773
+ {
4774
+ label: "Save",
4775
+ action: () => {
4776
+ void this.onSave(state.name).then(() => {
4777
+ this.menuSystem.closeAll();
4778
+ });
4779
+ }
4780
+ },
4781
+ {
4782
+ label: "Cancel",
4783
+ action: () => this.menuSystem.popMenu()
4784
+ }
4785
+ ]
4786
+ };
4787
+ }
4788
+ createConfirmOverwriteMenu(save) {
4789
+ return {
4790
+ title: `Overwrite ${save.name}?`,
4791
+ items: [
4792
+ {
4793
+ label: "Yes, Overwrite",
4794
+ action: () => {
4795
+ void this.onSave(save.name).then(() => {
4796
+ this.menuSystem.closeAll();
4797
+ });
4798
+ }
4799
+ },
4800
+ {
4801
+ label: "No, Cancel",
4802
+ action: () => this.menuSystem.popMenu()
4803
+ }
4804
+ ]
4805
+ };
4806
+ }
4807
+ };
4808
+ function formatTime(seconds) {
4809
+ const h = Math.floor(seconds / 3600);
4810
+ const m = Math.floor(seconds % 3600 / 60);
4811
+ const s = Math.floor(seconds % 60);
4812
+ return `${h}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
4813
+ }
4814
+
4815
+ // src/ui/menu/system.ts
4816
+ var MenuSystem = class {
4817
+ constructor() {
4818
+ this.activeMenu = null;
4819
+ this.selectedIndex = 0;
4820
+ this.menuStack = [];
4821
+ }
4822
+ pushMenu(menu) {
4823
+ if (this.activeMenu) {
4824
+ this.menuStack.push(this.activeMenu);
4825
+ if (!menu.parent) {
4826
+ menu.parent = this.activeMenu;
4827
+ }
4828
+ }
4829
+ this.activeMenu = menu;
4830
+ this.selectedIndex = 0;
4831
+ }
4832
+ popMenu() {
4833
+ if (this.menuStack.length > 0) {
4834
+ this.activeMenu = this.menuStack.pop();
4835
+ this.selectedIndex = 0;
4836
+ } else {
4837
+ this.activeMenu = null;
4838
+ }
4839
+ }
4840
+ closeAll() {
4841
+ this.activeMenu = null;
4842
+ this.menuStack = [];
4843
+ this.selectedIndex = 0;
4844
+ }
4845
+ handleInput(action, char) {
4846
+ if (!this.activeMenu) {
4847
+ return false;
4848
+ }
4849
+ const currentItem = this.activeMenu.items[this.selectedIndex];
4850
+ if (action === "up") {
4851
+ this.selectedIndex = (this.selectedIndex - 1 + this.activeMenu.items.length) % this.activeMenu.items.length;
4852
+ return true;
4853
+ }
4854
+ if (action === "down") {
4855
+ this.selectedIndex = (this.selectedIndex + 1) % this.activeMenu.items.length;
4856
+ return true;
4857
+ }
4858
+ if (action === "select") {
4859
+ if (currentItem.action) {
4860
+ currentItem.action();
4861
+ }
4862
+ return true;
4863
+ }
4864
+ if (action === "back") {
4865
+ this.popMenu();
4866
+ return true;
4867
+ }
4868
+ if (currentItem.type === "input" && currentItem.onUpdate && currentItem.getValue) {
4869
+ const currentValue = currentItem.getValue();
4870
+ if (action === "char" && char) {
4871
+ const newValue = (currentValue || "") + char;
4872
+ currentItem.onUpdate(newValue);
4873
+ } else if (action === "left") {
4874
+ const str3 = String(currentValue || "");
4875
+ if (str3.length > 0) {
4876
+ currentItem.onUpdate(str3.slice(0, -1));
4877
+ }
4878
+ }
4879
+ }
4880
+ return true;
4881
+ }
4882
+ isActive() {
4883
+ return this.activeMenu !== null;
4884
+ }
4885
+ getState() {
4886
+ return {
4887
+ activeMenu: this.activeMenu,
4888
+ selectedIndex: this.selectedIndex
4889
+ };
4890
+ }
4891
+ };
4892
+
4599
4893
  // src/input/bindings.ts
4600
4894
  var DEFAULT_BINDINGS = [
4601
4895
  { code: "KeyW", command: "+forward" },
@@ -5128,6 +5422,12 @@ function createClient(imports) {
5128
5422
  predict(command) {
5129
5423
  return prediction.enqueueCommand(command);
5130
5424
  },
5425
+ createMainMenu(options, storage, saveCallback, loadCallback, deleteCallback) {
5426
+ const menuSystem = new MenuSystem();
5427
+ const saveLoadFactory = new SaveLoadMenuFactory(menuSystem, storage, saveCallback, loadCallback, deleteCallback);
5428
+ const factory = new MainMenuFactory(menuSystem, saveLoadFactory, options);
5429
+ return { menuSystem, factory };
5430
+ },
5131
5431
  render(sample) {
5132
5432
  const playbackState = demoPlayback.getState();
5133
5433
  if (playbackState === PlaybackState.Playing) {