diff --git a/assets/fonts/eightbit_atari_grube2.font.png b/assets/fonts/eightbit_atari_grube2.font.png new file mode 100644 index 000000000..5eae75113 Binary files /dev/null and b/assets/fonts/eightbit_atari_grube2.font.png differ diff --git a/assets/lumbers/l_sfx_being_attacked.mid b/assets/lumbers/l_sfx_being_attacked.mid new file mode 100644 index 000000000..7828a963b Binary files /dev/null and b/assets/lumbers/l_sfx_being_attacked.mid differ diff --git a/assets/lumbers/l_sfx_brick.mid b/assets/lumbers/l_sfx_brick.mid new file mode 100644 index 000000000..299e0a651 Binary files /dev/null and b/assets/lumbers/l_sfx_brick.mid differ diff --git a/assets/lumbers/l_sfx_enemy_death.mid b/assets/lumbers/l_sfx_enemy_death.mid new file mode 100644 index 000000000..7a54ccfb2 Binary files /dev/null and b/assets/lumbers/l_sfx_enemy_death.mid differ diff --git a/assets/lumbers/l_sfx_enemy_flip.mid b/assets/lumbers/l_sfx_enemy_flip.mid new file mode 100644 index 000000000..0b3a2b1ea Binary files /dev/null and b/assets/lumbers/l_sfx_enemy_flip.mid differ diff --git a/assets/lumbers/l_sfx_jump.mid b/assets/lumbers/l_sfx_jump.mid new file mode 100644 index 000000000..9da6b893f Binary files /dev/null and b/assets/lumbers/l_sfx_jump.mid differ diff --git a/assets/lumbers/l_sfx_pear.mid b/assets/lumbers/l_sfx_pear.mid new file mode 100644 index 000000000..ad65f4024 Binary files /dev/null and b/assets/lumbers/l_sfx_pear.mid differ diff --git a/assets/lumbers/l_sfx_upgrade.mid b/assets/lumbers/l_sfx_upgrade.mid new file mode 100644 index 000000000..35cb055ac Binary files /dev/null and b/assets/lumbers/l_sfx_upgrade.mid differ diff --git a/assets/lumbers/l_sfx_water.mid b/assets/lumbers/l_sfx_water.mid new file mode 100644 index 000000000..31e1f6594 Binary files /dev/null and b/assets/lumbers/l_sfx_water.mid differ diff --git a/assets/lumbers/l_song_attack.mid b/assets/lumbers/l_song_attack.mid new file mode 100644 index 000000000..a1694fbae Binary files /dev/null and b/assets/lumbers/l_song_attack.mid differ diff --git a/assets/lumbers/l_song_attack_title.mid b/assets/lumbers/l_song_attack_title.mid new file mode 100644 index 000000000..fe3b03c69 Binary files /dev/null and b/assets/lumbers/l_song_attack_title.mid differ diff --git a/assets/lumbers/l_song_gameover.mid b/assets/lumbers/l_song_gameover.mid new file mode 100644 index 000000000..9468fe605 Binary files /dev/null and b/assets/lumbers/l_song_gameover.mid differ diff --git a/assets/lumbers/l_song_panic.mid b/assets/lumbers/l_song_panic.mid new file mode 100644 index 000000000..7dc7e03c4 Binary files /dev/null and b/assets/lumbers/l_song_panic.mid differ diff --git a/assets/lumbers/l_song_panic_title.mid b/assets/lumbers/l_song_panic_title.mid new file mode 100644 index 000000000..2de16bb9c Binary files /dev/null and b/assets/lumbers/l_song_panic_title.mid differ diff --git a/assets/lumbers/l_song_respawn.mid b/assets/lumbers/l_song_respawn.mid new file mode 100644 index 000000000..38ec7ab50 Binary files /dev/null and b/assets/lumbers/l_song_respawn.mid differ diff --git a/assets/lumbers/lumberjacks.tsx b/assets/lumbers/lumberjacks.tsx new file mode 100644 index 000000000..4be864001 --- /dev/null +++ b/assets/lumbers/lumberjacks.tsx @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/lumbers/lumberjacks_attack_1.bin b/assets/lumbers/lumberjacks_attack_1.bin new file mode 100644 index 000000000..190188c3f Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_1.bin differ diff --git a/assets/lumbers/lumberjacks_attack_10.bin b/assets/lumbers/lumberjacks_attack_10.bin new file mode 100644 index 000000000..03af5fbbf Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_10.bin differ diff --git a/assets/lumbers/lumberjacks_attack_2.bin b/assets/lumbers/lumberjacks_attack_2.bin new file mode 100644 index 000000000..846ea0c33 Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_2.bin differ diff --git a/assets/lumbers/lumberjacks_attack_3.bin b/assets/lumbers/lumberjacks_attack_3.bin new file mode 100644 index 000000000..c73ba04e4 Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_3.bin differ diff --git a/assets/lumbers/lumberjacks_attack_4.bin b/assets/lumbers/lumberjacks_attack_4.bin new file mode 100644 index 000000000..a91cdb1e3 Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_4.bin differ diff --git a/assets/lumbers/lumberjacks_attack_5.bin b/assets/lumbers/lumberjacks_attack_5.bin new file mode 100644 index 000000000..4472a1a7d Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_5.bin differ diff --git a/assets/lumbers/lumberjacks_attack_6.bin b/assets/lumbers/lumberjacks_attack_6.bin new file mode 100644 index 000000000..5e3f72d6c Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_6.bin differ diff --git a/assets/lumbers/lumberjacks_attack_7.bin b/assets/lumbers/lumberjacks_attack_7.bin new file mode 100644 index 000000000..b45d2015d Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_7.bin differ diff --git a/assets/lumbers/lumberjacks_attack_8.bin b/assets/lumbers/lumberjacks_attack_8.bin new file mode 100644 index 000000000..3f8acac37 Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_8.bin differ diff --git a/assets/lumbers/lumberjacks_attack_9.bin b/assets/lumbers/lumberjacks_attack_9.bin new file mode 100644 index 000000000..8ae81ebf4 Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_9.bin differ diff --git a/assets/lumbers/lumberjacks_attack_vs.bin b/assets/lumbers/lumberjacks_attack_vs.bin new file mode 100644 index 000000000..e4dd3e74b Binary files /dev/null and b/assets/lumbers/lumberjacks_attack_vs.bin differ diff --git a/assets/lumbers/lumberjacks_panic_1.bin b/assets/lumbers/lumberjacks_panic_1.bin new file mode 100644 index 000000000..2fce60cb0 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_1.bin differ diff --git a/assets/lumbers/lumberjacks_panic_10.bin b/assets/lumbers/lumberjacks_panic_10.bin new file mode 100644 index 000000000..e7a03a4a9 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_10.bin differ diff --git a/assets/lumbers/lumberjacks_panic_2.bin b/assets/lumbers/lumberjacks_panic_2.bin new file mode 100644 index 000000000..8a2bf3725 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_2.bin differ diff --git a/assets/lumbers/lumberjacks_panic_3.bin b/assets/lumbers/lumberjacks_panic_3.bin new file mode 100644 index 000000000..9a39d0696 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_3.bin differ diff --git a/assets/lumbers/lumberjacks_panic_4.bin b/assets/lumbers/lumberjacks_panic_4.bin new file mode 100644 index 000000000..9ac2710a1 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_4.bin differ diff --git a/assets/lumbers/lumberjacks_panic_5.bin b/assets/lumbers/lumberjacks_panic_5.bin new file mode 100644 index 000000000..ee6485fa7 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_5.bin differ diff --git a/assets/lumbers/lumberjacks_panic_6.bin b/assets/lumbers/lumberjacks_panic_6.bin new file mode 100644 index 000000000..3f3555873 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_6.bin differ diff --git a/assets/lumbers/lumberjacks_panic_7.bin b/assets/lumbers/lumberjacks_panic_7.bin new file mode 100644 index 000000000..c9ff3e200 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_7.bin differ diff --git a/assets/lumbers/lumberjacks_panic_8.bin b/assets/lumbers/lumberjacks_panic_8.bin new file mode 100644 index 000000000..20f89112a Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_8.bin differ diff --git a/assets/lumbers/lumberjacks_panic_9.bin b/assets/lumbers/lumberjacks_panic_9.bin new file mode 100644 index 000000000..80e5be03d Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_9.bin differ diff --git a/assets/lumbers/lumberjacks_panic_vs.bin b/assets/lumbers/lumberjacks_panic_vs.bin new file mode 100644 index 000000000..865603651 Binary files /dev/null and b/assets/lumbers/lumberjacks_panic_vs.bin differ diff --git a/assets/lumbers/alert.png b/assets/lumbers/lumbers_alert.png similarity index 100% rename from assets/lumbers/alert.png rename to assets/lumbers/lumbers_alert.png diff --git a/assets/lumbers/lumbers_bonus_0.png b/assets/lumbers/lumbers_bonus_0.png new file mode 100644 index 000000000..aa1a46a77 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_0.png differ diff --git a/assets/lumbers/lumbers_bonus_1.png b/assets/lumbers/lumbers_bonus_1.png new file mode 100644 index 000000000..6b7d1bc7d Binary files /dev/null and b/assets/lumbers/lumbers_bonus_1.png differ diff --git a/assets/lumbers/lumbers_bonus_2.png b/assets/lumbers/lumbers_bonus_2.png new file mode 100644 index 000000000..09eae35c8 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_2.png differ diff --git a/assets/lumbers/lumbers_bonus_3.png b/assets/lumbers/lumbers_bonus_3.png new file mode 100644 index 000000000..f2d662f0a Binary files /dev/null and b/assets/lumbers/lumbers_bonus_3.png differ diff --git a/assets/lumbers/lumbers_bonus_4.png b/assets/lumbers/lumbers_bonus_4.png new file mode 100644 index 000000000..14dec9b32 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_4.png differ diff --git a/assets/lumbers/lumbers_bonus_5.png b/assets/lumbers/lumbers_bonus_5.png new file mode 100644 index 000000000..68d7e9274 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_5.png differ diff --git a/assets/lumbers/lumbers_bonus_6.png b/assets/lumbers/lumbers_bonus_6.png new file mode 100644 index 000000000..be56b88a4 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_6.png differ diff --git a/assets/lumbers/lumbers_bonus_7.png b/assets/lumbers/lumbers_bonus_7.png new file mode 100644 index 000000000..116595986 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_7.png differ diff --git a/assets/lumbers/lumbers_bonus_8.png b/assets/lumbers/lumbers_bonus_8.png new file mode 100644 index 000000000..82cf33bdd Binary files /dev/null and b/assets/lumbers/lumbers_bonus_8.png differ diff --git a/assets/lumbers/lumbers_bonus_9.png b/assets/lumbers/lumbers_bonus_9.png new file mode 100644 index 000000000..d7f7e1aa5 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_9.png differ diff --git a/assets/lumbers/lumbers_bonus_x.png b/assets/lumbers/lumbers_bonus_x.png new file mode 100644 index 000000000..0d161cc16 Binary files /dev/null and b/assets/lumbers/lumbers_bonus_x.png differ diff --git a/assets/lumbers/bottom_floor1.png b/assets/lumbers/lumbers_bottom_floor1.png similarity index 100% rename from assets/lumbers/bottom_floor1.png rename to assets/lumbers/lumbers_bottom_floor1.png diff --git a/assets/lumbers/bottom_floor10.png b/assets/lumbers/lumbers_bottom_floor10.png similarity index 100% rename from assets/lumbers/bottom_floor10.png rename to assets/lumbers/lumbers_bottom_floor10.png diff --git a/assets/lumbers/bottom_floor2.png b/assets/lumbers/lumbers_bottom_floor2.png similarity index 100% rename from assets/lumbers/bottom_floor2.png rename to assets/lumbers/lumbers_bottom_floor2.png diff --git a/assets/lumbers/bottom_floor3.png b/assets/lumbers/lumbers_bottom_floor3.png similarity index 100% rename from assets/lumbers/bottom_floor3.png rename to assets/lumbers/lumbers_bottom_floor3.png diff --git a/assets/lumbers/bottom_floor4.png b/assets/lumbers/lumbers_bottom_floor4.png similarity index 100% rename from assets/lumbers/bottom_floor4.png rename to assets/lumbers/lumbers_bottom_floor4.png diff --git a/assets/lumbers/bottom_floor5.png b/assets/lumbers/lumbers_bottom_floor5.png similarity index 100% rename from assets/lumbers/bottom_floor5.png rename to assets/lumbers/lumbers_bottom_floor5.png diff --git a/assets/lumbers/bottom_floor6.png b/assets/lumbers/lumbers_bottom_floor6.png similarity index 100% rename from assets/lumbers/bottom_floor6.png rename to assets/lumbers/lumbers_bottom_floor6.png diff --git a/assets/lumbers/bottom_floor7.png b/assets/lumbers/lumbers_bottom_floor7.png similarity index 100% rename from assets/lumbers/bottom_floor7.png rename to assets/lumbers/lumbers_bottom_floor7.png diff --git a/assets/lumbers/bottom_floor8.png b/assets/lumbers/lumbers_bottom_floor8.png similarity index 100% rename from assets/lumbers/bottom_floor8.png rename to assets/lumbers/lumbers_bottom_floor8.png diff --git a/assets/lumbers/bottom_floor9.png b/assets/lumbers/lumbers_bottom_floor9.png similarity index 100% rename from assets/lumbers/bottom_floor9.png rename to assets/lumbers/lumbers_bottom_floor9.png diff --git a/assets/lumbers/lumbers_cho_1.png b/assets/lumbers/lumbers_cho_1.png new file mode 100644 index 000000000..fd3482c28 Binary files /dev/null and b/assets/lumbers/lumbers_cho_1.png differ diff --git a/assets/lumbers/lumbers_cho_10.png b/assets/lumbers/lumbers_cho_10.png new file mode 100644 index 000000000..8e284de17 Binary files /dev/null and b/assets/lumbers/lumbers_cho_10.png differ diff --git a/assets/lumbers/lumbers_cho_11.png b/assets/lumbers/lumbers_cho_11.png new file mode 100644 index 000000000..a1099fc5c Binary files /dev/null and b/assets/lumbers/lumbers_cho_11.png differ diff --git a/assets/lumbers/lumbers_cho_12.png b/assets/lumbers/lumbers_cho_12.png new file mode 100644 index 000000000..8b885f15d Binary files /dev/null and b/assets/lumbers/lumbers_cho_12.png differ diff --git a/assets/lumbers/lumbers_cho_13.png b/assets/lumbers/lumbers_cho_13.png new file mode 100644 index 000000000..3ecee6bf6 Binary files /dev/null and b/assets/lumbers/lumbers_cho_13.png differ diff --git a/assets/lumbers/lumbers_cho_14.png b/assets/lumbers/lumbers_cho_14.png new file mode 100644 index 000000000..75f744a96 Binary files /dev/null and b/assets/lumbers/lumbers_cho_14.png differ diff --git a/assets/lumbers/lumbers_cho_15.png b/assets/lumbers/lumbers_cho_15.png new file mode 100644 index 000000000..f04a94210 Binary files /dev/null and b/assets/lumbers/lumbers_cho_15.png differ diff --git a/assets/lumbers/lumbers_cho_16.png b/assets/lumbers/lumbers_cho_16.png new file mode 100644 index 000000000..f68810ad0 Binary files /dev/null and b/assets/lumbers/lumbers_cho_16.png differ diff --git a/assets/lumbers/lumbers_cho_17.png b/assets/lumbers/lumbers_cho_17.png new file mode 100644 index 000000000..83d7de70c Binary files /dev/null and b/assets/lumbers/lumbers_cho_17.png differ diff --git a/assets/lumbers/lumbers_cho_18.png b/assets/lumbers/lumbers_cho_18.png new file mode 100644 index 000000000..9b218d84e Binary files /dev/null and b/assets/lumbers/lumbers_cho_18.png differ diff --git a/assets/lumbers/lumbers_cho_2.png b/assets/lumbers/lumbers_cho_2.png new file mode 100644 index 000000000..3d05ee3ce Binary files /dev/null and b/assets/lumbers/lumbers_cho_2.png differ diff --git a/assets/lumbers/lumbers_cho_3.png b/assets/lumbers/lumbers_cho_3.png new file mode 100644 index 000000000..8bacde4c9 Binary files /dev/null and b/assets/lumbers/lumbers_cho_3.png differ diff --git a/assets/lumbers/lumbers_cho_4.png b/assets/lumbers/lumbers_cho_4.png new file mode 100644 index 000000000..36f55ea86 Binary files /dev/null and b/assets/lumbers/lumbers_cho_4.png differ diff --git a/assets/lumbers/lumbers_cho_5.png b/assets/lumbers/lumbers_cho_5.png new file mode 100644 index 000000000..b8d1886f5 Binary files /dev/null and b/assets/lumbers/lumbers_cho_5.png differ diff --git a/assets/lumbers/lumbers_cho_6.png b/assets/lumbers/lumbers_cho_6.png new file mode 100644 index 000000000..a3bf191f3 Binary files /dev/null and b/assets/lumbers/lumbers_cho_6.png differ diff --git a/assets/lumbers/lumbers_cho_7.png b/assets/lumbers/lumbers_cho_7.png new file mode 100644 index 000000000..78166e360 Binary files /dev/null and b/assets/lumbers/lumbers_cho_7.png differ diff --git a/assets/lumbers/lumbers_cho_8.png b/assets/lumbers/lumbers_cho_8.png new file mode 100644 index 000000000..55bb1eb25 Binary files /dev/null and b/assets/lumbers/lumbers_cho_8.png differ diff --git a/assets/lumbers/lumbers_cho_9.png b/assets/lumbers/lumbers_cho_9.png new file mode 100644 index 000000000..e06328773 Binary files /dev/null and b/assets/lumbers/lumbers_cho_9.png differ diff --git a/assets/lumbers/lumbers_cho_lives.png b/assets/lumbers/lumbers_cho_lives.png new file mode 100644 index 000000000..d8eca2e12 Binary files /dev/null and b/assets/lumbers/lumbers_cho_lives.png differ diff --git a/assets/lumbers/lumbers_conn_lost.png b/assets/lumbers/lumbers_conn_lost.png new file mode 100644 index 000000000..f22c6fdf2 Binary files /dev/null and b/assets/lumbers/lumbers_conn_lost.png differ diff --git a/assets/lumbers/enemy_a1.png b/assets/lumbers/lumbers_enemy_a1.png similarity index 100% rename from assets/lumbers/enemy_a1.png rename to assets/lumbers/lumbers_enemy_a1.png diff --git a/assets/lumbers/enemy_a2.png b/assets/lumbers/lumbers_enemy_a2.png similarity index 100% rename from assets/lumbers/enemy_a2.png rename to assets/lumbers/lumbers_enemy_a2.png diff --git a/assets/lumbers/enemy_a3.png b/assets/lumbers/lumbers_enemy_a3.png similarity index 100% rename from assets/lumbers/enemy_a3.png rename to assets/lumbers/lumbers_enemy_a3.png diff --git a/assets/lumbers/enemy_a4.png b/assets/lumbers/lumbers_enemy_a4.png similarity index 100% rename from assets/lumbers/enemy_a4.png rename to assets/lumbers/lumbers_enemy_a4.png diff --git a/assets/lumbers/enemy_a5.png b/assets/lumbers/lumbers_enemy_a5.png similarity index 100% rename from assets/lumbers/enemy_a5.png rename to assets/lumbers/lumbers_enemy_a5.png diff --git a/assets/lumbers/enemy_a6.png b/assets/lumbers/lumbers_enemy_a6.png similarity index 100% rename from assets/lumbers/enemy_a6.png rename to assets/lumbers/lumbers_enemy_a6.png diff --git a/assets/lumbers/enemy_a7.png b/assets/lumbers/lumbers_enemy_a7.png similarity index 100% rename from assets/lumbers/enemy_a7.png rename to assets/lumbers/lumbers_enemy_a7.png diff --git a/assets/lumbers/enemy_b1.png b/assets/lumbers/lumbers_enemy_b1.png similarity index 100% rename from assets/lumbers/enemy_b1.png rename to assets/lumbers/lumbers_enemy_b1.png diff --git a/assets/lumbers/enemy_b2.png b/assets/lumbers/lumbers_enemy_b2.png similarity index 100% rename from assets/lumbers/enemy_b2.png rename to assets/lumbers/lumbers_enemy_b2.png diff --git a/assets/lumbers/enemy_b3.png b/assets/lumbers/lumbers_enemy_b3.png similarity index 100% rename from assets/lumbers/enemy_b3.png rename to assets/lumbers/lumbers_enemy_b3.png diff --git a/assets/lumbers/enemy_b4.png b/assets/lumbers/lumbers_enemy_b4.png similarity index 100% rename from assets/lumbers/enemy_b4.png rename to assets/lumbers/lumbers_enemy_b4.png diff --git a/assets/lumbers/enemy_b5.png b/assets/lumbers/lumbers_enemy_b5.png similarity index 100% rename from assets/lumbers/enemy_b5.png rename to assets/lumbers/lumbers_enemy_b5.png diff --git a/assets/lumbers/enemy_b6.png b/assets/lumbers/lumbers_enemy_b6.png similarity index 100% rename from assets/lumbers/enemy_b6.png rename to assets/lumbers/lumbers_enemy_b6.png diff --git a/assets/lumbers/enemy_b7.png b/assets/lumbers/lumbers_enemy_b7.png similarity index 100% rename from assets/lumbers/enemy_b7.png rename to assets/lumbers/lumbers_enemy_b7.png diff --git a/assets/lumbers/enemy_c1.png b/assets/lumbers/lumbers_enemy_c1.png similarity index 100% rename from assets/lumbers/enemy_c1.png rename to assets/lumbers/lumbers_enemy_c1.png diff --git a/assets/lumbers/enemy_c2.png b/assets/lumbers/lumbers_enemy_c2.png similarity index 100% rename from assets/lumbers/enemy_c2.png rename to assets/lumbers/lumbers_enemy_c2.png diff --git a/assets/lumbers/enemy_c3.png b/assets/lumbers/lumbers_enemy_c3.png similarity index 100% rename from assets/lumbers/enemy_c3.png rename to assets/lumbers/lumbers_enemy_c3.png diff --git a/assets/lumbers/enemy_c4.png b/assets/lumbers/lumbers_enemy_c4.png similarity index 100% rename from assets/lumbers/enemy_c4.png rename to assets/lumbers/lumbers_enemy_c4.png diff --git a/assets/lumbers/enemy_c5.png b/assets/lumbers/lumbers_enemy_c5.png similarity index 100% rename from assets/lumbers/enemy_c5.png rename to assets/lumbers/lumbers_enemy_c5.png diff --git a/assets/lumbers/enemy_c6.png b/assets/lumbers/lumbers_enemy_c6.png similarity index 100% rename from assets/lumbers/enemy_c6.png rename to assets/lumbers/lumbers_enemy_c6.png diff --git a/assets/lumbers/enemy_c7.png b/assets/lumbers/lumbers_enemy_c7.png similarity index 100% rename from assets/lumbers/enemy_c7.png rename to assets/lumbers/lumbers_enemy_c7.png diff --git a/assets/lumbers/enemy_d1.png b/assets/lumbers/lumbers_enemy_d1.png similarity index 100% rename from assets/lumbers/enemy_d1.png rename to assets/lumbers/lumbers_enemy_d1.png diff --git a/assets/lumbers/enemy_d2.png b/assets/lumbers/lumbers_enemy_d2.png similarity index 100% rename from assets/lumbers/enemy_d2.png rename to assets/lumbers/lumbers_enemy_d2.png diff --git a/assets/lumbers/lumbers_enemy_e1.png b/assets/lumbers/lumbers_enemy_e1.png new file mode 100644 index 000000000..afa1e26be Binary files /dev/null and b/assets/lumbers/lumbers_enemy_e1.png differ diff --git a/assets/lumbers/lumbers_enemy_e2.png b/assets/lumbers/lumbers_enemy_e2.png new file mode 100644 index 000000000..f17ee5915 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_e2.png differ diff --git a/assets/lumbers/lumbers_enemy_e3.png b/assets/lumbers/lumbers_enemy_e3.png new file mode 100644 index 000000000..69773412a Binary files /dev/null and b/assets/lumbers/lumbers_enemy_e3.png differ diff --git a/assets/lumbers/lumbers_enemy_e4.png b/assets/lumbers/lumbers_enemy_e4.png new file mode 100644 index 000000000..1cfaf537a Binary files /dev/null and b/assets/lumbers/lumbers_enemy_e4.png differ diff --git a/assets/lumbers/lumbers_enemy_e5.png b/assets/lumbers/lumbers_enemy_e5.png new file mode 100644 index 000000000..47a2978f6 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_e5.png differ diff --git a/assets/lumbers/lumbers_enemy_e6.png b/assets/lumbers/lumbers_enemy_e6.png new file mode 100644 index 000000000..574c1a0a0 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_e6.png differ diff --git a/assets/lumbers/lumbers_enemy_e7.png b/assets/lumbers/lumbers_enemy_e7.png new file mode 100644 index 000000000..cea7e28c8 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_e7.png differ diff --git a/assets/lumbers/lumbers_enemy_f1.png b/assets/lumbers/lumbers_enemy_f1.png new file mode 100644 index 000000000..9701a8522 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_f1.png differ diff --git a/assets/lumbers/lumbers_enemy_f2.png b/assets/lumbers/lumbers_enemy_f2.png new file mode 100644 index 000000000..ad10f41b2 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_f2.png differ diff --git a/assets/lumbers/lumbers_enemy_f3.png b/assets/lumbers/lumbers_enemy_f3.png new file mode 100644 index 000000000..0e904be10 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_f3.png differ diff --git a/assets/lumbers/lumbers_enemy_f4.png b/assets/lumbers/lumbers_enemy_f4.png new file mode 100644 index 000000000..cf09eac25 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_f4.png differ diff --git a/assets/lumbers/lumbers_enemy_f5.png b/assets/lumbers/lumbers_enemy_f5.png new file mode 100644 index 000000000..55fff49b5 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_f5.png differ diff --git a/assets/lumbers/lumbers_enemy_f6.png b/assets/lumbers/lumbers_enemy_f6.png new file mode 100644 index 000000000..c3382fc55 Binary files /dev/null and b/assets/lumbers/lumbers_enemy_f6.png differ diff --git a/assets/lumbers/lumbers_enemy_f7.png b/assets/lumbers/lumbers_enemy_f7.png new file mode 100644 index 000000000..4f9e357ca Binary files /dev/null and b/assets/lumbers/lumbers_enemy_f7.png differ diff --git a/assets/lumbers/lumbers_game_over.png b/assets/lumbers/lumbers_game_over.png new file mode 100644 index 000000000..788e57918 Binary files /dev/null and b/assets/lumbers/lumbers_game_over.png differ diff --git a/assets/lumbers/lumbers_game_over_win.png b/assets/lumbers/lumbers_game_over_win.png new file mode 100644 index 000000000..58bb05d43 Binary files /dev/null and b/assets/lumbers/lumbers_game_over_win.png differ diff --git a/assets/lumbers/secret_swadgeland_20.png b/assets/lumbers/lumbers_green_22.png similarity index 79% rename from assets/lumbers/secret_swadgeland_20.png rename to assets/lumbers/lumbers_green_22.png index a8ca081d7..f2e7afea9 100644 Binary files a/assets/lumbers/secret_swadgeland_20.png and b/assets/lumbers/lumbers_green_22.png differ diff --git a/assets/lumbers/lumbers_green_ax_block.png b/assets/lumbers/lumbers_green_ax_block.png new file mode 100644 index 000000000..e623d8a7b Binary files /dev/null and b/assets/lumbers/lumbers_green_ax_block.png differ diff --git a/assets/lumbers/secret_swadgeland_22.png b/assets/lumbers/lumbers_green_ax_block1.png similarity index 77% rename from assets/lumbers/secret_swadgeland_22.png rename to assets/lumbers/lumbers_green_ax_block1.png index f3243941b..c764aaddb 100644 Binary files a/assets/lumbers/secret_swadgeland_22.png and b/assets/lumbers/lumbers_green_ax_block1.png differ diff --git a/assets/lumbers/secret_swadgeland_21.png b/assets/lumbers/lumbers_green_ax_block2.png similarity index 77% rename from assets/lumbers/secret_swadgeland_21.png rename to assets/lumbers/lumbers_green_ax_block2.png index f3243941b..34182f47a 100644 Binary files a/assets/lumbers/secret_swadgeland_21.png and b/assets/lumbers/lumbers_green_ax_block2.png differ diff --git a/assets/lumbers/lumbers_green_ax_block3.png b/assets/lumbers/lumbers_green_ax_block3.png new file mode 100644 index 000000000..e237096e5 Binary files /dev/null and b/assets/lumbers/lumbers_green_ax_block3.png differ diff --git a/assets/lumbers/lumbers_green_ax_block4.png b/assets/lumbers/lumbers_green_ax_block4.png new file mode 100644 index 000000000..2c37c144c Binary files /dev/null and b/assets/lumbers/lumbers_green_ax_block4.png differ diff --git a/assets/lumbers/lumbers_green_ax_block5.png b/assets/lumbers/lumbers_green_ax_block5.png new file mode 100644 index 000000000..88b656273 Binary files /dev/null and b/assets/lumbers/lumbers_green_ax_block5.png differ diff --git a/assets/lumbers/lumbers_green_ax_block6.png b/assets/lumbers/lumbers_green_ax_block6.png new file mode 100644 index 000000000..35c383803 Binary files /dev/null and b/assets/lumbers/lumbers_green_ax_block6.png differ diff --git a/assets/lumbers/lumbers_green_ax_block7.png b/assets/lumbers/lumbers_green_ax_block7.png new file mode 100644 index 000000000..91996d3cd Binary files /dev/null and b/assets/lumbers/lumbers_green_ax_block7.png differ diff --git a/assets/lumbers/lumbers_green_lives.png b/assets/lumbers/lumbers_green_lives.png new file mode 100644 index 000000000..e21322a68 Binary files /dev/null and b/assets/lumbers/lumbers_green_lives.png differ diff --git a/assets/lumbers/lumbers_item_ui.png b/assets/lumbers/lumbers_item_ui.png new file mode 100644 index 000000000..d3306969c Binary files /dev/null and b/assets/lumbers/lumbers_item_ui.png differ diff --git a/assets/lumbers/lumbers_items_grapes1.png b/assets/lumbers/lumbers_items_grapes1.png new file mode 100644 index 000000000..4ba72e55e Binary files /dev/null and b/assets/lumbers/lumbers_items_grapes1.png differ diff --git a/assets/lumbers/lumbers_items_grapes2.png b/assets/lumbers/lumbers_items_grapes2.png new file mode 100644 index 000000000..5ce9879b0 Binary files /dev/null and b/assets/lumbers/lumbers_items_grapes2.png differ diff --git a/assets/lumbers/lumbers_items_grapes3.png b/assets/lumbers/lumbers_items_grapes3.png new file mode 100644 index 000000000..da795deb0 Binary files /dev/null and b/assets/lumbers/lumbers_items_grapes3.png differ diff --git a/assets/lumbers/lumbers_items_grapes4.png b/assets/lumbers/lumbers_items_grapes4.png new file mode 100644 index 000000000..7347bb22c Binary files /dev/null and b/assets/lumbers/lumbers_items_grapes4.png differ diff --git a/assets/lumbers/lumbers_items_grapes5.png b/assets/lumbers/lumbers_items_grapes5.png new file mode 100644 index 000000000..b6c931d14 Binary files /dev/null and b/assets/lumbers/lumbers_items_grapes5.png differ diff --git a/assets/lumbers/lumbers_items_grapes6.png b/assets/lumbers/lumbers_items_grapes6.png new file mode 100644 index 000000000..d8257ee3e Binary files /dev/null and b/assets/lumbers/lumbers_items_grapes6.png differ diff --git a/assets/lumbers/lumbers_items_orange1.png b/assets/lumbers/lumbers_items_orange1.png new file mode 100644 index 000000000..af6992689 Binary files /dev/null and b/assets/lumbers/lumbers_items_orange1.png differ diff --git a/assets/lumbers/lumbers_items_orange2.png b/assets/lumbers/lumbers_items_orange2.png new file mode 100644 index 000000000..f47aab1ae Binary files /dev/null and b/assets/lumbers/lumbers_items_orange2.png differ diff --git a/assets/lumbers/lumbers_items_orange3.png b/assets/lumbers/lumbers_items_orange3.png new file mode 100644 index 000000000..6b20e3114 Binary files /dev/null and b/assets/lumbers/lumbers_items_orange3.png differ diff --git a/assets/lumbers/lumbers_items_orange4.png b/assets/lumbers/lumbers_items_orange4.png new file mode 100644 index 000000000..08fa29841 Binary files /dev/null and b/assets/lumbers/lumbers_items_orange4.png differ diff --git a/assets/lumbers/lumbers_items_orange5.png b/assets/lumbers/lumbers_items_orange5.png new file mode 100644 index 000000000..a4e20d87b Binary files /dev/null and b/assets/lumbers/lumbers_items_orange5.png differ diff --git a/assets/lumbers/lumbers_items_orange6.png b/assets/lumbers/lumbers_items_orange6.png new file mode 100644 index 000000000..8f74425d8 Binary files /dev/null and b/assets/lumbers/lumbers_items_orange6.png differ diff --git a/assets/lumbers/lumbers_items_pear1.png b/assets/lumbers/lumbers_items_pear1.png new file mode 100644 index 000000000..f0a1b9104 Binary files /dev/null and b/assets/lumbers/lumbers_items_pear1.png differ diff --git a/assets/lumbers/lumbers_items_pear2.png b/assets/lumbers/lumbers_items_pear2.png new file mode 100644 index 000000000..95cdb8b25 Binary files /dev/null and b/assets/lumbers/lumbers_items_pear2.png differ diff --git a/assets/lumbers/lumbers_items_pear3.png b/assets/lumbers/lumbers_items_pear3.png new file mode 100644 index 000000000..d7b9ae50c Binary files /dev/null and b/assets/lumbers/lumbers_items_pear3.png differ diff --git a/assets/lumbers/lumbers_items_pear4.png b/assets/lumbers/lumbers_items_pear4.png new file mode 100644 index 000000000..8cfc23c1a Binary files /dev/null and b/assets/lumbers/lumbers_items_pear4.png differ diff --git a/assets/lumbers/lumbers_items_pear5.png b/assets/lumbers/lumbers_items_pear5.png new file mode 100644 index 000000000..43765f4b7 Binary files /dev/null and b/assets/lumbers/lumbers_items_pear5.png differ diff --git a/assets/lumbers/lumbers_items_pear6.png b/assets/lumbers/lumbers_items_pear6.png new file mode 100644 index 000000000..8ae7abc1d Binary files /dev/null and b/assets/lumbers/lumbers_items_pear6.png differ diff --git a/assets/lumbers/lumbers_itemused_block.png b/assets/lumbers/lumbers_itemused_block.png new file mode 100644 index 000000000..889611fff Binary files /dev/null and b/assets/lumbers/lumbers_itemused_block.png differ diff --git a/assets/lumbers/lumbers_normal_ax_block1.png b/assets/lumbers/lumbers_normal_ax_block1.png new file mode 100644 index 000000000..e7a8de929 Binary files /dev/null and b/assets/lumbers/lumbers_normal_ax_block1.png differ diff --git a/assets/lumbers/lumbers_normal_ax_block2.png b/assets/lumbers/lumbers_normal_ax_block2.png new file mode 100644 index 000000000..a7a498a8c Binary files /dev/null and b/assets/lumbers/lumbers_normal_ax_block2.png differ diff --git a/assets/lumbers/lumbers_normal_ax_block3.png b/assets/lumbers/lumbers_normal_ax_block3.png new file mode 100644 index 000000000..f5a9e38c1 Binary files /dev/null and b/assets/lumbers/lumbers_normal_ax_block3.png differ diff --git a/assets/lumbers/lumbers_normal_ax_block4.png b/assets/lumbers/lumbers_normal_ax_block4.png new file mode 100644 index 000000000..34a2b9731 Binary files /dev/null and b/assets/lumbers/lumbers_normal_ax_block4.png differ diff --git a/assets/lumbers/lumbers_normal_ax_block5.png b/assets/lumbers/lumbers_normal_ax_block5.png new file mode 100644 index 000000000..90e7996f1 Binary files /dev/null and b/assets/lumbers/lumbers_normal_ax_block5.png differ diff --git a/assets/lumbers/lumbers_normal_ax_block6.png b/assets/lumbers/lumbers_normal_ax_block6.png new file mode 100644 index 000000000..d031e0662 Binary files /dev/null and b/assets/lumbers/lumbers_normal_ax_block6.png differ diff --git a/assets/lumbers/lumbers_normal_ax_block7.png b/assets/lumbers/lumbers_normal_ax_block7.png new file mode 100644 index 000000000..79df2fcde Binary files /dev/null and b/assets/lumbers/lumbers_normal_ax_block7.png differ diff --git a/assets/lumbers/secret_swadgeland_19.png b/assets/lumbers/lumbers_red_22.png similarity index 79% rename from assets/lumbers/secret_swadgeland_19.png rename to assets/lumbers/lumbers_red_22.png index c6427ed01..5ab34676e 100644 Binary files a/assets/lumbers/secret_swadgeland_19.png and b/assets/lumbers/lumbers_red_22.png differ diff --git a/assets/lumbers/lumbers_red_ax_block1.png b/assets/lumbers/lumbers_red_ax_block1.png new file mode 100644 index 000000000..ef9012401 Binary files /dev/null and b/assets/lumbers/lumbers_red_ax_block1.png differ diff --git a/assets/lumbers/lumbers_red_ax_block2.png b/assets/lumbers/lumbers_red_ax_block2.png new file mode 100644 index 000000000..8558fcccf Binary files /dev/null and b/assets/lumbers/lumbers_red_ax_block2.png differ diff --git a/assets/lumbers/lumbers_red_ax_block3.png b/assets/lumbers/lumbers_red_ax_block3.png new file mode 100644 index 000000000..efa47bfe0 Binary files /dev/null and b/assets/lumbers/lumbers_red_ax_block3.png differ diff --git a/assets/lumbers/lumbers_red_ax_block4.png b/assets/lumbers/lumbers_red_ax_block4.png new file mode 100644 index 000000000..c81f6022d Binary files /dev/null and b/assets/lumbers/lumbers_red_ax_block4.png differ diff --git a/assets/lumbers/lumbers_red_ax_block5.png b/assets/lumbers/lumbers_red_ax_block5.png new file mode 100644 index 000000000..fa0168a65 Binary files /dev/null and b/assets/lumbers/lumbers_red_ax_block5.png differ diff --git a/assets/lumbers/lumbers_red_ax_block6.png b/assets/lumbers/lumbers_red_ax_block6.png new file mode 100644 index 000000000..ca89e89bc Binary files /dev/null and b/assets/lumbers/lumbers_red_ax_block6.png differ diff --git a/assets/lumbers/lumbers_red_ax_block7.png b/assets/lumbers/lumbers_red_ax_block7.png new file mode 100644 index 000000000..06a2395e3 Binary files /dev/null and b/assets/lumbers/lumbers_red_ax_block7.png differ diff --git a/assets/lumbers/lumbers_red_lives.png b/assets/lumbers/lumbers_red_lives.png new file mode 100644 index 000000000..6d694c59b Binary files /dev/null and b/assets/lumbers/lumbers_red_lives.png differ diff --git a/assets/lumbers/lumbers_rtile_1.png b/assets/lumbers/lumbers_rtile_1.png new file mode 100644 index 000000000..3858ed9fe Binary files /dev/null and b/assets/lumbers/lumbers_rtile_1.png differ diff --git a/assets/lumbers/lumbers_rtile_2.png b/assets/lumbers/lumbers_rtile_2.png new file mode 100644 index 000000000..c32026873 Binary files /dev/null and b/assets/lumbers/lumbers_rtile_2.png differ diff --git a/assets/lumbers/lumbers_rtile_3.png b/assets/lumbers/lumbers_rtile_3.png new file mode 100644 index 000000000..9e1d8a0b0 Binary files /dev/null and b/assets/lumbers/lumbers_rtile_3.png differ diff --git a/assets/lumbers/lumbers_rtile_4.png b/assets/lumbers/lumbers_rtile_4.png new file mode 100644 index 000000000..59e156fc5 Binary files /dev/null and b/assets/lumbers/lumbers_rtile_4.png differ diff --git a/assets/lumbers/secret_swadgeland_1.png b/assets/lumbers/lumbers_swadgeland_1.png similarity index 100% rename from assets/lumbers/secret_swadgeland_1.png rename to assets/lumbers/lumbers_swadgeland_1.png diff --git a/assets/lumbers/secret_swadgeland_10.png b/assets/lumbers/lumbers_swadgeland_10.png similarity index 100% rename from assets/lumbers/secret_swadgeland_10.png rename to assets/lumbers/lumbers_swadgeland_10.png diff --git a/assets/lumbers/secret_swadgeland_11.png b/assets/lumbers/lumbers_swadgeland_11.png similarity index 100% rename from assets/lumbers/secret_swadgeland_11.png rename to assets/lumbers/lumbers_swadgeland_11.png diff --git a/assets/lumbers/secret_swadgeland_12.png b/assets/lumbers/lumbers_swadgeland_12.png similarity index 100% rename from assets/lumbers/secret_swadgeland_12.png rename to assets/lumbers/lumbers_swadgeland_12.png diff --git a/assets/lumbers/secret_swadgeland_13.png b/assets/lumbers/lumbers_swadgeland_13.png similarity index 100% rename from assets/lumbers/secret_swadgeland_13.png rename to assets/lumbers/lumbers_swadgeland_13.png diff --git a/assets/lumbers/secret_swadgeland_14.png b/assets/lumbers/lumbers_swadgeland_14.png similarity index 100% rename from assets/lumbers/secret_swadgeland_14.png rename to assets/lumbers/lumbers_swadgeland_14.png diff --git a/assets/lumbers/secret_swadgeland_15.png b/assets/lumbers/lumbers_swadgeland_15.png similarity index 100% rename from assets/lumbers/secret_swadgeland_15.png rename to assets/lumbers/lumbers_swadgeland_15.png diff --git a/assets/lumbers/secret_swadgeland_16.png b/assets/lumbers/lumbers_swadgeland_16.png similarity index 100% rename from assets/lumbers/secret_swadgeland_16.png rename to assets/lumbers/lumbers_swadgeland_16.png diff --git a/assets/lumbers/secret_swadgeland_17.png b/assets/lumbers/lumbers_swadgeland_17.png similarity index 100% rename from assets/lumbers/secret_swadgeland_17.png rename to assets/lumbers/lumbers_swadgeland_17.png diff --git a/assets/lumbers/secret_swadgeland_2.png b/assets/lumbers/lumbers_swadgeland_2.png similarity index 100% rename from assets/lumbers/secret_swadgeland_2.png rename to assets/lumbers/lumbers_swadgeland_2.png diff --git a/assets/lumbers/secret_swadgeland_18.png b/assets/lumbers/lumbers_swadgeland_22.png similarity index 82% rename from assets/lumbers/secret_swadgeland_18.png rename to assets/lumbers/lumbers_swadgeland_22.png index 4446cda3a..916d09f2e 100644 Binary files a/assets/lumbers/secret_swadgeland_18.png and b/assets/lumbers/lumbers_swadgeland_22.png differ diff --git a/assets/lumbers/secret_swadgeland_3.png b/assets/lumbers/lumbers_swadgeland_3.png similarity index 100% rename from assets/lumbers/secret_swadgeland_3.png rename to assets/lumbers/lumbers_swadgeland_3.png diff --git a/assets/lumbers/secret_swadgeland_4.png b/assets/lumbers/lumbers_swadgeland_4.png similarity index 100% rename from assets/lumbers/secret_swadgeland_4.png rename to assets/lumbers/lumbers_swadgeland_4.png diff --git a/assets/lumbers/secret_swadgeland_5.png b/assets/lumbers/lumbers_swadgeland_5.png similarity index 100% rename from assets/lumbers/secret_swadgeland_5.png rename to assets/lumbers/lumbers_swadgeland_5.png diff --git a/assets/lumbers/secret_swadgeland_6.png b/assets/lumbers/lumbers_swadgeland_6.png similarity index 100% rename from assets/lumbers/secret_swadgeland_6.png rename to assets/lumbers/lumbers_swadgeland_6.png diff --git a/assets/lumbers/secret_swadgeland_7.png b/assets/lumbers/lumbers_swadgeland_7.png similarity index 100% rename from assets/lumbers/secret_swadgeland_7.png rename to assets/lumbers/lumbers_swadgeland_7.png diff --git a/assets/lumbers/secret_swadgeland_8.png b/assets/lumbers/lumbers_swadgeland_8.png similarity index 100% rename from assets/lumbers/secret_swadgeland_8.png rename to assets/lumbers/lumbers_swadgeland_8.png diff --git a/assets/lumbers/secret_swadgeland_9.png b/assets/lumbers/lumbers_swadgeland_9.png similarity index 100% rename from assets/lumbers/secret_swadgeland_9.png rename to assets/lumbers/lumbers_swadgeland_9.png diff --git a/assets/lumbers/lumbers_swadgeland_lives.png b/assets/lumbers/lumbers_swadgeland_lives.png new file mode 100644 index 000000000..92cc6abf7 Binary files /dev/null and b/assets/lumbers/lumbers_swadgeland_lives.png differ diff --git a/assets/lumbers/lumbers_title.png b/assets/lumbers/lumbers_title.png new file mode 100644 index 000000000..5c218f6e0 Binary files /dev/null and b/assets/lumbers/lumbers_title.png differ diff --git a/assets/lumbers/lumbers_title_attack_green.png b/assets/lumbers/lumbers_title_attack_green.png new file mode 100644 index 000000000..33955164f Binary files /dev/null and b/assets/lumbers/lumbers_title_attack_green.png differ diff --git a/assets/lumbers/lumbers_title_attack_red.png b/assets/lumbers/lumbers_title_attack_red.png new file mode 100644 index 000000000..74e584350 Binary files /dev/null and b/assets/lumbers/lumbers_title_attack_red.png differ diff --git a/assets/lumbers/lumbers_title_attack_white.png b/assets/lumbers/lumbers_title_attack_white.png new file mode 100644 index 000000000..b4110baa9 Binary files /dev/null and b/assets/lumbers/lumbers_title_attack_white.png differ diff --git a/assets/lumbers/lumbers_title_panic_green.png b/assets/lumbers/lumbers_title_panic_green.png new file mode 100644 index 000000000..4f1807c4c Binary files /dev/null and b/assets/lumbers/lumbers_title_panic_green.png differ diff --git a/assets/lumbers/lumbers_title_panic_red.png b/assets/lumbers/lumbers_title_panic_red.png new file mode 100644 index 000000000..7796898a0 Binary files /dev/null and b/assets/lumbers/lumbers_title_panic_red.png differ diff --git a/assets/lumbers/lumbers_title_panic_white.png b/assets/lumbers/lumbers_title_panic_white.png new file mode 100644 index 000000000..492a0e4bf Binary files /dev/null and b/assets/lumbers/lumbers_title_panic_white.png differ diff --git a/assets/lumbers/water_floor0.png b/assets/lumbers/lumbers_water_floor0.png similarity index 100% rename from assets/lumbers/water_floor0.png rename to assets/lumbers/lumbers_water_floor0.png diff --git a/assets/lumbers/water_floor1.png b/assets/lumbers/lumbers_water_floor1.png similarity index 100% rename from assets/lumbers/water_floor1.png rename to assets/lumbers/lumbers_water_floor1.png diff --git a/assets/lumbers/water_floor2.png b/assets/lumbers/lumbers_water_floor2.png similarity index 100% rename from assets/lumbers/water_floor2.png rename to assets/lumbers/lumbers_water_floor2.png diff --git a/assets/lumbers/water_floor3.png b/assets/lumbers/lumbers_water_floor3.png similarity index 100% rename from assets/lumbers/water_floor3.png rename to assets/lumbers/lumbers_water_floor3.png diff --git a/assets/lumbers/water_floor4.png b/assets/lumbers/lumbers_water_floor4.png similarity index 100% rename from assets/lumbers/water_floor4.png rename to assets/lumbers/lumbers_water_floor4.png diff --git a/assets/lumbers/water_floor_b1.png b/assets/lumbers/lumbers_water_floor_b1.png similarity index 100% rename from assets/lumbers/water_floor_b1.png rename to assets/lumbers/lumbers_water_floor_b1.png diff --git a/assets/lumbers/water_floor_b2.png b/assets/lumbers/lumbers_water_floor_b2.png similarity index 100% rename from assets/lumbers/water_floor_b2.png rename to assets/lumbers/lumbers_water_floor_b2.png diff --git a/assets/lumbers/water_floor_b3.png b/assets/lumbers/lumbers_water_floor_b3.png similarity index 100% rename from assets/lumbers/water_floor_b3.png rename to assets/lumbers/lumbers_water_floor_b3.png diff --git a/assets/lumbers/water_floor_b4.png b/assets/lumbers/lumbers_water_floor_b4.png similarity index 100% rename from assets/lumbers/water_floor_b4.png rename to assets/lumbers/lumbers_water_floor_b4.png diff --git a/main/modes/demo/demoMode.c b/main/modes/demo/demoMode.c index a1419373d..50d11fb83 100644 --- a/main/modes/demo/demoMode.c +++ b/main/modes/demo/demoMode.c @@ -54,6 +54,7 @@ swadgeMode_t demoMode = { typedef struct { + bool inMenu; font_t ibm; wsg_t king_donut; song_t ode_to_joy; @@ -62,6 +63,7 @@ typedef struct uint16_t recvPackets; connectionEvt_t conStatus; menu_t* menu; + menuLogbookRenderer_t* menuLogbookRenderer; } demoVars_t; demoVars_t* dv; @@ -99,6 +101,8 @@ static void demoEnterMode(void) addSingleItemToMenu(dv->menu, demoMenu5); addSingleItemToMenu(dv->menu, demoMenu6); + dv->menuLogbookRenderer = initMenuLogbookRenderer(&dv->ibm); + dv->conStatus = CON_LOST; p2pInitialize(&dv->p2p, 'p', demoConCb, demoMsgRxCb, -70); @@ -114,6 +118,8 @@ static void demoEnterMode(void) printf("High score in NVS is %" PRId32 "\n", highScoreToRead); } } + + dv->inMenu = true; } /** @@ -145,22 +151,39 @@ static void demoMainLoop(int64_t elapsedUs) static uint32_t lastBtnState = 0; while (checkButtonQueueWrapper(&evt)) { - dv->menu = menuButton(dv->menu, evt); - - // printf("state: %04X, button: %d, down: %s\n", evt.state, evt.button, evt.down ? "down" : "up"); lastBtnState = evt.state; - // drawScreen = evt.down; - if (evt.button == PB_B && evt.down && dv->conStatus == CON_ESTABLISHED) + if (dv->inMenu) { - printf("Sending packet\n"); - const uint8_t testMsg[] = {0x01, 0x02, 0x03, 0x04}; - p2pSendMsg(&dv->p2p, testMsg, ARRAY_SIZE(testMsg), demoMsgTxCbFn); + dv->menu = menuButton(dv->menu, evt); + + if (evt.button == PB_A && evt.down) + { + dv->inMenu = false; + } } + else + { + // printf("state: %04X, button: %d, down: %s\n", evt.state, evt.button, evt.down ? "down" : "up"); + // drawScreen = evt.down; + + if (evt.button == PB_B && evt.down && dv->conStatus == CON_ESTABLISHED) + { + printf("Sending packet\n"); + const uint8_t testMsg[] = {0x01, 0x02, 0x03, 0x04}; + p2pSendMsg(&dv->p2p, testMsg, ARRAY_SIZE(testMsg), demoMsgTxCbFn); + } + + static hid_gamepad_report_t report; + report.buttons = lastBtnState; + sendUsbGamepadReport(&report); + } + } - static hid_gamepad_report_t report; - report.buttons = lastBtnState; - sendUsbGamepadReport(&report); + if (dv->inMenu) + { + drawMenuLogbook(dv->menu, dv->menuLogbookRenderer, elapsedUs); + return; } // Fill the display area with a dark cyan @@ -420,4 +443,8 @@ static void demoMsgTxCbFn(p2pInfo* p2p, messageStatus_t status, const uint8_t* d static void demoMenuCb(const char* label, bool selected, uint32_t settingVal) { printf("%s %s\n", label, selected ? "selected" : "scrolled to"); + + if (selected) + { + } } diff --git a/main/modes/lumberjack/lumberjack.c b/main/modes/lumberjack/lumberjack.c index 8e7dd6157..7bab4ef62 100644 --- a/main/modes/lumberjack/lumberjack.c +++ b/main/modes/lumberjack/lumberjack.c @@ -5,18 +5,26 @@ #include #include +#include "mainMenu.h" #include "menu.h" +#include "mode_ray.h" // For lumberjack #include "lumberjack.h" #include "lumberjackGame.h" +#define LUMBERJACK_VLEN 7 +#define LUMBERJACK_VERSION "231118a" + +#define DEFAULT_HIGHSCORE 5000 + static void lumberjackEnterMode(void); static void lumberjackExitMode(void); static void lumberjackMainLoop(int64_t elapsedUs); static void lumberjackMenuLoop(int64_t elapsedUs); static void lumberjackAudioCallback(uint16_t* samples, uint32_t sampleCnt); static void lumberjackBackgroundDrawCallback(int16_t x, int16_t y, int16_t w, int16_t h, int16_t up, int16_t upNum); +static void lumberjackInstructionText(const char* string, paletteColor_t color, int locationX, int locationY); static void lumberjackEspNowRecvCb(const esp_now_recv_info_t* esp_now_info, const uint8_t* data, uint8_t len, int8_t rssi); static void lumberjackEspNowSendCb(const uint8_t* mac_addr, esp_now_send_status_t status); @@ -27,23 +35,30 @@ static void lumberjackMsgTxCbFn(p2pInfo* p2p, messageStatus_t status, const uint static void lumberjackMenuCb(const char*, bool selected, uint32_t settingVal); +static void lumberjackLoadSave(void); static void lumberjackJoinGame(void); +static bool lumberjackChoUnlocked(void); +static bool lumberjackSwadgeGuyUnlocked(void); + -static const char lumberjackName[] = "Lumberjack"; +static const char lumberjackName[] = "Lumber Jacks"; static const char lumberjackPanic[] = "Panic"; static const char lumberjackAttack[] = "Attack"; -static const char lumberjackBack[] = "Back"; +static const char lumberjackInstructions[] = "How to Play"; +static const char lumberjackExit[] = "Exit"; -// static const char lumberjackNone[] = "None"; -static const char lumberjackRedCharacter[] = "Character: Red"; -static const char lumberjackGreen[] = "Character: Green"; -static const char lumberjackSpecialCharacter[] = "Character: Special"; +static char lumberjackRedCharacter[] = "Character: Red"; +static char lumberjackGreenCharacter[] = "Character: Green"; +static char lumberjackSpecialCharacter[] = "Character: Guy"; +static char lumberjackChoCharacter[] = "Character: Cho"; -static const char lumberjackMenuSinglePlayer[] = "Single Player"; -static const char lumberjackMenuMultiPlayerHost[] = "Multi-Player"; -static const char lumberjackMenuMultiPlayerClient[] = "Multi-Player Join"; +static const char lumberjackMenuSinglePlayer[] = "Single Player"; +static const char lumberjackMenuMultiPlayer[] = "Multi-Player"; +static const char lumberjackPlatformerUnlock[] = "pf_scores"; +static const char lumberjackChoUnlock[] = "ray"; const char* LUM_TAG = "LUM"; +const char LUMBERJACK_SAVE[] = "lumberjackdata"; swadgeMode_t lumberjackMode = { .modeName = lumberjackName, @@ -62,17 +77,30 @@ swadgeMode_t lumberjackMode = { .fnAdvancedUSB = NULL, }; +typedef enum +{ + VERSION_MSG, + READY_MSG, + ATTACK_MSG, + DEATH_MSG, + SCORE_MSG, + WATER_MSG, + HOST_MSG, + CHARACTER_MSG, + BUMP_MSG +} lumberjackMessageType_t; + lumberjack_t* lumberjack = NULL; static void lumberjackEnterMode(void) { - ESP_LOGI(LUM_TAG, "Lumber!"); // Allocate and clear all memory for the menu mode. lumberjack = calloc(1, sizeof(lumberjack_t)); - loadFont("ibm_vga8.font", &lumberjack->ibm, false); - loadFont("logbook.font", &lumberjack->logbook, false); + lumberjackLoadSave(); + loadFont("logbook.font", &lumberjack->logbook, false); + loadFont("eightbit_atari_grube2.font", &lumberjack->arcade, false); lumberjack->menu = initMenu(lumberjackName, lumberjackMenuCb); lumberjack->menuLogbookRenderer = initMenuLogbookRenderer(&lumberjack->logbook); @@ -82,35 +110,93 @@ static void lumberjackEnterMode(void) lumberjack->menu = startSubMenu(lumberjack->menu, lumberjackPanic); addSingleItemToMenu(lumberjack->menu, lumberjackMenuSinglePlayer); - addSingleItemToMenu(lumberjack->menu, lumberjackMenuMultiPlayerHost); - addSingleItemToMenu(lumberjack->menu, lumberjackMenuMultiPlayerClient); + addSingleItemToMenu(lumberjack->menu, lumberjackMenuMultiPlayer); + addSingleItemToMenu(lumberjack->menu, lumberjackInstructions); + lumberjack->menu = endSubMenu(lumberjack->menu); + + lumberjack->menu = startSubMenu(lumberjack->menu, lumberjackAttack); + addSingleItemToMenu(lumberjack->menu, lumberjackMenuSinglePlayer); + addSingleItemToMenu(lumberjack->menu, lumberjackMenuMultiPlayer); + addSingleItemToMenu(lumberjack->menu, lumberjackInstructions); lumberjack->menu = endSubMenu(lumberjack->menu); - addSingleItemToMenu(lumberjack->menu, lumberjackAttack); + int characters = 2; - if (true) // Ignore this line + if (lumberjack->save.choUnlocked) { - static const char* defaultCharacters[] = {lumberjackRedCharacter, lumberjackGreen}; + characters++; + } - addMultiItemToMenu(lumberjack->menu, defaultCharacters, ARRAY_SIZE(defaultCharacters), 0); + if (lumberjack->save.swadgeGuyUnlocked) + { + characters++; } - else + + lumberjack->charactersArray = calloc(characters, sizeof(char*)); + + lumberjack->charactersArray[0] = lumberjackRedCharacter; + lumberjack->charactersArray[1] = lumberjackGreenCharacter; + + int index = 2; + + if (lumberjack->save.choUnlocked) { - static const char* defaultCharacterswUnlocks[] - = {lumberjackRedCharacter, lumberjackGreen, lumberjackSpecialCharacter}; + lumberjack->charactersArray[index++] = lumberjackChoCharacter; + } - addMultiItemToMenu(lumberjack->menu, defaultCharacterswUnlocks, ARRAY_SIZE(defaultCharacterswUnlocks), 0); + if (lumberjack->save.swadgeGuyUnlocked) + { + lumberjack->charactersArray[index++] = lumberjackSpecialCharacter; } + addMultiItemToMenu(lumberjack->menu, lumberjack->charactersArray, characters, 0); + addSingleItemToMenu(lumberjack->menu, lumberjackExit); + lumberjack->screen = LUMBERJACK_MENU; - // Lumberjack. Game 19 - // Init menu :( - bzrStop(true); // Stop the buzzer? - // High score stuff? - // Unlockables ? Save data? +} + +static void lumberjackLoadSave(void) +{ + size_t len = sizeof(lumberjack->save); + readNvsBlob(LUMBERJACK_SAVE, &lumberjack->save, &len); + if (lumberjack->save.choUnlocked == false) + { + lumberjack->save.choUnlocked = lumberjackChoUnlocked(); + } + + if (lumberjack->save.swadgeGuyUnlocked == false) + { + lumberjack->save.swadgeGuyUnlocked = lumberjackSwadgeGuyUnlocked(); + } + //writeNvsBlob(breakoutNvsKey_scores, &(self->highScores), size); + + int highscore = lumberjack->save.highScore; + + if (highscore < DEFAULT_HIGHSCORE) + { + lumberjack->save.highScore = DEFAULT_HIGHSCORE; + } + + if (lumberjack->save.attackHighScore < DEFAULT_HIGHSCORE) + { + lumberjack->save.attackHighScore = DEFAULT_HIGHSCORE; + } + + if (lumberjack->save.panicHighScore < DEFAULT_HIGHSCORE) + { + lumberjack->save.panicHighScore = DEFAULT_HIGHSCORE; + } + + writeNvsBlob(LUMBERJACK_SAVE, &lumberjack->save, len); +} + +void lumberjackSaveSave(void) +{ + size_t len = sizeof(lumberjack->save); + writeNvsBlob(LUMBERJACK_SAVE, &lumberjack->save, len); } static void lumberjackJoinGame(void) @@ -118,6 +204,7 @@ static void lumberjackJoinGame(void) if (lumberjack->gameMode == LUMBERJACK_MODE_PANIC) { lumberjack->screen = LUMBERJACK_A; + lumberjack->save.highScore = lumberjack->save.panicHighScore; lumberjackStartGameMode(lumberjack, lumberjack->selected); return; } @@ -125,6 +212,7 @@ static void lumberjackJoinGame(void) if (lumberjack->gameMode == LUMBERJACK_MODE_ATTACK) { lumberjack->screen = LUMBERJACK_B; + lumberjack->save.highScore = lumberjack->save.attackHighScore; lumberjackStartGameMode(lumberjack, lumberjack->selected); return; } @@ -134,12 +222,14 @@ static void lumberjackJoinGame(void) static void lumberjackExitMode(void) { + lumberjackUnloadLevel(); lumberjackExitGameMode(); - + free(lumberjack->charactersArray); p2pDeinit(&lumberjack->p2p); - freeFont(&lumberjack->ibm); freeFont(&lumberjack->logbook); + freeFont(&lumberjack->arcade); deinitMenu(lumberjack->menu); + deinitMenuLogbookRenderer(lumberjack->menuLogbookRenderer); free(lumberjack); } @@ -159,6 +249,7 @@ static void lumberjackMainLoop(int64_t elapsedUs) break; } } + } static void lumberjackMenuLoop(int64_t elapsedUs) @@ -166,10 +257,115 @@ static void lumberjackMenuLoop(int64_t elapsedUs) buttonEvt_t evt = {0}; while (checkButtonQueueWrapper(&evt)) { - lumberjack->menu = menuButton(lumberjack->menu, evt); + if (lumberjack->instructions) + { + if (evt.state & PB_B) + { + lumberjack->instructions = false; + } + } + else + { + lumberjack->menu = menuButton(lumberjack->menu, evt); + } } - drawMenuLogbook(lumberjack->menu, lumberjack->menuLogbookRenderer, elapsedUs); + if (lumberjack->instructions) + { + fillDisplayArea(0, 0, TFT_WIDTH , TFT_HEIGHT , c145); + + + const char* closeText = "Press B to close"; + int16_t cWidthH = textWidth(&lumberjack->arcade, closeText); + int16_t dOffset = 15; + int16_t dyOffset = 50; + int16_t iWidth = 10; + + + if (lumberjack->gameMode == LUMBERJACK_MODE_PANIC) + { + + const char* titleText = "Panic"; + int16_t tWidthH = textWidth(&lumberjack->arcade, titleText); + lumberjackInstructionText(titleText, c555, (TFT_WIDTH-tWidthH)/2, 15); + + const char* ins = "Press A to jump\nAvoid upright baddies\nHit baddies from under\nThen kick them off\nDuck DOWN to avoid ghost\nAxe blocks lowers water\nDon't drown"; + /* + lumberjackInstructionText("Press A to jump", c355, dOffset, 50); + lumberjackInstructionText("Avoid upright baddies", c355, dOffset, 70); + lumberjackInstructionText("Hit baddies from under", c355, dOffset, 90); + lumberjackInstructionText("Then go kick them off", c355, dOffset, 110); + lumberjackInstructionText("Duck Down to avoid ghost", c355, dOffset, 130); + lumberjackInstructionText("Axe blocks lowers water", c355, dOffset, 150); + */ + dOffset = 15; dyOffset = 49; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + dOffset = 15; dyOffset = 52; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + dOffset = 14; dyOffset = 50; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + dOffset = 16; dyOffset = 50; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth + 1, TFT_HEIGHT - dOffset); + + dOffset = 15; dyOffset = 50; + drawTextWordWrap(&lumberjack->arcade, c355, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + } + else if (lumberjack->gameMode == LUMBERJACK_MODE_ATTACK) + { + const char* titleText = "Attack"; + int16_t tWidthH = textWidth(&lumberjack->arcade, titleText); + lumberjackInstructionText(titleText, c555, (TFT_WIDTH-tWidthH)/2, 15); + + const char* ins = "Press A to jump\nAvoid upright baddies\nHit baddies from under\nThen kick them off\nDuck DOWN to avoid ghost\nAxe blocks give item\nPress B uses item\n Upgrange: Harder baddies\n Impearvious: Invincible\n Grapes O' Wrath: Flip baddies"; + /* + lumberjackInstructionText("Press A to jump", c355, dOffset, 50); + lumberjackInstructionText("Avoid upright baddies", c355, dOffset, 70); + lumberjackInstructionText("Hit baddies from under", c355, dOffset, 90); + lumberjackInstructionText("Then go kick them off", c355, dOffset, 110); + lumberjackInstructionText("Duck Down to avoid ghost", c355, dOffset, 130); + lumberjackInstructionText("Axe blocks give items", c355, dOffset, 150); + lumberjackInstructionText("Press B uses item", c355, dOffset, 170); + */ + dOffset = 15; dyOffset = 49; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + dOffset = 15; dyOffset = 52; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + dOffset = 14; dyOffset = 50; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + dOffset = 16; dyOffset = 50; + drawTextWordWrap(&lumberjack->arcade, c000, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth + 1, TFT_HEIGHT - dOffset); + + dOffset = 15; dyOffset = 50; + drawTextWordWrap(&lumberjack->arcade, c355, ins, &dOffset, &dyOffset, TFT_WIDTH - iWidth, TFT_HEIGHT - dOffset); + + } + + dOffset = 15; dyOffset = 50; + + //dOffset = 20; + //drawText(&lumberjack->arcade, c555, closeText, (TFT_WIDTH-cWidthH)/2,(TFT_HEIGHT - dOffset - 5)); + lumberjackInstructionText(closeText, c555, (TFT_WIDTH-cWidthH)/2,(TFT_HEIGHT - dOffset - 5)); + + } +} + +static void lumberjackInstructionText(const char* string, paletteColor_t color, int locationX, int locationY) +{ + drawText(&lumberjack->arcade, c000, string, locationX, locationY-1); + drawText(&lumberjack->arcade, c000, string, locationX, locationY+2); + drawText(&lumberjack->arcade, c000, string, locationX -1, locationY); + drawText(&lumberjack->arcade, c000, string, locationX + 1, locationY); + drawText(&lumberjack->arcade, color, string, locationX, locationY); + + //drawTextWordWrap(&lumberjack->arcade, c555, string, &dOffset, &dOffset, TFT_WIDTH - dOffset, TFT_HEIGHT - dOffset); + } static void lumberjackAudioCallback(uint16_t* samples, uint32_t sampleCnt) @@ -183,41 +379,84 @@ static void lumberjackBackgroundDrawCallback(int16_t x, int16_t y, int16_t w, in // Are we drawing the game here? } + +//============================================================================== +// UNLOCKS +//============================================================================== + +static bool lumberjackChoUnlocked() +{ + rayPlayer_t cho; + size_t size = sizeof(cho); + + return readNvsBlob(lumberjackChoUnlock, &cho, &(size)); +} + +static bool lumberjackSwadgeGuyUnlocked() +{ + pfHighScores_t highScores; + size_t size = sizeof(pfHighScores_t); + // Try reading the value + + return readNvsBlob(lumberjackPlatformerUnlock, &(highScores), &(size)); + +} + //============================================================================== // ESP_NOW //============================================================================== static void lumberjackEspNowRecvCb(const esp_now_recv_info_t* esp_now_info, const uint8_t* data, uint8_t len, int8_t rssi) { - // ESP_LOGI(LUM_TAG, "Getting: %d", (uint8_t)&data); - p2pRecvCb(&lumberjack->p2p, esp_now_info->src_addr, data, len, rssi); + /*ESP_LOGD(LUM_TAG, "Getting: %d %d", len, rssi); + for (int i = 0; i < len; i++) + { + ESP_LOGD(LUM_TAG, "data %d) %d", i, data[i]); + }*/ + p2pRecvCb(&lumberjack->p2p, esp_now_info->src_addr, (const uint8_t*)data, len, rssi); } static void lumberjackEspNowSendCb(const uint8_t* mac_addr, esp_now_send_status_t status) { + //ESP_LOGD(LUM_TAG, "STATUS %d", status); p2pSendCb(&lumberjack->p2p, mac_addr, status); } static void lumberjackConCb(p2pInfo* p2p, connectionEvt_t evt) { - // Do anything - if (evt == CON_ESTABLISHED) + switch(evt) { - ESP_LOGI(LUM_TAG, "LumberJack.Net ready! %d", (int)p2pGetPlayOrder(p2p)); + case CON_STARTED: + case RX_GAME_START_ACK: + case RX_GAME_START_MSG: + { + // TODO, optional, update menu to indicate connection progress + ESP_LOGI(LUM_TAG, "LumberJack.Net ack! "); - if (GOING_FIRST == p2pGetPlayOrder(p2p)) + break; + } + case CON_ESTABLISHED: { - ESP_LOGI(LUM_TAG, "HOST?"); - const uint8_t testMsg[] = {0x01, 0x02, 0x03, 0x04}; + int index = (int)p2pGetPlayOrder(p2p); + ESP_LOGI(LUM_TAG, "LumberJack.Net ready! %d", index); + lumberjack->host = (GOING_FIRST == index); + + uint8_t payload[1 + LUMBERJACK_VLEN] = {VERSION_MSG}; + memcpy(&payload[1], LUMBERJACK_VERSION, LUMBERJACK_VLEN); - p2pSendMsg(&lumberjack->p2p, testMsg, ARRAY_SIZE(testMsg), lumberjackMsgTxCbFn); + p2pSendMsg(&lumberjack->p2p, payload, sizeof(payload), lumberjackMsgTxCbFn); + lumberjackGameReady(); + break; } - } + case CON_LOST: + { + // TODO drop back to main menu or show an error or something, its not recoverable + ESP_LOGI(LUM_TAG, "We lost connection!"); - if (evt == CON_LOST) - { - // Do we attempt to get it back? - ESP_LOGW(LUM_TAG, "We lost connection!"); + lumberjack->connLost = true; + //lumberjack->menuReturn = 3000; + break; + } } lumberjack->conStatus = evt; @@ -226,38 +465,149 @@ static void lumberjackConCb(p2pInfo* p2p, connectionEvt_t evt) static void lumberjackMsgRxCb(p2pInfo* p2p, const uint8_t* payload, uint8_t len) { // Do anything + ESP_LOGD(LUM_TAG, "Ya boi got something! %d", (uint8_t)payload[0]); + + lumberjackQualityCheck(); - if (len > 1) + if (len > 0) { - if (payload[0] == 0x19) + if (payload[0] == VERSION_MSG) { - int locX = (int)payload[1] << 0 | (uint32_t)payload[2] << 8; - int locY = (int)payload[3] << 0 | (uint32_t)payload[4] << 8; - uint8_t frame = (uint8_t)payload[5]; - printf("Got %d,%d %d|", locX, locY, frame); + ESP_LOGD(LUM_TAG, "Version received!"); + if (memcmp(&payload[1], LUMBERJACK_VERSION, LUMBERJACK_VLEN)) + { + ESP_LOGD("LUM_TAG", "We're in!"); + } + } - lumberjackUpdateRemote(locX, locY, frame); + if (payload[0] == READY_MSG) + { + ESP_LOGD(LUM_TAG,"Test message"); + lumberjackPlayGame(); } + + if (payload[0] == ATTACK_MSG) + { + ESP_LOGD(LUM_TAG, "Incoming attack!"); + lumberjackOnReceiveAttack(payload, len); + } + + if (payload[0] == SCORE_MSG) + { + lumberjackOnReceiveScore(payload); + } + + if (payload[0] == CHARACTER_MSG) + { + ESP_LOGI(LUM_TAG, "CH"); + lumberjackOnReceiveCharacter(payload[1]); + } + + if (payload[0] == BUMP_MSG) + { + lumberjackOnReceiveBump(); + } + + if (payload[0] == DEATH_MSG) + { + lumberjackOnReceiveDeath(payload[1]); + } + + if (payload[0] == HOST_MSG) + { + if (lumberjack->host == false) + { + lumberjack->host = true; + } + } + + /* + if (payload[0] == 0x19) + { + //int locX = (int)payload[1] << 0 | (uint32_t)payload[2] << 8; + //int locY = (int)payload[3] << 0 | (uint32_t)payload[4] << 8; + //uint8_t frame = (uint8_t)payload[5]; + //ESP_LOGD(LUM_TAG,"Got %d,%d %d|", locX, locY, frame); + + }*/ } - printf("Received %d %d!\n", *payload, len); + + ESP_LOGD(LUM_TAG,"Received %d %d!\n", *payload, len); } -void lumberjackSendAttack(int number) +void lumberjackSendGo(void) { - const uint8_t testMsg[] = {0x13}; - p2pSendMsg(&lumberjack->p2p, testMsg, ARRAY_SIZE(testMsg), lumberjackMsgTxCbFn); + if (lumberjack->networked) + { + const uint8_t msg[] = {READY_MSG}; + p2pSendMsg(&lumberjack->p2p, msg, ARRAY_SIZE(msg), lumberjackMsgTxCbFn); + } +} + +void lumberjackSendHostRequest(void) +{ + if (lumberjack->networked) + { + const uint8_t msg[] = {HOST_MSG}; + p2pSendMsg(&lumberjack->p2p, msg, ARRAY_SIZE(msg), lumberjackMsgTxCbFn); + } +} + +void lumberjackSendAttack(uint8_t* number) +{ + if (lumberjack->networked) + { + uint8_t payload[9] = {ATTACK_MSG}; + memcpy(&payload[1], number, 8); + + p2pSendMsg(&lumberjack->p2p, payload, ARRAY_SIZE(payload), lumberjackMsgTxCbFn); + } +} + +void lumberjackSendBump(void) +{ + if (lumberjack->networked) + { + uint8_t payload[1] = {BUMP_MSG}; + p2pSendMsg(&lumberjack->p2p, payload, ARRAY_SIZE(payload), lumberjackMsgTxCbFn); + } +} + +void lumberjackSendScore(int score) +{ + if (lumberjack->networked) + { + + uint8_t payload[4] = {SCORE_MSG}; + + payload[3] = score >> 16 & 0xFF; + payload[2] = score >> 8 & 0xFF; + payload[1] = score & 0xFF; + p2pSendMsg(&lumberjack->p2p, payload, ARRAY_SIZE(payload), lumberjackMsgTxCbFn); + } +} + +void lumberjackSendCharacter(uint8_t character) +{ + if (lumberjack->networked) + { + uint8_t payload[2] = {CHARACTER_MSG, character}; + p2pSendMsg(&lumberjack->p2p, payload, ARRAY_SIZE(payload), lumberjackMsgTxCbFn); + } } -void lumberjackUpdateLocation(int ghostX, int ghostY, int frame) +void lumberjackSendDeath(uint8_t lives) { - const uint8_t locationMessage[6] - = {0x19, (uint8_t)(ghostX >> 0), (uint8_t)(ghostX >> 8), (uint8_t)(ghostY >> 0), (uint8_t)(ghostY >> 8), frame}; - p2pSendMsg(&lumberjack->p2p, locationMessage, ARRAY_SIZE(locationMessage), lumberjackMsgTxCbFn); + if (lumberjack->networked) + { + const uint8_t payload[2] = {DEATH_MSG, lives}; + p2pSendMsg(&lumberjack->p2p, payload, ARRAY_SIZE(payload), lumberjackMsgTxCbFn); + } } /** - * @brief TODO use this somewhere + * @brief This is called after transmitting a p2p packet and receiving (or not receiving) an ack * * @param p2p * @param status @@ -266,44 +616,71 @@ void lumberjackUpdateLocation(int ghostX, int ghostY, int frame) */ static void lumberjackMsgTxCbFn(p2pInfo* p2p, messageStatus_t status, const uint8_t* data, uint8_t len) { + switch(status) + { + case MSG_ACKED: + { + // All good + break; + } + case MSG_FAILED: + { + // TODO figure out what to do if a message fails to transmit (i.e. no ack). Retry? + ESP_LOGI(LUM_TAG, "Failed?"); + break; + } + } +} + +void lumberjackInitp2p() +{ + p2pDeinit(&lumberjack->p2p); + lumberjack->conStatus = CON_LOST; + p2pInitialize(&lumberjack->p2p,(lumberjack->gameMode == LUMBERJACK_MODE_PANIC ? 0x13 : 0x15), lumberjackConCb, lumberjackMsgRxCb, -70); + p2pStartConnection(&lumberjack->p2p); } static void lumberjackMenuCb(const char* label, bool selected, uint32_t settingVal) { - ESP_LOGI(LUM_TAG, "Info "); if (selected) { + if (lumberjack->screen != LUMBERJACK_MENU) + { + return; + } + if (label == lumberjackPanic) { - ESP_LOGI(LUM_TAG, "Panic"); lumberjack->gameMode = LUMBERJACK_MODE_PANIC; - // lumberjack->screen = LUMBERJACK_A; - // lumberjackStartGameMode(LUMBERJACK_MODE_PANIC, lumberjack->selected); } else if (label == lumberjackAttack) { - ESP_LOGI(LUM_TAG, "Attack"); lumberjack->gameMode = LUMBERJACK_MODE_ATTACK; - - // lumberjack->screen = LUMBERJACK_B; - // lumberjackStartGameMode(LUMBERJACK_MODE_ATTACK, lumberjack->selected); } - if (label == lumberjackMenuMultiPlayerHost) + if (label == lumberjackInstructions) { - p2pInitialize(&lumberjack->p2p, 0x13, lumberjackConCb, lumberjackMsgRxCb, -70); - p2pStartConnection(&lumberjack->p2p); - lumberjack->networked = true; - lumberjack->host = true; - lumberjackJoinGame(); + + if (lumberjack->gameMode == LUMBERJACK_MODE_PANIC) + { + lumberjack->instructions = true; + } + else if (lumberjack->gameMode == LUMBERJACK_MODE_ATTACK) + { + lumberjack->instructions = true; + + } + + //There was a 3rd game mode planned but... I don't want to take any chances + } - else if (label == lumberjackMenuMultiPlayerClient) + + if (label == lumberjackMenuMultiPlayer) { - p2pInitialize(&lumberjack->p2p, 0x13, lumberjackConCb, lumberjackMsgRxCb, -70); - p2pStartConnection(&lumberjack->p2p); lumberjack->networked = true; - lumberjack->host = false; + // lumberjack->host is filled in after connection is established lumberjackJoinGame(); + // Start p2p after loading sprites, which takes time } else if (label == lumberjackMenuSinglePlayer) { @@ -311,38 +688,39 @@ static void lumberjackMenuCb(const char* label, bool selected, uint32_t settingV lumberjack->host = false; lumberjackJoinGame(); } - - if (label == lumberjackRedCharacter) - { - lumberjack->selected = 0; - } - else if (label == lumberjackGreen) - { - lumberjack->selected = 1; - } - else if (label == lumberjackSpecialCharacter) + else if (label == lumberjackExit) { - lumberjack->selected = 2; - } + switchToSwadgeMode(&mainMenuMode); + } - if (label == lumberjackBack) - { - //.switchToSwadgeMode(&mainMenuMode); - } } else { + + if (label == lumberjackPanic) + { + lumberjack->gameMode = LUMBERJACK_MODE_PANIC; + } + else if (label == lumberjackAttack) + { + lumberjack->gameMode = LUMBERJACK_MODE_ATTACK; + } + if (label == lumberjackRedCharacter) { lumberjack->selected = 0; } - else if (label == lumberjackGreen) + else if (label == lumberjackGreenCharacter) { lumberjack->selected = 1; } else if (label == lumberjackSpecialCharacter) { lumberjack->selected = 2; + }else if (label == lumberjackChoCharacter) + { + lumberjack->selected = 3; + } } } \ No newline at end of file diff --git a/main/modes/lumberjack/lumberjack.h b/main/modes/lumberjack/lumberjack.h index e3b2655bf..fbb3cb018 100644 --- a/main/modes/lumberjack/lumberjack.h +++ b/main/modes/lumberjack/lumberjack.h @@ -23,23 +23,45 @@ typedef enum LUMBERJACK_MODE_ATTACK } lumberjackGameType_t; +typedef enum +{ + LUMBERJACK_GAMESTATE_TITLE, + LUMBERJACK_GAMESTATE_PLAYING, + LUMBERJACK_GAMESTATE_WINNING, + LUMBERJACK_GAMESTATE_GAMEOVER +} lumberjackGameState_t; + +typedef struct +{ + int highScore; + int attackHighScore; + int panicHighScore; + bool swadgeGuyUnlocked; + bool choUnlocked; +}lumberjackUnlock_t; + typedef struct { menu_t* menu; menuLogbookRenderer_t* menuLogbookRenderer; - font_t ibm; font_t logbook; + font_t arcade; uint8_t selected; - bool networked; bool host; + bool instructions; + + bool networked; + bool connLost; // The pass throughs p2pInfo p2p; connectionEvt_t conStatus; lumberjackScreen_t screen; lumberjackGameType_t gameMode; + lumberjackUnlock_t save; + const char** charactersArray; } lumberjack_t; typedef struct @@ -47,7 +69,6 @@ typedef struct /* data */ int x; int y; - int collision; int type; int index; int offset; @@ -57,43 +78,173 @@ typedef struct typedef struct { + int x; + int y; + int type; + bool active; + +} lumberjackAxeBlock_t; + + + +typedef struct +{ + int x; + int y; + int time; + bool active; + int bonusAmount; +} lumberjackBonus_t; + +typedef struct +{ + bool levelMusic; bool loaded; - font_t ibm; + bool hasWon; + bool gameReady; + font_t arcade; lumberjack_t* lumberjackMain; menu_t* menu; uint16_t btnState; ///<-- The STOLEN! ;) + lumberjackGameState_t gameState; int yOffset; + int levelIndex; + int upgrade; + int resume; int lives; + uint8_t nLives; + int64_t worldTimer; + int64_t levelTime; + int64_t transitionTimer; int64_t physicsTimer; int liquidAnimationFrame; + int stageAnimationFrame; int currentMapHeight; + int totalEnemyCount; + int enemyKillCount; int spawnTimer; int spawnIndex; int spawnSide; + int score; + int highscore; + int localPlayerType; + uint8_t netPlayerType; + + int enemyAttackQueue; + + int waterLevel; + int waterTimer; + int waterSpeed; + int waterDirection; + int playerSpawnX; + int playerSpawnY; + + + + int enemy1Count; + int enemy2Count; + int enemy3Count; + int enemy4Count; + int enemy5Count; + int enemy6Count; + int enemy7Count; + int enemy8Count; + + int enemySpawnTime; + int enemyReceiveSpawnTime; + int enemySpawnAmount; + + int comboTime; + int comboAmount; + + uint8_t attackQueue[8]; + + int wakeupSignal; + int lastResponseSignal; + wsg_t floorTiles[20]; wsg_t animationTiles[20]; + wsg_t minicharacters[4]; + wsg_t itemIcons[18]; - lumberjackTile_t tile[400]; - uint8_t anim[400]; + lumberjackBonus_t* bonusDisplay[16]; + uint8_t activeBonusIndex; - wsg_t enemySprites[21]; - wsg_t playerSprites[54]; + wsg_t title; + wsg_t subtitle_red; + wsg_t subtitle_green; + wsg_t subtitle_white; + wsg_t gameoverSprite; + wsg_t gamewinSprite; + wsg_t connectLostSprite; - wsg_t alertSprite; + lumberjackTile_t* tile; + + wsg_t greenBlockSprite[7]; + wsg_t redBlockSprite[7]; + wsg_t unknownBlockSprite[7]; + wsg_t unusedBlockSprite[7]; + + wsg_t enemySprites[37]; + wsg_t playerSprites[18]; + wsg_t bonusSprites[11]; - wsg_t slowload[400]; + wsg_t ui[6]; + + wsg_t alertSprite; - lumberjackEntity_t* enemy[8]; + lumberjackEntity_t* enemy[32]; + lumberjackAxeBlock_t* axeBlocks[8]; lumberjackEntity_t* localPlayer; - lumberjackEntity_t* remotePlayer; + //Ghost + lumberjackGhost_t* ghost; + int ghostSpawnTime; + + //Item Block + int itemBlockTime; + bool itemBlockReady; + int itemBlockIndex; + int itemBlockItemAnimation; + int itemBlockAnimationTime; + int itemBlockItemFrame; + + uint8_t invincibleColor; + int invincibleTimer; + int invincibleFlicker; + bool invincibleFlickerOn; + lumberjackGameType_t gameType; + //sounds + song_t sfx_item_get; + song_t sfx_item_use; + song_t sfx_jump; + song_t sfx_bump; + song_t sfx_flip; + song_t sfx_player_death; + song_t sfx_enemy_death; + + song_t song_theme; + song_t song_respawn; + song_t song_gameover; + song_t song_title; + } lumberjackVars_t; +#define NUM_PLATFORMER_HIGH_SCORES 5 + +typedef struct { + uint32_t scores[NUM_PLATFORMER_HIGH_SCORES]; + char initials[NUM_PLATFORMER_HIGH_SCORES][3]; +} pfHighScores_t; + +typedef struct +{ ///< All the players items +} pfRay_t; #endif \ No newline at end of file diff --git a/main/modes/lumberjack/lumberjackEntity.c b/main/modes/lumberjack/lumberjackEntity.c index 5b0a1f1e1..29dc730e4 100644 --- a/main/modes/lumberjack/lumberjackEntity.c +++ b/main/modes/lumberjack/lumberjackEntity.c @@ -5,15 +5,17 @@ void lumberjackSetupEnemy(lumberjackEntity_t* enemy, int character) { - enemy->direction = 1; - enemy->state = LUMBERJACK_RUN; - enemy->maxVX = 0; - enemy->active = false; - enemy->ready = true; - enemy->showAlert = false; - enemy->spriteOffset = 0; - enemy->cW = 15; - enemy->cH = 15; + enemy->direction = 1; + enemy->state = LUMBERJACK_RUN; + enemy->maxVX = 0; + enemy->active = false; + enemy->ready = true; + enemy->showAlert = false; + enemy->spriteOffset = 0; + enemy->cW = 15; + enemy->cH = 15; + enemy->submergedTimer = 0; + enemy->queueable = true; lumberjackUpdateEnemy(enemy, character); } @@ -39,6 +41,7 @@ void lumberjackRespawnEnemy(lumberjackEntity_t* enemy, int side) enemy->active = true; enemy->ready = false; enemy->y = 0; + enemy->lives = 1; // I need to figure out why when moving right he appears to move faster if (side == 1) @@ -76,6 +79,8 @@ void lumberjackUpdateEnemy(lumberjackEntity_t* enemy, int newIndex) enemy->maxVX = 4; enemy->spriteOffset = 0; enemy->maxLevel = 2; + enemy->scoreValue = 100; + enemy->type = newIndex; enemy->cW = 15; enemy->cH = 15; @@ -89,7 +94,10 @@ void lumberjackUpdateEnemy(lumberjackEntity_t* enemy, int newIndex) enemy->spriteOffset = 7; enemy->maxLevel = 2; enemy->cW = 15; + enemy->scoreValue = 250; enemy->cH = 15; + enemy->type = newIndex; + } else if (newIndex == 2) { @@ -100,17 +108,42 @@ void lumberjackUpdateEnemy(lumberjackEntity_t* enemy, int newIndex) enemy->spriteOffset = 14; enemy->maxLevel = 2; enemy->cW = 15; + enemy->scoreValue = 500; enemy->cH = 15; + enemy->type = newIndex; + + } + else if (newIndex == 4) + { + enemy->width = 15; + enemy->height = 15; + enemy->tileHeight = 1; + enemy->maxVX = 10; + enemy->spriteOffset = 23; + enemy->maxLevel = 6; + enemy->cW = 15; + enemy->scoreValue = 500; + enemy->cH = 15; + enemy->type = newIndex; + } + else if (newIndex == 5) + { + enemy->width = 15; + enemy->height = 15; + enemy->tileHeight = 1; + enemy->maxVX = 10; + enemy->spriteOffset = 30; + enemy->maxLevel = 6; + enemy->cW = 15; + enemy->scoreValue = 500; + enemy->cH = 15; + enemy->type = newIndex; } -} -void lumberjackDoEnemyControls(lumberjackEntity_t* enemy) -{ - // pick between types I guess - // if enemy->type 1, 2, or 3... continue - // enemy->direction = -1; + } + void lumberjackUpdateEnemyCollision(lumberjackEntity_t* enemy) { enemy->cX = enemy->x; @@ -158,7 +191,7 @@ uint8_t lumberjackGetEnemyAnimation(lumberjackEntity_t* enemy) if (animation == LUMBERJACK_BUMPED) { const int anim[] = {4}; - return anim[enemy->currentFrame % 2]; + return anim[0]; } if (animation == LUMBERJACK_BUMPED_IDLE) diff --git a/main/modes/lumberjack/lumberjackEntity.h b/main/modes/lumberjack/lumberjackEntity.h index ced2eabaf..0b3e2ca5a 100644 --- a/main/modes/lumberjack/lumberjackEntity.h +++ b/main/modes/lumberjack/lumberjackEntity.h @@ -8,6 +8,7 @@ typedef struct bool flipped; bool onGround; bool active; + bool queueable; bool flying; @@ -26,11 +27,14 @@ typedef struct int y; int spriteOffset; int vx; + int lives; float vy; int maxVX; int type; int maxLevel; int respawn; + int scoreValue; + int submergedTimer; int cX; int cY; @@ -48,17 +52,26 @@ typedef struct int direction; int animationSpeed; int64_t timerFrameUpdate; - char name[16]; } lumberjackEntity_t; +typedef struct { + bool active; + int x; + int y; + int startSide; + int currentFrame; + int64_t spawnTime; + int64_t timerFrameUpdate; +} lumberjackGhost_t; + + void lumberjackSetupEnemy(lumberjackEntity_t* enemy, int character); uint8_t lumberjackGetEnemyAnimation(lumberjackEntity_t* enemy); void lumberjackResetEnemy(lumberjackEntity_t* enemy); void lumberjackRespawnEnemy(lumberjackEntity_t* enemy, int side); bool checkCollision(lumberjackEntity_t* AA, lumberjackEntity_t* BB); void lumberjackUpdateEnemy(lumberjackEntity_t* enemy, int newIndex); -void lumberjackDoEnemyControls(lumberjackEntity_t* enemy); void lumberjackUpdateEnemyCollision(lumberjackEntity_t* enemy); void lumberjackUpdatePlayerCollision(lumberjackEntity_t* player); diff --git a/main/modes/lumberjack/lumberjackGame.c b/main/modes/lumberjack/lumberjackGame.c index 13a9a0cf1..f53e32444 100644 --- a/main/modes/lumberjack/lumberjackGame.c +++ b/main/modes/lumberjack/lumberjackGame.c @@ -11,596 +11,2080 @@ #include "lumberjackEntity.h" #include "lumberjackPlayer.h" +#include "esp_random.h" + + +//redundancy +#include "hdw-spiffs.h" + +#include +#include +#include +#include + //============================================================================== // Defines //============================================================================== -#define LUMBERJACK_TILEANIMATION_SPEED 150500 +#define LUMBERJACK_TILEANIMATION_SPEED 150500 + +#define LUMBERJACK_SCREEN_X_OFFSET 299 +#define LUMBERJACK_SCREEN_X_MAX 270 + +#define LUMBERJACK_SCREEN_Y_OFFSET 140 +#define LUMBERJACK_SCREEN_Y_MIN -36 + +#define LUMBERJACK_MAP_WIDTH 18 +#define LUMBERJACK_BLOCK_ANIMATION_MAX 7 +#define LUMBERJACK_ROTATE_ANIMATION_MAX 4 +#define LUMBERJACK_RESPAWN_PANIC_MIN 3750 +#define LUMBERJACK_RESPAWN_ATTACK_MIN 1000 +#define LUMBERJACK_RESPAWN_VS_MIN 250 +#define LUMBERJACK_UPGRADE_TIMER_OFFSET 250 +#define LUMBERJACK_SUBMERGE_TIMER 300 +#define LUMBERJACK_WORLD_WRAP 295 -#define LUMBERJACK_SCREEN_X_OFFSET 299 -#define LUMBERJACK_SCREEN_X_MIN 0 -#define LUMBERJACK_SCREEN_X_MAX 270 +#define LUMBERJACK_GHOST_SPAWNTIME_MIN 2000 +#define LUMBERJACK_GHOST_SPEED_NORMAL 3 +#define LUMBERJACK_GHOST_SPEED_FAST 3 +#define LUMBERJACK_GHOST_BOX 28 +#define LUMBERJACK_GHOST_ANIMATION 2500 -#define LUMBERJACK_SCREEN_Y_OFFSET 140 -#define LUMBERJACK_SCREEN_Y_MIN -16 -#define LUMBERJACK_SCREEN_Y_MAX 96 +#define LUMBERJACK_BONUS_DISPLAYDURATI 4000 + +#define LUMBERJACK_WATER_FAST_DRAIN 6 +#define LUMBERJACK_WATER_SLOW_DRAIN 3 +#define LUMBERJACK_WATER_INCREASE 10 + +#define LUMBERJACK_ITEM_RESETTIME 2500 +#define LUMBERJACK_INVINCIBLE_TIME 7000 +#define LUMBERJACK_COMBO_RESET_TIME 1500 + +#define LUMBERJACK_TILE_SIZE 16 static lumberjackTile_t* lumberjackGetTile(int x, int y); static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs); static bool lumberjackIsCollisionTile(int index); +bool lumberjackLoadLevel(void); +void lumberjackOnLocalPlayerDeath(void); + +void DrawTitle(void); void DrawGame(void); lumberjackVars_t* lumv; -lumberjackTile_t lumberjackCollisionCheckTiles[32] = {}; void lumberjackStartGameMode(lumberjack_t* main, uint8_t characterIndex) { - lumv = calloc(1, sizeof(lumberjackVars_t)); - lumv->lumberjackMain = main; - loadFont("ibm_vga8.font", &lumv->ibm, false); + drawRect(0, 0, 280, 220, c050); + lumv = calloc(1, sizeof(lumberjackVars_t)); + lumv->lumberjackMain = main; + lumv->localPlayerType = characterIndex; + lumv->netPlayerType = 1; + lumv->score = 0; + lumv->highscore = lumv->lumberjackMain->save.highScore; + + loadFont("eightbit_atari_grube2.font", &lumv->arcade, false); bzrStop(true); // Stop the buzzer? + for (int i = 0; i < ARRAY_SIZE(lumv->axeBlocks); i++) + { + lumv->axeBlocks[i] = calloc(1, sizeof(lumberjackAxeBlock_t)); + lumv->axeBlocks[i]->x = -90; + lumv->axeBlocks[i]->y = -1000; + lumv->axeBlocks[i]->active = false; + } + + lumv->ghost = NULL; lumv->worldTimer = 0; lumv->liquidAnimationFrame = 0; + lumv->stageAnimationFrame = 0; lumv->loaded = false; lumv->gameType = main->gameMode; + lumv->gameState = LUMBERJACK_GAMESTATE_TITLE; + lumv->levelIndex = 0; + lumv->lives = 3; + lumv->nLives = 3; + lumv->gameReady = !(main->networked); + lumv->invincibleColor = c000; - ESP_LOGI(LUM_TAG, "Loading floor Tiles"); - loadWsg("bottom_floor1.wsg", &lumv->floorTiles[0], true); - loadWsg("bottom_floor2.wsg", &lumv->floorTiles[1], true); - loadWsg("bottom_floor3.wsg", &lumv->floorTiles[2], true); - loadWsg("bottom_floor4.wsg", &lumv->floorTiles[3], true); - loadWsg("bottom_floor5.wsg", &lumv->floorTiles[4], true); - loadWsg("bottom_floor6.wsg", &lumv->floorTiles[5], true); - loadWsg("bottom_floor7.wsg", &lumv->floorTiles[6], true); - loadWsg("bottom_floor8.wsg", &lumv->floorTiles[7], true); - loadWsg("bottom_floor9.wsg", &lumv->floorTiles[8], true); - loadWsg("bottom_floor10.wsg", &lumv->floorTiles[9], true); - ESP_LOGI(LUM_TAG, "Loading Animation Tiles"); - - loadWsg("water_floor1.wsg", &lumv->animationTiles[0], true); - loadWsg("water_floor2.wsg", &lumv->animationTiles[1], true); - loadWsg("water_floor3.wsg", &lumv->animationTiles[2], true); - loadWsg("water_floor4.wsg", &lumv->animationTiles[3], true); - loadWsg("water_floor0.wsg", &lumv->animationTiles[4], true); - loadWsg("water_floor0.wsg", &lumv->animationTiles[5], true); - loadWsg("water_floor0.wsg", &lumv->animationTiles[6], true); - loadWsg("water_floor0.wsg", &lumv->animationTiles[7], true); - loadWsg("water_floor_b1.wsg", &lumv->animationTiles[8], true); - loadWsg("water_floor_b2.wsg", &lumv->animationTiles[9], true); - loadWsg("water_floor_b3.wsg", &lumv->animationTiles[10], true); - loadWsg("water_floor_b4.wsg", &lumv->animationTiles[11], true); - - ESP_LOGI(LUM_TAG, "Loading Characters"); - loadWsg("lumbers_red_1.wsg", &lumv->playerSprites[0], true); - loadWsg("lumbers_red_2.wsg", &lumv->playerSprites[1], true); - loadWsg("lumbers_red_3.wsg", &lumv->playerSprites[2], true); - loadWsg("lumbers_red_4.wsg", &lumv->playerSprites[3], - true); // These two things break 3 seconds after the game loads - loadWsg("lumbers_red_5.wsg", &lumv->playerSprites[4], true); // I think the memory is being replaces - loadWsg("lumbers_red_6.wsg", &lumv->playerSprites[5], true); - loadWsg("lumbers_red_7.wsg", &lumv->playerSprites[6], true); - loadWsg("lumbers_red_8.wsg", &lumv->playerSprites[7], true); - loadWsg("lumbers_red_9.wsg", &lumv->playerSprites[8], true); - loadWsg("lumbers_red_10.wsg", &lumv->playerSprites[9], true); - loadWsg("lumbers_red_11.wsg", &lumv->playerSprites[10], true); - loadWsg("lumbers_red_12.wsg", &lumv->playerSprites[11], true); - loadWsg("lumbers_red_13.wsg", &lumv->playerSprites[12], true); - loadWsg("lumbers_red_14.wsg", &lumv->playerSprites[13], true); - loadWsg("lumbers_red_15.wsg", &lumv->playerSprites[14], true); - loadWsg("lumbers_red_16.wsg", &lumv->playerSprites[15], true); - loadWsg("lumbers_red_17.wsg", &lumv->playerSprites[16], true); - - loadWsg("lumbers_green_1.wsg", &lumv->playerSprites[17], true); - loadWsg("lumbers_green_2.wsg", &lumv->playerSprites[18], true); - loadWsg("lumbers_green_3.wsg", &lumv->playerSprites[19], true); - loadWsg("lumbers_green_4.wsg", &lumv->playerSprites[20], true); - loadWsg("lumbers_green_5.wsg", &lumv->playerSprites[21], true); - loadWsg("lumbers_green_6.wsg", &lumv->playerSprites[22], true); - loadWsg("lumbers_green_7.wsg", &lumv->playerSprites[23], true); - loadWsg("lumbers_green_8.wsg", &lumv->playerSprites[24], true); - loadWsg("lumbers_green_9.wsg", &lumv->playerSprites[25], true); - loadWsg("lumbers_green_10.wsg", &lumv->playerSprites[26], true); - loadWsg("lumbers_green_11.wsg", &lumv->playerSprites[27], true); - loadWsg("lumbers_green_12.wsg", &lumv->playerSprites[28], true); - loadWsg("lumbers_green_13.wsg", &lumv->playerSprites[29], true); - loadWsg("lumbers_green_14.wsg", &lumv->playerSprites[30], true); - loadWsg("lumbers_green_15.wsg", &lumv->playerSprites[31], true); - loadWsg("lumbers_green_16.wsg", &lumv->playerSprites[32], true); - loadWsg("lumbers_green_17.wsg", &lumv->playerSprites[33], true); - - loadWsg("secret_swadgeland_1.wsg", &lumv->playerSprites[34], true); - loadWsg("secret_swadgeland_2.wsg", &lumv->playerSprites[35], true); - loadWsg("secret_swadgeland_3.wsg", &lumv->playerSprites[36], true); - loadWsg("secret_swadgeland_4.wsg", &lumv->playerSprites[37], true); - loadWsg("secret_swadgeland_5.wsg", &lumv->playerSprites[38], true); - loadWsg("secret_swadgeland_6.wsg", &lumv->playerSprites[39], true); - loadWsg("secret_swadgeland_7.wsg", &lumv->playerSprites[40], true); - loadWsg("secret_swadgeland_8.wsg", &lumv->playerSprites[41], true); - loadWsg("secret_swadgeland_9.wsg", &lumv->playerSprites[42], true); - loadWsg("secret_swadgeland_10.wsg", &lumv->playerSprites[43], true); - loadWsg("secret_swadgeland_11.wsg", &lumv->playerSprites[44], true); - loadWsg("secret_swadgeland_12.wsg", &lumv->playerSprites[45], true); - loadWsg("secret_swadgeland_13.wsg", &lumv->playerSprites[46], true); - loadWsg("secret_swadgeland_14.wsg", &lumv->playerSprites[47], true); - loadWsg("secret_swadgeland_15.wsg", &lumv->playerSprites[48], true); - loadWsg("secret_swadgeland_16.wsg", &lumv->playerSprites[49], true); - loadWsg("secret_swadgeland_17.wsg", &lumv->playerSprites[50], true); - loadWsg("secret_swadgeland_18.wsg", &lumv->playerSprites[51], true); - loadWsg("secret_swadgeland_19.wsg", &lumv->playerSprites[52], true); - loadWsg("secret_swadgeland_20.wsg", &lumv->playerSprites[53], true); - loadWsg("secret_swadgeland_21.wsg", &lumv->playerSprites[54], true); - - ESP_LOGI(LUM_TAG, "Loading Enemies"); - loadWsg("enemy_a1.wsg", &lumv->enemySprites[0], true); - loadWsg("enemy_a2.wsg", &lumv->enemySprites[1], true); - loadWsg("enemy_a3.wsg", &lumv->enemySprites[2], true); - loadWsg("enemy_a4.wsg", &lumv->enemySprites[3], true); - loadWsg("enemy_a5.wsg", &lumv->enemySprites[4], true); - loadWsg("enemy_a6.wsg", &lumv->enemySprites[5], true); - loadWsg("enemy_a7.wsg", &lumv->enemySprites[6], true); - loadWsg("enemy_b1.wsg", &lumv->enemySprites[7], true); - loadWsg("enemy_b2.wsg", &lumv->enemySprites[8], true); - loadWsg("enemy_b3.wsg", &lumv->enemySprites[9], true); - loadWsg("enemy_b4.wsg", &lumv->enemySprites[10], true); - loadWsg("enemy_b5.wsg", &lumv->enemySprites[11], true); - loadWsg("enemy_b6.wsg", &lumv->enemySprites[12], true); - loadWsg("enemy_b7.wsg", &lumv->enemySprites[13], true); - loadWsg("enemy_c1.wsg", &lumv->enemySprites[14], true); - loadWsg("enemy_c2.wsg", &lumv->enemySprites[15], true); - loadWsg("enemy_c3.wsg", &lumv->enemySprites[16], true); - loadWsg("enemy_c4.wsg", &lumv->enemySprites[17], true); - loadWsg("enemy_c5.wsg", &lumv->enemySprites[18], true); - loadWsg("enemy_c6.wsg", &lumv->enemySprites[19], true); - loadWsg("enemy_c7.wsg", &lumv->enemySprites[20], true); - - loadWsg("alert.wsg", &lumv->alertSprite, true); + lumv->itemBlockAnimationTime = 0; + lumv->itemBlockItemFrame = 0; + lumv->itemBlockIndex = -1; + lumv->itemBlockItemAnimation = 0; - if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + + loadWsg("lumbers_title.wsg", &lumv->title, true); + + if (main->screen == LUMBERJACK_A) { - lumberjackSetupLevel(characterIndex); + loadWsg("lumbers_title_panic_red.wsg", &lumv->subtitle_red, true); + loadWsg("lumbers_title_panic_green.wsg", &lumv->subtitle_green, true); + loadWsg("lumbers_title_panic_white.wsg", &lumv->subtitle_white, true); + lumv->enemySpawnTime = LUMBERJACK_RESPAWN_PANIC_MIN; + lumv->enemyReceiveSpawnTime = LUMBERJACK_RESPAWN_VS_MIN; + lumv->enemySpawnAmount = 1; } - else if (lumv->gameType == LUMBERJACK_MODE_PANIC) + + if (main->screen == LUMBERJACK_B) { - lumberjackSetupLevel(characterIndex); + + loadWsg("lumbers_title_attack_red.wsg", &lumv->subtitle_red, true); + loadWsg("lumbers_title_attack_green.wsg", &lumv->subtitle_green, true); + loadWsg("lumbers_title_attack_white.wsg", &lumv->subtitle_white, true); + lumv->enemySpawnTime = LUMBERJACK_RESPAWN_ATTACK_MIN; + lumv->enemyReceiveSpawnTime = LUMBERJACK_RESPAWN_VS_MIN; + lumv->enemySpawnAmount = 4; } - ESP_LOGI(LUM_TAG, "height %d", TFT_HEIGHT); -} + loadWsg("lumbers_game_over.wsg", &lumv->gameoverSprite, true); + if (lumv->lumberjackMain->networked) + { + loadWsg("lumbers_game_over_win.wsg", &lumv->gamewinSprite, true); + loadWsg("lumbers_conn_lost.wsg", &lumv->connectLostSprite, true); + } -void lumberjackSetupLevel(int characterIndex) -{ - // This all to be loaded externally - lumv->yOffset = 0; - lumv->currentMapHeight = 21; - lumv->lives = 3; - lumv->spawnIndex = 0; - lumv->spawnTimer = 2750; - lumv->spawnSide = 0; + // Loading floor Tiles + loadWsg("lumbers_bottom_floor1.wsg", &lumv->floorTiles[0], true); + loadWsg("lumbers_bottom_floor2.wsg", &lumv->floorTiles[1], true); + loadWsg("lumbers_bottom_floor3.wsg", &lumv->floorTiles[2], true); + loadWsg("lumbers_bottom_floor4.wsg", &lumv->floorTiles[3], true); + loadWsg("lumbers_bottom_floor5.wsg", &lumv->floorTiles[4], true); + loadWsg("lumbers_bottom_floor6.wsg", &lumv->floorTiles[5], true); + loadWsg("lumbers_bottom_floor7.wsg", &lumv->floorTiles[6], true); + loadWsg("lumbers_bottom_floor8.wsg", &lumv->floorTiles[7], true); + loadWsg("lumbers_bottom_floor9.wsg", &lumv->floorTiles[8], true); + loadWsg("lumbers_bottom_floor10.wsg", &lumv->floorTiles[9], true); + loadWsg("lumbers_itemused_block.wsg", &lumv->floorTiles[10], true); + loadWsg("lumbers_rtile_1.wsg", &lumv->floorTiles[11], true); + + //Loading Animation Tiles + loadWsg("lumbers_water_floor1.wsg", &lumv->animationTiles[0], true); + loadWsg("lumbers_water_floor2.wsg", &lumv->animationTiles[1], true); + loadWsg("lumbers_water_floor3.wsg", &lumv->animationTiles[2], true); + loadWsg("lumbers_water_floor4.wsg", &lumv->animationTiles[3], true); + loadWsg("lumbers_water_floor0.wsg", &lumv->animationTiles[4], true); + loadWsg("lumbers_water_floor0.wsg", &lumv->animationTiles[5], true); + loadWsg("lumbers_water_floor0.wsg", &lumv->animationTiles[6], true); + loadWsg("lumbers_water_floor0.wsg", &lumv->animationTiles[7], true); + loadWsg("lumbers_water_floor_b1.wsg", &lumv->animationTiles[8], true); + loadWsg("lumbers_water_floor_b2.wsg", &lumv->animationTiles[9], true); + loadWsg("lumbers_water_floor_b3.wsg", &lumv->animationTiles[10], true); + loadWsg("lumbers_water_floor_b4.wsg", &lumv->animationTiles[11], true); + loadWsg("lumbers_rtile_1.wsg", &lumv->animationTiles[12], true); + loadWsg("lumbers_rtile_2.wsg", &lumv->animationTiles[13], true); + loadWsg("lumbers_rtile_3.wsg", &lumv->animationTiles[14], true); + loadWsg("lumbers_rtile_4.wsg", &lumv->animationTiles[15], true); + + + //Loading Characters + //*Loading character icons + loadWsg("lumbers_red_lives.wsg", &lumv->minicharacters[0], true); + loadWsg("lumbers_green_lives.wsg", &lumv->minicharacters[1], true); + loadWsg("lumbers_swadgeland_lives.wsg", &lumv->minicharacters[2], true); + loadWsg("lumbers_cho_lives.wsg", &lumv->minicharacters[3], true); + + //*Loading character sprites + if (characterIndex == 0) + { + loadWsg("lumbers_red_1.wsg", &lumv->playerSprites[0], true); + loadWsg("lumbers_red_2.wsg", &lumv->playerSprites[1], true); + loadWsg("lumbers_red_3.wsg", &lumv->playerSprites[2], true); + loadWsg("lumbers_red_4.wsg", &lumv->playerSprites[3], true); + loadWsg("lumbers_red_5.wsg", &lumv->playerSprites[4], true); + loadWsg("lumbers_red_6.wsg", &lumv->playerSprites[5], true); + loadWsg("lumbers_red_7.wsg", &lumv->playerSprites[6], true); + loadWsg("lumbers_red_8.wsg", &lumv->playerSprites[7], true); + loadWsg("lumbers_red_9.wsg", &lumv->playerSprites[8], true); + loadWsg("lumbers_red_10.wsg", &lumv->playerSprites[9], true); + loadWsg("lumbers_red_11.wsg", &lumv->playerSprites[10], true); + loadWsg("lumbers_red_12.wsg", &lumv->playerSprites[11], true); + loadWsg("lumbers_red_13.wsg", &lumv->playerSprites[12], true); + loadWsg("lumbers_red_14.wsg", &lumv->playerSprites[13], true); + loadWsg("lumbers_red_15.wsg", &lumv->playerSprites[14], true); + loadWsg("lumbers_red_16.wsg", &lumv->playerSprites[15], true); + loadWsg("lumbers_red_17.wsg", &lumv->playerSprites[16], true); + loadWsg("lumbers_red_22.wsg", &lumv->playerSprites[17], true); + lumv->invincibleColor = c500; - lumv->localPlayer = calloc(1, sizeof(lumberjackEntity_t)); - lumv->remotePlayer = calloc(1, sizeof(lumberjackEntity_t)); - lumberjackSetupPlayer(lumv->localPlayer, characterIndex); - lumberjackSpawnPlayer(lumv->localPlayer, 94, 0, 0); + } + else if (characterIndex == 1) + { + loadWsg("lumbers_green_1.wsg", &lumv->playerSprites[0], true); + loadWsg("lumbers_green_2.wsg", &lumv->playerSprites[1], true); + loadWsg("lumbers_green_3.wsg", &lumv->playerSprites[2], true); + loadWsg("lumbers_green_4.wsg", &lumv->playerSprites[3], true); + loadWsg("lumbers_green_5.wsg", &lumv->playerSprites[4], true); + loadWsg("lumbers_green_6.wsg", &lumv->playerSprites[5], true); + loadWsg("lumbers_green_7.wsg", &lumv->playerSprites[6], true); + loadWsg("lumbers_green_8.wsg", &lumv->playerSprites[7], true); + loadWsg("lumbers_green_9.wsg", &lumv->playerSprites[8], true); + loadWsg("lumbers_green_10.wsg", &lumv->playerSprites[9], true); + loadWsg("lumbers_green_11.wsg", &lumv->playerSprites[10], true); + loadWsg("lumbers_green_12.wsg", &lumv->playerSprites[11], true); + loadWsg("lumbers_green_13.wsg", &lumv->playerSprites[12], true); + loadWsg("lumbers_green_14.wsg", &lumv->playerSprites[13], true); + loadWsg("lumbers_green_15.wsg", &lumv->playerSprites[14], true); + loadWsg("lumbers_green_16.wsg", &lumv->playerSprites[15], true); + loadWsg("lumbers_green_17.wsg", &lumv->playerSprites[16], true); + loadWsg("lumbers_green_22.wsg", &lumv->playerSprites[17], true); + lumv->invincibleColor = c050; - // snprintf(lumv->localPlayer->name, sizeof(lumv->localPlayer->name), "Player"); - strcpy(lumv->localPlayer->name, " Dennis"); // If you see this... this name means nothing + } + else if (characterIndex == 2) + { - for (int eSpawnIndex = 0; eSpawnIndex < 2; eSpawnIndex++) + loadWsg("lumbers_swadgeland_1.wsg", &lumv->playerSprites[0], true); + loadWsg("lumbers_swadgeland_2.wsg", &lumv->playerSprites[1], true); + loadWsg("lumbers_swadgeland_3.wsg", &lumv->playerSprites[2], true); + loadWsg("lumbers_swadgeland_4.wsg", &lumv->playerSprites[3], true); + loadWsg("lumbers_swadgeland_5.wsg", &lumv->playerSprites[4], true); + loadWsg("lumbers_swadgeland_6.wsg", &lumv->playerSprites[5], true); + loadWsg("lumbers_swadgeland_7.wsg", &lumv->playerSprites[6], true); + loadWsg("lumbers_swadgeland_8.wsg", &lumv->playerSprites[7], true); + loadWsg("lumbers_swadgeland_9.wsg", &lumv->playerSprites[8], true); + loadWsg("lumbers_swadgeland_10.wsg", &lumv->playerSprites[9], true); + loadWsg("lumbers_swadgeland_11.wsg", &lumv->playerSprites[10], true); + loadWsg("lumbers_swadgeland_12.wsg", &lumv->playerSprites[11], true); + loadWsg("lumbers_swadgeland_13.wsg", &lumv->playerSprites[12], true); + loadWsg("lumbers_swadgeland_14.wsg", &lumv->playerSprites[13], true); + loadWsg("lumbers_swadgeland_15.wsg", &lumv->playerSprites[14], true); + loadWsg("lumbers_swadgeland_16.wsg", &lumv->playerSprites[15], true); + loadWsg("lumbers_swadgeland_17.wsg", &lumv->playerSprites[16], true); + loadWsg("lumbers_swadgeland_22.wsg", &lumv->playerSprites[17], true); + lumv->invincibleColor = c305; + + } + else if (characterIndex == 3) + { + loadWsg("lumbers_cho_1.wsg", &lumv->playerSprites[0], true); + loadWsg("lumbers_cho_2.wsg", &lumv->playerSprites[1], true); + loadWsg("lumbers_cho_3.wsg", &lumv->playerSprites[2], true); + loadWsg("lumbers_cho_4.wsg", &lumv->playerSprites[3], true); + loadWsg("lumbers_cho_5.wsg", &lumv->playerSprites[4], true); + loadWsg("lumbers_cho_6.wsg", &lumv->playerSprites[5], true); + loadWsg("lumbers_cho_7.wsg", &lumv->playerSprites[6], true); + loadWsg("lumbers_cho_8.wsg", &lumv->playerSprites[7], true); + loadWsg("lumbers_cho_9.wsg", &lumv->playerSprites[8], true); + loadWsg("lumbers_cho_10.wsg", &lumv->playerSprites[9], true); + loadWsg("lumbers_cho_11.wsg", &lumv->playerSprites[10], true); + loadWsg("lumbers_cho_12.wsg", &lumv->playerSprites[11], true); + loadWsg("lumbers_cho_13.wsg", &lumv->playerSprites[12], true); + loadWsg("lumbers_cho_14.wsg", &lumv->playerSprites[13], true); + loadWsg("lumbers_cho_15.wsg", &lumv->playerSprites[14], true); + loadWsg("lumbers_cho_16.wsg", &lumv->playerSprites[15], true); + loadWsg("lumbers_cho_17.wsg", &lumv->playerSprites[16], true); + loadWsg("lumbers_cho_18.wsg", &lumv->playerSprites[17], true); + lumv->invincibleColor = c103; + + } + + //Loading Enemies + loadWsg("lumbers_enemy_a1.wsg", &lumv->enemySprites[0], true); + loadWsg("lumbers_enemy_a2.wsg", &lumv->enemySprites[1], true); + loadWsg("lumbers_enemy_a3.wsg", &lumv->enemySprites[2], true); + loadWsg("lumbers_enemy_a4.wsg", &lumv->enemySprites[3], true); + loadWsg("lumbers_enemy_a5.wsg", &lumv->enemySprites[4], true); + loadWsg("lumbers_enemy_a6.wsg", &lumv->enemySprites[5], true); + loadWsg("lumbers_enemy_a7.wsg", &lumv->enemySprites[6], true); + loadWsg("lumbers_enemy_b1.wsg", &lumv->enemySprites[7], true); + loadWsg("lumbers_enemy_b2.wsg", &lumv->enemySprites[8], true); + loadWsg("lumbers_enemy_b3.wsg", &lumv->enemySprites[9], true); + loadWsg("lumbers_enemy_b4.wsg", &lumv->enemySprites[10], true); + loadWsg("lumbers_enemy_b5.wsg", &lumv->enemySprites[11], true); + loadWsg("lumbers_enemy_b6.wsg", &lumv->enemySprites[12], true); + loadWsg("lumbers_enemy_b7.wsg", &lumv->enemySprites[13], true); + loadWsg("lumbers_enemy_c1.wsg", &lumv->enemySprites[14], true); + loadWsg("lumbers_enemy_c2.wsg", &lumv->enemySprites[15], true); + loadWsg("lumbers_enemy_c3.wsg", &lumv->enemySprites[16], true); + loadWsg("lumbers_enemy_c4.wsg", &lumv->enemySprites[17], true); + loadWsg("lumbers_enemy_c5.wsg", &lumv->enemySprites[18], true); + loadWsg("lumbers_enemy_c6.wsg", &lumv->enemySprites[19], true); + loadWsg("lumbers_enemy_c7.wsg", &lumv->enemySprites[20], true); + loadWsg("lumbers_enemy_d1.wsg", &lumv->enemySprites[21], true); + loadWsg("lumbers_enemy_d2.wsg", &lumv->enemySprites[22], true); + loadWsg("lumbers_enemy_e1.wsg", &lumv->enemySprites[23], true); + loadWsg("lumbers_enemy_e2.wsg", &lumv->enemySprites[24], true); + loadWsg("lumbers_enemy_e3.wsg", &lumv->enemySprites[25], true); + loadWsg("lumbers_enemy_e4.wsg", &lumv->enemySprites[26], true); + loadWsg("lumbers_enemy_e5.wsg", &lumv->enemySprites[27], true); + loadWsg("lumbers_enemy_e6.wsg", &lumv->enemySprites[28], true); + loadWsg("lumbers_enemy_e7.wsg", &lumv->enemySprites[29], true); + loadWsg("lumbers_enemy_f1.wsg", &lumv->enemySprites[30], true); + loadWsg("lumbers_enemy_f2.wsg", &lumv->enemySprites[31], true); + loadWsg("lumbers_enemy_f3.wsg", &lumv->enemySprites[32], true); + loadWsg("lumbers_enemy_f4.wsg", &lumv->enemySprites[33], true); + loadWsg("lumbers_enemy_f5.wsg", &lumv->enemySprites[34], true); + loadWsg("lumbers_enemy_f6.wsg", &lumv->enemySprites[35], true); + loadWsg("lumbers_enemy_f7.wsg", &lumv->enemySprites[36], true); + + loadWsg("lumbers_green_ax_block1.wsg", &lumv->greenBlockSprite[0], true); + loadWsg("lumbers_green_ax_block2.wsg", &lumv->greenBlockSprite[1], true); + loadWsg("lumbers_green_ax_block3.wsg", &lumv->greenBlockSprite[2], true); + loadWsg("lumbers_green_ax_block4.wsg", &lumv->greenBlockSprite[3], true); + loadWsg("lumbers_green_ax_block5.wsg", &lumv->greenBlockSprite[4], true); + loadWsg("lumbers_green_ax_block6.wsg", &lumv->greenBlockSprite[5], true); + loadWsg("lumbers_green_ax_block7.wsg", &lumv->greenBlockSprite[6], true); + + loadWsg("lumbers_red_ax_block1.wsg", &lumv->redBlockSprite[0], true); + loadWsg("lumbers_red_ax_block2.wsg", &lumv->redBlockSprite[1], true); + loadWsg("lumbers_red_ax_block3.wsg", &lumv->redBlockSprite[2], true); + loadWsg("lumbers_red_ax_block4.wsg", &lumv->redBlockSprite[3], true); + loadWsg("lumbers_red_ax_block5.wsg", &lumv->redBlockSprite[4], true); + loadWsg("lumbers_red_ax_block6.wsg", &lumv->redBlockSprite[5], true); + loadWsg("lumbers_red_ax_block7.wsg", &lumv->redBlockSprite[6], true); + + loadWsg("lumbers_normal_ax_block1.wsg", &lumv->unusedBlockSprite[0], true); + loadWsg("lumbers_normal_ax_block2.wsg", &lumv->unusedBlockSprite[1], true); + loadWsg("lumbers_normal_ax_block3.wsg", &lumv->unusedBlockSprite[2], true); + loadWsg("lumbers_normal_ax_block4.wsg", &lumv->unusedBlockSprite[3], true); + loadWsg("lumbers_normal_ax_block5.wsg", &lumv->unusedBlockSprite[4], true); + loadWsg("lumbers_normal_ax_block6.wsg", &lumv->unusedBlockSprite[5], true); + loadWsg("lumbers_normal_ax_block7.wsg", &lumv->unusedBlockSprite[6], true); + + loadWsg("lumbers_bonus_0.wsg", &lumv->bonusSprites[0], true); + loadWsg("lumbers_bonus_1.wsg", &lumv->bonusSprites[1], true); + loadWsg("lumbers_bonus_2.wsg", &lumv->bonusSprites[2], true); + loadWsg("lumbers_bonus_3.wsg", &lumv->bonusSprites[3], true); + loadWsg("lumbers_bonus_4.wsg", &lumv->bonusSprites[4], true); + loadWsg("lumbers_bonus_5.wsg", &lumv->bonusSprites[5], true); + loadWsg("lumbers_bonus_6.wsg", &lumv->bonusSprites[6], true); + loadWsg("lumbers_bonus_7.wsg", &lumv->bonusSprites[7], true); + loadWsg("lumbers_bonus_8.wsg", &lumv->bonusSprites[8], true); + loadWsg("lumbers_bonus_9.wsg", &lumv->bonusSprites[9], true); + loadWsg("lumbers_bonus_x.wsg", &lumv->bonusSprites[10], true); + + + loadWsg("lumbers_item_ui.wsg", &lumv->ui[0], true); + loadWsg("lumbers_alert.wsg", &lumv->alertSprite, true); + + for (int i = 0; i < ARRAY_SIZE(lumv->bonusDisplay); i++) { - lumv->enemy[eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); - lumberjackSetupEnemy(lumv->enemy[eSpawnIndex], 0); + lumv->bonusDisplay[i] = calloc(1, sizeof(lumberjackBonus_t)); + } + lumv->activeBonusIndex = 0; + - sprintf(lumv->enemy[eSpawnIndex]->name, "Enemy %d", eSpawnIndex); + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + loadWsg("lumbers_items_grapes1.wsg", &lumv->itemIcons[0], true); + loadWsg("lumbers_items_grapes2.wsg", &lumv->itemIcons[1], true); + loadWsg("lumbers_items_grapes3.wsg", &lumv->itemIcons[2], true); + loadWsg("lumbers_items_grapes4.wsg", &lumv->itemIcons[3], true); + loadWsg("lumbers_items_grapes5.wsg", &lumv->itemIcons[4], true); + loadWsg("lumbers_items_grapes6.wsg", &lumv->itemIcons[5], true); + loadWsg("lumbers_items_orange1.wsg", &lumv->itemIcons[6], true); + loadWsg("lumbers_items_orange2.wsg", &lumv->itemIcons[7], true); + loadWsg("lumbers_items_orange3.wsg", &lumv->itemIcons[8], true); + loadWsg("lumbers_items_orange4.wsg", &lumv->itemIcons[9], true); + loadWsg("lumbers_items_orange5.wsg", &lumv->itemIcons[10], true); + loadWsg("lumbers_items_orange6.wsg", &lumv->itemIcons[11], true); + loadWsg("lumbers_items_pear1.wsg", &lumv->itemIcons[12], true); + loadWsg("lumbers_items_pear2.wsg", &lumv->itemIcons[13], true); + loadWsg("lumbers_items_pear3.wsg", &lumv->itemIcons[14], true); + loadWsg("lumbers_items_pear4.wsg", &lumv->itemIcons[15], true); + loadWsg("lumbers_items_pear5.wsg", &lumv->itemIcons[16], true); + loadWsg("lumbers_items_pear6.wsg", &lumv->itemIcons[17], true); } - const uint8_t level[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 3, 3, 4, 4, 0, - 0, 0, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 5, 0, 0, 0, 0, 0, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 10, 0, 0, 0, - }; - const uint8_t ani[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 1, 3, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, - }; + //Sounds? - for (int tileIndex = 0; tileIndex < ARRAY_SIZE(ani); tileIndex++) + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) { - lumv->anim[tileIndex] = ani[tileIndex]; - - lumv->tile[tileIndex].x = tileIndex % 18; - lumv->tile[tileIndex].y = tileIndex / 18; - lumv->tile[tileIndex].type = level[tileIndex]; + loadSong("l_sfx_upgrade.sng", &lumv->sfx_item_use, false); + loadSong("l_song_attack_title.sng", &lumv->song_title, false); + loadSong("l_song_attack.sng", &lumv->song_theme, false); + } + else + { + loadSong("l_song_panic.sng", &lumv->song_theme, false); + loadSong("l_song_panic_title.sng", &lumv->song_title, false); + loadSong("l_sfx_water.sng", &lumv->sfx_item_use, false); } - ESP_LOGI(LUM_TAG, "LOADED"); -} - -/** - * @brief TODO use this somewhere - */ -void restartLevel(void) -{ - lumberjackRespawn(lumv->localPlayer); + loadSong("r_p_shoot.sng", &lumv->sfx_item_get, false); + loadSong("l_sfx_jump.sng", &lumv->sfx_jump, false); + loadSong("l_sfx_brick.sng", &lumv->sfx_bump, false); + loadSong("l_sfx_enemy_flip.sng", &lumv->sfx_flip, false); + loadSong("r_e_dead.sng", &lumv->sfx_player_death, false); + loadSong("l_sfx_enemy_death.sng", &lumv->sfx_enemy_death, false); + + loadSong("l_song_respawn.sng", &lumv->song_respawn, false); + loadSong("l_song_gameover.sng", &lumv->song_gameover, false); + lumv->song_theme.shouldLoop = true; + lumv->song_title.shouldLoop = true; + + + bzrPlayBgm(&lumv->song_title, BZR_STEREO); + + if (lumv->lumberjackMain->networked) + { + lumberjackInitp2p(); + } } -void lumberjackGameLoop(int64_t elapsedUs) +bool lumberjackLoadLevel() { - baseMode(elapsedUs); + char* fname = "lumberjacks_panic_vs.bin"; + + lumv->upgrade = 0; + if (lumv->gameType == LUMBERJACK_MODE_PANIC) + { - // If networked - if (lumv->lumberjackMain->networked && lumv->lumberjackMain->conStatus == CON_ESTABLISHED) - lumberjackUpdateLocation(lumv->localPlayer->x, lumv->localPlayer->y, lumv->localPlayer->drawFrame); + if (!lumv->lumberjackMain->networked) + { + char* levelName[] = + { + "lumberjacks_panic_1.bin", + "lumberjacks_panic_2.bin", + "lumberjacks_panic_3.bin", + "lumberjacks_panic_4.bin", + "lumberjacks_panic_5.bin", + "lumberjacks_panic_6.bin", + "lumberjacks_panic_7.bin", + "lumberjacks_panic_8.bin", + "lumberjacks_panic_9.bin", + "lumberjacks_panic_10.bin", + }; + + fname = levelName[lumv->levelIndex % ARRAY_SIZE(levelName)]; + + lumv->upgrade = (int)(lumv->levelIndex / ARRAY_SIZE(levelName)); + } + else + { + fname = "lumberjacks_panic_vs.bin"; + } + + lumv->enemySpawnAmount = 1; + } - DrawGame(); -} + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + if (!lumv->lumberjackMain->networked) + { + char* attackLevelName[] = + { + "lumberjacks_attack_1.bin", + "lumberjacks_attack_2.bin", + "lumberjacks_attack_3.bin", + "lumberjacks_attack_4.bin", + "lumberjacks_attack_5.bin", + "lumberjacks_attack_6.bin", + "lumberjacks_attack_7.bin", + "lumberjacks_attack_8.bin", + "lumberjacks_attack_9.bin", + "lumberjacks_attack_10.bin", + }; + + fname = attackLevelName[lumv->levelIndex % ARRAY_SIZE(attackLevelName)]; + lumv->upgrade = (int)(lumv->levelIndex / ARRAY_SIZE(attackLevelName)); + } + else + { + fname = "lumberjacks_attack_vs.bin"; + } -void lumberjackUpdateRemote(int remoteX, int remoteY, int remoteFrame) -{ - lumv->remotePlayer->x = remoteX; - lumv->remotePlayer->y = remoteY; - lumv->remotePlayer->drawFrame = remoteFrame; - lumv->remotePlayer->active = true; -} + for (int i = 0; i < 8; i++) + { + lumv->attackQueue[i] = 0; + } + + lumv->enemySpawnAmount = 4; + lumv->itemBlockIndex = -1; + } -void baseMode(int64_t elapsedUs) -{ - // Ignore the first frame because everything was loading - // Here we might want to do something like say "On first frame loaded do stuff" - if (lumv->loaded == false) + ESP_LOGI(LUM_TAG, "Loading level!"); + + size_t ms; + uint8_t *buffer = spiffsReadFile(fname, &ms, false); + + // Buffer 0 = map height + lumv->tile = (lumberjackTile_t*)malloc((int)buffer[0] * LUMBERJACK_MAP_WIDTH * sizeof(lumberjackTile_t)); + lumv->currentMapHeight = (int)buffer[0]; + lumv->levelTime = 0; + lumv->itemBlockTime = 0; + lumv->itemBlockReady = true; + + lumv->enemy1Count = (int) buffer[1]; + lumv->enemy2Count = (int) buffer[2]; + lumv->enemy3Count = (int) buffer[3]; + lumv->enemy4Count = (int) buffer[4]; + lumv->enemy5Count = (int) buffer[5]; + lumv->enemy6Count = (int) buffer[6]; + lumv->enemy7Count = (int) buffer[7]; + lumv->enemy8Count = (int) buffer[8]; + + if (lumv->enemy4Count > 1) lumv->enemy4Count = 1; //Only one ghost + + lumv->totalEnemyCount = lumv->enemy1Count; + lumv->totalEnemyCount += lumv->enemy2Count; + lumv->totalEnemyCount += lumv->enemy3Count; + //Ghost don't count + lumv->totalEnemyCount += lumv->enemy5Count; + lumv->totalEnemyCount += lumv->enemy6Count; + lumv->totalEnemyCount += lumv->enemy7Count; + lumv->totalEnemyCount += lumv->enemy8Count; + + + if (lumv->upgrade == 1) { - lumv->loaded = true; + lumv->enemy3Count += lumv->enemy2Count; + lumv->enemy2Count = lumv->enemy1Count; + lumv->enemy1Count = 0; // + } + else if (lumv->upgrade >= 2) + { + lumv->enemy3Count += lumv->enemy2Count + lumv->enemy1Count; + lumv->enemy2Count = 0; + lumv->enemy1Count = 0; + } - ESP_LOGI(LUM_TAG, "Load Time %ld", (long)elapsedUs); + if (lumv->enemy4Count > 0) + { + lumv->ghostSpawnTime = (int)buffer[9] * 1000; - // If networked, send "Loaded complete!" ? + if (lumv->ghostSpawnTime < LUMBERJACK_GHOST_SPAWNTIME_MIN) lumv->ghostSpawnTime = LUMBERJACK_GHOST_SPAWNTIME_MIN; //Make sure if the ghost is active at least 10 seconds must past before spawning - return; } - // Update State - buttonEvt_t evt = {0}; - while (checkButtonQueueWrapper(&evt)) + lumv->waterSpeed = (int)buffer[11]; + lumv->waterTimer = (int)buffer[11]; + + //return false; + + for (int i = 0; i < lumv->currentMapHeight * LUMBERJACK_MAP_WIDTH; i++) { - lumv->btnState = evt.state; + lumv->tile[i].index = i; + lumv->tile[i].x = i % LUMBERJACK_MAP_WIDTH; + lumv->tile[i].y = i / LUMBERJACK_MAP_WIDTH; + lumv->tile[i].type = (int)buffer[i+12]; + lumv->tile[i].offset = 0; + lumv->tile[i].offset_time = 0; + } - // return; - // Check Controls - if (lumv->localPlayer->state != LUMBERJACK_DEAD && lumv->localPlayer->state != LUMBERJACK_UNSPAWNED) + for (int i = 0; i < ARRAY_SIZE(lumv->bonusDisplay); i++) { - bool attackThisFrame = lumv->localPlayer->attackPressed; - lumberjackDoControls(); - - if (!attackThisFrame && lumv->localPlayer->attackPressed) - { - ESP_LOGI(LUM_TAG, "Attack this frame!"); - lumberjackSendAttack(0); - } + lumv->bonusDisplay[i]->active = false; } + + int offset = (lumv->currentMapHeight * LUMBERJACK_MAP_WIDTH) + 12; + + lumv->playerSpawnX = (int)buffer[offset]; + lumv->playerSpawnY = (int)buffer[offset + 1] + ((int)buffer[offset + 2] << 8); + //lumv->yOffset = lumv->playerSpawnY - LUMBERJACK_SCREEN_Y_OFFSET; - for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) - { - if (lumv->enemy[enemyIndex] == NULL) - continue; + free(buffer); - lumberjackDoEnemyControls(lumv->enemy[enemyIndex]); - } + return true; +} - // Clear cruft - lumberjackUpdate(elapsedUs); +void lumberjackSetupLevel(int characterIndex) +{ + //bzrStop(true); // Stop the buzzer? + + lumv->enemyKillCount = 0; + lumv->totalEnemyCount = 0; + lumv->comboTime = 0; + lumv->comboAmount = 0; + lumv->hasWon = false; + lumv->wakeupSignal = 0; + lumv->lastResponseSignal = 1000; + + //LOADING LEVEL + lumberjackLoadLevel(); + + // This all to be loaded externally + lumv->yOffset = 0; + lumv->spawnIndex = 0; + lumv->spawnTimer = 2750; + lumv->transitionTimer = 0; + lumv->spawnSide = 0; + lumv->waterLevel = lumv->currentMapHeight * LUMBERJACK_TILE_SIZE; + lumv->waterDirection = -1; // This needs to be taken in to account with the intro timer - // Check spawn - lumberjackSpawnCheck(elapsedUs); + lumv->localPlayer = calloc(1, sizeof(lumberjackEntity_t)); + lumv->localPlayer->scoreValue = 0; + lumv->invincibleTimer = LUMBERJACK_INVINCIBLE_TIME; + + lumberjackSetupPlayer(lumv->localPlayer, characterIndex); + lumberjackSpawnPlayer(lumv->localPlayer, lumv->playerSpawnX, lumv->playerSpawnY, 0); - for (int colTileIndex = 0; colTileIndex < ARRAY_SIZE(lumberjackCollisionCheckTiles); colTileIndex++) + int offset = 0; + + //Load enemies + + // START ENEMY 1 + if (false == lumv->lumberjackMain->networked) { - lumberjackCollisionCheckTiles[colTileIndex].type = -1; - lumberjackCollisionCheckTiles[colTileIndex].x = -1; - lumberjackCollisionCheckTiles[colTileIndex].y = -1; - lumberjackCollisionCheckTiles[colTileIndex].collision = -1; - lumberjackCollisionCheckTiles[colTileIndex].index = -1; - lumberjackCollisionCheckTiles[colTileIndex].offset = 0; - lumberjackCollisionCheckTiles[colTileIndex].offset_time = 0; + for (int eSpawnIndex = 0; eSpawnIndex < lumv->enemy1Count; eSpawnIndex++) + { + lumv->enemy[eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[eSpawnIndex], 0); + } + offset += lumv->enemy1Count; } - - if (lumv->localPlayer->onGround && !lumv->localPlayer->jumpReady) + else { - if (lumv->localPlayer->jumpPressed == false) + for (int eSpawnIndex = 0; eSpawnIndex < 4; eSpawnIndex++) { - lumv->localPlayer->jumpReady = true; + lumv->enemy[eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[eSpawnIndex], 0); + + if (eSpawnIndex >= lumv->enemy1Count) + { + lumv->enemy[eSpawnIndex]->queueable = false; + } } - } - // Check physics - lumberjackUpdatePlayerCollision(lumv->localPlayer); + offset += 4; + } - // Enemy - for (int eIdx = 0; eIdx < ARRAY_SIZE(lumv->enemy); eIdx++) + + if (false == lumv->lumberjackMain->networked) { - lumberjackEntity_t* enemy = lumv->enemy[eIdx]; - if (enemy == NULL || enemy->ready == true) - continue; + for (int eSpawnIndex = 0; eSpawnIndex < lumv->enemy2Count; eSpawnIndex++) + { + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 1); + } - enemy->showAlert = false; - if (enemy->state == LUMBERJACK_BUMPED_IDLE) + offset += lumv->enemy2Count; + } + else + { + for (int eSpawnIndex = 0; eSpawnIndex < 8; eSpawnIndex++) { - enemy->respawn -= elapsedUs / 10000; + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 1); - enemy->showAlert = enemy->respawn < 200; - if (enemy->showAlert) + if (eSpawnIndex >= lumv->enemy2Count) { - enemy->upgrading = true; + lumv->enemy[offset + eSpawnIndex]->queueable = false; } + } - if (enemy->respawn <= 0) - { - // Hopefully the enemy isn't dead off screen. - enemy->state = LUMBERJACK_RUN; + offset += 8; + } - enemy->direction = (enemy->flipped) ? -1 : 1; - enemy->showAlert = false; - enemy->vy = -10; + + if (false == lumv->lumberjackMain->networked) + { + for (int eSpawnIndex = 0; eSpawnIndex < lumv->enemy3Count; eSpawnIndex++) + { + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 2); + } + + offset += lumv->enemy3Count; + } + else + { + for (int eSpawnIndex = 0; eSpawnIndex < 8; eSpawnIndex++) + { + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 2); - lumberjackUpdateEnemy(enemy, enemy->type + 1); + if (eSpawnIndex >= lumv->enemy3Count) + { + lumv->enemy[offset + eSpawnIndex]->queueable = false; } } - lumberjackUpdateEntity(enemy, elapsedUs); - - for (int oeIdx = 0; oeIdx < ARRAY_SIZE(lumv->enemy); oeIdx++) - { - if (lumv->enemy[oeIdx] == NULL) - continue; + offset += 8; - lumberjackUpdateEnemyCollision(lumv->enemy[oeIdx]); - } } + + + //END ENEMY 1 - // Player - if (lumv->localPlayer->ready) - { - lumv->localPlayer->respawn -= elapsedUs / 10000; - if (lumv->localPlayer->respawn <= 0 && lumv->lives > 0) - { - // Respawn player - lumv->localPlayer->respawn = 0; - lumberjackRespawn(lumv->localPlayer); - } + + //GHOST + if (lumv->enemy4Count > 0) + { + lumv->enemy4Count = 1; + lumv->ghost = calloc(1, sizeof(lumberjackGhost_t)); + lumv->ghost->spawnTime = lumv->ghostSpawnTime ; } - else if (lumv->localPlayer->state != LUMBERJACK_OFFSCREEN && lumv->localPlayer->state != LUMBERJACK_VICTORY) + + offset += lumv->enemy4Count; + for (int eSpawnIndex = 0; eSpawnIndex < lumv->enemy5Count; eSpawnIndex++) { - lumberjackUpdateEntity(lumv->localPlayer, elapsedUs); + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 4); + } - // - for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) - { - lumberjackEntity_t* enemy = lumv->enemy[enemyIndex]; + offset += lumv->enemy5Count; + for (int eSpawnIndex = 0; eSpawnIndex < lumv->enemy6Count; eSpawnIndex++) + { + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 5); + } - if (enemy == NULL || lumv->localPlayer->state == LUMBERJACK_DEAD) - continue; + offset += lumv->enemy6Count; + for (int eSpawnIndex = 0; eSpawnIndex < lumv->enemy7Count; eSpawnIndex++) + { + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 0); + } - if (enemy->state != LUMBERJACK_DEAD && enemy->state != LUMBERJACK_OFFSCREEN) - { - // DO AABB checking - if (checkCollision(lumv->localPlayer, enemy)) - { - if (enemy->state == LUMBERJACK_BUMPED || enemy->state == LUMBERJACK_BUMPED_IDLE) - { - enemy->state = LUMBERJACK_DEAD; - enemy->vy = -30; - if (lumv->localPlayer->vx != 0) - { - enemy->direction = abs(lumv->localPlayer->vx) / lumv->localPlayer->vx; - } - else - { - enemy->direction = 0; - } - enemy->vx = enemy->direction * 10; - enemy->active = false; - } - else - { - // Kill player - // ESP_LOGI(LUM_TAG, "KILL PLAYER"); - lumv->localPlayer->state = LUMBERJACK_DEAD; - lumv->localPlayer->vy = -20; - lumv->localPlayer->active = false; - lumv->localPlayer->jumping = false; - lumv->localPlayer->jumpTimer = 0; - } - } - } - } - } + offset += lumv->enemy7Count; + for (int eSpawnIndex = 0; eSpawnIndex < lumv->enemy8Count; eSpawnIndex++) + { + lumv->enemy[offset + eSpawnIndex] = calloc(1, sizeof(lumberjackEntity_t)); + lumberjackSetupEnemy(lumv->enemy[offset + eSpawnIndex], 0); + } - lumv->worldTimer += elapsedUs; + //Ghost is separate for reasons - if (lumv->worldTimer > LUMBERJACK_TILEANIMATION_SPEED) + //ESP_LOGD(LUM_TAG, "LOADED"); + if (!lumv->levelMusic) { - lumv->worldTimer -= LUMBERJACK_TILEANIMATION_SPEED; - lumv->liquidAnimationFrame++; - lumv->liquidAnimationFrame %= 4; + bzrPlayBgm(&lumv->song_theme, BZR_STEREO); + lumv->levelMusic = true; } - // Update animation - // Enemy Animation - for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) +} + +void lumberjackUnloadLevel(void) +{ + if(NULL != lumv) { - if (lumv->enemy[enemyIndex] == NULL) - continue; + free(lumv->tile); + free(lumv->localPlayer); - lumv->enemy[enemyIndex]->timerFrameUpdate += elapsedUs; - if (lumv->enemy[enemyIndex]->timerFrameUpdate > lumv->enemy[enemyIndex]->animationSpeed) + //Unload previous enemies + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) { - lumv->enemy[enemyIndex]->currentFrame++; - lumv->enemy[enemyIndex]->timerFrameUpdate = 0; //; + free(lumv->enemy[i]); + lumv->enemy[i] = NULL; } - } - // Player - lumv->localPlayer->timerFrameUpdate += elapsedUs; - if (lumv->localPlayer->timerFrameUpdate > lumv->localPlayer->animationSpeed) - { - lumv->localPlayer->currentFrame++; - lumv->localPlayer->timerFrameUpdate = 0; //; + free(lumv->ghost); + lumv->ghost = NULL; } - - lumv->yOffset = lumv->localPlayer->y - LUMBERJACK_SCREEN_Y_OFFSET; - if (lumv->yOffset < LUMBERJACK_SCREEN_Y_MIN) - lumv->yOffset = LUMBERJACK_SCREEN_Y_MIN; - if (lumv->yOffset > LUMBERJACK_SCREEN_Y_MAX) - lumv->yOffset = LUMBERJACK_SCREEN_Y_MAX; } -void DrawGame(void) +void restartLevel(void) { - // Draw section - // Redraw bottom - lumberjackTileMap(); + lumv->lives--; + lumberjackRespawn(lumv->localPlayer, lumv->playerSpawnX, lumv->playerSpawnY); - // Draw enemies +} - for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) +void lumberjackTitleLoop(int64_t elapsedUs) +{ + + // Update State + buttonEvt_t evt = {0}; + while (checkButtonQueueWrapper(&evt)) { - if (lumv->enemy[enemyIndex] == NULL || lumv->enemy[enemyIndex]->ready) - continue; - lumberjackEntity_t* enemy = lumv->enemy[enemyIndex]; + lumv->btnState = evt.state; + } - int eFrame = lumberjackGetEnemyAnimation(enemy); - drawWsg(&lumv->enemySprites[enemy->spriteOffset + eFrame], enemy->x, enemy->y - lumv->yOffset, enemy->flipped, - false, 0); + if (lumv->btnState & PB_B) + { + p2pDeinit(&lumv->lumberjackMain->p2p); - if (enemy->x > LUMBERJACK_SCREEN_X_MAX) + switchToSwadgeMode(&lumberjackMode); + } + else if (lumv->lumberjackMain->networked) + { + if (lumv->btnState & PB_A && lumv->gameReady && lumv->lumberjackMain->host && lumv->lumberjackMain->conStatus == CON_ESTABLISHED) // And Game Ready! { - drawWsg(&lumv->enemySprites[enemy->spriteOffset + eFrame], enemy->x - LUMBERJACK_SCREEN_X_OFFSET, - enemy->y - lumv->yOffset, enemy->flipped, false, 0); + lumberjackSendCharacter(lumv->localPlayerType); + lumberjackSendGo(); + lumberjackPlayGame(); + } - if (enemy->showAlert) + if (lumv->lumberjackMain->host == false && lumv->btnState & PB_START) { - // Fix the magic number :( - drawWsg(&lumv->alertSprite, enemy->x + 6, enemy->y - 26 - lumv->yOffset, enemy->flipped, false, 0); + lumberjackSendHostRequest(); } - } - int currentFrame = lumberjackGetPlayerAnimation(lumv->localPlayer); + lumv->highscore = 0; - if (lumv->localPlayer->state == LUMBERJACK_DEAD) + } else if (lumv->btnState & PB_A && lumv->gameReady) // And Game Ready! { - // ESP_LOGI(LUM_TAG, "DEAD %d", currentFrame); - } + lumberjackPlayGame(); + } - lumv->localPlayer->drawFrame = lumv->localPlayer->spriteOffset + currentFrame; - - // This is where it breaks. When it tries to play frame 3 or 4 it crashes. - drawWsg(&lumv->playerSprites[lumv->localPlayer->drawFrame], lumv->localPlayer->x - 4, - lumv->localPlayer->y - lumv->yOffset, lumv->localPlayer->flipped, false, 0); + //Update Animation + lumv->worldTimer += elapsedUs; - if (lumv->localPlayer->x > LUMBERJACK_SCREEN_X_MAX) + if (lumv->worldTimer > LUMBERJACK_TILEANIMATION_SPEED) { - drawWsg(&lumv->playerSprites[lumv->localPlayer->drawFrame], lumv->localPlayer->x - LUMBERJACK_SCREEN_X_OFFSET, - lumv->localPlayer->y - lumv->yOffset, lumv->localPlayer->flipped, false, 0); + lumv->worldTimer -= LUMBERJACK_TILEANIMATION_SPEED; + lumv->liquidAnimationFrame++; + lumv->liquidAnimationFrame %= 4; + lumv->stageAnimationFrame++; } - if (lumv->remotePlayer->active) + DrawTitle(); +} + +void lumberjackPlayGame() +{ + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING) { - drawWsg(&lumv->playerSprites[lumv->remotePlayer->drawFrame], lumv->remotePlayer->x - 4, - lumv->remotePlayer->y - lumv->yOffset, false, false, 0); + return; } - // Debug + lumv->gameState = LUMBERJACK_GAMESTATE_PLAYING; + lumberjackSetupLevel(lumv->localPlayerType); - char debug[20] = {0}; - snprintf(debug, sizeof(debug), "Debug: %d %d %d", lumv->localPlayer->x, lumv->localPlayer->y, - lumv->localPlayer->cH); - - drawText(&lumv->ibm, c000, debug, 16, 16); - - // drawRect(lumv->localPlayer->cX, lumv->localPlayer->cY - lumv->yOffset, lumv->localPlayer->cX + - // lumv->localPlayer->cW, lumv->localPlayer->cY - lumv->yOffset + lumv->localPlayer->cH, c050); - - if (lumv->localPlayer->jumpPressed) + if (lumv->lumberjackMain->networked) { - drawText(&lumv->ibm, c555, "A", 16, 32); + lumberjackSendCharacter(lumv->localPlayerType); } - else +} + +void lumberjackGameReady(void) +{ + lumv->gameReady = true; +} + +void lumberjackGameLoop(int64_t elapsedUs) +{ + + if (lumv->gameState == LUMBERJACK_GAMESTATE_TITLE) + { + lumberjackTitleLoop(elapsedUs); + return; + } + + if (lumv->gameState == LUMBERJACK_GAMESTATE_WINNING) + { + lumv->levelTime += elapsedUs / 1000; + + if (lumv->ghost != NULL && lumv->ghost->active) + lumv->ghost->currentFrame = 0; + + if (lumv->levelTime > 3000) + { + lumberjackUnloadLevel(); + + lumberjackSetupLevel(lumv->localPlayerType); + + lumv->gameState = LUMBERJACK_GAMESTATE_PLAYING; + } + + } + + baseMode(elapsedUs); + + if (lumv->lumberjackMain->networked && lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING) + { + //Check for connection lost + lumv->wakeupSignal -= elapsedUs/10000; + lumv->lastResponseSignal -= elapsedUs/10000; + + if (lumv->lumberjackMain->connLost) lumv->lastResponseSignal = 0; + + if (lumv->wakeupSignal < 0) + { + lumv->wakeupSignal = 100; + lumberjackSendScore(lumv->score); //Send score just to ping + } + + if (lumv->lastResponseSignal <= 0) + { + bzrStop(true); + //ESP_LOGD(LUM_TAG, "Connection lost!"); + lumv->gameState = LUMBERJACK_GAMESTATE_GAMEOVER; + lumv->transitionTimer = 500; + lumv->localPlayer->state = LUMBERJACK_DEAD; + } + } + + if (lumv->gameState == LUMBERJACK_GAMESTATE_GAMEOVER) + { + lumv->transitionTimer -= elapsedUs/10000; + + if (lumv->transitionTimer <= 0) + { + lumv->transitionTimer = 0; + switchToSwadgeMode(&lumberjackMode); + } + } + + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING && lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + if (lumv->itemBlockTime > 0 && lumv->itemBlockIndex == -1) + { + lumv->itemBlockTime -= elapsedUs/10000; + + if (lumv->itemBlockTime <= 0) + { + lumv->itemBlockReady = true; + lumv->itemBlockTime = 0; + } + } + + } + + //if panic mode do water + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING && lumv->gameType == LUMBERJACK_MODE_PANIC) + { + if (lumv->itemBlockTime > 0) + { + lumv->itemBlockTime -= elapsedUs/10000; + + if (lumv->itemBlockTime <= 0) + { + lumv->itemBlockReady = true; + lumv->itemBlockTime = 0; + //Play note? + } + } + + lumv->waterTimer -= elapsedUs/10000; + if (lumv->waterTimer < 0) + { + lumv->waterTimer += lumv->waterSpeed; + lumv->waterLevel += lumv->waterDirection * (lumv->upgrade + 1); + + if (lumv->waterLevel > lumv->currentMapHeight * LUMBERJACK_TILE_SIZE) + { + lumv->waterLevel = lumv->currentMapHeight * LUMBERJACK_TILE_SIZE; + lumv->waterTimer = lumv->waterSpeed * LUMBERJACK_WATER_INCREASE; // Magic number + lumv->waterDirection = -1; + } + + if (lumv->waterLevel < 0) + { + lumv->waterLevel = 0; + } + + } + + } + + //if attack mode animate item + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING && lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + if (lumv->itemBlockIndex != -1) + { + lumv->itemBlockAnimationTime += elapsedUs; + + if (lumv->itemBlockAnimationTime > 80000) + { + lumv->itemBlockAnimationTime -= 80000; + lumv->itemBlockItemAnimation++; + lumv->itemBlockItemAnimation %= 6; + + lumv->itemBlockItemFrame = (lumv->itemBlockIndex * 6) + lumv->itemBlockItemAnimation; + + } + } + + } + + DrawGame(); +} + +void baseMode(int64_t elapsedUs) +{ + // Ignore the first frame because everything was loading + // Here we might want to do something like say "On first frame loaded do stuff" + if (lumv->loaded == false) + { + lumv->loaded = true; + + //ESP_LOGD(LUM_TAG, "Load Time %ld", (long)elapsedUs); + + // If networked, send "Loaded complete!" ? + + return; + } + + // Update State + buttonEvt_t evt = {0}; + while (checkButtonQueueWrapper(&evt)) + { + lumv->btnState = evt.state; + } + + // return; + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING) + { + lumv->levelTime += elapsedUs / 1000; + + if (lumv->resume > 0) + { + lumv->resume -= elapsedUs / 1000; + + if (lumv->resume <= 0) + { + bzrPlayBgm(&lumv->song_theme, BZR_STEREO); + } + } + + if (lumv->comboTime > 0) + { + lumv->comboTime -= elapsedUs / 1000; + + if (lumv->comboTime < 0) + { + lumv->comboTime = 0; + + if (lumv->lumberjackMain->networked && lumv->comboAmount > 0) + { + + lumberjackSendAttack(lumv->attackQueue); + + for (int i = 0; i < ARRAY_SIZE(lumv->attackQueue); i++) + { + lumv->attackQueue[i] = 0; + } + } + + lumv->comboAmount = 0; + } + + } + + // Check Controls + if (lumv->localPlayer->state != LUMBERJACK_DEAD && lumv->localPlayer->state != LUMBERJACK_UNSPAWNED) + { + bool attackThisFrame = lumv->localPlayer->attackPressed; + lumberjackDoControls(); + + if (!attackThisFrame && lumv->localPlayer->attackPressed) + { + // ESP_LOGD(LUM_TAG, "Attack this frame!"); + int x = 0; + for (int i = 0; i < 32; i ++) + { + if (lumv->enemy[i] != NULL && lumv->enemy[i]->type == 2 && lumv->enemy[i]->queueable) + { + x++; + } + } + + if (lumv->gameType == LUMBERJACK_MODE_ATTACK && lumv->itemBlockIndex != -1) + { + if (lumv->itemBlockIndex == 0) + { + if (lumv->enemy4Count > 0) + { + lumv->ghost->spawnTime = lumv->ghostSpawnTime ; + lumv->ghost->x = 400; + } + + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) + { + lumberjackEntity_t* enemy = lumv->enemy[i]; + + if (enemy == NULL || enemy->state == LUMBERJACK_DEAD) continue; + + + enemy->vy = -20; + enemy->onGround = false; + if (enemy->state == LUMBERJACK_BUMPED || enemy->state == LUMBERJACK_BUMPED_IDLE) + { + enemy->state = LUMBERJACK_RUN; + enemy->direction = enemy->flipped ? 1 : -1; // Go opposite direction + enemy->flipped = !enemy->flipped; + } + else + { + enemy->direction = 0; + enemy->state = LUMBERJACK_BUMPED; + } + + } + } + + if (lumv->itemBlockIndex == 1) + { + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) + { + lumberjackEntity_t* enemy = lumv->enemy[i]; + + if (enemy == NULL || enemy->state == LUMBERJACK_DEAD) continue; + + if (enemy->active) + { + enemy->vy = -20; + lumberjackUpdateEnemy(enemy, enemy->type + 1); + } + } + + if (lumv->lumberjackMain->networked) + { + lumberjackSendBump(); + } + } + + if (lumv->itemBlockIndex >= 2) + { + lumv->invincibleTimer = LUMBERJACK_INVINCIBLE_TIME; + } + + lumv->itemBlockIndex = -1; + } + } + } + + for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) + { + if (lumv->enemy[enemyIndex] == NULL) + continue; + + } + + //Do Ghost Controls + if (lumv->ghost != NULL && lumv->ghost->active) + { + if (lumv->localPlayer->state != LUMBERJACK_DEAD) + { + lumv->ghost->x += LUMBERJACK_GHOST_SPEED_NORMAL * -lumv->ghost->startSide * elapsedUs / 100000.0; + } + else + { + lumv->ghost->x += LUMBERJACK_GHOST_SPEED_FAST * -lumv->ghost->startSide * elapsedUs / 100000.0; + } + + if (lumv->localPlayer->y < lumv->ghost->y) + { + lumv->ghost->y -= 1; + + } + if (lumv->localPlayer->y > lumv->ghost->y) + { + lumv->ghost->y += 1; + } + + } + + if (lumv->localPlayer->onGround && lumv->hasWon) + { + lumv->localPlayer->flipped = 1; + if (lumv->lumberjackMain->networked) + { + lumv->localPlayer->state = LUMBERJACK_VICTORY; + lumv->gameState = LUMBERJACK_GAMESTATE_GAMEOVER; + lumv->transitionTimer = 400; + } + else + { + lumv->gameState = LUMBERJACK_GAMESTATE_WINNING; + lumv->localPlayer->state = LUMBERJACK_VICTORY; + lumv->levelTime = 0; + lumv->levelIndex++; + } + + + } + } + + // Clear cruft + lumberjackUpdate(elapsedUs); + + + if (lumv->lumberjackMain->networked) + { + + lumv->totalEnemyCount = 0; + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) + { + if (lumv->enemy[i] == NULL) continue; + + if (lumv->enemy[i]->queueable) + { + lumv->totalEnemyCount++; + } + } + + int enemyKilled = 0; + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) + { + if (lumv->enemy[i] == NULL) continue; + if (lumv->enemy[i]->state == LUMBERJACK_DEAD) + { + if (lumv->enemy[i]->y == 640) + { + enemyKilled++; + } + } + } + + if (enemyKilled >= lumv->totalEnemyCount) + { + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) + { + if (lumv->enemy[i] == NULL || lumv->enemy[i]->queueable == false) continue; + + lumberjackResetEnemy(lumv->enemy[i]); + lumberjackUpdateEnemy(lumv->enemy[i], lumv->enemy[i]->type+1); + lumv->enemy[i]->state = LUMBERJACK_RUN; + } + + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) + { + if (lumv->enemy[i] == NULL) continue; + + if (lumv->enemy[i]->queueable == false) + { + lumv->enemy[i]->queueable = true; + break; + } + } + + + } + + } + + // Check spawn + bool spawnedEnemy = false; + //if (false == lumv->hasWon) spawnedEnemy = lumberjackSpawnCheck(elapsedUs); + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING && !lumv->hasWon) + { + spawnedEnemy = lumberjackSpawnCheck(elapsedUs); + } + + + if (spawnedEnemy) + { + lumv->enemySpawnAmount --; + if (lumv->enemySpawnAmount <= 0) + { + lumv->spawnSide++; + lumv->spawnSide %= 2; + if (lumv->gameType == LUMBERJACK_MODE_PANIC) + { + lumv->enemySpawnAmount = 1; + } + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + lumv->enemySpawnAmount = 4; + lumv->spawnTimer = LUMBERJACK_RESPAWN_PANIC_MIN; + } + } + } + + if (lumv->localPlayer->onGround && !lumv->localPlayer->jumpReady) + { + if (lumv->localPlayer->jumpPressed == false) + { + lumv->localPlayer->jumpReady = true; + } + } + + // Check physics + lumberjackUpdatePlayerCollision(lumv->localPlayer); + + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING) + { + // Enemy + for (int eIdx = 0; eIdx < ARRAY_SIZE(lumv->enemy); eIdx++) + { + lumberjackEntity_t* enemy = lumv->enemy[eIdx]; + if (enemy == NULL || enemy->ready == true) + continue; + + enemy->showAlert = false; + if (enemy->state == LUMBERJACK_BUMPED_IDLE) + { + enemy->respawn -= elapsedUs / 10000; + + enemy->showAlert = enemy->respawn < 200; + if (enemy->showAlert) + { + enemy->upgrading = true; + } + + if (enemy->respawn <= 0) + { + // Hopefully the enemy isn't dead off screen. + enemy->state = LUMBERJACK_RUN; + + enemy->direction = (enemy->flipped) ? -1 : 1; + + enemy->showAlert = false; + enemy->vy = -10; + + lumberjackUpdateEnemy(enemy, enemy->type + 1); + } + } + + lumberjackUpdateEntity(enemy, elapsedUs); + + + if (enemy->direction != 0 && enemy->onGround) + { + + lumberjackTile_t* facingTile = lumberjackGetTile(enemy->x + (enemy->direction > 0 ? 28 : -8) , enemy->y + 2); + + if (facingTile != NULL && facingTile->type != 0 && lumberjackIsCollisionTile(facingTile->type)) + { + enemy->direction = enemy->flipped ? 1 : -1; // Go opposite direction + enemy->flipped = !enemy->flipped; //Debug + enemy->vx = (enemy->direction == 1) ? enemy->maxVX : -enemy->maxVX; + } + } + + lumberjackUpdateEnemyCollision(enemy); + } + + // Player + if (lumv->localPlayer->ready) + { + lumv->localPlayer->respawn -= elapsedUs / 10000; + + if (lumv->localPlayer->respawn <= 0 && lumv->lives > 0) + { + + //ESP_LOGD(LUM_TAG, "RESPAWN PLAYER!"); + bzrStop(true); + bzrPlaySfx(&lumv->song_respawn, BZR_RIGHT); + + // Respawn player + lumv->localPlayer->respawn = 0; + lumv->resume = 2000; + lumv->lives--; + lumv->invincibleTimer = LUMBERJACK_INVINCIBLE_TIME; + lumberjackRespawn(lumv->localPlayer, lumv->playerSpawnX, lumv->playerSpawnY); + } + } + else if (lumv->localPlayer->state != LUMBERJACK_OFFSCREEN && lumv->localPlayer->state != LUMBERJACK_VICTORY) + { + lumberjackUpdateEntity(lumv->localPlayer, elapsedUs); + + // + for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) + { + lumberjackEntity_t* enemy = lumv->enemy[enemyIndex]; + + if (enemy == NULL || lumv->localPlayer->state == LUMBERJACK_DEAD) + continue; + + if (enemy->state != LUMBERJACK_DEAD && enemy->state != LUMBERJACK_OFFSCREEN) + { + // DO AABB checking + if (checkCollision(lumv->localPlayer, enemy)) + { + if (enemy->state == LUMBERJACK_BUMPED || enemy->state == LUMBERJACK_BUMPED_IDLE) + { + enemy->state = LUMBERJACK_DEAD; // Enemy Death + enemy->vy = -30; + + if (lumv->comboTime > 0) + { + ++lumv->comboAmount; + + lumv->activeBonusIndex++; + lumv->activeBonusIndex %= ARRAY_SIZE(lumv->bonusDisplay); + lumberjackBonus_t* currentBonus = lumv->bonusDisplay[lumv->activeBonusIndex]; + + currentBonus->x = enemy->x; + currentBonus->y = enemy->y; + currentBonus->active = true; + currentBonus->time = 0; + currentBonus->bonusAmount = lumv->comboAmount + 1; + + + if (lumv->lumberjackMain->networked) + { + lumv->attackQueue[enemy->type]++; + } + } + + if (lumv->lumberjackMain->networked) + { + lumv->attackQueue[enemy->type]++; + } + + lumv->score += enemy->scoreValue * (lumv->comboAmount + 1); + + if (lumv->lumberjackMain->networked) + { + lumberjackSendScore(lumv->score); + } + else + { + if (lumv->score > lumv->highscore) + { + lumv->highscore = lumv->score; + } + } + + lumv->comboTime = LUMBERJACK_COMBO_RESET_TIME; + bzrPlaySfx(&lumv->sfx_enemy_death, BZR_RIGHT); + + + //if game mode is single player decide if you're going to clear the level + lumv->enemyKillCount ++; + + if (lumv->enemyKillCount >= lumv->totalEnemyCount) + { + //And game mode == blah + if (!lumv->lumberjackMain->networked) + { + lumv->hasWon = true; + lumv->invincibleTimer = 0; + + if (NULL != lumv->ghost && lumv->ghost->active) + { + lumv->ghost->x = 1000; + } + } + } + + if (lumv->localPlayer->vx != 0) + { + enemy->direction = abs(lumv->localPlayer->vx) / lumv->localPlayer->vx; + } + else + { + enemy->direction = 0; + } + enemy->vx = enemy->direction * 10; + enemy->active = false; + } + else if (lumv->invincibleTimer <= 0) + { + // Kill player + lumberjackOnLocalPlayerDeath(); + + } + } + } + } + } + } + + lumv->worldTimer += elapsedUs; + + if (lumv->worldTimer > LUMBERJACK_TILEANIMATION_SPEED) + { + lumv->worldTimer -= LUMBERJACK_TILEANIMATION_SPEED; + lumv->liquidAnimationFrame++; + lumv->liquidAnimationFrame %= 4; + lumv->stageAnimationFrame++; + } + + //Check invincibility timer + if (lumv->invincibleTimer > 0) + { + lumv->invincibleTimer -= elapsedUs / 1000; + lumv->invincibleFlicker -= elapsedUs/1000; + + if (lumv->invincibleFlicker <= 0) + { + lumv->invincibleFlicker = 250; + lumv->invincibleFlickerOn = !lumv->invincibleFlickerOn; + } + } + + // Update animation + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING) + { + //if Panic mode... check to see if player's head is under water. + if (lumv->localPlayer->y > lumv->waterLevel && lumv->localPlayer->state != LUMBERJACK_DEAD && lumv->localPlayer->state != LUMBERJACK_OFFSCREEN) + { + //ESP_LOGD(LUM_TAG, "UNDER WATER! %d", lumv->localPlayer->submergedTimer); + lumv->localPlayer->submergedTimer -= elapsedUs / 10000; + + if (lumv->localPlayer->submergedTimer <= 0) + { + lumv->localPlayer->submergedTimer = 0; + lumberjackOnLocalPlayerDeath(); + } + } + else + { + lumv->localPlayer->submergedTimer = LUMBERJACK_SUBMERGE_TIMER; + } + + + // Enemy Animation + for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) + { + if (lumv->enemy[enemyIndex] == NULL) + continue; + + lumv->enemy[enemyIndex]->timerFrameUpdate += elapsedUs; + if (lumv->enemy[enemyIndex]->timerFrameUpdate > lumv->enemy[enemyIndex]->animationSpeed) + { + lumv->enemy[enemyIndex]->currentFrame++; + lumv->enemy[enemyIndex]->timerFrameUpdate = 0; //; + } + } + } + + // Player + lumv->localPlayer->timerFrameUpdate += elapsedUs; + if (lumv->localPlayer->timerFrameUpdate > lumv->localPlayer->animationSpeed) + { + lumv->localPlayer->currentFrame++; + lumv->localPlayer->timerFrameUpdate = 0; //; + } + + if (NULL != lumv->ghost && lumv->ghost->active && + lumv->gameState != LUMBERJACK_GAMESTATE_GAMEOVER) + { + lumv->ghost->timerFrameUpdate += elapsedUs; + if (lumv->ghost->timerFrameUpdate > LUMBERJACK_GHOST_ANIMATION) + { + lumv->ghost->timerFrameUpdate -= LUMBERJACK_GHOST_ANIMATION; + lumv->ghost->currentFrame++; + lumv->ghost->currentFrame %= 4; + } + } + + lumv->yOffset = lumv->localPlayer->y - LUMBERJACK_SCREEN_Y_OFFSET; + if (lumv->yOffset < LUMBERJACK_SCREEN_Y_MIN) + lumv->yOffset = LUMBERJACK_SCREEN_Y_MIN; + + // + if (lumv->yOffset > (lumv->currentMapHeight * LUMBERJACK_TILE_SIZE) - TFT_HEIGHT) + lumv->yOffset = (lumv->currentMapHeight * LUMBERJACK_TILE_SIZE) - TFT_HEIGHT; + + + for (int i = 0; i < ARRAY_SIZE(lumv->bonusDisplay); i++) + { + lumberjackBonus_t* currentBonus = lumv->bonusDisplay[i]; + if (false == currentBonus->active ) continue; + + currentBonus->time += elapsedUs / 1000; + if (currentBonus->time > LUMBERJACK_BONUS_DISPLAYDURATI) + { + currentBonus->active = false; + } + } + +} + +void lumberjackOnLocalPlayerDeath(void) +{ + lumv->localPlayer->state = LUMBERJACK_DEAD; + lumv->localPlayer->vy = -20; + lumv->localPlayer->active = false; + lumv->localPlayer->jumping = false; + lumv->localPlayer->jumpTimer = 0; + lumv->comboAmount = 0; + lumv->comboTime = 0; + + if (lumv->lives <= 0) + { + if (lumv->ghost != NULL && lumv->ghost->active) + lumv->ghost->currentFrame = 0; + + lumv->gameState = LUMBERJACK_GAMESTATE_GAMEOVER; + lumv->transitionTimer = 400; + bzrStop(true); + + bzrPlayBgm(&lumv->song_gameover, BZR_STEREO); + } + + bzrPlaySfx(&lumv->sfx_player_death, BZR_RIGHT); + + if (lumv->lumberjackMain->networked) + { + lumberjackSendDeath(lumv->lives); + + } +} + + + +void DrawTitle(void) +{ + drawWsgSimple(&lumv->title, (TFT_WIDTH / 2) - 51, (TFT_HEIGHT / 2) - 48); + + if (lumv->localPlayerType == 0) + { + drawWsgSimple(&lumv->subtitle_red, (TFT_WIDTH/2)- 36, (TFT_HEIGHT/2) -9); + } + else if (lumv->localPlayerType == 1) + { + drawWsgSimple(&lumv->subtitle_green, (TFT_WIDTH/2)- 36, (TFT_HEIGHT/2) -9); + } + else + { + drawWsgSimple(&lumv->subtitle_white, (TFT_WIDTH/2)- 36, (TFT_HEIGHT/2) -9); + + } + + for (int i = 0; i < LUMBERJACK_MAP_WIDTH; i++) + { + drawWsgSimple(&lumv->floorTiles[1], i * LUMBERJACK_TILE_SIZE, 208); + drawWsgSimple(&lumv->floorTiles[7], i * LUMBERJACK_TILE_SIZE, 224); + } + + if (lumv->lumberjackMain->connLost) + { + drawWsgSimple(&lumv->connectLostSprite, (TFT_WIDTH/2) - 90, (TFT_HEIGHT/2) - 9); + const char* error = "Press B"; + int16_t tWidthC = textWidth(&lumv->arcade, error); + + lumberjackTitleDisplayText(error, (TFT_WIDTH - tWidthC) / 2, 180); + } else if (lumv->gameReady) + { + const char* hostText = "Press A to start"; + const char* clientText = "Host must start"; + int16_t tWidthH = textWidth(&lumv->arcade, hostText); + int16_t tWidthC = textWidth(&lumv->arcade, clientText); + + if(lumv->lumberjackMain->networked) + { + if(lumv->lumberjackMain->host) + { + lumberjackTitleDisplayText(hostText, (TFT_WIDTH - tWidthH) / 2, 180); + } + else + { + lumberjackTitleDisplayText(clientText, (TFT_WIDTH - tWidthC) / 2, 180); + } + } + else + { + lumberjackTitleDisplayText(hostText, (TFT_WIDTH - tWidthH) / 2, 180); + } + } + else if (lumv->lumberjackMain->networked) + { + const char* connText = "Looking for connection"; + int16_t tWidth = textWidth(&lumv->arcade, connText); + lumberjackTitleDisplayText(connText, (TFT_WIDTH - tWidth)/2, 180); + } + + drawWsgSimple(&lumv->unusedBlockSprite[lumv->stageAnimationFrame % LUMBERJACK_BLOCK_ANIMATION_MAX], 8.5 * 16, 208 - 64); +} + +void DrawGame(void) +{ + // Draw section + // Redraw bottom + lumberjackTileMap(); + + // Draw enemies + + for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) + { + if (lumv->enemy[enemyIndex] == NULL || lumv->enemy[enemyIndex]->ready) + continue; + lumberjackEntity_t* enemy = lumv->enemy[enemyIndex]; + + int eFrame = lumberjackGetEnemyAnimation(enemy); + + drawWsg(&lumv->enemySprites[enemy->spriteOffset + eFrame], enemy->x, enemy->y - lumv->yOffset, enemy->flipped, + false, 0); + + if (enemy->x > LUMBERJACK_SCREEN_X_MAX) + { + drawWsg(&lumv->enemySprites[enemy->spriteOffset + eFrame], enemy->x - LUMBERJACK_SCREEN_X_OFFSET, + enemy->y - lumv->yOffset, enemy->flipped, false, 0); + } + + if (enemy->showAlert) + { + // Fix the magic number :( + drawWsg(&lumv->alertSprite, enemy->x + 6, enemy->y - 26 - lumv->yOffset, enemy->flipped, false, 0); + } + } + + int currentFrame = lumberjackGetPlayerAnimation(lumv->localPlayer); + + if (lumv->localPlayer->state == LUMBERJACK_DEAD) + { + + // If panic mode + if (lumv->gameType == LUMBERJACK_MODE_PANIC) + { + lumv->waterDirection = LUMBERJACK_WATER_SLOW_DRAIN; + lumv->waterTimer = lumv->waterSpeed; + lumv->waterLevel += lumv->waterDirection; + } + + } + + if (lumv->localPlayer->submergedTimer != LUMBERJACK_SUBMERGE_TIMER && ((lumv->localPlayer->submergedTimer/10) % 3) != 0) + { + drawWsg(&lumv->alertSprite, lumv->localPlayer->x + 6, lumv->localPlayer->y - 26 - lumv->yOffset, false, false, 0); + } + + lumv->localPlayer->drawFrame = currentFrame; + + // This is where it breaks. When it tries to play frame 3 or 4 it crashes. + if (lumv->invincibleTimer <= 0 || !lumv->invincibleFlickerOn) + { + + + drawWsg(&lumv->playerSprites[lumv->localPlayer->drawFrame], lumv->localPlayer->x - 4, + lumv->localPlayer->y - lumv->yOffset, lumv->localPlayer->flipped, false, 0); + } + else + { + + drawSolidWsg(&lumv->playerSprites[lumv->localPlayer->drawFrame], lumv->localPlayer->x - 4, + lumv->localPlayer->y - lumv->yOffset, lumv->localPlayer->flipped, false, lumv->invincibleColor); + } + + + if (lumv->localPlayer->x > LUMBERJACK_SCREEN_X_MAX) + { + drawWsg(&lumv->playerSprites[lumv->localPlayer->drawFrame], lumv->localPlayer->x - LUMBERJACK_SCREEN_X_OFFSET, + lumv->localPlayer->y - lumv->yOffset, lumv->localPlayer->flipped, false, 0); + } + + //This is where we draw the ghost + if (NULL != lumv->ghost && true == lumv->ghost->active && lumv->ghost->currentFrame % 2 == 0) + { + if (lumv->ghost->currentFrame == 2) + drawWsg(&lumv->enemySprites[21], lumv->ghost->x, lumv->ghost->y - lumv->yOffset, (lumv->ghost->startSide == 1), false, 0); + else + drawWsg(&lumv->enemySprites[22], lumv->ghost->x, lumv->ghost->y - lumv->yOffset, (lumv->ghost->startSide == 1), false, 0); + } + + + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + drawWsgSimple(&lumv->ui[0], (TFT_WIDTH / 2) - 12, 6); + + if (lumv->itemBlockIndex != -1) + { + drawWsgSimple(&lumv->itemIcons[lumv->itemBlockItemFrame], (TFT_WIDTH / 2) - 8, 10); + } + } + //If playing panic mode draw water + + lumberjackDrawWaterLevel(); + + for (int i = 0; i < lumv->lives; i++) + { + int icon = lumv->localPlayerType; + + if (icon > ARRAY_SIZE(lumv->minicharacters)) + { + icon = 0; + } + drawWsgSimple(&lumv->minicharacters[icon], (i * 14) + 22, 32); + } + + if (lumv->lumberjackMain->networked) + { + for (int i = 0; i < lumv->nLives; i++) + { + + int icon = lumv->netPlayerType; + + if (icon > ARRAY_SIZE(lumv->minicharacters)) + { + icon = 0; + } + drawWsgSimple(&lumv->minicharacters[icon], (i * 14) + 206, 32); + } + } + + if (lumv->lumberjackMain->connLost) + { + drawWsgSimple(&lumv->connectLostSprite, (TFT_WIDTH/2) -80, (TFT_HEIGHT/2) - 9); + } + else if (lumv->gameState == LUMBERJACK_GAMESTATE_GAMEOVER) { - drawText(&lumv->ibm, c000, "A", 16, 32); + if (lumv->lumberjackMain->networked && lumv->lastResponseSignal <= 0) + { + drawWsgSimple(&lumv->connectLostSprite, (TFT_WIDTH/2) -80, (TFT_HEIGHT/2) - 9); + } else if (lumv->hasWon) + { + drawWsgSimple(&lumv->gamewinSprite, (TFT_WIDTH/2) -72, (TFT_HEIGHT/2) - 9); + } + else + { + drawWsgSimple(&lumv->gameoverSprite, (TFT_WIDTH/2) -72, (TFT_HEIGHT/2) - 9); + } + } + + // + lumberjackScoreDisplay(lumv->score, 26); + lumberjackScoreDisplay(lumv->highscore, 206); + + if (lumv->gameState == LUMBERJACK_GAMESTATE_PLAYING && lumv->levelTime < 5000) + { + char level_display[20] = {0}; + + if (lumv->levelIndex < 9) + { + snprintf(level_display, sizeof(level_display), "Level 0%d", (lumv->levelIndex + 1)); + } + else + { + snprintf(level_display, sizeof(level_display), "Level %d", (lumv->levelIndex + 1)); + } + + drawText(&lumv->arcade, c000, level_display, (TFT_WIDTH/2) - 36, TFT_HEIGHT - 18); + drawText(&lumv->arcade, c000, level_display, (TFT_WIDTH/2) - 36, TFT_HEIGHT - 21); + drawText(&lumv->arcade, c000, level_display, (TFT_WIDTH/2) - 36 - 1, TFT_HEIGHT - 20); + drawText(&lumv->arcade, c000, level_display, (TFT_WIDTH/2) - 36 + 1, TFT_HEIGHT - 20); + drawText(&lumv->arcade, c555, level_display, (TFT_WIDTH/2) - 36, TFT_HEIGHT - 20); + } + + for (int i = 0; i < ARRAY_SIZE(lumv->bonusDisplay); i++) + { + lumberjackBonus_t* currentBonus = lumv->bonusDisplay[i]; + if (false == currentBonus->active ) continue; + + float offsetTime = (((float)currentBonus->time)/LUMBERJACK_BONUS_DISPLAYDURATI) + .9f; + + if (offsetTime > 1) offsetTime = 1; + + drawWsgSimple(&lumv->bonusSprites[10], currentBonus->x, currentBonus->y - lumv->yOffset - (20 - (20 * offsetTime))); + if (currentBonus->bonusAmount < 10) + { + drawWsgSimple(&lumv->bonusSprites[currentBonus->bonusAmount], currentBonus->x+8, currentBonus->y - lumv->yOffset - (20 - (20 * offsetTime))); + } + else + { + int tenDigit = (int)(currentBonus->bonusAmount / 10); + if (tenDigit > 9) tenDigit = 9; + int oneDigit = currentBonus->bonusAmount % 10; + + drawWsgSimple(&lumv->bonusSprites[tenDigit], currentBonus->x+8, currentBonus->y - lumv->yOffset - (20 - (20 * offsetTime))); + drawWsgSimple(&lumv->bonusSprites[oneDigit], currentBonus->x+16, currentBonus->y - lumv->yOffset - (20 - (20 * offsetTime))); + + + + } + } + - if (lumv->localPlayer->attackPressed) +} + +void lumberjackTitleDisplayText(const char* string, int locationX, int locationY) +{ + + drawText(&lumv->arcade, c000, string, locationX, locationY + 2); + drawText(&lumv->arcade, c000, string, locationX, locationY - 1); + drawText(&lumv->arcade, c000, string, locationX - 1, locationY); + drawText(&lumv->arcade, c000, string, locationX + 1, locationY); + drawText(&lumv->arcade, c555, string, locationX, locationY); +} + +void lumberjackScoreDisplay(int score, int locationX) +{ + char score_display[20] = {0}; + + if (score > 0) { - drawText(&lumv->ibm, c555, "B", 48, 32); + snprintf(score_display, sizeof(score_display), "%d", score); } else { - drawText(&lumv->ibm, c000, "B", 48, 32); + snprintf(score_display, sizeof(score_display), "000"); } + + drawText(&lumv->arcade, c000, score_display, locationX, 18); + drawText(&lumv->arcade, c000, score_display, locationX, 15); + drawText(&lumv->arcade, c000, score_display, locationX - 1, 16); + drawText(&lumv->arcade, c000, score_display, locationX + 1, 16); + drawText(&lumv->arcade, c555, score_display, locationX, 16); } -void lumberjackSpawnCheck(int64_t elapseUs) +bool lumberjackSpawnCheck(int64_t elapseUs) { + float elapse = (elapseUs / 1000); + if (lumv->ghost != NULL && lumv->ghost->active == false) + { + lumv->ghost->spawnTime -= elapse; + + if (lumv->ghost->spawnTime <= 0) + { + lumv->ghost->spawnTime = lumv->ghostSpawnTime; + + lumv->ghost->active = true; + + if (esp_random() % 2 > 0) + { + lumv->ghost->startSide = -1; + lumv->ghost->x = -5; + } + else + { + lumv->ghost->startSide = 1; + lumv->ghost->x = 280; + } + + lumv->ghost->y = lumv->localPlayer->y; + + if (esp_random() % 2 > 0) + { + lumv->ghost->y -= 32; + } + else + { + lumv->ghost->y += 32; + } + } + + } + + bool spawnReady = false; if (lumv->spawnTimer >= 0) { - bool spawnReady = true; - float elapse = (elapseUs / 1000); lumv->spawnTimer -= elapse; if (lumv->spawnTimer < 0) { for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) { - if (lumv->enemy[enemyIndex] == NULL) + if (lumv->enemy[enemyIndex] == NULL || lumv->enemy[enemyIndex]->queueable == false) continue; if (lumv->enemy[enemyIndex]->ready && lumv->enemy[enemyIndex]->state != LUMBERJACK_DEAD) { - lumv->spawnSide++; - lumv->spawnSide %= 2; - lumv->spawnTimer = 750; + //lumv->spawnTimer = LUMBERJACK_RESPAWN_TIMER - (lumv->upgrade * LUMBERJACK_UPGRADE_TIMER_OFFSET); + lumv->spawnTimer = lumv->enemySpawnTime; lumberjackRespawnEnemy(lumv->enemy[enemyIndex], lumv->spawnSide); - spawnReady = false; - // break; + spawnReady = true; + break; + } + } + + if (!spawnReady) + { + // No one was spawned. + lumv->spawnTimer = 500; + } + } + } + + return spawnReady; +} + +void lumberjackQualityCheck() +{ + lumv->wakeupSignal = 100; + lumv->lastResponseSignal = 2000; +} + +void lumberjackOnReceiveAttack(const uint8_t* attack, int len) +{ + if (lumv->gameType == LUMBERJACK_MODE_PANIC) + { + + lumv->waterDirection = -1; //Even if it is draining + lumv->waterSpeed -= 5; + if (lumv->waterSpeed < 0) + { + lumv->waterSpeed = 0; + } + } + + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + for (int i = 1; i < len; i++) + { + int rem = attack[i]; + for (int n = 0; n < ARRAY_SIZE(lumv->enemy); n++) + { + if (rem <= 0) break; + + if (lumv->enemy[n] == NULL || lumv->enemy[n]->queueable) continue; + + if (lumv->enemy[n]->type == i - 1) + { + lumv->enemy[n]->queueable = true; + rem--; + } + } + } + + lumv->totalEnemyCount = 0; + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++) + { + if (lumv->enemy[i] == NULL) continue; + + if (lumv->enemy[i]->queueable) + { + lumv->totalEnemyCount++; + } + } + + } +} + +void lumberjackOnReceiveScore(const uint8_t* score) +{ + int locX = (int)score[1] << 0 | (uint32_t)score[2] << 8 | (uint32_t)score[3] << 16; + lumv->highscore = locX; +} + +void lumberjackOnReceiveCharacter(uint8_t character) +{ + lumv->netPlayerType = character; +} + +void lumberjackOnReceiveBump(void) +{ + if (lumv->localPlayer->onGround) + { + lumv->localPlayer->vy = -20; //HERE + bzrPlaySfx(&lumv->sfx_bump, BZR_RIGHT); + + if (lumv->localPlayer->state == LUMBERJACK_DUCK) + { + bzrPlaySfx(&lumv->sfx_flip, BZR_RIGHT); + + lumv->localPlayer->vy = -40; + lumv->localPlayer->state = LUMBERJACK_BUMPED; + lumv->invincibleTimer = 0; + + if (lumv->ghost != NULL && lumv->ghost->active) + { + if (lumv->localPlayer->x < lumv->ghost->x + LUMBERJACK_GHOST_BOX && lumv->localPlayer->x + lumv->localPlayer->width > lumv->ghost->x + && lumv->localPlayer->y < lumv->ghost->y + LUMBERJACK_GHOST_BOX && lumv->localPlayer->y + lumv->localPlayer->height > lumv->ghost->y + ) + { + lumberjackOnLocalPlayerDeath(); } + } + } + + + } + + lumv->itemBlockIndex = -1; +} + +void lumberjackOnReceiveDeath(uint8_t lives) +{ + + if (lives < 1) + { + lumv->hasWon = true; + + for (int i = 0; i < ARRAY_SIZE(lumv->enemy); i++ ) + { + if (lumv->enemy[i] == NULL) continue; - if (spawnReady) - { - // No one was spawned. - lumv->spawnTimer = 500; - } + lumv->enemy[i]->state = LUMBERJACK_DEAD; } + } + ESP_LOGI(LUM_TAG, "Lives: %d", lives); + lumv->nLives = lives - 1; +} + +void lumberjackAttackCheck(int64_t elapseUs) +{ } static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs) @@ -608,16 +2092,23 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs bool onGround = false; // World wrap - entity->x %= 295; + entity->x %= LUMBERJACK_WORLD_WRAP; if (entity->x < -20) { - entity->x += 295; + entity->x += LUMBERJACK_WORLD_WRAP; } if (entity->state == LUMBERJACK_BUMPED) { entity->vy -= 2; - entity->respawn = 1500; + entity->respawn = 1500 - (lumv->upgrade * LUMBERJACK_UPGRADE_TIMER_OFFSET); + + if (entity->respawn < LUMBERJACK_UPGRADE_TIMER_OFFSET) + { + entity->respawn = LUMBERJACK_UPGRADE_TIMER_OFFSET; + } + + if (entity->vy >= 0) { @@ -636,6 +2127,9 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs entity->vy = -15; entity->jumpTimer = 225000; entity->onGround = false; + + bzrPlaySfx(&lumv->sfx_jump, BZR_RIGHT); + } else if (entity->jumping) { @@ -721,29 +2215,99 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs { lumberjackTile_t* tileA = lumberjackGetTile(destinationX, destinationY); lumberjackTile_t* tileB = lumberjackGetTile(destinationX + 16, destinationY); - - if (lumberjackIsCollisionTile(tileA->type) || lumberjackIsCollisionTile(tileB->type)) + bool flipOpponent = false; + bool bump = false; + if ((tileA != NULL && lumberjackIsCollisionTile(tileA->type)) || (tileB != NULL && lumberjackIsCollisionTile(tileB->type))) { - destinationY = ((tileA->y + 1) * 16); + // Put in the full if statement because cppcheck wasn't happy with ternary + if (tileA != NULL) + { + destinationY = (tileA->y + 1) * LUMBERJACK_TILE_SIZE; + } + else{ + destinationY = ((tileB->y + 1) * LUMBERJACK_TILE_SIZE); + } + entity->jumpTimer = 0; entity->jumping = false; entity->vy = 0; - if (lumberjackIsCollisionTile(tileA->type)) + if (tileA != NULL && lumberjackIsCollisionTile(tileA->type)) { - lumv->tile[tileA->index].offset = 10; - lumv->tile[tileA->index].offset_time = 100; + bump = true; + if (tileA->type != 11 || lumv->itemBlockReady == true) + { + + lumv->tile[tileA->index].offset = 10; + lumv->tile[tileA->index].offset_time = 100; + + + if (tileA->type == 12) + { + lumv->tile[tileA->index].type = 13; + lumv->tile[tileA->index].offset *= 10; + lumv->tile[tileA->index].offset_time *= 10; + } + + if (lumv->tile[tileA->index].type != 13) + { + if(lumberjackDetectBump(tileA)) + { + flipOpponent = true; + } + + } + if (tileA->type == 11) + { + lumberjackUseBlock(); + bump = false; + } + + } - lumberjackDetectBump(tileA); } - if (lumberjackIsCollisionTile(tileB->type)) + if (tileB!= NULL && lumberjackIsCollisionTile(tileB->type)) { - lumberjackDetectBump(tileB); + bump = true; + if (tileB->type != 11 || lumv->itemBlockReady == true) + { + + + lumv->tile[tileB->index].offset = 10; + lumv->tile[tileB->index].offset_time = 100; + if (tileB->type == 12) + { + lumv->tile[tileB->index].type = 13; + lumv->tile[tileB->index].offset *= 10; + lumv->tile[tileB->index].offset_time *= 10; + } + + if (lumv->tile[tileB->index].type != 13) + { + if (lumberjackDetectBump(tileB)) + { + flipOpponent = true; + } + } + if (tileB->type == 11) + { + lumberjackUseBlock(); + bump = false; + } + } + } + - lumv->tile[tileB->index].offset = 10; - lumv->tile[tileB->index].offset_time = 100; + if (flipOpponent) + { + bzrPlaySfx(&lumv->sfx_flip, BZR_RIGHT); + } + else if (bump) + { + bzrPlaySfx(&lumv->sfx_bump, BZR_RIGHT); } + } } else if (entity->vy > 0 && entity->active) @@ -754,7 +2318,7 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs if ((tileA != NULL && lumberjackIsCollisionTile(tileA->type)) || (tileB != NULL && lumberjackIsCollisionTile(tileB->type))) { - destinationY = ((tileA->y - entity->tileHeight) * 16); + destinationY = ((tileA->y - entity->tileHeight) * LUMBERJACK_TILE_SIZE); entity->vy = 0; onGround = true; } @@ -762,17 +2326,12 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs entity->onGround = onGround; - if (entity->vx > entity->maxVX) - { - // ESP_LOGI(LUM_TAG, "ERROR"); - } - entity->x = destinationX; entity->y = destinationY; - if (entity->y > 350) + if (entity->y > lumv->currentMapHeight * LUMBERJACK_TILE_SIZE) { - entity->y = 350; + entity->y = lumv->currentMapHeight * LUMBERJACK_TILE_SIZE; entity->active = false; if (entity->state == LUMBERJACK_DEAD) { @@ -781,15 +2340,15 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs { if (entity->respawn == 0) { - // ESP_LOGI(LUM_TAG, "DEAD & hit the ground %d", entity->respawn); - entity->respawn = 250; + entity->respawn = LUMBERJACK_UPGRADE_TIMER_OFFSET; entity->ready = true; + return; } - } - else + } else if (entity->upgrading) { - // Entity is not local player + lumberjackResetEnemy(entity); + lumberjackUpdateEnemy(entity, entity->type + 1); } } @@ -799,7 +2358,7 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs { entity->respawn = 500; entity->ready = true; - lumv->localPlayer->state = LUMBERJACK_DEAD; + lumberjackOnLocalPlayerDeath(); return; } else @@ -808,61 +2367,122 @@ static void lumberjackUpdateEntity(lumberjackEntity_t* entity, int64_t elapsedUs entity->ready = true; } } - if (entity->state != LUMBERJACK_DEAD) + if (entity->state != LUMBERJACK_DEAD && !lumv->hasWon) + { entity->state = LUMBERJACK_OFFSCREEN; + + + } + + if (entity->state != LUMBERJACK_DEAD && entity->state != LUMBERJACK_OFFSCREEN && lumv->hasWon) + { + lumv->gameState = LUMBERJACK_GAMESTATE_WINNING; + lumv->localPlayer->state = LUMBERJACK_VICTORY; + lumv->levelTime = 0; + lumv->levelIndex++; + } + } + + if (entity == lumv->localPlayer && lumv->ghost != NULL && lumv->ghost->active) + { + if (lumv->localPlayer->x < lumv->ghost->x + LUMBERJACK_GHOST_BOX && lumv->localPlayer->x + lumv->localPlayer->width > lumv->ghost->x + && lumv->localPlayer->y < lumv->ghost->y + LUMBERJACK_GHOST_BOX && lumv->localPlayer->y + lumv->localPlayer->height > lumv->ghost->y + && lumv->localPlayer->state != LUMBERJACK_DEAD && lumv->localPlayer->state != LUMBERJACK_DUCK && lumv->invincibleTimer <= 0) + { + lumberjackOnLocalPlayerDeath(); + } + } } void lumberjackUpdate(int64_t elapseUs) { - for (int tileIndex = 0; tileIndex < ARRAY_SIZE(lumv->tile); tileIndex++) + for (int tileIndex = 0; tileIndex < lumv->currentMapHeight * LUMBERJACK_MAP_WIDTH; tileIndex++) { if (lumv->tile[tileIndex].offset > 0) { - // ESP_LOGI(LUM_TAG, "Update %d",lumv->tile[tileIndex].offset); - lumv->tile[tileIndex].offset_time -= elapseUs; if (lumv->tile[tileIndex].offset_time < 0) { lumv->tile[tileIndex].offset_time += 2500; lumv->tile[tileIndex].offset--; + + if (lumv->tile[tileIndex].type == 13 && lumv->tile[tileIndex].offset <= 0) + { + lumv->tile[tileIndex].type = 12; + } } } } + + if (lumv->ghost != NULL && lumv->ghost->active) + { + if ((lumv->ghost->x < -28 && lumv->ghost->startSide > 0) || (lumv->ghost->x > 290 && lumv->ghost->startSide < 0 )) + { + lumv->ghost->active = false; + } + } } void lumberjackTileMap(void) { - // TODO: Stop drawing any area of the map that is off screen - for (int y = 0; y < 21; y++) + for (int y = 0; y < lumv->currentMapHeight; y++) { - for (int x = 0; x < 18; x++) + for (int x = 0; x < LUMBERJACK_MAP_WIDTH; x++) { - int index = (y * 18) + x; + int index = (y * LUMBERJACK_MAP_WIDTH) + x; + int tileIndex = lumv->tile[index].type; - int animIndex = lumv->anim[index]; int offset = lumv->tile[index].offset; - if ((y * 16) - lumv->yOffset >= -16) + if ((y * LUMBERJACK_TILE_SIZE) - lumv->yOffset >= -16) { - if (animIndex > 0 && animIndex < 4) - { - drawWsgSimple(&lumv->animationTiles[((animIndex - 1) * 4) + (lumv->liquidAnimationFrame % 4)], - x * 16, (y * 16) - lumv->yOffset + 8 - offset); - } - - if (tileIndex > 0 && tileIndex < 13) + if (tileIndex > 0 && tileIndex < 15) { if (tileIndex < 11) { - drawWsgSimple(&lumv->floorTiles[tileIndex - 1], x * 16, (y * 16) - lumv->yOffset - offset); + drawWsgSimple(&lumv->floorTiles[tileIndex - 1], x * LUMBERJACK_TILE_SIZE, (y * LUMBERJACK_TILE_SIZE) - lumv->yOffset - offset); + } + else if (tileIndex == 11) + { + if (lumv->itemBlockReady) + { + drawWsgSimple(&lumv->unusedBlockSprite[lumv->stageAnimationFrame % LUMBERJACK_BLOCK_ANIMATION_MAX], x * LUMBERJACK_TILE_SIZE, (y * LUMBERJACK_TILE_SIZE) - lumv->yOffset - offset); + } + else + { + drawWsgSimple(&lumv->floorTiles[tileIndex - 1], x * LUMBERJACK_TILE_SIZE, (y * LUMBERJACK_TILE_SIZE) - lumv->yOffset - offset); + } + } + else if (tileIndex == 12) + { + drawWsgSimple(&lumv->animationTiles[12], x * LUMBERJACK_TILE_SIZE, (y * LUMBERJACK_TILE_SIZE) - lumv->yOffset); + } + else if (tileIndex == 13) + { + drawWsgSimple(&lumv->animationTiles[12 + (offset % LUMBERJACK_ROTATE_ANIMATION_MAX)], x * LUMBERJACK_TILE_SIZE, (y * LUMBERJACK_TILE_SIZE) - lumv->yOffset); } } + } } } + +} + +void lumberjackDrawWaterLevel(void) +{ + //If GameMode is Panic... draw the water + for (int i = 0; i < LUMBERJACK_MAP_WIDTH; i++) + { + drawWsgSimple(&lumv->animationTiles[lumv->liquidAnimationFrame], i * LUMBERJACK_TILE_SIZE, lumv->waterLevel - lumv->yOffset); + } + + fillDisplayArea(0, lumv->waterLevel + 16 - lumv->yOffset, TFT_WIDTH, ((lumv->currentMapHeight+1) * LUMBERJACK_TILE_SIZE)- lumv->yOffset , c134); + } + void lumberjackDoControls(void) { lumv->localPlayer->cW = 15; @@ -871,14 +2491,14 @@ void lumberjackDoControls(void) if (lumv->btnState & PB_LEFT) { lumv->localPlayer->flipped = true; - lumv->localPlayer->state = 2; + lumv->localPlayer->state = LUMBERJACK_RUN; lumv->localPlayer->direction = -1; buttonPressed = true; } else if (lumv->btnState & PB_RIGHT) { lumv->localPlayer->flipped = false; - lumv->localPlayer->state = 2; + lumv->localPlayer->state = LUMBERJACK_RUN; lumv->localPlayer->direction = 1; buttonPressed = true; @@ -904,7 +2524,6 @@ void lumberjackDoControls(void) buttonPressed = true; } - // TODO: This is sloppy Troy if (lumv->btnState & PB_A) { lumv->localPlayer->jumpPressed = true; @@ -914,7 +2533,6 @@ void lumberjackDoControls(void) lumv->localPlayer->jumpPressed = false; } - // TODO: This is sloppy too Troy if (lumv->btnState & PB_B) { lumv->localPlayer->attackPressed = true; @@ -926,7 +2544,7 @@ void lumberjackDoControls(void) if (buttonPressed == false && lumv->localPlayer->active) { - lumv->localPlayer->state = 1; // Do a ton of other checks here + lumv->localPlayer->state = LUMBERJACK_IDLE; // Do a ton of other checks here } if (lumv->localPlayer->state != previousState) @@ -938,8 +2556,8 @@ void lumberjackDoControls(void) static lumberjackTile_t* lumberjackGetTile(int x, int y) { - int tx = (int)x / 16; - int ty = (int)y / 16; + int tx = (int)x / LUMBERJACK_TILE_SIZE; + int ty = (int)y / LUMBERJACK_TILE_SIZE; if (tx < 0) tx = 17; @@ -947,46 +2565,31 @@ static lumberjackTile_t* lumberjackGetTile(int x, int y) tx = 0; if (ty < 0) - ty = 0; - if (ty > lumv->currentMapHeight) - ty = lumv->currentMapHeight; - - // int test = -1; - for (int colTileIndex = 0; colTileIndex < 32; colTileIndex++) { - if (lumberjackCollisionCheckTiles[colTileIndex].type == -1) - { - if (lumberjackCollisionCheckTiles[colTileIndex].index == (ty * 18) + tx) - return &lumberjackCollisionCheckTiles[colTileIndex]; - - lumberjackCollisionCheckTiles[colTileIndex].index = (ty * 18) + tx; - lumberjackCollisionCheckTiles[colTileIndex].x = tx; - lumberjackCollisionCheckTiles[colTileIndex].y = ty; - lumberjackCollisionCheckTiles[colTileIndex].type = lumv->tile[(ty * 18) + tx].type; - - return &lumberjackCollisionCheckTiles[colTileIndex]; - } - // test = i; + return NULL; } + if (ty >= lumv->currentMapHeight) + { + return NULL; + } + + return &lumv->tile[(ty * LUMBERJACK_MAP_WIDTH) + tx]; - // ESP_LOGI(LUM_TAG,"NO TILE at %d %d!", test, ty); - return NULL; } static bool lumberjackIsCollisionTile(int index) { - if (index == 0 || index == 1 || index == 6 || index == 5 || index == 10) + if (index == 0 || index == 1 || index == 6 || index == 5 || index == 10 || index == 13) return false; + + return true; } -void lumberjackDetectBump(lumberjackTile_t* tile) +bool lumberjackDetectBump(lumberjackTile_t* tile) { - if (lumv->localPlayer->state != LUMBERJACK_BUMPED && lumv->localPlayer->state != LUMBERJACK_DEAD) - { - // TODO put in bump the player - } + bool bump = false; for (int enemyIndex = 0; enemyIndex < ARRAY_SIZE(lumv->enemy); enemyIndex++) { @@ -996,9 +2599,9 @@ void lumberjackDetectBump(lumberjackTile_t* tile) if (enemy->onGround || enemy->flying) { - int tx = ((enemy->x - 8) / 16); - int ty = ((enemy->y) / 16) + 1; - int tx2 = ((enemy->x + 8) / 16); + int tx = ((enemy->x - 8) / LUMBERJACK_TILE_SIZE); + int ty = ((enemy->y) / LUMBERJACK_TILE_SIZE) + 1; + int tx2 = ((enemy->x + 8) / LUMBERJACK_TILE_SIZE); if (tx < 0) tx = 0; @@ -1013,39 +2616,267 @@ void lumberjackDetectBump(lumberjackTile_t* tile) if (ty > lumv->currentMapHeight) ty = lumv->currentMapHeight; - lumberjackTile_t* tileA = &lumv->tile[(ty * 18) + tx]; - lumberjackTile_t* tileB = &lumv->tile[(ty * 18) + tx2]; + lumberjackTile_t* tileA = &lumv->tile[(ty * LUMBERJACK_MAP_WIDTH) + tx]; + lumberjackTile_t* tileB = &lumv->tile[(ty * LUMBERJACK_MAP_WIDTH) + tx2]; - if ((tileA != NULL && (ty * 18) + tx == tile->index) || (tileB != NULL && (ty * 18) + tx2 == tile->index)) + if ((tileA != NULL && (ty * LUMBERJACK_MAP_WIDTH) + tx == tile->index) || (tileB != NULL && (ty * LUMBERJACK_MAP_WIDTH) + tx2 == tile->index)) { enemy->vy = -20; enemy->onGround = false; - + bump = true; if (enemy->state == LUMBERJACK_BUMPED_IDLE) { enemy->state = LUMBERJACK_RUN; - enemy->direction = enemy->flipped ? -1 : 1; + enemy->direction = enemy->flipped ? 1 : -1; // Go opposite direction + enemy->flipped = !enemy->flipped; } else { enemy->direction = 0; enemy->state = LUMBERJACK_BUMPED; + + if (enemy->type == 4) + { + lumberjackUpdateEnemy(enemy, enemy->type + 1); + enemy->state = LUMBERJACK_RUN; + enemy->direction = enemy->flipped ? 1 : -1; // Go opposite direction + enemy->flipped = !enemy->flipped; + } } } } } + + return bump; +} + +void lumberjackUseBlock() +{ + lumv->itemBlockReady = false; + + if (lumv->gameType == LUMBERJACK_MODE_PANIC) + { + bzrPlaySfx(&lumv->sfx_item_use, BZR_RIGHT); + + + lumv->waterDirection = LUMBERJACK_WATER_FAST_DRAIN; + lumv->waterTimer = lumv->waterSpeed; + lumv->waterLevel += lumv->waterDirection; + + lumv->itemBlockTime = LUMBERJACK_ITEM_RESETTIME; + + if (lumv->lumberjackMain->networked) + { + //Increase speed of opponent's water! + lumberjackSendAttack(lumv->attackQueue); + + for (int i = 0; i < ARRAY_SIZE(lumv->attackQueue); i++) + { + lumv->attackQueue[i] = 0; + } + } + } + + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + lumv->itemBlockIndex = esp_random() % 3; + lumv->itemBlockTime = LUMBERJACK_ITEM_RESETTIME; + + if (lumv->itemBlockIndex == 0) + { + + } + else if (lumv->itemBlockIndex == 1) + { + + } + else { + + } + + } +} + +/// CODE ++ + +/** + * @brief Draw solid color of a WSG to the display + * + * @param wsg The WSG to draw to the display + * @param xOff The x offset to draw the WSG at + * @param yOff The y offset to draw the WSG at + * @param flipLR true to flip the image across the Y axis + * @param flipUD true to flip the image across the X axis + * @param color The color we're sending instead + */ +void drawSolidWsg(const wsg_t* wsg, int16_t xOff, int16_t yOff, bool flipLR, bool flipUD, uint8_t inColor) +{ + + if (NULL == wsg->px) + { + return; + } + + // Draw the image's pixels (no rotation or transformation) + uint32_t w = TFT_WIDTH; + paletteColor_t* px = getPxTftFramebuffer(); + + uint16_t wsgw = wsg->w; + uint16_t wsgh = wsg->h; + + int32_t xstart = 0; + int16_t xend = wsgw; + int32_t xinc = 1; + + // Reflect over Y axis? + if (flipLR) + { + xstart = wsgw - 1; + xend = -1; + xinc = -1; + } + + if (xOff < 0) + { + if (xinc > 0) + { + xstart -= xOff; + if (xstart >= xend) + { + return; + } + } + else + { + xstart += xOff; + if (xend >= xstart) + { + return; + } + } + xOff = 0; + } + + if (xOff + wsgw > w) + { + int32_t peelBack = (xOff + wsgw) - w; + if (xinc > 0) + { + xend -= peelBack; + if (xstart >= xend) + { + return; + } + } + else + { + xend += peelBack; + if (xend >= xstart) + { + return; + } + } + } + + for (int16_t srcY = 0; srcY < wsgh; srcY++) + { + int32_t usey = srcY; + + // Reflect over X axis? + if (flipUD) + { + usey = wsgh - 1 - usey; + } + + const paletteColor_t* linein = &wsg->px[usey * wsgw]; + + // Transform this pixel's draw location as necessary + uint32_t dstY = srcY + yOff; + + // It is too complicated to detect both directions and backoff correctly, so we just do this here. + // It does slow things down a "tiny" bit. People in the future could optimze out this check. + if (dstY >= TFT_HEIGHT) + { + continue; + } + + int32_t lineOffset = dstY * w; + int32_t dstx = xOff + lineOffset; + + for (int32_t srcX = xstart; srcX != xend; srcX += xinc) + { + // Draw if not transparent + uint8_t color = linein[srcX]; + if (cTransparent != color) + { + px[dstx] = inColor; + } + dstx++; + } + } + } + + + /// /// void lumberjackExitGameMode(void) { + bzrStop(true); + // Everything crashes if you don't load it first if (lumv == NULL) return; + + if (lumv->lumberjackMain->networked == false) + { + + if (lumv->gameType == LUMBERJACK_MODE_ATTACK) + { + lumv->lumberjackMain->save.attackHighScore = lumv->highscore; + } + + if (lumv->gameType == LUMBERJACK_MODE_PANIC) + { + lumv->lumberjackMain->save.panicHighScore = lumv->highscore; + } + lumberjackSaveSave(); + } //** FREE THE SPRITES **// + + freeWsg(&lumv->gameoverSprite); + + if (lumv->lumberjackMain->networked) + { + freeWsg(&lumv->gamewinSprite); + freeWsg(&lumv->connectLostSprite); + + } + + freeSong(&lumv->sfx_item_use); + freeSong(&lumv->sfx_item_get); + freeSong(&lumv->sfx_jump); + freeSong(&lumv->sfx_bump); + freeSong(&lumv->sfx_flip); + freeSong(&lumv->sfx_player_death); + freeSong(&lumv->sfx_enemy_death); + + freeSong(&lumv->song_theme); + freeSong(&lumv->song_title); + freeSong(&lumv->song_respawn); + freeSong(&lumv->song_gameover); + + + // Free the bonus + for (int i = 0; i < ARRAY_SIZE(lumv->bonusDisplay); i++) + { + free(lumv->bonusDisplay[i]); + } + // Free the enemies for (int i = 0; i < ARRAY_SIZE(lumv->enemySprites); i++) { @@ -1064,8 +2895,62 @@ void lumberjackExitGameMode(void) freeWsg(&lumv->animationTiles[i]); } + //Free the axes + for (int i = 0; i < ARRAY_SIZE(lumv->greenBlockSprite); i++) + { + freeWsg(&lumv->greenBlockSprite[i]); + } + + //Free the axes + for (int i = 0; i < ARRAY_SIZE(lumv->redBlockSprite); i++) + { + freeWsg(&lumv->redBlockSprite[i]); + } + + //Free the axes + for (int i = 0; i < ARRAY_SIZE(lumv->unusedBlockSprite); i++) + { + freeWsg(&lumv->unusedBlockSprite[i]); + } + freeWsg(&lumv->alertSprite); - freeFont(&lumv->ibm); + for (int i = 0; i < ARRAY_SIZE(lumv->axeBlocks); i++) + { + free(lumv->axeBlocks[i]); + } + + for (int i = 0; i < ARRAY_SIZE(lumv->itemIcons); i++) + { + freeWsg(&lumv->itemIcons[i]); + } + + for (int i = 0; i < ARRAY_SIZE(lumv->floorTiles); i++) + { + freeWsg(&lumv->floorTiles[i]); + } + + for (int i = 0; i < ARRAY_SIZE(lumv->bonusSprites); i++) + { + freeWsg(&lumv->bonusSprites[i]); + } + + for (int i = 0; i < ARRAY_SIZE(lumv->minicharacters); i++) + { + freeWsg(&lumv->minicharacters[i]); + } + + for (int i = 0; i < ARRAY_SIZE(lumv->ui); i++) + { + freeWsg(&lumv->ui[i]); + } + + freeWsg(&lumv->title); + freeWsg(&lumv->subtitle_red); + freeWsg(&lumv->subtitle_green); + freeWsg(&lumv->subtitle_white); + + freeFont(&lumv->arcade); free(lumv); -} + lumv = NULL; +} \ No newline at end of file diff --git a/main/modes/lumberjack/lumberjackGame.h b/main/modes/lumberjack/lumberjackGame.h index f5646a930..f57f5a7aa 100644 --- a/main/modes/lumberjack/lumberjackGame.h +++ b/main/modes/lumberjack/lumberjackGame.h @@ -3,25 +3,56 @@ void lumberjackStartGameMode(lumberjack_t* main, uint8_t characterIndex); -// void lumberjackStartGameMode(lumberjackGameType_t type, uint8_t characterIndex); void lumberjackExitGameMode(void); void lumberjackSetupLevel(int index); +void lumberjackUnloadLevel(void); void lumberjackDoControls(void); void lumberjackTileMap(void); +void lumberjackDrawWaterLevel(void); void lumberjackUpdate(int64_t elapseUs); + +void lumberjackInitp2p(void); +void lumberjackTitleLoop(int64_t elapsedUs); void lumberjackGameLoop(int64_t elapsedUs); -void lumberjackUpdateLocation(int ghostX, int ghostY, int frame); -void lumberjackUpdateRemote(int remoteX, int remoteY, int remoteFrame); void restartLevel(void); void lumberjackGameDebugLoop(int64_t elapsedUs); -void lumberjackDetectBump(lumberjackTile_t* tile); -void lumberjackSpawnCheck(int64_t elapseUs); +bool lumberjackDetectBump(lumberjackTile_t* tile); +bool lumberjackSpawnCheck(int64_t elapseUs); +void lumberjackAttackCheck(int64_t elapseUs); + +void lumberjackScoreDisplay(int score, int locationX); +void lumberjackTitleDisplayText(const char* string, int locationX, int locationY); void baseMode(int64_t elapsedUs); -void lumberjackSendAttack(int number); + +void lumberjackQualityCheck(void); + +void lumberjackSendAttack(uint8_t* number); +void lumberjackSendScore(int score); +void lumberjackSendCharacter(uint8_t character); +void lumberjackSendDeath(uint8_t lives); +void lumberjackSendBump(void); + +void lumberjackOnReceiveAttack(const uint8_t* attack, int len); +void lumberjackOnReceiveScore(const uint8_t* score); +void lumberjackOnReceiveCharacter(uint8_t character); +void lumberjackOnReceiveDeath(uint8_t lives); +void lumberjackOnReceiveBump(void); + +void lumberjackGameReady(void); +void lumberjackPlayGame(void); +void lumberjackSendGo(void); +void lumberjackSendHostRequest(void); + +void drawSolidWsg(const wsg_t* wsg, int16_t xOff, int16_t yOff, bool flipLR, bool flipUD, uint8_t inColor); + + +void lumberjackUseBlock(void); +void lumberjackSaveSave(void); + #endif \ No newline at end of file diff --git a/main/modes/lumberjack/lumberjackPlayer.c b/main/modes/lumberjack/lumberjackPlayer.c index 08b90b529..0997a6432 100644 --- a/main/modes/lumberjack/lumberjackPlayer.c +++ b/main/modes/lumberjack/lumberjackPlayer.c @@ -6,7 +6,6 @@ #include #define LUMBERJACK_DEFAULT_ANIMATION_SPEED 150000 -#define LUMBERJACK_SPAWN_Y 270 #define LUMBERJACK_HERO_WIDTH 24 #define LUMBERJACK_HERO_HEIGHT 31 #define LUMBERJACK_HERO_DUCK_HEIGHT 31 @@ -25,24 +24,12 @@ void lumberjackSetupPlayer(lumberjackEntity_t* hero, int character) hero->type = character; hero->state = LUMBERJACK_UNSPAWNED; - if (character == 0) - { - hero->spriteOffset = 0; - } - else if (character == 1) - { - hero->spriteOffset = 17; - } - else - { - hero->spriteOffset = 34; - } } void lumberjackSpawnPlayer(lumberjackEntity_t* hero, int x, int y, int facing) { hero->x = x; - hero->y = LUMBERJACK_SPAWN_Y; + hero->y = y; hero->vx = 0; hero->maxVX = 15; hero->vy = 0; @@ -55,11 +42,11 @@ void lumberjackSpawnPlayer(lumberjackEntity_t* hero, int x, int y, int facing) hero->respawn = 0; } -void lumberjackRespawn(lumberjackEntity_t* hero) +void lumberjackRespawn(lumberjackEntity_t* hero, int x, int y) { - hero->x = 130; + hero->x = x; hero->maxVX = 15; - hero->y = LUMBERJACK_SPAWN_Y; + hero->y = y; hero->active = true; hero->ready = false; hero->vx = 0; @@ -69,11 +56,12 @@ void lumberjackRespawn(lumberjackEntity_t* hero) hero->timerFrameUpdate = 0; hero->onGround = true; hero->maxLevel = 0; + hero->submergedTimer = 5000; + } int lumberjackGetPlayerAnimation(lumberjackEntity_t* hero) { - // int animationNone[] = {0}; int animation = hero->state; hero->animationSpeed = LUMBERJACK_DEFAULT_ANIMATION_SPEED; @@ -120,12 +108,6 @@ int lumberjackGetPlayerAnimation(lumberjackEntity_t* hero) hero->animationSpeed = LUMBERJACK_DEFAULT_ANIMATION_SPEED; return animationVictory[hero->currentFrame % ARRAY_SIZE(animationVictory)]; } - if (animation == LUMBERJACK_CLIMB) - { - const int animationClimb[] = {17, 18, 19, 20}; - hero->animationSpeed = LUMBERJACK_DEFAULT_ANIMATION_SPEED; - return animationClimb[hero->currentFrame % ARRAY_SIZE(animationClimb)]; - } return 0; } \ No newline at end of file diff --git a/main/modes/lumberjack/lumberjackPlayer.h b/main/modes/lumberjack/lumberjackPlayer.h index dff11ff6c..ba1dbc9c5 100644 --- a/main/modes/lumberjack/lumberjackPlayer.h +++ b/main/modes/lumberjack/lumberjackPlayer.h @@ -4,8 +4,8 @@ #include "lumberjack_types.h" void lumberjackSpawnPlayer(lumberjackEntity_t* hero, int x, int y, int facing); -void lumberjackRespawn(lumberjackEntity_t* hero); +void lumberjackRespawn(lumberjackEntity_t* hero, int x, int y); int lumberjackGetPlayerAnimation(lumberjackEntity_t* hero); void lumberjackSetupPlayer(lumberjackEntity_t* hero, int character); -#endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/main/modes/lumberjack/lumberjack_types.h b/main/modes/lumberjack/lumberjack_types.h index 03453915e..af74771dc 100644 --- a/main/modes/lumberjack/lumberjack_types.h +++ b/main/modes/lumberjack/lumberjack_types.h @@ -13,7 +13,7 @@ enum lumberjackPlayerState LUMBERJACK_FALLING = 6, LUMBERJACK_OFFSCREEN = 7, // reserved for enemies only LUMBERJACK_BUMPED = 8, - LUMBERJACK_BUMPED_IDLE = 9 + LUMBERJACK_BUMPED_IDLE = 9, }; // Animation speeds diff --git a/main/modes/mainMenu/mainMenu.c b/main/modes/mainMenu/mainMenu.c index 9f53f49a8..f731cf735 100644 --- a/main/modes/mainMenu/mainMenu.c +++ b/main/modes/mainMenu/mainMenu.c @@ -349,7 +349,7 @@ static void mainMenuCb(const char* label, bool selected, uint32_t settingVal) } else if (label == sokoMode.modeName) { - switchToSwadgeMode(&sokoMode); + switchToSwadgeMode(&demoMode); } else if (label == touchTestMode.modeName) { diff --git a/main/swadge2024.c b/main/swadge2024.c index 61bfb783a..99d691168 100644 --- a/main/swadge2024.c +++ b/main/swadge2024.c @@ -190,6 +190,7 @@ static void swadgeModeEspNowRecvCb(const esp_now_recv_info_t* esp_now_info, cons int8_t rssi); static void swadgeModeEspNowSendCb(const uint8_t* mac_addr, esp_now_send_status_t status); static void setSwadgeMode(void* swadgeMode); +static void initOptionalPeripherals(void); //============================================================================== // Functions @@ -267,17 +268,6 @@ void app_main(void) initBuzzer(GPIO_NUM_40, LEDC_TIMER_0, LEDC_CHANNEL_0, // GPIO_NUM_42, LEDC_TIMER_1, LEDC_CHANNEL_1, getBgmVolumeSetting(), getSfxVolumeSetting()); - // Init mic if it is used by the mode - if (NULL != cSwadgeMode->fnAudioCallback) - { - initMic(GPIO_NUM_7); - startMic(); - } - else - { - initBattmon(GPIO_NUM_6); - } - // Init TFT, use a different LEDC channel than buzzer initTFT(SPI2_HOST, GPIO_NUM_36, // sclk @@ -294,27 +284,8 @@ void app_main(void) // Initialize the RGB LEDs initLeds(GPIO_NUM_39, GPIO_NUM_18, getLedBrightnessSetting()); - // Init esp-now if requested by the mode - if ((ESP_NOW == cSwadgeMode->wifiMode) || (ESP_NOW_IMMEDIATE == cSwadgeMode->wifiMode)) - { - initEspNow(&swadgeModeEspNowRecvCb, &swadgeModeEspNowSendCb, GPIO_NUM_NC, GPIO_NUM_NC, UART_NUM_MAX, - cSwadgeMode->wifiMode); - } - - // Init accelerometer - if (cSwadgeMode->usesAccelerometer) - { - initAccelerometer(GPIO_NUM_3, // SDA - GPIO_NUM_41, // SCL - GPIO_PULLUP_ENABLE); - accelIntegrate(); - } - - // Init the temperature sensor - if (cSwadgeMode->usesThermometer) - { - initTemperatureSensor(); - } + // Initialize optional peripherals, depending on the mode's requests + initOptionalPeripherals(); // Initialize the loop timer static int64_t tLastLoopUs = 0; @@ -472,6 +443,45 @@ void app_main(void) deinitSystem(); } +/** + * @brief Initialize optional hardware peripherals for this Swadge mode + */ +static void initOptionalPeripherals(void) +{ + // Init mic if it is used by the mode + if (NULL != cSwadgeMode->fnAudioCallback) + { + initMic(GPIO_NUM_7); + startMic(); + } + else + { + initBattmon(GPIO_NUM_6); + } + + // Init esp-now if requested by the mode + if ((ESP_NOW == cSwadgeMode->wifiMode) || (ESP_NOW_IMMEDIATE == cSwadgeMode->wifiMode)) + { + initEspNow(&swadgeModeEspNowRecvCb, &swadgeModeEspNowSendCb, GPIO_NUM_NC, GPIO_NUM_NC, UART_NUM_MAX, + cSwadgeMode->wifiMode); + } + + // Init accelerometer + if (cSwadgeMode->usesAccelerometer) + { + initAccelerometer(GPIO_NUM_3, // SDA + GPIO_NUM_41, // SCL + GPIO_PULLUP_ENABLE); + accelIntegrate(); + } + + // Init the temperature sensor + if (cSwadgeMode->usesThermometer) + { + initTemperatureSensor(); + } +} + /** * @brief Deinitialize all components in the system */ @@ -590,11 +600,8 @@ void softSwitchToPendingSwadge(void) cSwadgeMode = pendingSwadgeMode; pendingSwadgeMode = NULL; - // Start mic if requested - if (NULL != cSwadgeMode->fnAudioCallback) - { - startMic(); - } + // Initialize optional peripherals for this mode + initOptionalPeripherals(); // Enter the next mode if (NULL != cSwadgeMode->fnEnterMode) diff --git a/main/utils/p2pConnection.c b/main/utils/p2pConnection.c index a797f482b..53e2d1c4d 100644 --- a/main/utils/p2pConnection.c +++ b/main/utils/p2pConnection.c @@ -26,6 +26,14 @@ // (240 steps of rotation + (252/4) steps of decay) * 12ms #define FAILURE_RESTART_US 8000000 +// #define P2P_DEBUG +#ifdef P2P_DEBUG + static const char* P2P_TAG = "P2P"; + #define P2P_LOG(...) ESP_LOGI(P2P_TAG, ##__VA_ARGS__) +#else + #define P2P_LOG(...) +#endif + //============================================================================== // Function Prototypes //============================================================================== @@ -63,7 +71,7 @@ static void p2pModeMsgFailure(p2pInfo* p2p); */ void p2pInitialize(p2pInfo* p2p, uint8_t modeId, p2pConCbFn conCbFn, p2pMsgRxCbFn msgRxCbFn, int8_t connectionRssi) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); // Make sure everything is zero! memset(p2p, 0, sizeof(p2pInfo)); @@ -166,7 +174,7 @@ void p2pSetAsymmetric(p2pInfo* p2p, uint8_t incomingModeId) */ void p2pStartConnection(p2pInfo* p2p) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); p2p->cnc.isActive = true; esp_timer_start_once(p2p->tmr.Connection, 1000); @@ -184,7 +192,7 @@ void p2pStartConnection(p2pInfo* p2p) */ void p2pDeinit(p2pInfo* p2p) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); if (NULL != p2p->tmr.Connection) { @@ -206,7 +214,7 @@ void p2pDeinit(p2pInfo* p2p) */ static void p2pConnectionTimeout(void* arg) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); p2pInfo* p2p = (p2pInfo*)arg; // Send a connection broadcast @@ -216,7 +224,7 @@ static void p2pConnectionTimeout(void* arg) uint32_t timeoutUs = 1000 * (100 * (5 + (esp_random() % 11))); // Start the timer again - // ESP_LOGD("P2P", "retry broadcast in %dus", timeoutUs); + P2P_LOG("retry broadcast in %"PRIu32"us", timeoutUs); esp_timer_start_once(p2p->tmr.Connection, timeoutUs); } @@ -230,13 +238,13 @@ static void p2pConnectionTimeout(void* arg) */ static void p2pTxRetryTimeout(void* arg) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); p2pInfo* p2p = (p2pInfo*)arg; if (p2p->ack.msgToAckLen > 0) { - // ESP_LOGD("P2P", "Retrying message"); + P2P_LOG("Retrying message"); p2pSendMsgEx(p2p, (uint8_t*)&p2p->ack.msgToAck, p2p->ack.msgToAckLen, true, p2p->ack.SuccessFn, p2p->ack.FailureFn); } @@ -253,7 +261,7 @@ static void p2pTxRetryTimeout(void* arg) */ static void p2pTxAllRetriesTimeout(void* arg) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); p2pInfo* p2p = (p2pInfo*)arg; @@ -262,7 +270,7 @@ static void p2pTxAllRetriesTimeout(void* arg) esp_timer_stop(p2p->tmr.TxAllRetries); // Call the failure function - // ESP_LOGD("P2P", "Message totally failed"); + P2P_LOG("Message totally failed"); if (NULL != p2p->ack.FailureFn) { p2p->ack.FailureFn(p2p); @@ -284,7 +292,7 @@ static void p2pTxAllRetriesTimeout(void* arg) */ void p2pSendMsg(p2pInfo* p2p, const uint8_t* payload, uint16_t len, p2pMsgTxCbFn msgTxCbFn) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); p2pDataMsg_t builtMsg = {0}; uint8_t builtMsgLen = sizeof(p2pCommonHeader_t); @@ -318,7 +326,7 @@ void p2pSendMsg(p2pInfo* p2p, const uint8_t* payload, uint16_t len, p2pMsgTxCbFn */ static void p2pModeMsgSuccess(p2pInfo* p2p, const uint8_t* data, uint8_t dataLen) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); if (NULL != p2p->msgTxCbFn) { @@ -334,7 +342,7 @@ static void p2pModeMsgSuccess(p2pInfo* p2p, const uint8_t* data, uint8_t dataLen */ static void p2pModeMsgFailure(p2pInfo* p2p) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); if (NULL != p2p->msgTxCbFn) { @@ -356,15 +364,17 @@ static void p2pModeMsgFailure(p2pInfo* p2p) static void p2pSendMsgEx(p2pInfo* p2p, uint8_t* msg, uint16_t len, bool shouldAck, p2pAckSuccessFn success, p2pAckFailureFn failure) { - // char dbgStr[12 + 2 + 2 + (len*3)]; - // sprintf(dbgStr, "%12s: ", __func__); - // for(int i = 0; i < len; i++) - // { - // char tmp[8]; - // sprintf(tmp, "%02X ", msg[i]); - // strcat(dbgStr, tmp); - // } - // ESP_LOGD("P2P", "%s", dbgStr); +#ifdef P2P_DEBUG + char dbgStr[12 + 2 + 2 + (len*3)]; + sprintf(dbgStr, "%12s: ", __func__); + for(int i = 0; i < len; i++) + { + char tmp[8]; + sprintf(tmp, "%02X ", msg[i]); + strcat(dbgStr, tmp); + } + P2P_LOG("%s", dbgStr); +#endif // If this is a first time message and longer than a connection message if (((void*)&(p2p->ack.msgToAck) != (void*)msg) && sizeof(p2pConMsg_t) < len) @@ -384,7 +394,7 @@ static void p2pSendMsgEx(p2pInfo* p2p, uint8_t* msg, uint16_t len, bool shouldAc // If this is not a retry if ((void*)&(p2p->ack.msgToAck) != (void*)msg) { - // ESP_LOGD("P2P", "sending for the first time"); + P2P_LOG("sending for the first time"); // Store the message for potential retries memcpy(&(p2p->ack.msgToAck), msg, len); @@ -398,7 +408,7 @@ static void p2pSendMsgEx(p2pInfo* p2p, uint8_t* msg, uint16_t len, bool shouldAc } else { - // ESP_LOGD("P2P", "this is a retry"); + P2P_LOG("this is a retry"); } // Mark the time this transmission started, the retry timer gets @@ -425,28 +435,30 @@ void p2pRecvCb(p2pInfo* p2p, const uint8_t* mac_addr, const uint8_t* data, uint8 return; } - // char dbgStr[12 + 3 + 5 + 17 + (len*3)]; - // sprintf(dbgStr, "%12s - From %02X:%02X:%02X:%02X:%02X:%02X - ", __func__, - // mac_addr[0], - // mac_addr[1], - // mac_addr[2], - // mac_addr[3], - // mac_addr[4], - // mac_addr[5]); - // for(int i = 0; i < len; i++) - // { - // char tmp[8]; - // sprintf(tmp, "%02X ", data[i]); - // strcat(dbgStr, tmp); - // } - // ESP_LOGD("P2P", "%s", dbgStr); +#ifdef P2P_DEBUG + char dbgStr[64 + (len*3)]; + sprintf(dbgStr, "%12s - From %02X:%02X:%02X:%02X:%02X:%02X - ", __func__, + mac_addr[0], + mac_addr[1], + mac_addr[2], + mac_addr[3], + mac_addr[4], + mac_addr[5]); + for(int i = 0; i < len; i++) + { + char tmp[8]; + sprintf(tmp, "%02X ", data[i]); + strcat(dbgStr, tmp); + } + P2P_LOG("%s", dbgStr); +#endif // Check if this message matches our message ID if (len < sizeof(p2pConMsg_t) || ((const p2pConMsg_t*)data)->startByte != P2P_START_BYTE || ((const p2pConMsg_t*)data)->modeId != p2p->incomingModeId) { // This message is too short, or does not match our message ID - // ESP_LOGD("P2P", "DISCARD: Not a message for '%c'", p2p->modeId); + P2P_LOG("DISCARD: Not a message for '%c'", p2p->modeId); return; } @@ -456,17 +468,19 @@ void p2pRecvCb(p2pInfo* p2p, const uint8_t* mac_addr, const uint8_t* data, uint8 // If this message has a MAC, check it if (len >= sizeof(p2pCommonHeader_t) && 0 != memcmp(p2pHdr->macAddr, p2p->cnc.myMac, sizeof(p2p->cnc.myMac))) { +#ifdef P2P_DEBUG // This MAC isn't for us - // ESP_LOGD("P2P", "DISCARD: Not for our MAC."); - // ESP_LOGD("P2P", " Our MAC: %02X:%02X:%02X:%02X:%02X:%02X", - // p2p->cnc.myMac[0], p2p->cnc.myMac[1], - // p2p->cnc.myMac[2], p2p->cnc.myMac[3], - // p2p->cnc.myMac[4], p2p->cnc.myMac[5]); - // const p2pCommonHeader_t* hdr = (const p2pCommonHeader_t*)data; - // ESP_LOGD("P2P", " rx MAC: %02X:%02X:%02X:%02X:%02X:%02X", - // hdr->macAddr[0], hdr->macAddr[1], - // hdr->macAddr[2], hdr->macAddr[3], - // hdr->macAddr[4], hdr->macAddr[5]); + P2P_LOG("DISCARD: Not for our MAC."); + P2P_LOG(" Our MAC: %02X:%02X:%02X:%02X:%02X:%02X", + p2p->cnc.myMac[0], p2p->cnc.myMac[1], + p2p->cnc.myMac[2], p2p->cnc.myMac[3], + p2p->cnc.myMac[4], p2p->cnc.myMac[5]); + const p2pCommonHeader_t* hdr = (const p2pCommonHeader_t*)data; + P2P_LOG(" rx MAC: %02X:%02X:%02X:%02X:%02X:%02X", + hdr->macAddr[0], hdr->macAddr[1], + hdr->macAddr[2], hdr->macAddr[3], + hdr->macAddr[4], hdr->macAddr[5]); +#endif return; } @@ -475,7 +489,7 @@ void p2pRecvCb(p2pInfo* p2p, const uint8_t* mac_addr, const uint8_t* data, uint8 && 0 != memcmp(mac_addr, p2p->cnc.otherMac, sizeof(p2p->cnc.otherMac))) { // This isn't from the other known swadge - // ESP_LOGD("P2P", "DISCARD: Not from the other MAC"); + P2P_LOG("DISCARD: Not from the other MAC"); return; } @@ -494,13 +508,13 @@ void p2pRecvCb(p2pInfo* p2p, const uint8_t* mac_addr, const uint8_t* data, uint8 // Check it against the last known sequence number if (p2pHdr->seqNum == p2p->cnc.lastSeqNum) { - // ESP_LOGD("P2P", "DISCARD: Duplicate sequence number"); + P2P_LOG("DISCARD: Duplicate sequence number"); return; } else { p2p->cnc.lastSeqNum = p2pHdr->seqNum; - // ESP_LOGD("P2P", "Store lastSeqNum %d", p2p->cnc.lastSeqNum); + P2P_LOG("Store lastSeqNum %"PRIu8, p2p->cnc.lastSeqNum); } } @@ -510,7 +524,7 @@ void p2pRecvCb(p2pInfo* p2p, const uint8_t* mac_addr, const uint8_t* data, uint8 // ACKs can be received in any state if (p2p->ack.isWaitingForAck && isAck) { - // ESP_LOGD("P2P", "ACK Received when waiting for one"); + P2P_LOG("ACK Received when waiting for one"); // Save the function pointer to call it after clearing ACK vars p2pAckSuccessFn tmpSuccessFn = p2p->ack.SuccessFn; @@ -574,7 +588,7 @@ void p2pRecvCb(p2pInfo* p2p, const uint8_t* mac_addr, const uint8_t* data, uint8 // Received a response to our broadcast else if (!p2p->cnc.rxGameStartMsg && sizeof(p2p->startMsg) == len && p2pHdr->messageType == P2P_MSG_START) { - // ESP_LOGD("P2P", "Game start message received, ACKing"); + P2P_LOG("Game start message received, ACKing"); // This is another swadge trying to start a game, which means // they received our p2p->conMsg. First disable our p2p->conMsg @@ -587,11 +601,11 @@ void p2pRecvCb(p2pInfo* p2p, const uint8_t* mac_addr, const uint8_t* data, uint8 } else if (len >= sizeof(p2pCommonHeader_t)) { - // ESP_LOGD("P2P", "cnc.isconnected is true"); + P2P_LOG("cnc.isconnected is true"); // Let the mode handle it if (NULL != p2p->msgRxCbFn) { - // ESP_LOGD("P2P", "letting mode handle message"); + P2P_LOG("letting mode handle message"); // Call the callback p2p->msgRxCbFn(p2p, ((const p2pDataMsg_t*)data)->data, len - sizeof(p2pCommonHeader_t)); @@ -647,7 +661,7 @@ void p2pClearDataInAck(p2pInfo* p2p) */ static void p2pSendAckToMac(p2pInfo* p2p, const uint8_t* mac_addr) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); // Write the destination MAC address // Everything else should already be written @@ -665,7 +679,7 @@ static void p2pSendAckToMac(p2pInfo* p2p, const uint8_t* mac_addr) */ static void p2pGameStartAckRecv(p2pInfo* p2p, const uint8_t* data, uint8_t dataLen) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); p2pProcConnectionEvt(p2p, RX_GAME_START_ACK); } @@ -683,8 +697,8 @@ static void p2pGameStartAckRecv(p2pInfo* p2p, const uint8_t* data, uint8_t dataL */ static void p2pProcConnectionEvt(p2pInfo* p2p, connectionEvt_t event) { - // ESP_LOGD("P2P", "%s evt: %d, p2p->cnc.rxGameStartMsg %d, p2p->cnc.rxGameStartAck %d", __func__, event, - // p2p->cnc.rxGameStartMsg, p2p->cnc.rxGameStartAck); + P2P_LOG("%s evt: %"PRId16", p2p->cnc.rxGameStartMsg %s, p2p->cnc.rxGameStartAck %s", __func__, event, + p2p->cnc.rxGameStartMsg ? "true" : "false", p2p->cnc.rxGameStartAck ? "true" : "false"); switch (event) { @@ -755,7 +769,7 @@ static void p2pProcConnectionEvt(p2pInfo* p2p, connectionEvt_t event) */ static void p2pStartRestartTimer(void* arg) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); p2pInfo* p2p = (p2pInfo*)arg; // If the connection isn't established in FAILURE_RESTART_MS, restart @@ -781,7 +795,7 @@ static void p2pRestartTmrCb(void* arg) */ static void p2pRestart(p2pInfo* p2p) { - // ESP_LOGD("P2P", "%s", __func__); + P2P_LOG("%s", __func__); if (NULL != p2p->conCbFn) { @@ -813,8 +827,8 @@ static void p2pRestart(p2pInfo* p2p) */ void p2pSendCb(p2pInfo* p2p, const uint8_t* mac_addr __attribute__((unused)), esp_now_send_status_t status) { - // ESP_LOGD("P2P", "%s - %s", __func__, status == ESP_NOW_SEND_SUCCESS ? "ESP_NOW_SEND_SUCCESS" : - // "ESP_NOW_SEND_FAIL"); + P2P_LOG("%s - %s", __func__, status == ESP_NOW_SEND_SUCCESS ? "ESP_NOW_SEND_SUCCESS" : + "ESP_NOW_SEND_FAIL"); switch (status) { @@ -822,8 +836,10 @@ void p2pSendCb(p2pInfo* p2p, const uint8_t* mac_addr __attribute__((unused)), es { if (0 != p2p->ack.timeSentUs) { - // uint32_t transmissionTimeUs = esp_timer_get_time() - p2p->ack.timeSentUs; - // // ESP_LOGD("P2P", "Transmission time %dus", transmissionTimeUs); +#ifdef P2P_DEBUG + uint32_t transmissionTimeUs = esp_timer_get_time() - p2p->ack.timeSentUs; + P2P_LOG("Transmission time %"PRIu32"us", transmissionTimeUs); +#endif // // The timers are all millisecond, so make sure that // // transmissionTimeUs is at least 1ms // if (transmissionTimeUs < 1000) @@ -839,7 +855,7 @@ void p2pSendCb(p2pInfo* p2p, const uint8_t* mac_addr __attribute__((unused)), es // uint32_t waitTimeUs = 1000 * (((transmissionTimeUs + 500) / 1000) + 69 + (esp_random() & 0b1111)); // Start the timer - // ESP_LOGD("P2P", "ack timer set for %dus", waitTimeUs); + P2P_LOG("ack timer set for %"PRIu32"us", waitTimeUs); esp_timer_start_once(p2p->tmr.TxRetry, waitTimeUs); } break; diff --git a/tools/lumber_jacks/base.tmx b/tools/lumber_jacks/base.tmx new file mode 100644 index 000000000..feb0118ae --- /dev/null +++ b/tools/lumber_jacks/base.tmx @@ -0,0 +1,57 @@ + + + + + + + + +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,0,0,0,3,3,3,0,0,0,3,3,3,3,3, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,0,0,0,0,0,0,0,3,3,3,3, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,3,3,3,3,3,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +4,4,4,4,4,4,0,0,0,0,0,0,4,4,4,4,4,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, +8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + + + + + + + + + diff --git a/tools/lumber_jacks/exporter/lumberjacks-editor.js b/tools/lumber_jacks/exporter/lumberjacks-editor.js new file mode 100644 index 000000000..8ea812d71 --- /dev/null +++ b/tools/lumber_jacks/exporter/lumberjacks-editor.js @@ -0,0 +1,153 @@ +tiled.registerMapFormat("Lumber Jacks", { + name: "Lumber Jacks map format", + extension: "bin", + read: (fileName) => { + var file = new BinaryFile(fileName, BinaryFile.ReadOnly); + var filePath = FileInfo.path(fileName); + var buffer = file.read(file.size); + var view = new Uint8Array(buffer); + const tileDataOffset = 12; + const tileSizeInPixels = 16; + + + var map = new TileMap(); + + //The first two bytes contain the width and height of the tilemap in tiles + var tileDataLength = 18 * view[0]; + map.setSize(18, view[0]); + map.setTileSize(tileSizeInPixels, tileSizeInPixels); + + var tileset = tiled.open(filePath + '/lumberjacks.tsx'); + + var layer = new TileLayer(); + + map.addTileset(tileset); + + layer.width = map.width; + layer.height = map.height; + layer.name = 'Main'; + + map.setProperty("enemy1", view[1]); + map.setProperty("enemy2", view[2]); + map.setProperty("enemy3", view[3]); + map.setProperty("enemy4", view[4]); + map.setProperty("enemy5", view[5]); + map.setProperty("enemy6", view[6]); + map.setProperty("enemy7", view[7]); + map.setProperty("enemy8", view[8]); + + map.setProperty("ghost spawn time", view[9]); //Seriously Troy! Document your code! + //map.setProperty("???", view[10]); // - The maniac who knows where you live! + + map.setProperty("time", view[11]); //Time + + var layerEdit = layer.edit(); + var importTileX = 0; + var importTileY = 0; + + + //Import tile data + for(let i = 0; i < tileDataLength; i++){ + let tileId = view[i + 12] - 1; + + if (tileId >= 0) + layerEdit.setTile(importTileX, importTileY, tileset.tile(tileId)); + + importTileX++; + if(importTileX >= map.width){ + importTileY++; + importTileX=0; + } + } + + var writePosition = 12 + tileDataLength; + map.setProperty("spawnx", view[writePosition]); + map.setProperty("spawny", (view[writePosition + 1]) + (view[writePosition + 2] << 8)); + map.setProperty("switches", view[writePosition+3]); + tiled.log(writePosition); + /* + //I need to decide where to put the switches. I believe this is where the switches layout was going to be. + view [writePosition+4] = 8; //WTF Troy? + view [writePosition+5] = 9; //WTF Troy? + view [writePosition+6] = 8; //WTF Troy? + view [writePosition+7] = 4; //WTF Troy?*/ + + //map.setProperty("???", view[writePosition+4]); //Yay more undocumented variables! + //map.setProperty("???", view[writePosition+5]); //Yay more undocumented variables! + //map.setProperty("???", view[writePosition+6]); //Yay more undocumented variables! + //map.setProperty("???", view[writePosition+7]); //Yay more undocumented variables! + + layerEdit.apply(); + map.addLayer(layer); + + + + + file.close(); + return map; + }, + write: (map, fileName) => { + var layer; + + for (let i = 0; i < map.layerCount; ++i) + { + layer = map.layerAt(0); + if (layer.isTileLayer) break; + } + + if (!layer.isTileLayer) + { + return; + } + + let file = new BinaryFile(fileName, BinaryFile.WriteOnly); + let buffer = new ArrayBuffer(20 + layer.height * layer.width); + let view = new Uint8Array(buffer); + let writePosition = 12; + view[0] = layer.height; + view[1] = map.property("enemy1"); //Enemy 1 + view[2] = map.property("enemy2"); //Enemy 2 + view[3] = map.property("enemy3"); //Enemy 3 + view[4] = map.property("enemy4"); //Enemy 4 + view[5] = map.property("enemy5"); //Enemy 5 + view[6] = map.property("enemy6"); //Enemy 6 + view[7] = map.property("enemy7"); //Enemy 7 + view[8] = map.property("enemy8"); //Enemy 8 + view[9] = map.property("ghost spawn time"); // Only if Enemy 4 is set to 1 or higher + view[10] = 0; // + view[11] = 30; //Time + + //write level + for (let y = 0; y > 8; + + //extra data for I don't know what + view [writePosition+3] = 2; //Number of switches + view [writePosition+4] = 8; //WTF Troy? + view [writePosition+5] = 9; //WTF Troy? + view [writePosition+6] = 8; //WTF Troy? + view [writePosition+7] = 4; //WTF Troy? + + file.write(buffer); + file.commit(); + } + }, +); \ No newline at end of file diff --git a/tools/lumber_jacks/lumberjackTileset.tsx b/tools/lumber_jacks/lumberjackTileset.tsx new file mode 100644 index 000000000..9a4e7e038 --- /dev/null +++ b/tools/lumber_jacks/lumberjackTileset.tsx @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/lumber_jacks/tiles/bottom_floor1.png b/tools/lumber_jacks/tiles/bottom_floor1.png new file mode 100644 index 000000000..b5c5e54d0 Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor1.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor10.png b/tools/lumber_jacks/tiles/bottom_floor10.png new file mode 100644 index 000000000..912565bed Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor10.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor2.png b/tools/lumber_jacks/tiles/bottom_floor2.png new file mode 100644 index 000000000..6cc50cf56 Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor2.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor3.png b/tools/lumber_jacks/tiles/bottom_floor3.png new file mode 100644 index 000000000..8c374a903 Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor3.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor4.png b/tools/lumber_jacks/tiles/bottom_floor4.png new file mode 100644 index 000000000..977d0fed9 Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor4.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor5.png b/tools/lumber_jacks/tiles/bottom_floor5.png new file mode 100644 index 000000000..ad46a896c Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor5.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor6.png b/tools/lumber_jacks/tiles/bottom_floor6.png new file mode 100644 index 000000000..b6816beec Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor6.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor7.png b/tools/lumber_jacks/tiles/bottom_floor7.png new file mode 100644 index 000000000..fdfb74284 Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor7.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor8.png b/tools/lumber_jacks/tiles/bottom_floor8.png new file mode 100644 index 000000000..3b3d39e70 Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor8.png differ diff --git a/tools/lumber_jacks/tiles/bottom_floor9.png b/tools/lumber_jacks/tiles/bottom_floor9.png new file mode 100644 index 000000000..ca8915fe9 Binary files /dev/null and b/tools/lumber_jacks/tiles/bottom_floor9.png differ