# combat_kit.ludic — the shooter kit over ludic.gameplay: Dash (a dodge with i-frames), # Melee (an arc swing with knockback and MeleeHit), build stats on Stats applied by # Combat.damage (damage_pct, crit_pct, thorns; a Crit event), Stats.add, and the # Dungeon package (arena, exits, entry points). Prints: # 6846 153196 31 107110 6000 5002 1 80 97 11 10 700 110 program CombatKit { import "ludic.core/components.ludic" import "ludic.shooter/shooter.ludic" import "ludic.dungeon/dungeon.ludic" import "ludic.prefs/prefs.ludic" property Foe { n: int = 0 } model Hero { Position, Body, Collider, TopDown, Weapon, Faction, Stats, Dash, Melee } model Creature { Position, Body, Collider, Faction, Stats, Foe } model WorldRules { Solids } state CombatKitState { frames: int = 0 hero: int = -1 } @On(MeleeHit) handler H { print(5000 + target) } @On(Crit) handler C { print(6000) } handler Tick(combat_kit_st: mut CombatKitState) phase Update { combat_kit_st.frames += 1 if combat_kit_st.frames == 1 { Map.size(20, 15) Dungeon.arena(Dungeon.random_style(), '#', '.') Dungeon.set_exit(Side.North, 'D') spawn WorldRules { Solids { tile: 16, wall: '#', solid2: 'D' } } print(Map.get(x: 9, y: 0) * 100 + Map.get(x: 9, y: 7)) # 6846: the sealed door, the open lane let e = Dungeon.entry_point(Side.South, 24, 14, 20) print(e.x * 1000 + e.y) # 153196 print(Dungeon.opposite(Side.West) * 10 + Dungeon.at_edge(IVec2.make(0, 3))) # 31 Weapon.def(name: "p", fire_rate: 10, damage: 10, speed: 8, spread: 0, pellets: 1, pattern: 0) combat_kit_st.hero = spawn Hero { Position { x: 100, y: 100 }, Collider { w: 14, h: 20 }, Body { policy: 1 }, TopDown { move_speed: 4, aim_mode: AimMode.Manual, aim_angle: 0 }, Faction { id: 1 }, Stats { hp: 100, max_hp: 100 }, Dash { frames: 3, speed: 9, cooldown_frames: 5 }, Melee { range: 30, damage: 7, knockback: 4 } } Stats.add(combat_kit_st.hero, StatKind.CritPct, 100) Stats.add(combat_kit_st.hero, StatKind.DamagePct, 50) let c = Collider.center(combat_kit_st.hero); print(c.x * 1000 + c.y) # 107110 spawn Creature { Position { x: 120, y: 100 }, Collider { w: 14, h: 20 }, Body { policy: 1 }, Faction { id: 2 }, Stats { hp: 100, max_hp: 100, thorns: 3 }, Foe { n: 1 } } Faction.set(1, 2, 2) print(Melee.swing(combat_kit_st.hero)) # 1 hit (after 6000 and 5002) for (s, f) in query [Stats, Foe] { print(s.hp) } # 80: 7 * 150% doubled by the crit print(Stats.of(combat_kit_st.hero).hp) # 97: thorns print(Dash.start(combat_kit_st.hero, 0, 0) * 10 + Dash.active(combat_kit_st.hero)) # 11 print(Prefs.max("best", 5) * 10 + Prefs.max("best", 3)) # 10 } if combat_kit_st.frames == 7 { print(700 + Dash.active(combat_kit_st.hero)); print(Position.of(combat_kit_st.hero).x); quit() } # 700 110 } }