diff --git a/assets.h b/assets.h index 541298a..0b2938e 100644 --- a/assets.h +++ b/assets.h @@ -656,6 +656,45 @@ SFG_PROGRAM_MEMORY uint8_t SFG_monsterSprites[][SFG_TEXTURE_STORE_SIZE] = 51,51,33,0,0,0,0,0,26,172,221,222,16,1,17,118,34,38,97,0,0,0,0,0,26,204,221,238, 16,0,0,17,17,17,16,0,0,0,0,0,26,205,238,17,0,0,0,0,0,0,0,0,0,0,0,0,17,17,17,0,0, 0,0,0,0,0,0,0,0,0,0 + }, + { // 6. warrior idle +175,0,3,5,1,4,6,7,2,62,170,63,92,93,95,151,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,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,17,17,17,17,17, +17,17,16,0,0,0,0,0,0,0,23,119,119,119,119,119,119,119,113,0,0,0,0,0,0,1,136,255, +153,187,187,187,185,153,241,0,0,0,0,0,0,1,17,17,17,17,17,17,17,31,133,16,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,85,16,0,0,1,17,16,0,0,0,0,0,0,0,0,0,21,81,0,1,19,53,82,0, +0,0,0,0,0,0,0,0,1,33,1,22,99,51,82,0,0,17,0,0,0,0,0,0,1,40,22,102,51,51,36,0,0, +23,16,0,17,16,0,0,18,40,119,102,99,50,68,0,0,22,113,17,234,113,0,1,85,85,85,54, +51,50,68,0,0,19,103,122,234,102,16,24,60,205,51,38,99,50,68,0,0,1,51,54,162,54, +65,130,57,220,211,38,51,50,68,0,0,0,21,51,102,99,72,34,57,156,211,38,99,51,36,0, +1,17,34,85,51,102,52,34,57,220,211,38,51,51,82,0,19,51,51,51,51,51,84,34,60,205, +50,86,99,53,82,0,1,17,34,37,51,53,84,34,51,51,35,102,50,34,36,0,0,0,18,85,85,85, +72,40,51,50,55,98,34,34,36,0,0,1,37,85,162,82,72,136,34,36,117,34,36,68,68,0,0, +21,85,42,234,34,65,132,34,36,82,36,68,34,36,0,0,21,33,17,234,33,0,20,34,36,36, +68,66,83,82,0,0,18,16,0,17,16,0,1,17,17,36,68,68,68,68,0,0,17,0,0,0,0,0,0,0,1, +36,68,68,34,36,0,0,0,0,0,0,0,0,0,0,0,18,36,66,83,82,0,0,0,0,0,0,0,0,0,0,0,1,18, +36,68,68,0,0,0,0,0,0,0,0,0,0,0,0,1,18,34,36,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,16,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0 + }, + { // 7, warrior attacking +175,0,5,1,3,4,2,7,6,63,170,92,93,62,95,148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +17,0,0,1,17,16,0,0,0,0,0,0,0,0,0,1,71,16,1,18,37,84,0,0,1,16,0,0,0,0,0,18,73,17, +24,130,34,84,0,0,1,113,16,1,17,0,1,36,63,115,72,34,34,67,0,0,1,135,113,30,167, +16,1,102,99,150,68,130,36,51,0,0,0,24,119,174,168,33,22,82,35,247,52,34,36,51,0, +0,0,18,34,138,162,131,102,43,188,57,100,66,36,51,0,0,0,1,82,40,136,35,68,45,203, +61,115,66,36,51,0,0,1,17,20,85,40,130,52,45,219,195,150,68,34,67,0,0,18,34,34, +34,34,37,52,45,203,195,151,52,34,84,0,0,1,17,68,82,34,85,52,43,188,34,57,100,66, +84,0,0,0,1,69,85,85,83,68,34,34,36,57,115,69,84,0,0,0,20,85,90,165,67,102,34,34, +66,99,148,100,67,0,0,0,21,84,174,164,67,54,68,67,84,67,215,51,51,0,0,1,84,17,30, +164,16,3,102,99,70,51,57,52,84,0,0,1,65,0,1,17,0,0,51,51,70,51,51,115,51,0,0,1, +16,0,0,0,0,0,0,1,100,51,51,147,68,0,0,0,0,0,0,0,0,0,0,0,17,68,102,55,19,0,0,0,0, +0,0,0,0,0,0,0,0,17,20,57,17,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,16,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }; diff --git a/assets/monster_warrior_attack.png b/assets/monster_warrior_attack.png index 588f19b..54acd72 100644 Binary files a/assets/monster_warrior_attack.png and b/assets/monster_warrior_attack.png differ diff --git a/assets/monster_warrior_idle.png b/assets/monster_warrior_idle.png index 279e92c..a2b540a 100644 Binary files a/assets/monster_warrior_idle.png and b/assets/monster_warrior_idle.png differ diff --git a/levels.h b/levels.h index fc29c89..ecb2f50 100644 --- a/levels.h +++ b/levels.h @@ -95,6 +95,7 @@ typedef struct */ #define SFG_LEVEL_ELEMENT_MONSTER_SPIDER 0x00 #define SFG_LEVEL_ELEMENT_MONSTER_DESTROYER 0x10 +#define SFG_LEVEL_ELEMENT_MONSTER_WARRIOR 0x20 typedef struct { @@ -245,7 +246,7 @@ SFG_PROGRAM_MEMORY SFG_Level SFG_level0 = {SFG_LEVEL_ELEMENT_BARREL, {13, 4}}, {SFG_LEVEL_ELEMENT_BARREL, {12, 6}}, {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {15, 7}}, {SFG_LEVEL_ELEMENT_MONSTER_SPIDER, {16, 8}}, {SFG_LEVEL_ELEMENT_MONSTER_DESTROYER, {16, 7}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, - {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, + {SFG_LEVEL_ELEMENT_MONSTER_WARRIOR, {18, 31}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, {SFG_LEVEL_ELEMENT_NONE, {0, 0}}, diff --git a/main.c b/main.c index ea40ed1..ef44356 100755 --- a/main.c +++ b/main.c @@ -501,6 +501,12 @@ const uint8_t *SFG_getMonsterSprite( } break; + case SFG_LEVEL_ELEMENT_MONSTER_WARRIOR: + return state != SFG_MONSTER_STATE_ATTACKING ? + SFG_monsterSprites[6] : SFG_monsterSprites[7]; + + break; + case SFG_LEVEL_ELEMENT_MONSTER_DESTROYER: switch (state) { @@ -1055,6 +1061,7 @@ void SFG_setAndInitLevel(const SFG_Level *level) case SFG_LEVEL_ELEMENT_MONSTER_SPIDER: case SFG_LEVEL_ELEMENT_MONSTER_DESTROYER: + case SFG_LEVEL_ELEMENT_MONSTER_WARRIOR: SFG_LOG("adding monster"); monster = @@ -1179,55 +1186,98 @@ void SFG_monsterPerformAI(SFG_MonsterRecord *monster) coordAdd[0] = 0; coordAdd[1] = 0; + uint8_t melee = type == SFG_LEVEL_ELEMENT_MONSTER_WARRIOR; + if (SFG_random() < SFG_AI_RANDOM_CHANGE_PROBABILITY) { // sometimes randomly change state - if (SFG_random() % 4 != 0) + if (!melee && (SFG_random() % 4 != 0)) { // attack state = SFG_MONSTER_STATE_ATTACKING; - RCL_Vector2D pos; - RCL_Vector2D dir; + if (type != SFG_LEVEL_ELEMENT_MONSTER_WARRIOR) + { + RCL_Vector2D pos; + RCL_Vector2D dir; - pos.x = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]); - pos.y = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]); + pos.x = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[0]); + pos.y = SFG_MONSTER_COORD_TO_RCL_UNITS(monster->coords[1]); - dir.x = SFG_player.camera.position.x - pos.x; - dir.y = SFG_player.camera.position.y - pos.y; + dir.x = SFG_player.camera.position.x - pos.x; + dir.y = SFG_player.camera.position.y - pos.y; - dir = RCL_normalize(dir); + dir = RCL_normalize(dir); - SFG_launchProjectile( - SFG_PROJECTILE_FIREBALL, - pos, - SFG_floorHeightAt( - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), - SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1]) - ) + RCL_UNITS_PER_SQUARE / 2, - dir, - 0, - SFG_ELEMENT_COLLISION_DISTANCE - ); + SFG_launchProjectile( + SFG_PROJECTILE_FIREBALL, + pos, + SFG_floorHeightAt( + SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]), + SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1]) + ) + RCL_UNITS_PER_SQUARE / 2, + dir, + 0, + SFG_ELEMENT_COLLISION_DISTANCE + ); + } } else state = SFG_MONSTER_STATE_IDLE; } else if (state == SFG_MONSTER_STATE_IDLE) { - switch (SFG_random() % 8) + if (melee) { - case 0: state = SFG_MONSTER_STATE_GOING_E; break; - case 1: state = SFG_MONSTER_STATE_GOING_W; break; - case 2: state = SFG_MONSTER_STATE_GOING_N; break; - case 3: state = SFG_MONSTER_STATE_GOING_S; break; - case 4: state = SFG_MONSTER_STATE_GOING_NE; break; - case 5: state = SFG_MONSTER_STATE_GOING_NW; break; - case 6: state = SFG_MONSTER_STATE_GOING_SE; break; - case 7: state = SFG_MONSTER_STATE_GOING_SW; break; - default: break; + // melee monsters walk towards player + + uint8_t mX = SFG_MONSTER_COORD_TO_SQUARES(monster->coords[0]); + uint8_t mY = SFG_MONSTER_COORD_TO_SQUARES(monster->coords[1]); + + if (mX > SFG_player.squarePosition[0]) + { + if (mY > SFG_player.squarePosition[1]) + state = SFG_MONSTER_STATE_GOING_NW; + else if (mY < SFG_player.squarePosition[1]) + state = SFG_MONSTER_STATE_GOING_SW; + else + state = SFG_MONSTER_STATE_GOING_W; + } + else if (mX < SFG_player.squarePosition[0]) + { + if (mY > SFG_player.squarePosition[1]) + state = SFG_MONSTER_STATE_GOING_NE; + else if (mY < SFG_player.squarePosition[1]) + state = SFG_MONSTER_STATE_GOING_SE; + else + state = SFG_MONSTER_STATE_GOING_E; + } + else + { + if (mY > SFG_player.squarePosition[1]) + state = SFG_MONSTER_STATE_GOING_N; + else if (mY < SFG_player.squarePosition[1]) + state = SFG_MONSTER_STATE_GOING_S; + } + } + else + { + // ranged monsters choose direction randomly + + switch (SFG_random() % 8) + { + case 0: state = SFG_MONSTER_STATE_GOING_E; break; + case 1: state = SFG_MONSTER_STATE_GOING_W; break; + case 2: state = SFG_MONSTER_STATE_GOING_N; break; + case 3: state = SFG_MONSTER_STATE_GOING_S; break; + case 4: state = SFG_MONSTER_STATE_GOING_NE; break; + case 5: state = SFG_MONSTER_STATE_GOING_NW; break; + case 6: state = SFG_MONSTER_STATE_GOING_SE; break; + case 7: state = SFG_MONSTER_STATE_GOING_SW; break; + default: break; + } } } else if (state == SFG_MONSTER_STATE_ATTACKING)