diff --git a/community/audio/readme.md b/community/audio/readme.md new file mode 100644 index 00000000..a25e7240 --- /dev/null +++ b/community/audio/readme.md @@ -0,0 +1 @@ +For music download `.ogg` (or other) from [archive.org](https://archive.org/details/C418-MinecraftSoundtrackVolumeAlpha/) and put them into the music dir \ No newline at end of file diff --git a/community/audio/readme.txt b/community/audio/readme.txt deleted file mode 100644 index b14182ed..00000000 --- a/community/audio/readme.txt +++ /dev/null @@ -1 +0,0 @@ -For music download .ogg or other from https://archive.org/details/C418-MinecraftSoundtrackVolumeAlpha/ and put them into the music dir \ No newline at end of file diff --git a/community/baseinput.py b/community/baseinput.py new file mode 100644 index 00000000..cbcc76c8 --- /dev/null +++ b/community/baseinput.py @@ -0,0 +1,126 @@ +import random +import player +import chunk +import hit + +from enum import IntEnum + +class BaseInput: + class InteractMode(IntEnum): + PLACE = 0 + BREAK = 1 + PICK = 2 + + class MiscMode(IntEnum): + RANDOM = 0 + SAVE = 1 + ESCAPE = 2 + SPEED_TIME = 3 + FULLSCREEN = 4 + FLY = 5 + TELEPORT = 6 + TOGGLE_F3 = 7 + TOGGLE_AO = 8 + + class MoveMode(IntEnum): + LEFT = 0 + RIGHT = 1 + DOWN = 2 + UP = 3 + BACKWARD = 4 + FORWARD = 5 + + class ModifierMode(IntEnum): + SPRINT = 0 + + def __init__(self, game): + self.game = game + + def interact(self, mode): + def hit_callback(current_block, next_block): + if mode == self.InteractMode.PLACE: self.game.world.try_set_block(current_block, self.game.holding, self.game.player.collider) + elif mode == self.InteractMode.BREAK: self.game.world.set_block(next_block, 0) + elif mode == self.InteractMode.PICK: self.game.holding = self.game.world.get_block_number(next_block) + + x, y, z = self.game.player.position + y += self.game.player.eyelevel + + hit_ray = hit.Hit_ray(self.game.world, self.game.player.rotation, (x, y, z)) + + while hit_ray.distance < hit.HIT_RANGE: + if hit_ray.step(hit_callback): + return True + return False + + def misc(self, mode): + if mode == self.MiscMode.RANDOM: + self.game.holding = random.randint(1, len(self.game.world.block_types) - 1) + elif mode == self.MiscMode.SAVE: + self.game.world.save.save() + elif mode == self.MiscMode.ESCAPE: + self.game.mouse_captured = False + self.game.set_exclusive_mouse(False) + elif mode == self.MiscMode.SPEED_TIME: + self.game.world.speed_daytime() + elif mode == self.MiscMode.FULLSCREEN: + self.game.toggle_fullscreen() + elif mode == self.MiscMode.FLY: + self.game.player.flying = not self.game.player.flying + elif mode == self.MiscMode.TELEPORT: + # how large is the world? + + max_y = 0 + + max_x, max_z = (0, 0) + min_x, min_z = (0, 0) + + for pos in self.game.world.chunks: + x, y, z = pos + + max_y = max(max_y, (y + 1) * chunk.CHUNK_HEIGHT) + + max_x = max(max_x, (x + 1) * chunk.CHUNK_WIDTH) + min_x = min(min_x, x * chunk.CHUNK_WIDTH) + + max_z = max(max_z, (z + 1) * chunk.CHUNK_LENGTH) + min_z = min(min_z, z * chunk.CHUNK_LENGTH) + + # get random X & Z coordinates to teleport the player to + + x = random.randint(min_x, max_x) + z = random.randint(min_z, max_z) + + # find height at which to teleport to, by finding the first non-air block from the top of the world + + for y in range(chunk.CHUNK_HEIGHT - 1, -1, -1): + if not self.game.world.get_block_number((x, y, z)): + continue + + self.game.player.teleport((x, y + 1, z)) + break + elif mode == self.MiscMode.TOGGLE_F3: + self.game.show_f3 = not self.game.show_f3 + elif mode == self.MiscMode.TOGGLE_AO: + self.game.world.toggle_AO() + + def update_move(self, axis): + self.game.player.input[axis] = round(max(-1, min(self.game.controls[axis], 1))) + + def start_move(self, mode): + axis = int((mode if mode % 2 == 0 else mode - 1) / 2) + self.game.controls[axis] += (-1 if mode % 2 == 0 else 1) + self.update_move(axis) + + def end_move(self, mode): + axis = int((mode if mode % 2 == 0 else mode - 1) / 2) + self.game.controls[axis] -= (-1 if mode % 2 == 0 else 1) + self.update_move(axis) + + def start_modifier(self, mode): + if mode == self.ModifierMode.SPRINT: + self.game.player.target_speed = player.SPRINTING_SPEED + + def end_modifier(self, mode): + if mode == self.ModifierMode.SPRINT: + self.game.player.target_speed = player.WALKING_SPEED + diff --git a/community/controller.py b/community/controller.py index 7972e38c..1239e929 100644 --- a/community/controller.py +++ b/community/controller.py @@ -1,124 +1,96 @@ -import random +import pyglet.input + +import baseinput import player -import chunk -import hit - -from enum import IntEnum - -class Controller: - class InteractMode(IntEnum): - PLACE = 0 - BREAK = 1 - PICK = 2 - - class MiscMode(IntEnum): - RANDOM = 0 - SAVE = 1 - ESCAPE = 2 - SPEED_TIME = 3 - FULLSCREEN = 4 - FLY = 5 - TELEPORT = 6 - TOGGLE_F3 = 7 - TOGGLE_AO = 8 - - class MoveMode(IntEnum): - LEFT = 0 - RIGHT = 1 - DOWN = 2 - UP = 3 - BACKWARD = 4 - FORWARD = 5 - - class ModifierMode(IntEnum): - SPRINT = 0 +import math +import time +class Controller(baseinput.BaseInput): def __init__(self, game): - self.game = game - - def interact(self, mode): - def hit_callback(current_block, next_block): - if mode == self.InteractMode.PLACE: self.game.world.try_set_block(current_block, self.game.holding, self.game.player.collider) - elif mode == self.InteractMode.BREAK: self.game.world.set_block(next_block, 0) - elif mode == self.InteractMode.PICK: self.game.holding = self.game.world.get_block_number(next_block) - - x, y, z = self.game.player.position - y += self.game.player.eyelevel - - hit_ray = hit.Hit_ray(self.game.world, self.game.player.rotation, (x, y, z)) - - while hit_ray.distance < hit.HIT_RANGE: - if hit_ray.step(hit_callback): - break - - def misc(self, mode): - if mode == self.MiscMode.RANDOM: - self.game.holding = random.randint(1, len(self.game.world.block_types) - 1) - elif mode == self.MiscMode.SAVE: - self.game.world.save.save() - elif mode == self.MiscMode.ESCAPE: - self.game.mouse_captured = False - self.game.set_exclusive_mouse(False) - elif mode == self.MiscMode.SPEED_TIME: - self.game.world.speed_daytime() - elif mode == self.MiscMode.FULLSCREEN: - self.game.toggle_fullscreen() - elif mode == self.MiscMode.FLY: - self.game.player.flying = not self.game.player.flying - elif mode == self.MiscMode.TELEPORT: - # how large is the world? - - max_y = 0 - - max_x, max_z = (0, 0) - min_x, min_z = (0, 0) - - for pos in self.game.world.chunks: - x, y, z = pos - - max_y = max(max_y, (y + 1) * chunk.CHUNK_HEIGHT) - - max_x = max(max_x, (x + 1) * chunk.CHUNK_WIDTH) - min_x = min(min_x, x * chunk.CHUNK_WIDTH) - - max_z = max(max_z, (z + 1) * chunk.CHUNK_LENGTH) - min_z = min(min_z, z * chunk.CHUNK_LENGTH) - - # get random X & Z coordinates to teleport the player to - - x = random.randint(min_x, max_x) - z = random.randint(min_z, max_z) - - # find height at which to teleport to, by finding the first non-air block from the top of the world - - for y in range(chunk.CHUNK_HEIGHT - 1, -1, -1): - if not self.game.world.get_block_number((x, y, z)): - continue - - self.game.player.teleport((x, y + 1, z)) - break - elif mode == self.MiscMode.TOGGLE_F3: - self.game.show_f3 = not self.game.show_f3 - elif mode == self.MiscMode.TOGGLE_AO: - self.game.world.toggle_AO() - - def update_move(self, axis): - self.game.player.input[axis] = round(max(-1, min(self.game.controls[axis], 1))) - - def start_move(self, mode): - axis = int((mode if mode % 2 == 0 else mode - 1) / 2) - self.game.controls[axis] += (-1 if mode % 2 == 0 else 1) - self.update_move(axis) - - def end_move(self, mode): - axis = int((mode if mode % 2 == 0 else mode - 1) / 2) - self.game.controls[axis] -= (-1 if mode % 2 == 0 else 1) - self.update_move(axis) - - def start_modifier(self, mode): - if mode == self.ModifierMode.SPRINT: - self.game.player.target_speed = player.SPRINTING_SPEED - - def end_modifier(self, mode): - if mode == self.ModifierMode.SPRINT: - self.game.player.target_speed = player.WALKING_SPEED \ No newline at end of file + super().__init__(game) + self.controller_manager = pyglet.input.ControllerManager() + + self.camera_sensitivity = 2.5 + self.joystick_deadzone = 0.25 + self.update_delay = 0.15 + self.last_update = 0 + + self.joystick_move = [0, 0] + self.joystick_look = [0, 0] + self.joystick_interact = [0, 0] + + self.main_controller = None + self.try_get_main_controller() + + @self.controller_manager.event + def on_connect(controller): + if self.main_controller is None: + self.new_main_controller(controller) + + print("Connect:", controller) + + @self.controller_manager.event + def on_disconnect(controller): + if self.main_controller == controller: + self.main_controller = None + self.try_get_main_controller() + + print("Disconnect:", controller) + + def try_get_main_controller(self): + if self.main_controller is None: + if len(self.controller_manager.get_controllers()) > 0: + self.new_main_controller(self.controller_manager.get_controllers()[0]) + + def new_main_controller(self, controller): + self.main_controller = controller + self.main_controller.open() + + @self.main_controller.event + def on_stick_motion(controller, stick, x, y): + if controller == self.main_controller: + if stick == "left": + self.joystick_move = [x, y] + elif stick == "right": + self.joystick_look = [x, y] + + def update_controller(self, delta_time): + if not self.game.mouse_captured or self.main_controller is None: + return + + self.joystick_move = self.apply_deadzone([self.main_controller.leftx, self.main_controller.lefty]) + self.joystick_look = self.apply_deadzone([self.main_controller.rightx, self.main_controller.righty]) + self.joystick_interact = [self.main_controller.lefttrigger, self.main_controller.righttrigger] + + self.game.player.rotation[0] += self.joystick_look[0] * self.camera_sensitivity * delta_time + self.game.player.rotation[1] += self.joystick_look[1] * self.camera_sensitivity * delta_time + + self.game.player.rotation[1] = max(-math.tau / 4, min(math.tau / 4, self.game.player.rotation[1])) + + if round(max(self.joystick_interact)) > 0 and (self.last_update + self.update_delay) <= time.process_time(): + if round(self.joystick_interact[0]) > 0: + if self.interact(self.InteractMode.BREAK): + self.main_controller.rumble_play_weak(1, duration=0.05) + if round(self.joystick_interact[1]) > 0: self.interact(self.InteractMode.PLACE) + + self.last_update = time.process_time() + + if self.main_controller.x: self.interact(self.InteractMode.PICK) + if self.main_controller.y: self.misc(self.MiscMode.RANDOM) + if self.main_controller.b: self.misc(self.MiscMode.SAVE) + + if self.main_controller.leftstick: + if self.game.player.target_speed == player.SPRINTING_SPEED: self.end_modifier(self.ModifierMode.SPRINT) + elif self.game.player.target_speed == player.WALKING_SPEED: self.start_modifier(self.ModifierMode.SPRINT) + + self.game.controls[0] = round(self.joystick_move[0]) + self.game.controls[1] = round(int(self.main_controller.a == True) - int(self.main_controller.rightstick == True)) + self.game.controls[2] = round(self.joystick_move[1]) + + for axis in range(3): self.update_move(axis) + + def apply_deadzone(self, value): + if abs(value[0]) < self.joystick_deadzone: value[0] = 0 + if abs(value[1]) < self.joystick_deadzone: value[1] = 0 + return value + diff --git a/community/joystick.py b/community/joystick.py deleted file mode 100644 index 455b136a..00000000 --- a/community/joystick.py +++ /dev/null @@ -1,144 +0,0 @@ -import pyglet.input - -import controller -import threading -import player -import math -import time - -class Joystick_controller(controller.Controller): - def __init__(self, game): - super().__init__(game) - self.init_joysticks(pyglet.input.get_joysticks()) - - self.camera_sensitivity = 0.007 - self.joystick_deadzone = 0.25 - self.update_delay = 0.15 - self.last_update = 0 - - self.joystick_move = [0, 0] - self.joystick_look = [0, 0] - self.joystick_interact = [0, 0] - - self.joystick_updater = threading.Thread(target=self.updater, daemon=True, name="Joystick Updater") - self.joystick_updater.start() - - def updater(self): - while True: - if len(pyglet.input.get_joysticks()) != len(self.joysticks): - self.init_joysticks(pyglet.input.get_joysticks()) - - time.sleep(2) - - def init_joysticks(self, joysticks): - self.joysticks = joysticks - - for joystick in self.joysticks: - joystick.on_joybutton_press = self.on_joybutton_press - joystick.on_joybutton_release = self.on_joybutton_release - joystick.on_joyaxis_motion = self.on_joyaxis_motion - joystick.on_joyhat_motion = self.on_joyhat_motion - joystick.open(exclusive=True) - - def update_controller(self): - if not self.game.mouse_captured or not self.joysticks: - return - - self.game.player.rotation[0] += self.joystick_look[0] * self.camera_sensitivity - self.game.player.rotation[1] += -self.joystick_look[1] * self.camera_sensitivity - - self.game.player.rotation[1] = max(-math.tau / 4, min(math.tau / 4, self.game.player.rotation[1])) - - if round(max(self.joystick_interact)) > 0 and (self.last_update + self.update_delay) <= time.process_time(): - if round(self.joystick_interact[0]) > 0: self.interact(self.InteractMode.BREAK) - if round(self.joystick_interact[1]) > 0: self.interact(self.InteractMode.PLACE) - - self.last_update = time.process_time() - - def on_joybutton_press(self, joystick, button): - if "xbox" in joystick.device.name.lower(): - if button == 1: self.misc(self.MiscMode.RANDOM) - elif button == 2: self.interact(self.InteractMode.PICK) - elif button == 3: self.misc(self.MiscMode.SAVE) - - elif button == 0: self.start_move(self.MoveMode.UP) - elif button == 9: self.start_move(self.MoveMode.DOWN) - - elif button == 8: - if self.game.player.target_speed == player.SPRINTING_SPEED: self.end_modifier(self.ModifierMode.SPRINT) - elif self.game.player.target_speed == player.WALKING_SPEED: self.start_modifier(self.ModifierMode.SPRINT) - - elif "wireless controller" == joystick.device.name.lower(): - if button == 2: self.misc(self.MiscMode.RANDOM) - elif button == 0: self.interact(self.InteractMode.PICK) - elif button == 3: self.misc(self.MiscMode.SAVE) - - elif button == 1: self.start_move(self.MoveMode.UP) - elif button == 11: self.start_move(self.MoveMode.DOWN) - - elif button == 10: - if self.game.player.target_speed == player.SPRINTING_SPEED: self.end_modifier(self.ModifierMode.SPRINT) - elif self.game.player.target_speed == player.WALKING_SPEED: self.start_modifier(self.ModifierMode.SPRINT) - - def on_joybutton_release(self, joystick, button): - if "xbox" in joystick.device.name.lower(): - if button == 0: self.end_move(self.MoveMode.UP) - elif button == 9: self.end_move(self.MoveMode.DOWN) - - elif "wireless controller" == joystick.device.name.lower(): - if button == 1: self.end_move(self.MoveMode.UP) - elif button == 11: self.end_move(self.MoveMode.DOWN) - - def on_joyaxis_motion(self, joystick, axis, value): - if abs(value) < self.joystick_deadzone: - value = 0 - - if "xbox" in joystick.device.name.lower(): - if axis == "x": - if math.ceil(value) > 0 and self.joystick_move[0] == 0: self.start_move(self.MoveMode.RIGHT) - elif math.floor(value) < 0 and self.joystick_move[0] == 0: self.start_move(self.MoveMode.LEFT) - elif value == 0 and math.ceil(self.joystick_move[0]) > 0: self.end_move(self.MoveMode.RIGHT) - elif value == 0 and math.floor(self.joystick_move[0]) < 0: self.end_move(self.MoveMode.LEFT) - - self.joystick_move[0] = value - elif axis == "y": - if math.ceil(value) > 0 and self.joystick_move[1] == 0: self.start_move(self.MoveMode.BACKWARD) - elif math.floor(value) < 0 and self.joystick_move[1] == 0: self.start_move(self.MoveMode.FORWARD) - elif value == 0 and math.ceil(self.joystick_move[1]) > 0: self.end_move(self.MoveMode.BACKWARD) - elif value == 0 and math.floor(self.joystick_move[1]) < 0: self.end_move(self.MoveMode.FORWARD) - - self.joystick_move[1] = value - - if axis == "rx": self.joystick_look[0] = value - if axis == "ry": self.joystick_look[1] = value - - if axis == "z": - if value < 0: self.joystick_interact[0] = -value - if value > 0: self.joystick_interact[1] = value - - elif "wireless controller" == joystick.device.name.lower(): - if axis == "x": - if math.ceil(value) > 0 and self.joystick_move[0] == 0: self.start_move(self.MoveMode.RIGHT) - elif math.floor(value) < 0 and self.joystick_move[0] == 0: self.start_move(self.MoveMode.LEFT) - elif value == 0 and math.ceil(self.joystick_move[0]) > 0: self.end_move(self.MoveMode.RIGHT) - elif value == 0 and math.floor(self.joystick_move[0]) < 0: self.end_move(self.MoveMode.LEFT) - - self.joystick_move[0] = value - elif axis == "y": - if math.ceil(value) > 0 and self.joystick_move[1] == 0: self.start_move(self.MoveMode.BACKWARD) - elif math.floor(value) < 0 and self.joystick_move[1] == 0: self.start_move(self.MoveMode.FORWARD) - elif value == 0 and math.ceil(self.joystick_move[1]) > 0: self.end_move(self.MoveMode.BACKWARD) - elif value == 0 and math.floor(self.joystick_move[1]) < 0: self.end_move(self.MoveMode.FORWARD) - - self.joystick_move[1] = value - - if axis == "z": self.joystick_look[0] = value - if axis == "rz": self.joystick_look[1] = value - - if axis == "rx": self.joystick_interact[0] = value - if axis == "ry": self.joystick_interact[1] = value - - print(axis) - - def on_joyhat_motion(self, joystick, hat_x, hat_y): - pass \ No newline at end of file diff --git a/community/keyboard_mouse.py b/community/keyboard_mouse.py index c1146707..9aca121e 100644 --- a/community/keyboard_mouse.py +++ b/community/keyboard_mouse.py @@ -1,9 +1,9 @@ import pyglet.window -import controller +import baseinput import math -class Keyboard_Mouse(controller.Controller): +class Keyboard_Mouse(baseinput.BaseInput): def __init__(self, game): super().__init__(game) diff --git a/community/main.py b/community/main.py index aaf34b2c..9aa966d5 100644 --- a/community/main.py +++ b/community/main.py @@ -22,7 +22,7 @@ import options import time -import joystick +import controller import keyboard_mouse from collections import deque @@ -125,7 +125,7 @@ def __init__(self, **args): self.controls = [0, 0, 0] # joystick stuff - self.joystick_controller = joystick.Joystick_controller(self) + self.controller = controller.Controller(self) # mouse and keyboard stuff self.keyboard_mouse = keyboard_mouse.Keyboard_Mouse(self) @@ -209,7 +209,7 @@ def update(self, delta_time): if not self.mouse_captured: self.player.input = [0, 0, 0] - self.joystick_controller.update_controller() + self.controller.update_controller(delta_time) self.player.update(delta_time) self.world.tick(delta_time)