Skip to content
Open
Show file tree
Hide file tree
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
37 changes: 37 additions & 0 deletions mods/cubyz/rotation/multistate/no_rotation.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
pub fn init() void {}
pub fn deinit() void {}
pub fn reset() void {}

pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex {

const modelId = zon.get([]const u8, "model", "cubyz:cube");
const stateCount = zon.get(u16, "states", 2);
const blockId = block.id();
if(stateCount <= 1) {
std.log.err("Block '{s}' uses multistate no_rotation with {} states. 'multistate no_rotation' should have at least 2 states, use 'no_rotation' instead", .{blockId, stateCount});
} else if(stateCount > 16) {
std.log.err("Block '{s}' uses multistate no_rotation with {} states. 'multistate no_rotation' can have at most 16 states.", .{blockId, stateCount});
}
modeData.* = stateCount;

const baseModel = main.models.getModelIndex(zon.as([]const u8, "cubyz:cube");).model();

return baseModel;
}

pub fn model(block: Block) ModelIndex {
return blocks.meshes.modelIndexStart(block).add(min@(block.data, block.modeData() - 1));
}

pub fn model(block: Block) ModelIndex {
return blocks.meshes.modelIndexStart(block).add(@min(block.data, block.modeData() - 1));
}

pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, _: ?Neighbor, currentData: *Block, _: Block, blockPlacing: bool) bool {
if(blockPlacing) {
currentData.data = 0;
return true;
}
return false;
}

87 changes: 87 additions & 0 deletions mods/cubyz/rotation/multistate/planar.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const std = @import("std");

const main = @import("main");
const blocks = main.blocks;
const Block = blocks.Block;
const Neighbor = main.chunk.Neighbor;
const ModelIndex = main.models.ModelIndex;
const rotation = main.rotation;
const Degrees = rotation.Degrees;
const vec = main.vec;
const Mat4f = vec.Mat4f;
const Vec3f = vec.Vec3f;
const Vec3i = vec.Vec3i;
const ZonElement = main.ZonElement;

var rotatedModels: std.StringHashMap(ModelIndex) = undefined;

pub fn init() void {
rotatedModels = .init(main.globalAllocator.allocator);
}

pub fn deinit() void {
rotatedModels.deinit();
}

pub fn reset() void {
rotatedModels.clearRetainingCapacity();
}

pub fn createBlockModel(_: Block, _: *u16, zon: ZonElement) ModelIndex {

const modelId = zon.get([]const u8, "model", "cubyz:cube");
const stateCount = zon.get(u16, "states", 2);
const blockId = block.id();
if(stateCount <= 1) {
std.log.err("Block '{s}' uses multistate planar with {} states. 'multistate planar' should have at least 2 states, use 'planar' instead", .{blockId, stateCount});
} else if(stateCount > 16) {
std.log.err("Block '{s}' uses multistate planar with {} states. 'multistate planar' can have at most 16 states.", .{blockId, stateCount});
}
modeData.* = stateCount;

const modelId = zon.as([]const u8, "cubyz:cube");
if(rotatedModels.get(modelId)) |modelIndex| return modelIndex;

const baseModel = main.models.getModelIndex(modelId).model();
// Rotate the model:
const modelIndex: ModelIndex = baseModel.transformModel(rotation.rotationMatrixTransform, .{Mat4f.rotationZ(std.math.pi/2.0)});
_ = baseModel.transformModel(rotation.rotationMatrixTransform, .{Mat4f.rotationZ(-std.math.pi/2.0)});
_ = baseModel.transformModel(rotation.rotationMatrixTransform, .{Mat4f.rotationZ(std.math.pi)});
_ = baseModel.transformModel(rotation.rotationMatrixTransform, .{Mat4f.identity()});
rotatedModels.put(modelId, modelIndex) catch unreachable;
return modelIndex;
}

pub fn model(block: Block) ModelIndex {
return blocks.meshes.modelIndexStart(block).add(min@(block.data, (block.modeData()*4) - 1));
}

pub fn rotateZ(data: u16, angle: Degrees) u16 {
comptime var rotationTable: [4][4]u8 = undefined;
comptime for(0..4) |i| {
rotationTable[0][i] = i;
};
comptime for(1..4) |a| {
for(0..4) |i| {
const neighbor: Neighbor = @enumFromInt(rotationTable[a - 1][i] + 2);
rotationTable[a][i] = neighbor.rotateZ().toInt() - 2;
}
};
if(data >= 4) return 0;
const runtimeTable = rotationTable;
return runtimeTable[@intFromEnum(angle)][data];
}

pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, playerDir: Vec3f, _: Vec3i, _: ?Neighbor, currentData: *Block, _: Block, blockPlacing: bool) bool {
if(blockPlacing) {
if(@abs(playerDir[0]) > @abs(playerDir[1])) {
const dir: Neighbor = if(playerDir[0] < 0) .dirNegX else .dirPosX;
currentData.data = dir.toInt() - 2;
} else {
const dir: Neighbor = if(playerDir[1] < 0) .dirNegY else .dirPosY;
currentData.data = dir.toInt() - 2;
}
return true;
}
return false;
}