zoria/src/register.py

209 lines
5.7 KiB
Python

import math, random, time
from . import assets, controller, sprite, spritesheet, tiles
from .vector import Vector
def is_collided(pos, map, player):
METER = map.METER
rect = player.rect
cx = player.pos.x + (rect[0] / METER)
cy = player.pos.y + (rect[1] / METER)
cw = cx + (rect[2] / METER)
ch = cy + (rect[3] / METER)
if cw >= pos[0] and cx <= (pos[0] + 1) and ch >= pos[1] and cy <= (pos[1] + 1):
return True
# Structure tiles
tiles.register_tile("map:floor", {
"textures": ["floor.png"],
})
tiles.register_tile("map:wall", {
"textures": [
"wall_0.png",
"wall_1.png",
"wall_2.png",
"wall_3.png",
],
})
tiles.register_tile("map:wall_corner_inner", {
"textures": [
"wall_corner_inner_0.png",
"wall_corner_inner_1.png",
"wall_corner_inner_2.png",
"wall_corner_inner_3.png",
],
})
tiles.register_tile("map:wall_corner_outer", {
"textures": [
"wall_corner_outer_0.png",
"wall_corner_outer_1.png",
"wall_corner_outer_2.png",
"wall_corner_outer_3.png",
],
})
# Stairs
def prev_level(self, dtime, map, player):
# Lazy distance check
if math.hypot(player.pos.x - self.pos[0], player.pos.y + 1 - self.pos[1]) <= 2 \
and player.pos.y + 0.5 > self.pos[1] and controller.is_down("shift") \
and time.time() - player.last_level_change > 0.5: # Prevent multiple shifts
player.z = max(1, player.z - 2)
generator = map.generators[player.z - 1]
player.set_pos(generator.exit[0], generator.exit[1] - 1)
player.dir = 2
player.last_level_change = time.time()
tiles.register_tile("map:stair_up", {
"textures": ["stair_up.png"],
"solid": True,
"on_step": prev_level,
})
def unlock_next(self, dtime, map, player):
if math.hypot(player.pos.x - self.pos[0], player.pos.y + 1 - self.pos[1]) <= 1 \
and player.key and controller.is_down("shift") and time.time() - player.last_level_change > 0.5:
map.set_tile(*self.pos, "map:stair_down")
player.hud.remove("key")
player.key = False
player.last_level_change = time.time()
tiles.register_tile("map:stair_down_locked", {
"textures": ["stair_down_locked.png"],
"solid": False,
"on_step": unlock_next,
})
def next_level(self, _, map, player):
if math.hypot(player.pos.x - self.pos[0], player.pos.y + 1 - self.pos[1]) <= 1 \
and controller.is_down("shift") and time.time() - player.last_level_change > 0.5:
player.z += 2
if not player.z - 1 in map.generators: # Generate level if new
map.generate(player.z - 1)
generator = map.generators[player.z - 1]
player.set_pos(generator.enterance[0], generator.enterance[1] + 0.1)
player.dir = 0
player.last_level_change = time.time()
tiles.register_tile("map:stair_down", {
"textures": ["stair_down.png"],
"solid": False,
"on_step": next_level,
})
# Items
def pick_up_key(self, dtime, map, player):
if is_collided(self.pos, map, player):
player.key = True
player.hud.add("key", [0, 0.6], {
"type": "image",
"texture": "key.png",
"scale": 1.5
})
map.set_tile(*self.pos, None)
tiles.register_tile("item:key", {
"textures": ["key.png"],
"solid": False,
"on_step": pick_up_key
})
# Loot
def pick_up_coin(self, dtime, map, player):
if is_collided(self.pos, map, player):
player.coins += random.randint(self.min_value, self.max_value)
player.hud.change("coincount", {
"text": player.coins
})
map.set_tile(*self.pos, None)
tiles.register_tile("loot:coins", {
"textures": ["loot_gold.png"],
"solid": False,
"min_value": 2,
"max_value": 5,
"on_step": pick_up_coin
})
tiles.register_tile("loot:pile", {
"textures": ["loot_pile.png"],
"solid": False,
"min_value": 6,
"max_value": 12,
"on_step": pick_up_coin
})
def pick_up_health(self, dtime, map, player):
if is_collided((self.pos.x, self.pos.y), map, player):
player.hp += 3
player.hud.change("hp", {
"text": player.hp
})
map.remove_sprite(self.id)
sprite.register_sprite("item:health", {
"texture": spritesheet.SpriteSheet(assets.get("health.png"), 32, 32),
"on_step": pick_up_health
})
def pick_up_xp(self, dtime, map, player):
if is_collided((self.pos.x, self.pos.y), map, player):
player.xp += self.amount
player.hud.change("xp", {
"text": player.xp
})
map.remove_sprite(self.id)
sprite.register_sprite("item:xp", {
"texture": spritesheet.SpriteSheet(assets.get("xp.png"), 32, 32),
"on_step": pick_up_xp
})
# Enemies
def spawn_slime(self, dtime, map, player):
map.set_tile(*self.pos, None)
sprite = map.add_sprite(*self.pos, "enemy:slime")
sprite.hp = 4 + (2 * sprite.z)
sprite.set_rect(0, 0, 32, 32)
sprite.texture.set_animation(0, 3, 4)
sprite.target_pos = Vector(self.pos[0], self.pos[1])
tiles.register_tile("enemy:slime", {
"textures": ["slime_spawner.png"],
"on_step": spawn_slime
})
tiles.register_tile("enemy:slime_dead", {
"textures": ["slime_dead.png"],
"solid": False,
})
from .slime import slime_logic
sprite.register_sprite("enemy:slime", {
"texture": spritesheet.SpriteSheet(assets.get("slime.png"), 32, 32),
"timer": 0,
"target_pos": Vector(0),
"on_step": slime_logic
})
# Effects
def slash(self, dtime, map, player):
self.timer += dtime
if self.timer >= 2 / 4:
map.remove_sprite(self.id)
sprite.register_sprite("player:slash", {
"texture": spritesheet.SpriteSheet(assets.get("magic_slash.png"), 32, 32),
"timer": 0,
"on_step": slash
})