Skip to content

Commit

Permalink
Allow teleporting to a biome with /tp.
Browse files Browse the repository at this point in the history
  • Loading branch information
IntegratedQuantum committed Dec 20, 2024
1 parent c784f16 commit 84afe1a
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
61 changes: 60 additions & 1 deletion src/server/command/tp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,68 @@ const main = @import("root");
const User = main.server.User;

pub const description = "Teleport to location.";
pub const usage = "/tp <x> <y>\n/tp <x> <y> <z>";
pub const usage = "/tp <x> <y>\n/tp <x> <y> <z>\n/tp <biome>";

pub fn execute(args: []const u8, source: *User) void {
if(std.mem.containsAtLeast(u8, args, 1, ":")) {
const biome = main.server.terrain.biomes.getById(args);
if(!std.mem.eql(u8, biome.id, args)) {
const msg = std.fmt.allocPrint(main.stackAllocator.allocator, "#ff0000Couldn't find biome with id \"{s}\"", .{args}) catch unreachable;
defer main.stackAllocator.free(msg);
source.sendMessage(msg);
return;
}
if(biome.isCave) {
source.sendMessage("#ff0000Teleport to biome is only available for surface biomes.");
return;
}
const radius = 16384;
const mapSize: i32 = main.server.terrain.ClimateMap.ClimateMapFragment.mapSize;
// Explore chunks in a spiral from the center:
const spiralLen = 2*radius/mapSize*2*radius/mapSize;
var wx = source.lastPos[0] & ~(mapSize - 1);
var wy = source.lastPos[1] & ~(mapSize - 1);
var dirChanges: usize = 1;
var dir: main.chunk.Neighbor = .dirNegX;
var stepsRemaining: usize = 1;
for(0..spiralLen) |_| {
const map = main.server.terrain.ClimateMap.getOrGenerateFragmentAndIncreaseRefCount(wx, wy);
defer map.decreaseRefCount();
for(0..map.map.len) |_| {
const x = main.random.nextIntBounded(u31, &main.seed, map.map.len);
const y = main.random.nextIntBounded(u31, &main.seed, map.map.len);
const sample = map.map[x][y];
if(sample.biome == biome) {
const z = sample.height + sample.hills + sample.mountains + sample.roughness;
const biomeSize = main.server.terrain.SurfaceMap.MapFragment.biomeSize;
main.network.Protocols.genericUpdate.sendTPCoordinates(source.conn, .{@floatFromInt(wx + x*biomeSize + biomeSize/2), @floatFromInt(wy + y*biomeSize + biomeSize/2), @floatCast(z + biomeSize/2)});
return;
}
}
switch (dir) {
.dirNegX => wx -%= mapSize,
.dirPosX => wx +%= mapSize,
.dirNegY => wy -%= mapSize,
.dirPosY => wy +%= mapSize,
else => unreachable,
}
stepsRemaining -= 1;
if(stepsRemaining == 0) {
switch (dir) {
.dirNegX => dir = .dirNegY,
.dirPosX => dir = .dirPosY,
.dirNegY => dir = .dirPosX,
.dirPosY => dir = .dirNegX,
else => unreachable,
}
dirChanges += 1;
// Every second turn the number of steps needed doubles.
stepsRemaining = dirChanges/2;
}
}
source.sendMessage("#ff0000Couldn't find biome. Searched in a radius of 16384 blocks.");
return;
}
var x: ?f64 = null;
var y: ?f64 = null;
var z: ?f64 = null;
Expand Down
2 changes: 1 addition & 1 deletion src/server/terrain/ClimateMap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ pub fn deinit() void {
cache.clear();
}

fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32) *ClimateMapFragment {
pub fn getOrGenerateFragmentAndIncreaseRefCount(wx: i32, wy: i32) *ClimateMapFragment {
const compare = ClimateMapFragmentPosition{.wx = wx, .wy = wy};
const result = cache.findOrCreate(compare, cacheInit, ClimateMapFragment.increaseRefCount);
return result;
Expand Down

0 comments on commit 84afe1a

Please sign in to comment.