Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 132 additions & 28 deletions src/gui/windows/save_creation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const ConnectionManager = main.network.ConnectionManager;
const settings = main.settings;
const Vec2f = main.vec.Vec2f;
const NeverFailingAllocator = main.heap.NeverFailingAllocator;
const Texture = main.graphics.Texture;
const ZonElement = main.ZonElement;

const gui = @import("../gui.zig");
Expand Down Expand Up @@ -38,6 +39,81 @@ var selectedPreset: usize = undefined;
var defaultPreset: usize = 0;
var presetButton: *Button = undefined;

var needsUpdate: bool = false;

var deleteIcon: Texture = undefined;
var fileExplorerIcon: Texture = undefined;

var page: Page = .generation;
const numPages: usize = std.meta.fields(Page).len;

const Page = enum(u8) {
generation = 0,
gameRules = 1,

pub fn fillSubmenu(self: Page, submenu: *VerticalList) void {
const maxWidth = 192;
switch (self) {
.generation => {
{ // world preset
const row = HorizontalList.init();
row.add(Label.init(.{0, 0}, maxWidth - 128, "Preset:", .left));
presetButton = Button.initText(.{0, 0}, 128, worldPresets[selectedPreset].key_ptr.*, .init(worldPresetCallback));
row.add(presetButton);
row.finish(.{0, 0}, .center);
submenu.add(row);
}

{ // seed
const row = HorizontalList.init();
row.add(Label.init(.{0, 0}, 48, "Seed:", .left));
seedInput = TextInput.init(.{0, 0}, maxWidth - 48, 22, "", .{.onNewline = .init(createWorld)});
row.add(seedInput);
row.finish(.{0, 0}, .center);
submenu.add(row);
}
},
.gameRules => {
{
const row = HorizontalList.init();
row.add(Label.init(.{0, 0}, maxWidth - 96, "Game Mode:", .left));
gamemodeInput = Button.initText(.{0, 0}, 96, @tagName(worldSettings.defaultGamemode), .init(gamemodeCallback));
row.add(gamemodeInput);
row.finish(.{0, 0}, .center);
submenu.add(row);
}

submenu.add(CheckBox.init(.{0, 0}, maxWidth, "Allow Cheats", worldSettings.allowCheats, &allowCheatsCallback));
},
}
}

pub fn label(self: Page) []const u8 {
switch (self) {
.generation => {
return "Generation (1/2)";
},
.gameRules => {
return "Game Rules (2/2)";
},
}
}
};

fn prevPage() void {
const oldPageInt = @intFromEnum(page);
const newPageInt = (oldPageInt -% 1);
page = std.meta.intToEnum(Page, newPageInt) catch .gameRules;
needsUpdate = true;
}

fn nextPage() void {
const oldPageInt = @intFromEnum(page);
const newPageInt = (oldPageInt + 1);
page = std.meta.intToEnum(Page, newPageInt) catch .generation;
needsUpdate = true;
}

fn chooseSeed(seedStr: []const u8) u64 {
if (seedStr.len == 0) {
return main.random.nextInt(u64, &main.seed);
Expand Down Expand Up @@ -80,7 +156,7 @@ fn createWorld() void {
}

pub fn onOpen() void {
const list = VerticalList.init(.{padding, 16 + padding}, 300, 8);
const list = VerticalList.init(.{padding, 16 + padding}, 500, 8);

if (worldPresets.len == 0) {
var presetMap = main.assets.worldPresets();
Expand All @@ -102,40 +178,48 @@ pub fn onOpen() void {
}
}
}
selectedPreset = defaultPreset;

var num: usize = 1;
while (true) {
const path = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/Save{}", .{num}) catch unreachable;
defer main.stackAllocator.free(path);
if (!main.files.cubyzDir().hasDir(path)) break;
num += 1;
if (!needsUpdate) selectedPreset = defaultPreset;

{ // name field
const label = Label.init(.{0, 0}, 96, "World Name:", .center);
var num: usize = 1;
while (true) {
const path = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/Save{}", .{num}) catch unreachable;
defer main.stackAllocator.free(path);
if (!main.files.cubyzDir().hasDir(path)) break;
num += 1;
}
const name = std.fmt.allocPrint(main.stackAllocator.allocator, "Save{}", .{num}) catch unreachable;
defer main.stackAllocator.free(name);
nameInput = TextInput.init(.{0, 0}, 256 - 96, 22, name, .{.onNewline = .init(createWorld)});
const nameRow = HorizontalList.init();
nameRow.add(label);
nameRow.add(nameInput);
nameRow.finish(.{0, 0}, .center);
list.add(nameRow);
}
const name = std.fmt.allocPrint(main.stackAllocator.allocator, "Save{}", .{num}) catch unreachable;
defer main.stackAllocator.free(name);
nameInput = TextInput.init(.{0, 0}, 128, 22, name, .{.onNewline = .init(createWorld)});
list.add(nameInput);

gamemodeInput = Button.initText(.{0, 0}, 128, @tagName(worldSettings.defaultGamemode), .init(gamemodeCallback));
list.add(gamemodeInput);
{ // page title and switch buttons
const leftArrow = Button.initText(.{0, 0}, 24, "<", .init(prevPage));
const label = Label.init(.{0, 0}, 224 - 48, page.label(), .center);
const rightArrow = Button.initText(.{0, 0}, 24, ">", .init(nextPage));
const header = HorizontalList.init();
header.add(leftArrow);
header.add(label);
header.add(rightArrow);
header.finish(.{0, 0}, .center);
list.add(header);
}

list.add(CheckBox.init(.{0, 0}, 128, "Allow Cheats", worldSettings.allowCheats, &allowCheatsCallback));
const submenu = VerticalList.init(.{0, 8}, 384, 8);
page.fillSubmenu(submenu);
submenu.finish(.center);
list.add(submenu);

if (!build_options.isTaggedRelease) {
list.add(CheckBox.init(.{0, 0}, 128, "Testing mode (for developers)", worldSettings.testingMode, &testingModeCallback));
list.add(CheckBox.init(.{0, 0}, 192, "Testing mode (for developers)", worldSettings.testingMode, &testingModeCallback));
}

presetButton = Button.initText(.{0, 0}, 128, worldPresets[selectedPreset].key_ptr.*, .init(worldPresetCallback));
list.add(presetButton);

const seedLabel = Label.init(.{0, 0}, 48, "Seed:", .left);
seedInput = TextInput.init(.{0, 0}, 128 - 48, 22, "", .{.onNewline = .init(createWorld)});
const seedRow = HorizontalList.init();
seedRow.add(seedLabel);
seedRow.add(seedInput);
seedRow.finish(.{0, 0}, .center);
list.add(seedRow);

list.add(Button.initText(.{0, 0}, 128, "Create World", .init(createWorld)));

list.finish(.center);
Expand All @@ -149,3 +233,23 @@ pub fn onClose() void {
comp.deinit();
}
}

pub fn render() void {
if (needsUpdate) {
var oldWorldName = window.rootComponent.?.verticalList.children.items[0].horizontalList.children.items[1].textInput.currentString.items;
oldWorldName = std.fmt.allocPrint(main.stackAllocator.allocator, "{s}", .{oldWorldName}) catch unreachable;
defer main.stackAllocator.free(oldWorldName);

const oldScroll = window.rootComponent.?.verticalList.children.items[2].verticalList.scrollBar.currentState;
const oldPage = page;

onClose();
page = oldPage;

onOpen();
window.rootComponent.?.verticalList.children.items[0].horizontalList.children.items[1].textInput.setString(oldWorldName);
window.rootComponent.?.verticalList.children.items[2].verticalList.scrollBar.currentState = oldScroll;

needsUpdate = false;
}
}
Loading