Let the player set the default gamemode and disable cheats during world creation (#915)

* let the user change the default world gamemode and enable or disable cheats

* changes

* make old worlds not have gamerules

* fixes
This commit is contained in:
OneAvargeCoder193 2025-01-11 17:40:31 -05:00 committed by GitHub
parent 16dde882e8
commit 2d783c9ece
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 3 deletions

View File

@ -13,6 +13,7 @@ const Button = @import("../components/Button.zig");
const HorizontalList = @import("../components/HorizontalList.zig");
const Label = @import("../components/Label.zig");
const TextInput = @import("../components/TextInput.zig");
const CheckBox = @import("../components/CheckBox.zig");
const VerticalList = @import("../components/VerticalList.zig");
pub var window = GuiWindow {
@ -23,6 +24,20 @@ const padding: f32 = 8;
var textInput: *TextInput = undefined;
var gamemode: main.game.Gamemode = .creative;
var gamemodeInput: *Button = undefined;
var allowCheats: bool = true;
fn gamemodeCallback(_: usize) void {
gamemode = std.meta.intToEnum(main.game.Gamemode, @intFromEnum(gamemode) + 1) catch @enumFromInt(0);
gamemodeInput.child.label.updateText(@tagName(gamemode));
}
fn allowCheatsCallback(allow: bool) void {
allowCheats = allow;
}
fn createWorld(_: usize) void {
flawedCreateWorld() catch |err| {
std.log.err("Error while creating new world: {s}", .{@errorName(err)});
@ -59,6 +74,17 @@ fn flawedCreateWorld() !void {
generatorSettings.put("climateWavelengths", climateWavelengths);
try main.files.writeZon(generatorSettingsPath, generatorSettings);
}
{
const gamerulePath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/gamerules.zig.zon", .{worldName}) catch unreachable;
defer main.stackAllocator.free(gamerulePath);
const gamerules = main.ZonElement.initObject(main.stackAllocator);
defer gamerules.deinit(main.stackAllocator);
gamerules.put("default_gamemode", @tagName(gamemode));
gamerules.put("cheats", allowCheats);
try main.files.writeZon(gamerulePath, gamerules);
}
{ // Make assets subfolder
const assetsPath = std.fmt.allocPrint(main.stackAllocator.allocator, "saves/{s}/assets", .{worldName}) catch unreachable;
defer main.stackAllocator.free(assetsPath);
@ -83,6 +109,12 @@ pub fn onOpen() void {
const name = std.fmt.bufPrint(&buf, "Save{}", .{num}) catch unreachable;
textInput = TextInput.init(.{0, 0}, 128, 22, name, .{.callback = &createWorld});
list.add(textInput);
gamemodeInput = Button.initText(.{0, 0}, 128, @tagName(gamemode), .{.callback = &gamemodeCallback});
list.add(gamemodeInput);
list.add(CheckBox.init(.{0, 0}, 128, "Allow Cheats", true, &allowCheatsCallback));
list.add(Button.initText(.{0, 0}, 128, "Create World", .{.callback = &createWorld}));
list.finish(.center);

View File

@ -467,8 +467,12 @@ pub fn connectInternal(user: *User) void {
pub fn messageFrom(msg: []const u8, source: *User) void { // MARK: message
if(msg[0] == '/') { // Command.
if (world.?.allowCheats) {
std.log.info("User \"{s}\" executed command \"{s}\"", .{source.name, msg}); // TODO use color \033[0;32m
command.execute(msg[1..], source);
} else {
source.sendMessage("Commands are not allowed because cheats are disabled");
}
} else {
const newMessage = std.fmt.allocPrint(main.stackAllocator.allocator, "[{s}§#ffffff] {s}", .{source.name, msg}) catch unreachable;
defer main.stackAllocator.free(newMessage);

View File

@ -428,6 +428,9 @@ pub const ServerWorld = struct { // MARK: ServerWorld
doGameTimeCycle: bool = true,
gravity: f32 = earthGravity,
defaultGamemode: main.game.Gamemode = undefined,
allowCheats: bool = undefined,
seed: u64,
name: []const u8,
spawn: Vec3i = undefined,
@ -528,6 +531,11 @@ pub const ServerWorld = struct { // MARK: ServerWorld
try files.writeZon(try std.fmt.bufPrint(&buf, "saves/{s}/palette.zig.zon", .{name}), self.blockPalette.save(arenaAllocator));
try files.writeZon(try std.fmt.bufPrint(&buf, "saves/{s}/biome_palette.zig.zon", .{name}), self.biomePalette.save(arenaAllocator));
var gamerules = files.readToZon(arenaAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/gamerules.zig.zon", .{name})) catch ZonElement.initObject(arenaAllocator);
self.defaultGamemode = std.meta.stringToEnum(main.game.Gamemode, gamerules.get([]const u8, "default_gamemode", "creative")) orelse .creative;
self.allowCheats = gamerules.get(bool, "cheats", true);
self.chunkManager = try ChunkManager.init(self, generatorSettings);
errdefer self.chunkManager.deinit();
return self;
@ -774,10 +782,12 @@ pub const ServerWorld = struct { // MARK: ServerWorld
const player = &user.player;
if(playerData == .null) {
player.pos = @floatFromInt(self.spawn);
main.items.Inventory.Sync.setGamemode(user, self.defaultGamemode);
} else {
player.loadFrom(playerData.getChild("entity"));
main.items.Inventory.Sync.setGamemode(user, std.meta.stringToEnum(main.game.Gamemode, playerData.get([]const u8, "gamemode", "survival")) orelse .survival);
main.items.Inventory.Sync.setGamemode(user, std.meta.stringToEnum(main.game.Gamemode, playerData.get([]const u8, "gamemode", @tagName(self.defaultGamemode))) orelse self.defaultGamemode);
}
}