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.
@@ -4628,6 +4628,300 @@ var ClientConfigStrings = class {
4628
4628
  }
4629
4629
  };
4630
4630
 
4631
+ // src/ui/menu/main.ts
4632
+ var MainMenuFactory = class {
4633
+ constructor(menuSystem, saveLoadFactory, options) {
4634
+ this.menuSystem = menuSystem;
4635
+ this.saveLoadFactory = saveLoadFactory;
4636
+ this.options = options;
4637
+ }
4638
+ createMainMenu() {
4639
+ const items = [
4640
+ {
4641
+ label: "New Game",
4642
+ action: () => {
4643
+ this.options.onNewGame();
4644
+ }
4645
+ },
4646
+ {
4647
+ label: "Load Game",
4648
+ action: () => {
4649
+ void this.saveLoadFactory.createLoadMenu().then((menu) => {
4650
+ this.menuSystem.pushMenu(menu);
4651
+ });
4652
+ }
4653
+ },
4654
+ {
4655
+ label: "Save Game",
4656
+ action: () => {
4657
+ void this.saveLoadFactory.createSaveMenu().then((menu) => {
4658
+ this.menuSystem.pushMenu(menu);
4659
+ });
4660
+ }
4661
+ },
4662
+ {
4663
+ label: "Options",
4664
+ action: () => {
4665
+ console.log("Options clicked");
4666
+ }
4667
+ },
4668
+ {
4669
+ label: "Quit",
4670
+ action: () => {
4671
+ this.options.onQuit();
4672
+ }
4673
+ }
4674
+ ];
4675
+ return {
4676
+ title: "Main Menu",
4677
+ items
4678
+ };
4679
+ }
4680
+ };
4681
+
4682
+ // src/ui/menu/saveLoad.ts
4683
+ var SaveLoadMenuFactory = class {
4684
+ constructor(menuSystem, storage, onSave, onLoad, onDelete) {
4685
+ this.menuSystem = menuSystem;
4686
+ this.storage = storage;
4687
+ this.onSave = onSave;
4688
+ this.onLoad = onLoad;
4689
+ this.onDelete = onDelete;
4690
+ }
4691
+ async createSaveMenu() {
4692
+ const saves = await this.storage.list();
4693
+ const items = [];
4694
+ items.push({
4695
+ label: "New Save...",
4696
+ action: () => {
4697
+ this.menuSystem.pushMenu(this.createNewSaveInputMenu());
4698
+ }
4699
+ });
4700
+ saves.forEach((save) => {
4701
+ items.push({
4702
+ label: `${save.name} - ${save.map} (${formatTime(save.playtimeSeconds)})`,
4703
+ action: () => {
4704
+ this.menuSystem.pushMenu(this.createConfirmOverwriteMenu(save));
4705
+ }
4706
+ });
4707
+ });
4708
+ items.push({
4709
+ label: "Back",
4710
+ action: () => this.menuSystem.popMenu()
4711
+ });
4712
+ return {
4713
+ title: "Save Game",
4714
+ items
4715
+ };
4716
+ }
4717
+ async createLoadMenu() {
4718
+ const saves = await this.storage.list();
4719
+ const items = [];
4720
+ saves.forEach((save) => {
4721
+ items.push({
4722
+ label: `${save.name} - ${save.map} (${formatTime(save.playtimeSeconds)})`,
4723
+ action: () => {
4724
+ this.menuSystem.pushMenu(this.createLoadActionMenu(save));
4725
+ }
4726
+ });
4727
+ });
4728
+ if (saves.length === 0) {
4729
+ items.push({
4730
+ label: "No saves found",
4731
+ action: () => {
4732
+ }
4733
+ });
4734
+ }
4735
+ items.push({
4736
+ label: "Back",
4737
+ action: () => this.menuSystem.popMenu()
4738
+ });
4739
+ return {
4740
+ title: "Load Game",
4741
+ items
4742
+ };
4743
+ }
4744
+ createLoadActionMenu(save) {
4745
+ return {
4746
+ title: `Slot: ${save.name}`,
4747
+ items: [
4748
+ {
4749
+ label: "Load Game",
4750
+ action: () => {
4751
+ void this.onLoad(save.id).then(() => {
4752
+ this.menuSystem.closeAll();
4753
+ });
4754
+ }
4755
+ },
4756
+ {
4757
+ label: "Delete Save",
4758
+ action: () => {
4759
+ this.menuSystem.pushMenu(this.createConfirmDeleteMenu(save));
4760
+ }
4761
+ },
4762
+ {
4763
+ label: "Back",
4764
+ action: () => this.menuSystem.popMenu()
4765
+ }
4766
+ ]
4767
+ };
4768
+ }
4769
+ createConfirmDeleteMenu(save) {
4770
+ return {
4771
+ title: `Delete ${save.name}?`,
4772
+ items: [
4773
+ {
4774
+ label: "Yes, Delete",
4775
+ action: () => {
4776
+ void this.onDelete(save.id).then(() => {
4777
+ this.menuSystem.popMenu();
4778
+ this.menuSystem.popMenu();
4779
+ this.menuSystem.popMenu();
4780
+ });
4781
+ }
4782
+ },
4783
+ {
4784
+ label: "No, Cancel",
4785
+ action: () => this.menuSystem.popMenu()
4786
+ }
4787
+ ]
4788
+ };
4789
+ }
4790
+ createNewSaveInputMenu() {
4791
+ const state = {
4792
+ name: `Save ${(/* @__PURE__ */ new Date()).toLocaleString()}`
4793
+ };
4794
+ return {
4795
+ title: "Enter Save Name",
4796
+ items: [
4797
+ {
4798
+ label: "Name",
4799
+ type: "input",
4800
+ getValue: () => state.name,
4801
+ onUpdate: (val) => {
4802
+ state.name = val;
4803
+ }
4804
+ },
4805
+ {
4806
+ label: "Save",
4807
+ action: () => {
4808
+ void this.onSave(state.name).then(() => {
4809
+ this.menuSystem.closeAll();
4810
+ });
4811
+ }
4812
+ },
4813
+ {
4814
+ label: "Cancel",
4815
+ action: () => this.menuSystem.popMenu()
4816
+ }
4817
+ ]
4818
+ };
4819
+ }
4820
+ createConfirmOverwriteMenu(save) {
4821
+ return {
4822
+ title: `Overwrite ${save.name}?`,
4823
+ items: [
4824
+ {
4825
+ label: "Yes, Overwrite",
4826
+ action: () => {
4827
+ void this.onSave(save.name).then(() => {
4828
+ this.menuSystem.closeAll();
4829
+ });
4830
+ }
4831
+ },
4832
+ {
4833
+ label: "No, Cancel",
4834
+ action: () => this.menuSystem.popMenu()
4835
+ }
4836
+ ]
4837
+ };
4838
+ }
4839
+ };
4840
+ function formatTime(seconds) {
4841
+ const h = Math.floor(seconds / 3600);
4842
+ const m = Math.floor(seconds % 3600 / 60);
4843
+ const s = Math.floor(seconds % 60);
4844
+ return `${h}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
4845
+ }
4846
+
4847
+ // src/ui/menu/system.ts
4848
+ var MenuSystem = class {
4849
+ constructor() {
4850
+ this.activeMenu = null;
4851
+ this.selectedIndex = 0;
4852
+ this.menuStack = [];
4853
+ }
4854
+ pushMenu(menu) {
4855
+ if (this.activeMenu) {
4856
+ this.menuStack.push(this.activeMenu);
4857
+ if (!menu.parent) {
4858
+ menu.parent = this.activeMenu;
4859
+ }
4860
+ }
4861
+ this.activeMenu = menu;
4862
+ this.selectedIndex = 0;
4863
+ }
4864
+ popMenu() {
4865
+ if (this.menuStack.length > 0) {
4866
+ this.activeMenu = this.menuStack.pop();
4867
+ this.selectedIndex = 0;
4868
+ } else {
4869
+ this.activeMenu = null;
4870
+ }
4871
+ }
4872
+ closeAll() {
4873
+ this.activeMenu = null;
4874
+ this.menuStack = [];
4875
+ this.selectedIndex = 0;
4876
+ }
4877
+ handleInput(action, char) {
4878
+ if (!this.activeMenu) {
4879
+ return false;
4880
+ }
4881
+ const currentItem = this.activeMenu.items[this.selectedIndex];
4882
+ if (action === "up") {
4883
+ this.selectedIndex = (this.selectedIndex - 1 + this.activeMenu.items.length) % this.activeMenu.items.length;
4884
+ return true;
4885
+ }
4886
+ if (action === "down") {
4887
+ this.selectedIndex = (this.selectedIndex + 1) % this.activeMenu.items.length;
4888
+ return true;
4889
+ }
4890
+ if (action === "select") {
4891
+ if (currentItem.action) {
4892
+ currentItem.action();
4893
+ }
4894
+ return true;
4895
+ }
4896
+ if (action === "back") {
4897
+ this.popMenu();
4898
+ return true;
4899
+ }
4900
+ if (currentItem.type === "input" && currentItem.onUpdate && currentItem.getValue) {
4901
+ const currentValue = currentItem.getValue();
4902
+ if (action === "char" && char) {
4903
+ const newValue = (currentValue || "") + char;
4904
+ currentItem.onUpdate(newValue);
4905
+ } else if (action === "left") {
4906
+ const str3 = String(currentValue || "");
4907
+ if (str3.length > 0) {
4908
+ currentItem.onUpdate(str3.slice(0, -1));
4909
+ }
4910
+ }
4911
+ }
4912
+ return true;
4913
+ }
4914
+ isActive() {
4915
+ return this.activeMenu !== null;
4916
+ }
4917
+ getState() {
4918
+ return {
4919
+ activeMenu: this.activeMenu,
4920
+ selectedIndex: this.selectedIndex
4921
+ };
4922
+ }
4923
+ };
4924
+
4631
4925
  // src/input/bindings.ts
4632
4926
  var DEFAULT_BINDINGS = [
4633
4927
  { code: "KeyW", command: "+forward" },
@@ -5160,6 +5454,12 @@ function createClient(imports) {
5160
5454
  predict(command) {
5161
5455
  return prediction.enqueueCommand(command);
5162
5456
  },
5457
+ createMainMenu(options, storage, saveCallback, loadCallback, deleteCallback) {
5458
+ const menuSystem = new MenuSystem();
5459
+ const saveLoadFactory = new SaveLoadMenuFactory(menuSystem, storage, saveCallback, loadCallback, deleteCallback);
5460
+ const factory = new MainMenuFactory(menuSystem, saveLoadFactory, options);
5461
+ return { menuSystem, factory };
5462
+ },
5163
5463
  render(sample) {
5164
5464
  const playbackState = demoPlayback.getState();
5165
5465
  if (playbackState === PlaybackState.Playing) {