# HG changeset patch # User Emmanuel Gil Peyrot # Date 1414255941 -7200 # Node ID d471b07ce4fda929d54fc6f40d02e2d036eff706 # Parent a7286a0facf9e2d828fee1421090e88a8d7bc3bc Add a sample Python ECL. diff --git a/pytouhou/games/sample/enemies.py b/pytouhou/games/sample/enemies.py new file mode 100644 --- /dev/null +++ b/pytouhou/games/sample/enemies.py @@ -0,0 +1,91 @@ +# -*- encoding: utf-8 -*- +## +## Copyright (C) 2014 Emmanuel Gil Peyrot +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +from math import radians +from pytouhou.vm import spawn_enemy +from pytouhou.game import NextStage + + +def disk(enemy, game): + if enemy.frame == 0: + enemy.set_anim(0) + + enemy.set_hitbox(32, 32) + + enemy.death_anim = 1 + + enemy.update_mode = 0 + enemy.angle, enemy.speed = radians(90), 1.5 + + elif enemy.frame == 10000: + enemy.removed = True + + +def boss(enemy, game): + if enemy.frame == 0: + enemy.set_anim(3) + enemy.set_hitbox(8, 32) + enemy.death_flags = 1 + enemy.set_boss(True) + + enemy.timeout = 20 * 60 + enemy.timeout_callback.enable(some_spellcard, (enemy, game)) + + enemy.low_life_trigger = 0x40 + enemy.low_life_callback.enable(some_spellcard, (enemy, game)) + + elif enemy.frame == 10000: + enemy.removed = True + + if enemy.frame % 10 == 0: + enemy.set_bullet_attributes(67, 0, 0, 3 if game.spellcard is not None else 1, 1, 6., 6., 0., radians(3), 0) + + +def some_spellcard(enemy, game): + enemy.life = 0x40 + enemy.difficulty_coeffs = (-.5, .5, 0, 0, 0, 0) + game.change_bullets_into_star_items() + game.spellcard = (42, 'Some Spellcard', 0) + game.enable_spellcard_effect() + + enemy.timeout = 10 * 60 + enemy.timeout_callback.enable(on_boss_death, (enemy, game)) + enemy.death_callback.enable(on_boss_death, (enemy, game)) + enemy.low_life_callback.disable() + + +def on_boss_death(enemy, game): + enemy.timeout_callback.disable() + enemy.death_callback.disable() + game.disable_spellcard_effect() + enemy.removed = True + + raise NextStage + + +def stage1(game): + if game.frame == 0x10: + spawn_enemy(game, disk, x=50., y=-32., life=20, score=300) + elif game.frame == 0x20: + spawn_enemy(game, disk, x=60., y=-32., life=20, score=300) + elif game.frame == 0x30: + spawn_enemy(game, disk, x=70., y=-32., life=20, score=300) + elif game.frame == 0x40: + spawn_enemy(game, disk, x=80., y=-32., life=20, score=300) + elif game.frame == 0x50: + spawn_enemy(game, disk, x=90., y=-32., life=20, score=300) + elif game.frame == 0x60: + spawn_enemy(game, disk, x=100., y=-32., life=20, score=300) + elif game.frame == 0x100: + spawn_enemy(game, boss, x=192., y=64., life=1000, item=-2, score=10000) diff --git a/pytouhou/games/sample/game.py b/pytouhou/games/sample/game.py --- a/pytouhou/games/sample/game.py +++ b/pytouhou/games/sample/game.py @@ -22,7 +22,8 @@ from pytouhou.game.player import Player from pytouhou.game.orb import Orb from pytouhou.game.background import Background -from pytouhou.vm import ECLMainRunner +from pytouhou.vm import PythonMainRunner +from . import enemies class Common(object): @@ -107,8 +108,8 @@ class Game(GameBase): 'stg%denm2.anm' % stage)) except KeyError: self.enm_anm = resource_loader.get_anm('stg%denm.anm' % stage) - ecl = resource_loader.get_ecl('ecldata%d.ecl' % stage) - self.ecl_runners = [ECLMainRunner(main, ecl.subs, self) for main in ecl.mains] + + self.ecl_runners = [PythonMainRunner(getattr(enemies, 'stage%d' % stage), self)] self.spellcard_effect_anm = resource_loader.get_single_anm('eff0%d.anm' % stage) diff --git a/pytouhou/vm/__init__.py b/pytouhou/vm/__init__.py --- a/pytouhou/vm/__init__.py +++ b/pytouhou/vm/__init__.py @@ -1,3 +1,29 @@ from .anmrunner import ANMRunner from .msgrunner import MSGRunner from .eclrunner import ECLMainRunner + + +class PythonMainRunner(object): + def __init__(self, main, game): + self.main = main + self.game = game + + def run_iter(self): + self.main(self.game) + + +class EnemyRunner(object): + def __init__(self, enemy, game, sub): + self.enemy = enemy + self.game = game + self.sub = sub + + def run_iteration(self): + self.sub(self.enemy, self.game) + + +def spawn_enemy(game, sub, x=0., y=0., life=1, item=-1, score=0, mirrored=False, random=False): + instr_type = (2 if mirrored else 0) | (4 if random else 0) + enemy = game.new_enemy((x, y, 0.), life, instr_type, item, score) + enemy.process = EnemyRunner(enemy, game, sub) + enemy.process.run_iteration()