Beispiel #1
0
static BlockID Particle_GetBlock(Int32 x, Int32 y, Int32 z) {
	if (World_IsValidPos(x, y, z)) { return World_GetBlock(x, y, z); }

	if (y >= WorldEnv_EdgeHeight) return BLOCK_AIR;
	if (y >= WorldEnv_SidesHeight) return WorldEnv_EdgeBlock;
	return WorldEnv_SidesBlock;
}
Beispiel #2
0
static inline Block fastBlockFetch(World* world, Chunk* chunk, Cluster* cluster, int x, int y, int z) {
	world->errFlags = 0;
	return (x < 0 || y < 0 || z < 0 || x >= CHUNK_WIDTH || y >= CHUNK_CLUSTER_HEIGHT || z >= CHUNK_DEPTH)
		   ? World_GetBlock(world, (chunk->x * CHUNK_WIDTH) + x, (cluster->y * CHUNK_CLUSTER_HEIGHT) + y, (chunk->z * CHUNK_DEPTH) + z)
		   : cluster->blocks[x][y][z];
}
BlockID World_SafeGetBlock_3I(Vector3I p) {
	return World_Contains(p.X, p.Y, p.Z) ? World_GetBlock(p.X, p.Y, p.Z) : BLOCK_AIR;
}
BlockID World_GetPhysicsBlock(int x, int y, int z) {
	if (y < 0 || !World_ContainsXZ(x, z)) return BLOCK_BEDROCK;
	if (y >= World.Height) return BLOCK_AIR;

	return World_GetBlock(x, y, z);
}
void InputHandler_PickBlocks(bool cooldown, bool left, bool middle, bool right) {
	TimeMS now = DateTime_CurrentUTC_MS();
	int delta  = (int)(now - input_lastClick);

	Vector3I pos;
	BlockID old, cur, block;
	int i;

	if (cooldown && delta < 250) return; /* 4 times per second */
	input_lastClick = now;

	if (Server.SupportsPlayerClick && !Gui_GetActiveScreen()->HandlesAllInput) {
		input_pickingId = -1;
		InputHandler_ButtonStateChanged(MOUSE_LEFT,   left);
		InputHandler_ButtonStateChanged(MOUSE_RIGHT,  right);
		InputHandler_ButtonStateChanged(MOUSE_MIDDLE, middle);
	}

	if (Gui_GetActiveScreen()->HandlesAllInput) return;

	if (left) {
		/* always play delete animations, even if we aren't picking a block */
		HeldBlockRenderer_ClickAnim(true);

		pos = Game_SelectedPos.BlockPos;
		if (!Game_SelectedPos.Valid || !World_Contains(pos.X, pos.Y, pos.Z)) return;

		old = World_GetBlock(pos.X, pos.Y, pos.Z);
		if (Blocks.Draw[old] == DRAW_GAS || !Blocks.CanDelete[old]) return;

		Game_ChangeBlock(pos.X, pos.Y, pos.Z, BLOCK_AIR);
		Event_RaiseBlock(&UserEvents.BlockChanged, pos, old, BLOCK_AIR);
	} else if (right) {
		pos = Game_SelectedPos.TranslatedPos;
		if (!Game_SelectedPos.Valid || !World_Contains(pos.X, pos.Y, pos.Z)) return;

		old   = World_GetBlock(pos.X, pos.Y, pos.Z);
		block = Inventory_SelectedBlock;
		if (AutoRotate_Enabled) block = AutoRotate_RotateBlock(block);

		if (Game_CanPick(old) || !Blocks.CanPlace[block]) return;
		/* air-ish blocks can only replace over other air-ish blocks */
		if (Blocks.Draw[block] == DRAW_GAS && Blocks.Draw[old] != DRAW_GAS) return;
		if (!InputHandler_CheckIsFree(block)) return;

		Game_ChangeBlock(pos.X, pos.Y, pos.Z, block);
		Event_RaiseBlock(&UserEvents.BlockChanged, pos, old, block);
	} else if (middle) {
		pos = Game_SelectedPos.BlockPos;
		if (!World_Contains(pos.X, pos.Y, pos.Z)) return;

		cur = World_GetBlock(pos.X, pos.Y, pos.Z);
		if (Blocks.Draw[cur] == DRAW_GAS) return;
		if (!(Blocks.CanPlace[cur] || Blocks.CanDelete[cur])) return;
		if (!Inventory_CheckChangeSelected() || Inventory_SelectedBlock == cur) return;

		/* Is the currently selected block an empty slot? */
		if (Inventory_SelectedBlock == BLOCK_AIR) {
			Inventory_SetSelectedBlock(cur); return;
		}

		/* Try to replace same block */
		for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) {
			if (Inventory_Get(i) != cur) continue;
			Inventory_SetSelectedIndex(i); return;
		}

		/* Try to replace empty slots */
		for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) {
			if (Inventory_Get(i) != BLOCK_AIR) continue;
			Inventory_Set(i, cur);
			Inventory_SetSelectedIndex(i); return;
		}

		/* Finally, replace the currently selected block */
		Inventory_SetSelectedBlock(cur);
	}
}