changeset 599:d471b07ce4fd

Add a sample Python ECL.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 25 Oct 2014 18:52:21 +0200
parents a7286a0facf9
children 2a748aa29c3f
files pytouhou/games/sample/enemies.py pytouhou/games/sample/game.py pytouhou/vm/__init__.py
diffstat 3 files changed, 121 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
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 <linkmauve@linkmauve.fr>
+##
+## 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)
--- 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)
 
--- 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()