/****************************************************************************/ /* The Legend of Zelda: Link's Awakening */ /* By: Jason Ho */ /* */ /* This header contains information about mobs in the game. Mob stands for */ /* mobile, and includes anything that is alive (monsters, people, dogs, */ /* chickens, Bowwow, Marin, etc). */ /****************************************************************************/ /*---------------------------------------------------------------------------*/ /* Aliases */ /*---------------------------------------------------------------------------*/ enum {MOB_NUMBER, MOB_X, MOB_Y, MOB_FRAME, MOB_DIRECTION, MOB_PAUSE, MOB_VAR1, MOB_VAR2}; //Used in mob_list enum {MOB_WANDER, MOB_FLUTTER, MOB_HOP, MOB_FOLLOW, MOB_SPIKE}; //Movement Types, used in function MoveMob //Found on the beach #define CRAB1 0 #define CRAB2 1 //Usually found in town #define BUTTERFLY1 2 #define BUTTERFLY2 3 //Classic Zelda Octapus-looking monster #define MONSTER1 4 #define MONSTER2 5 #define MONSTER3 6 #define MONSTER4 7 #define MONSTER5 8 #define MONSTER6 9 #define MONSTER7 10 #define MONSTER8 11 //Found on the beach (spikey looking things) #define URCHIN1 12 #define URCHIN2 13 #define URCHIN3 14 #define URCHIN4 15 //Usually found in town #define DOG1 16 #define DOG2 17 #define DOG3 18 #define DOG4 19 //Usually found in town #define CHICKEN1 20 #define CHICKEN2 21 #define CHICKEN3 22 #define CHICKEN4 23 //These are the creatures that come up from the ground, //twirl around a bit, then disappears into the sand again. #define SANDMOB1 24 #define SANDMOB2 25 #define SANDMOB3 26 #define SANDMOB4 27 //The mob in doungens that follows you and you can't slash it #define DMOB1 28 #define DMOB2 29 #define GOBLIN1 30 #define GOBLIN2 31 #define GOBLIN3 32 #define GOBLIN4 33 #define GOBLIN5 34 #define GOBLIN6 35 #define GOBLIN7 36 #define GOBLIN8 37 #define SPIKE1 38 /*---------------------------------------------------------------------------*/ /* Prototypes */ /*---------------------------------------------------------------------------*/ void AnimateMob(void); void MoveMob(int, short, short); void SlashMob(short, short, short, short); /*---------------------------------------------------------------------------*/ /* Pictures */ /*---------------------------------------------------------------------------*/ static unsigned short mob_pic_light[39][16] = { {0x0000,0x381C,0x4422,0x8C31,0x8A51,0x8A51,0x8A51,0xD66B,0x6FF6,0x3DBC,0x1DB8,0x3FFC,0x5BDA,0x9C39,0xBFFD,0xFFFF}, //Crab1 {0x1C38,0x2244,0x4662,0x45A2,0x45A2,0x45A2,0x6BD6,0x37EC,0x3DBC,0x1DB8,0x1FF8,0x3BDC,0x5C3A,0x4FF2,0x5FFA,0x7FFE}, //Crab2 {0x0000,0x0000,0x0000,0x0000,0x0000,0x03C0,0x05A0,0x0990,0x0990,0x0A50,0x0C30,0x0000,0x0000,0x0000,0x0000,0x0000}, //Butterfly1 {0x0000,0x0000,0x0000,0x0000,0x0C30,0x0A50,0x0990,0x0990,0x05A0,0x03C0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, //Butterfly2 {0x0000,0x1FF8,0x1C38,0xCFF3,0xE667,0xFFFF,0x781E,0x3A5C,0x366C,0x342C,0x33CC,0x3E7C,0x7C3E,0xFE7F,0xEFF7,0x07E0}, //Monster1 {0x0000,0x1FF8,0x1C38,0x0FF0,0x0660,0x0FF0,0xF81F,0xFA5F,0xF66F,0x742E,0x33CC,0xFE7F,0xFC3F,0x7E7E,0x0FF0,0x07E0}, //Monster2 {0x0000,0x079C,0x1C7C,0x35BB,0x62D7,0x621D,0x7615,0x7CD5,0x7D95,0x7D3D,0x3C7F,0x3FFF,0x339B,0x3FF8,0x7FFC,0x701C}, //Monster3 {0x07C0,0x1C60,0x35B3,0x62D7,0x621D,0x7615,0x7CD5,0x7D95,0x7D3D,0x3C7F,0x3FFF,0x339B,0x3FF0,0x1FF0,0x0EE0,0x06C0}, //Monster4 {0x0000,0x07E0,0xEFF7,0xFE7F,0x7C3E,0x3E7C,0x33CC,0x342C,0x366C,0x3A5C,0x781E,0xFFFF,0xE667,0xCFF3,0x1C38,0x1FF8}, //Monster5 {0x0000,0x07E0,0x0FF0,0x7E7E,0xFC3F,0xFE7F,0x33CC,0x742E,0xF66F,0xFA5F,0xF81F,0x0FF0,0x0660,0x0FF0,0x1C38,0x1FF8}, //Monster6 //10 pic mark {0x0000,0x1CF0,0x1F1C,0x6ED6,0x75A3,0x5C23,0x5437,0x559F,0x54DF,0x5E5F,0x7F1E,0x7FFE,0x6CE6,0x0FFE,0x1FFF,0x1C07}, //Monster7 {0x03E0,0x0638,0xCDAC,0xEB46,0xB846,0xA86E,0xAB3E,0xA9BE,0xBCBE,0xFE3C,0xFFFC,0xD9CC,0x0FFC,0x0FF8,0x0770,0x0360}, //Monster8 {0x0080,0x6143,0x514D,0x2FF2,0x1FEC,0x1B78,0x74B8,0xB4BE,0x74B1,0x1B7E,0x1FF8,0x2FE8,0x5FF4,0xB29A,0xC286,0x0100}, //Urchin1 {0x0100,0xC286,0xB28A,0x4FF4,0x37F8,0x1ED8,0x1D2E,0x7D2D,0x8D2E,0x7ED8,0x1FF8,0x17F4,0x2FFA,0x594D,0x6143,0x0080}, //Urchin2 {0x0080,0x6143,0x594D,0x2FFA,0x17F4,0x1FF8,0x7ED8,0x8D2E,0x7D2D,0x1D2E,0x1ED8,0x37F8,0x4FF4,0xB28A,0xC286,0x0100}, //Urchin3 {0x0100,0xC286,0xB29A,0x5FF4,0x2FE8,0x1FF8,0x1B7E,0x74B1,0xB4BE,0x74B8,0x1B78,0x1FEC,0x2FF2,0x514D,0x6143,0x0080}, //Urchin4 {0x0000,0x060C,0x071C,0x659C,0xF4FC,0xF2FC,0xF7FC,0xFBFE,0xFDFD,0x79FD,0x7FFE,0x3FFE,0x1FFC,0x3FF8,0x2668,0x3FF8}, //Dog1 {0x0000,0x060C,0x071C,0x1D9C,0x3CFC,0x3EFC,0x7FFC,0x7BFE,0x7DFD,0x79FD,0x3FFE,0x3FFE,0x1FFC,0x3FF8,0x2668,0x3FF8}, //Dog2 {0x0000,0x3060,0x38E0,0x39A6,0x3F2F,0x3F4F,0x3FEF,0x7FDF,0xBFBF,0xBF9E,0x7FFE,0x7FFC,0x3FF8,0x1FFC,0x1664,0x1FFC}, //Dog3 {0x0000,0x3060,0x38E0,0x39B8,0x3F3C,0x3F7C,0x3FFE,0x7FDE,0xBFBE,0xBF9E,0x7FFC,0x7FFC,0x3FF8,0x1FFC,0x1664,0x1FFC}, //Dog4 //20 pic mark {0x0000,0x0000,0x006C,0x1C7E,0x227E,0x398E,0x4402,0x6226,0x522D,0x400F,0xC63E,0x7FFE,0x3FF8,0x1FF0,0x0DE8,0x0FF8}, //Chicken1 {0x0000,0x006C,0x0E7E,0x127E,0x218E,0x3002,0x2026,0x1C2D,0x200F,0x409F,0x589F,0x71FC,0x3FF8,0x3FF0,0x0E20,0x07E0}, //Chicken2 {0x0000,0x0000,0x1B00,0x3F1C,0x3F22,0x38CE,0x2011,0x3223,0x5A25,0x7801,0x7C63,0x7FFE,0x1FFC,0x0FF8,0x17B0,0x1FF0}, //Chicken3 {0x0000,0x1B00,0x3F38,0x3F24,0x38C2,0x2006,0x3202,0x5A1C,0x7802,0x7C81,0x7C8D,0x1FC7,0x0FFE,0x07FE,0x0238,0x03F0}, //Chicken4 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0E70,0x1188,0x1248,0x4E72,0x4992,0x324C,0x0660,0x0180}, //SandMob1 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0A50,0x3A5C,0x2BD4,0x2FF4,0x27E4,0x73CE,0x9BD9,0x1FF8,0x2FF4,0x07E0}, //SandMob2 {0x0180,0x6246,0x524A,0x5BDA,0x4E72,0x4E72,0x6E76,0x3E7C,0x3FFC,0xFFFF,0x7FFE,0x7FFE,0xFE7F,0x3FFC,0x1FF8,0x0990}, //SandMob3 {0x0C30,0x1248,0x324C,0x2BD4,0x2FF4,0x27E4,0x33CC,0x13C8,0x3BDC,0x7FFE,0x7FFE,0xFFFF,0x7E7E,0x7FFE,0x0FF0,0x0660}, //SandMob4 {0x0000,0x0000,0x03c0,0x0ff0,0x1e78,0x3ffc,0x3ffc,0x7c3e,0xb00d,0xaff5,0xddbb,0x718e,0x9ff9,0xb99d,0xf3cf,0x3ffc}, {0x0000,0x03c0,0x0ff0,0x1e78,0x3ffc,0x3ffc,0x7c3e,0xb00d,0xaff5,0xddbb,0x718e,0x9ff9,0x9999,0xb99d,0xf3cf,0x3ffc}, {0xf3cf,0xffff,0x7ffe,0x380c,0x57f4,0x9ffe,0xbfff,0xffff,0xffff,0xfffe,0x3ffc,0x3ffc,0x3ffc,0x1ffc,0x3ffe,0x00fe}, {0xf3cf,0xffff,0x7ffe,0x301c,0x2fea,0x7ff9,0xfffd,0xffff,0xffff,0x7fff,0x3ffc,0x3ffc,0x3ffc,0x3ff8,0x7ffc,0x7f00}, {0x07f0,0x0fff,0x1fff,0x3fbf,0x5fff,0x6f7f,0xf33e,0xffb2,0xf9e6,0xbffc,0xbf98,0xffd8,0x3ff0,0x7fe0,0x7e40,0x7fe0}, {0x07f0,0x0fff,0x1fff,0x3fbf,0x5fff,0x6f7f,0xf33e,0xffb2,0xf9e6,0xbffc,0xbf98,0xffd8,0x3ff0,0x7fe0,0x7e40,0x7fe0}, {0xf3cf,0xfc3f,0x7c3e,0x3bdc,0x7e7e,0xf81f,0x97ef,0xb66f,0xfdb9,0x781d,0x7e7f,0x7ffe,0x7c1c,0x3ff0,0x49f8,0x7fc0}, {0xf3cf,0xfc3f,0x7c3e,0x3bdc,0x7e7e,0xf81f,0xf7e9,0xf66d,0x9dbf,0xb81e,0xfe7e,0x7ffe,0x383e,0x0ffc,0x1f92,0x03fe}, {0x0fe0,0xfff0,0xfff8,0xfdfc,0xfffa,0xfef6,0x7ccf,0x4dff,0x679f,0x3ffd,0x19fd,0x1bff,0x0ffc,0x07fe,0x027e,0x07fe}, {0x0fe0,0xfff0,0xfff8,0xfdfc,0xfffa,0xfef6,0x7ccf,0x4dff,0x679f,0x3ffd,0x19fd,0x1bff,0x0ffc,0x07fe,0x027e,0x07fe}, {0x0660,0x0a50,0x1248,0x27e4,0x4ff2,0x9ff9,0xffff,0x1ff8,0x1ff8,0xffff,0x9ff9,0x4ff2,0x27e4,0x1248,0x0a50,0x0660}, }; static unsigned short mob_pic_dark[39][16] = { {0x0000,0x381C,0x4422,0x8C31,0x8A51,0x8A51,0x8A51,0x9249,0x47E2,0x2DB4,0x1DB8,0x35AC,0x524A,0x9009,0xB81D,0xFFFF}, //Crab1 {0x1C38,0x2244,0x4662,0x45A2,0x45A2,0x45A2,0x4992,0x23C4,0x2DB4,0x1DB8,0x15A8,0x324C,0x500A,0x4812,0x5FFA,0x7FFE}, //Crab2 {0x0000,0x0000,0x0000,0x0000,0x0000,0x03C0,0x05A0,0x0990,0x0990,0x0A50,0x0C30,0x0000,0x0000,0x0000,0x0000,0x0000}, //Butterfly1 {0x0000,0x0000,0x0000,0x0000,0x0C30,0x0A50,0x0990,0x0990,0x05A0,0x03C0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, //Butterfly2 {0x0000,0x1FF8,0x1008,0xCFF3,0xA425,0x9C39,0x500A,0x324C,0x2664,0x2424,0x2004,0x2004,0x500A,0x9009,0xE817,0x07E0}, //Monster1 {0x0000,0x1FF8,0x1008,0x0FF0,0x0420,0x0C30,0xF00F,0xB24D,0xA665,0x6426,0x2004,0xE007,0x9009,0x700E,0x0810,0x07E0}, //Monster2 {0x0000,0x079C,0x1864,0x219B,0x40D5,0x400D,0x4005,0x40C5,0x4185,0x4105,0x201D,0x3E7D,0x339B,0x27C8,0x4FE4,0x701C}, //Monster3 {0x07C0,0x1860,0x2193,0x40D5,0x400D,0x4005,0x40C5,0x4185,0x4105,0x201D,0x3C7D,0x329B,0x3390,0x1390,0x0AA0,0x06C0}, //Monster4 {0x0000,0x07E0,0xE817,0x9009,0x500A,0x2004,0x2004,0x2424,0x2664,0x324C,0x500A,0x9C39,0xA425,0xCFF3,0x1008,0x1FF8}, //Monster5 {0x0000,0x07E0,0x0810,0x700E,0x9009,0xE007,0x2004,0x6426,0xA665,0xB24D,0xF00F,0x0C30,0x0420,0x0FF0,0x1008,0x1FF8}, //Monster6 //10 pic mark {0x0000,0x1CF0,0x130C,0x6CC2,0x5581,0x5801,0x5001,0x5181,0x50C1,0x5041,0x5C02,0x5F3E,0x6CE6,0x09F2,0x13F9,0x1C07}, //Monster7 {0x03E0,0x0618,0xC984,0xAB02,0xB002,0xA002,0xA302,0xA182,0xA082,0xB804,0xBE3C,0xD94C,0x09CC,0x09C8,0x0550,0x0360}, //Monster8 {0x0080,0x6143,0x514D,0x2FF2,0x1FE4,0x1038,0x6498,0xA49E,0x6491,0x103E,0x1FF8,0x2FE8,0x4FE4,0xB29A,0xC286,0x0100}, //Urchin1 {0x0100,0xC286,0xB28A,0x4FF4,0x27F8,0x1C08,0x1926,0x7925,0x8926,0x7C08,0x1FF8,0x17F4,0x27F2,0x594D,0x6143,0x0080}, //Urchin2 {0x0080,0x6143,0x594D,0x27F2,0x17F4,0x1FF8,0x7C08,0x8926,0x7925,0x1926,0x1C08,0x27F8,0x4FF4,0xB28A,0xC286,0x0100}, //Urchin3 {0x0100,0xC286,0xB29A,0x4FE4,0x2FE8,0x1FF8,0x103E,0x6491,0xA49E,0x6498,0x1038,0x1FE4,0x2FF2,0x514D,0x6143,0x0080}, //Urchin4 {0x0000,0x060C,0x0514,0x6494,0xF464,0xF204,0xD454,0x8852,0x8C01,0x4819,0x4F82,0x28C2,0x107C,0x2208,0x2648,0x3FF8}, //Dog1 {0x0000,0x060C,0x0514,0x1C94,0x3C64,0x3E04,0x6454,0x4852,0x4C01,0x4819,0x2F82,0x28C2,0x107C,0x2208,0x2648,0x3FF8}, //Dog2 {0x0000,0x3060,0x28A0,0x2926,0x262F,0x204F,0x2A2B,0x4A11,0x8031,0x9812,0x41F2,0x4314,0x3E08,0x1044,0x1264,0x1FFC}, //Dog3 {0x0000,0x3060,0x28A0,0x2938,0x263C,0x207C,0x2A26,0x4A12,0x8032,0x9812,0x41F4,0x4314,0x3E08,0x1044,0x1264,0x1FFC}, //Dog4 //20 pic mark {0x0000,0x0000,0x006C,0x1C7A,0x227E,0x398E,0x4402,0x6226,0x5029,0x4009,0x803A,0x403E,0x2408,0x1A30,0x09C8,0x0FF8}, //Chicken1 {0x0000,0x006C,0x0E7A,0x127E,0x218E,0x2002,0x2026,0x1829,0x2009,0x401D,0x509F,0x6084,0x2188,0x3EF0,0x0E20,0x07E0}, //Chicken2 {0x0000,0x0000,0x1B00,0x2F1C,0x3F22,0x38CE,0x2011,0x3223,0x4A05,0x4801,0x5C01,0x7C02,0x1024,0x0C58,0x1390,0x1FF0}, //Chicken3 {0x0000,0x1B00,0x2F38,0x3F24,0x38C2,0x2002,0x3202,0x4A0C,0x4802,0x5C01,0x7C85,0x1083,0x08C2,0x07BE,0x0238,0x03F0}, //Chicken4 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0E70,0x1188,0x1248,0x4E72,0x4992,0x324C,0x0660,0x0180}, //SandMob1 {0x0000,0x0000,0x0000,0x0000,0x0000,0x0660,0x0A50,0x3A5C,0x2BD4,0x2E74,0x27E4,0x63C6,0x93C9,0x1BD8,0x2FF4,0x07E0}, //SandMob2 {0x0180,0x6246,0x524A,0x5BDA,0x4E72,0x4E72,0x4E72,0x2E74,0x3E7C,0xDFFB,0x5FFA,0x67E6,0xF81F,0x3FFC,0x1FF8,0x0990}, //SandMob3 {0x0C30,0x1248,0x324C,0x2BD4,0x2E74,0x27E4,0x23C4,0x13C8,0x3BDC,0x5FFA,0x5FFA,0xE7E7,0x781E,0x7FFE,0x0FF0,0x0660}, //SandMob4 {0x0000,0x0000,0x03c0,0x0e70,0x1c38,0x3e7c,0x3ffc,0x781e,0xb00d,0x87e1,0x8db1,0x718e,0x8e71,0x9999,0xf18f,0x3ffc}, {0x0000,0x03c0,0x0e70,0x1c38,0x3e7c,0x3ffc,0x781e,0xb00d,0x87e1,0x8db1,0x718e,0x8e71,0x8991,0x9999,0xf18f,0x3ffc}, {0xf3cf,0x8c31,0x47f2,0x280c,0x57f4,0x9ffe,0x9ffd,0x9ffd,0x97f5,0xf006,0x380c,0x3ffc,0x3ffc,0x1ffc,0x3ffe,0x00fe}, {0xf3cf,0x8c31,0x4fe2,0x3014,0x2fea,0x7ff9,0xbff9,0xbff9,0xafe9,0x600f,0x301c,0x3ffc,0x3ffc,0x23f8,0x41fc,0x7f00}, {0x07f0,0x080f,0x166b,0x3831,0x5181,0x6d41,0xf32e,0xffb2,0xf1e2,0xa0ec,0xa118,0xe018,0x3110,0x7fe0,0x4040,0x7fe0}, {0x07f0,0x080f,0x166b,0x3831,0x5181,0x6d41,0xf32e,0xffb2,0xf1e2,0xa0ec,0xa118,0xe018,0x3110,0x7fe0,0x4040,0x7fe0}, {0xf3cf,0x8c31,0x542a,0x33cc,0x524a,0xf819,0x97ed,0x942f,0x9999,0x7009,0x7c39,0x73ee,0x7c1c,0x23f0,0x41f8,0x7fc0}, {0xf3cf,0x8c31,0x542a,0x33cc,0x524a,0x981f,0xb7e9,0xf429,0x9999,0x900e,0x9c3e,0x77ce,0x383e,0x0fc4,0x1f82,0x03fe}, {0x0fe0,0xf010,0xd668,0x8c1c,0x818a,0x82b6,0x74cf,0x4dff,0x478f,0x3705,0x1885,0x1807,0x088c,0x07fe,0x0202,0x07fe}, {0x0fe0,0xf010,0xd668,0x8c1c,0x818a,0x82b6,0x74cf,0x4dff,0x478f,0x3705,0x1885,0x1807,0x088c,0x07fe,0x0202,0x07fe}, {0x0660,0x0a50,0x1248,0x23c4,0x4422,0x8811,0xfa5f,0x1a58,0x1818,0xfc3f,0x8ff1,0x47e2,0x23c4,0x1248,0x0a50,0x0660}, }; static unsigned short mob_pic_mask[39][16] = { {~0x0000,~0x381C,~0x7C3E,~0xFC3F,~0xFE7F,~0xFE7F,~0xFE7F,~0xFE7F,~0x7FFE,~0x3FFC,~0x1FF8,~0x3FFC,~0x7FFE,~0xFFFF,~0xFFFF,~0xFFFF}, //Crab1 {~0x1C38,~0x3E7C,~0x7E7E,~0x7FFE,~0x7FFE,~0x7FFE,~0x7FFE,~0x3FFC,~0x3FFC,~0x1FF8,~0x1FF8,~0x3FFC,~0x7FFE,~0x7FFE,~0x7FFE,~0x7FFE}, //Crab2 {~0x0000,~0x0000,~0x0000,~0x0000,~0x0000,~0x03C0,~0x07E0,~0x0FF0,~0x0FF0,~0x0E70,~0x0C30,~0x0000,~0x0000,~0x0000,~0x0000,~0x0000}, //Butterfly1 {~0x0000,~0x0000,~0x0000,~0x0000,~0x0C30,~0x0E70,~0x0FF0,~0x0FF0,~0x07E0,~0x03C0,~0x0000,~0x0000,~0x0000,~0x0000,~0x0000,~0x0000}, //Butterfly2 {~0x0000,~0x1FF8,~0x1FF8,~0xCFF3,~0xE7E7,~0xFFFF,~0x7FFE,~0x3FFC,~0x3FFC,~0x3FFC,~0x3FFC,~0x3FFC,~0x7FFE,~0xFFFF,~0xEFF7,~0x07E0}, //Monster1 {~0x0000,~0x1FF8,~0x1FF8,~0x0FF0,~0x07E0,~0x0FF0,~0xFFFF,~0xFFFF,~0xFFFF,~0x7FFE,~0x3FFC,~0xFFFF,~0xFFFF,~0x7FFE,~0x0FF0,~0x07E0}, //Monster2 {~0x0000,~0x079C,~0x1FFC,~0x3FFB,~0x7FF7,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFF,~0x3FFF,~0x3FFF,~0x3FFB,~0x3FF8,~0x7FFC,~0x701C}, //Monster3 {~0x07C0,~0x1FE0,~0x3FF3,~0x7FF7,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFF,~0x3FFF,~0x3FFF,~0x3FFB,~0x3FF0,~0x1FF0,~0x0EE0,~0x06C0}, //Monster4 {~0x0000,~0x07E0,~0xEFF7,~0xFFFF,~0x7FFE,~0x3FFC,~0x3FFC,~0x3FFC,~0x3FFC,~0x3FFC,~0x7FFE,~0xFFFF,~0xE7E7,~0xCFF3,~0x1FF8,~0x1FF8}, //Monster5 {~0x0000,~0x07E0,~0x0FF0,~0x7FFE,~0xFFFF,~0xFFFF,~0x3FFC,~0x7FFE,~0xFFFF,~0xFFFF,~0xFFFF,~0x0FF0,~0x07E0,~0x0FF0,~0x1FF8,~0x1FF8}, //Monster6 //10 pic mark {~0x0000,~0x1CF0,~0x1FFC,~0x6FFE,~0x77FF,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFE,~0x7FFE,~0x6FFE,~0x0FFE,~0x1FFF,~0x1C07}, //Monster7 {~0x03E0,~0x07F8,~0xCFFC,~0xEFFE,~0xFFFE,~0xFFFE,~0xFFFE,~0xFFFE,~0xFFFE,~0xFFFC,~0xFFFC,~0xDFFC,~0x0FFC,~0x0FF8,~0x0770,~0x0360}, //Monster8 {~0x0080,~0x61C3,~0x71CF,~0x3FFE,~0x1FFC,~0x1FF8,~0x7FF8,~0xFFFE,~0x7FFF,~0x1FFE,~0x1FF8,~0x3FF8,~0x7FFC,~0xF39E,~0xC386,~0x0100}, //Urchin1 {~0x0100,~0xC386,~0xF38E,~0x7FFC,~0x3FF8,~0x1FF8,~0x1FFE,~0x7FFF,~0xFFFE,~0x7FF8,~0x1FF8,~0x1FFC,~0x3FFE,~0x79CF,~0x61C3,~0x0080}, //Urchin2 {~0x0080,~0x61C3,~0x79CF,~0x3FFE,~0x1FFC,~0x1FF8,~0x7FF8,~0xFFFE,~0x7FFF,~0x1FFE,~0x1FF8,~0x3FF8,~0x7FFC,~0xF38E,~0xC386,~0x0100}, //Urchin3 {~0x0100,~0xC386,~0xF39E,~0x7FFC,~0x3FF8,~0x1FF8,~0x1FFE,~0x7FFF,~0xFFFE,~0x7FF8,~0x1FF8,~0x1FFC,~0x3FFE,~0x71CF,~0x61C3,~0x0080}, //Urchin4 {~0x0000,~0x060C,~0x071C,~0x679C,~0xF7FC,~0xF3FC,~0xF7FC,~0xFFFE,~0xFFFF,~0x7FFF,~0x7FFE,~0x3FFE,~0x1FFC,~0x3FF8,~0x3FF8,~0xBFF8}, //Dog1 {~0x0000,~0x060C,~0x071C,~0x1F9C,~0x3FFC,~0x3FFC,~0x7FFC,~0x7FFE,~0x7FFF,~0x7FFF,~0x3FFE,~0x3FFE,~0x1FFC,~0x3FF8,~0x3FF8,~0x3FF8}, //Dog2 {~0x0000,~0x3060,~0x38E0,~0x39E6,~0x3FEF,~0x3FCF,~0x3FEF,~0x7FFF,~0xFFFF,~0xFFFE,~0x7FFE,~0x7FFC,~0x3FF8,~0x1FFC,~0x1FFC,~0x1FFC}, //Dog3 {~0x0000,~0x3060,~0x38E0,~0x39F8,~0x3FFC,~0x3FFC,~0x3FFE,~0x7FFE,~0xFFFE,~0xFFFE,~0x7FFC,~0x7FFC,~0x3FF8,~0x1FFC,~0x1FFC,~0x1FFC}, //Dog4 //20 pic mark {~0x0000,~0x0000,~0x006C,~0x1C7E,~0x3E7E,~0x3FFE,~0x7FFE,~0x7FFE,~0x7FFF,~0x7FFF,~0xFFFE,~0x7FFE,~0x3FF8,~0x1FF0,~0x0FF8,~0x0FF8}, //Chicken1 {~0x0000,~0x006C,~0x0E7E,~0x1E7E,~0x3FFE,~0x3FFE,~0x3FFE,~0x1FFF,~0x3FFF,~0x7FFF,~0x7FFF,~0x7FFC,~0x3FF8,~0x3FF0,~0x0FE0,~0x07E0}, //Chicken2 {~0x0000,~0x0000,~0x1B00,~0x3F1C,~0x3F3E,~0x3FFE,~0x3FFF,~0x3FFF,~0x7FFF,~0x7FFF,~0x7FFF,~0x7FFE,~0x1FFC,~0x0FF8,~0x1FF0,~0x1FF0}, //Chicken3 {~0x0000,~0x1B00,~0x3F38,~0x3F3C,~0x3FFE,~0x3FFE,~0x3FFE,~0x7FFC,~0x7FFE,~0x7FFF,~0x7FFF,~0x1FFF,~0x0FFE,~0x07FE,~0x03F8,~0x03F0}, //Chicken4 {~0x0000,~0x0000,~0x0000,~0x0000,~0x0000,~0x0000,~0x0000,~0x0000,~0x0E70,~0x1FF8,~0x3E7C,~0x7E7E,~0x799E,~0x33CC,~0x07E0,~0x0180}, //SandMob1 {~0x0000,~0x0000,~0x0000,~0x0000,~0x0000,~0x0660,~0x0E70,~0x3E7C,~0x3FFC,~0x3FFC,~0x3FFC,~0x7FFE,~0x9FF9,~0x1FF8,~0x2FF4,~0x07E0}, //SandMob2 {~0x0180,~0x63C6,~0x73CE,~0x7BDE,~0x7FFE,~0x7FFE,~0x7FFE,~0x3FFC,~0x3FFC,~0xFFFF,~0x7FFE,~0x7FFE,~0xFFFF,~0x3FFC,~0x1FF8,~0x0990}, //SandMob3 {~0x0C30,~0x1E78,~0x3E7C,~0x3FFC,~0x3FFC,~0x3FFC,~0x3FFC,~0x1FF8,~0x3FFC,~0x7FFE,~0x7FFE,~0xFFFF,~0x7FFE,~0x7FFE,~0x0FF0,~0x0660}, //SandMob4 {~0x0000,~0x0000,~0x03c0,~0x0ff0,~0x1ff8,~0x3ffc,~0x3ffc,~0x7ffe,~0xffff,~0xffff,~0xffff,~0x7ffe,~0xffff,~0xffff,~0xffff,~0x3ffc}, {~0x0000,~0x03c0,~0x0ff0,~0x1ff8,~0x3ffc,~0x3ffc,~0x7ffe,~0xffff,~0xffff,~0xffff,~0x7ffe,~0xffff,~0xffff,~0xffff,~0xffff,~0x3ffc}, {~0xf3cf,~0xffff,~0x7ffe,~0x3ffc,~0x7ffc,~0xfffe,~0xffff,~0xffff,~0xffff,~0xfffe,~0x3ffc,~0x3ffc,~0x3ffc,~0x1ffc,~0x3ffe,~0x00fe}, {~0xf3cf,~0xffff,~0x7ffe,~0x3ffc,~0x3ffe,~0x7fff,~0xffff,~0xffff,~0xffff,~0x7fff,~0x3ffc,~0x3ffc,~0x3ffc,~0x3ff8,~0x7ffc,~0x7f00}, {~0x07f0,~0x0fff,~0x1fff,~0x3fff,~0x7fff,~0x7fff,~0xfffe,~0xfffe,~0xfffe,~0xfffc,~0xfff8,~0xfff8,~0x3ff0,~0x7fe0,~0x7fc0,~0x7fe0}, {~0x07f0,~0x0fff,~0x1fff,~0x3fff,~0x7fff,~0x7fff,~0xfffe,~0xfffe,~0xfffe,~0xfffc,~0xfff8,~0xfff8,~0x3ff0,~0x7fe0,~0x7fc0,~0x7fe0}, {~0xf3cf,~0xffff,~0x7ffe,~0x3ffc,~0x7ffe,~0xffff,~0xffff,~0xffff,~0xffff,~0x7fff,~0x7fff,~0x7ffe,~0x7ffc,~0x3ff0,~0x7ff8,~0x7fc0}, {~0xf3cf,~0xffff,~0x7fff,~0x3fff,~0x7fff,~0xffff,~0xffff,~0xffff,~0xffff,~0xfffe,~0xfffe,~0x7ffe,~0x3ffe,~0x0ffc,~0x1ffe,~0x03fe}, {~0x0fe0,~0xfff0,~0xfff8,~0xfffc,~0xfffe,~0xfffe,~0x7fff,~0x7fff,~0x7fff,~0x3fff,~0x1fff,~0x1fff,~0x0ffc,~0x07fe,~0x03fe,~0x07fe}, {~0x0fe0,~0xfff0,~0xfff8,~0xfffc,~0xfffe,~0xfffe,~0x7fff,~0x7fff,~0x7fff,~0x3fff,~0x1fff,~0x1fff,~0x0ffc,~0x07fe,~0x03fe,~0x07fe}, {~0x07e0,~0x0ff0,~0x1ff8,~0x3ffc,~0x7ffe,~0xffff,~0xffff,~0xffff,~0xffff,~0xffff,~0xffff,~0x7ffe,~0x3ffc,~0x1ff8,~0x0ff0,~0x07e0}, }; /*---------------------------------------------------------------------------*/ /* Functions */ /*---------------------------------------------------------------------------*/ /*============================================================================*/ /* AnimateMob is used to define mob-specific behavior. It passes a mobs data */ /* to MoveMob, which defines general movement patterns, to create a mobs */ /* specific behavior. */ /*============================================================================*/ //--------------------------------------------------------------------------------- // MOB_NUMBER refers to the list number in mob_list // // MOB_X and MOB_Y keep track of where the mob is. // // MOB_FRAME applys to which frame a mobs animation is on. Each game loop this // frame is increased. Bascially a mob program just defines what a mob does on each // frame. This method is similar to how Link and Terrain animations are done too. // // MOB_DIRECTION stores what direction a mob is currently facing. // // MOB_PAUSE is used to store how long a mob's movement // is delayed. NOTE however that this IS NOT automatically done for you in AnimateMob // because of so many variations on mob pauses, so you'll have to write your own // routine to stop the mob from moving. (basically MOB_PAUSE could be used as a // free variable like the MOB_VARs, but i just added it cause it was so common. // // MOB_VAR1 and MOB_VAR2 are used to store mob-specific data that doesnt // apply to every mob. Bascially, they are free variables for whatever you want // to use them for. // //--------------------------------------------------------------------------------- void AnimateMob(void) { int list_num; int count1=0; //Used as temporary variable. NOT TO BE USED BETWEEN FRAMES! //------------------------------------------------------ // Cycles through each mob in mob_list //------------------------------------------------------ for (list_num=0;list_num<5;list_num++) { //--------------------------------------------------------------------- // This routine applys to all mobs. When MOB_PAUSE is less than 0, // they are reeling back from a blow (caused by a Sword, arrow, etc.) //--------------------------------------------------------------------- if (mob_list[list_num][MOB_PAUSE] < 0) { mob_list[list_num][MOB_PAUSE]++; switch (link_direction) { case UP: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_Y] -= 10; break; case RIGHT: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] += 10; break; case DOWN: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_Y] += 10; break; case LEFT: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] -= 10; break; } //--------------------------------------------------------------------- // Once mob recovers from the blow, make him explode if he dies. //--------------------------------------------------------------------- if (mob_list[list_num][MOB_PAUSE] == 0) { AddObject(EXPLODE1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]); mob_list[list_num][MOB_NUMBER] = -1; } } switch(mob_list[list_num][MOB_NUMBER]) { case CRAB1: //Crabs are usually found on the beach //--------------------------------- // Shows the crab shuffling about //--------------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 3: DrawImage(MOB, CRAB1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 4 ... 6: DrawImage(MOB, CRAB2, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, CRAB1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } //------------------------------------------------------- // Occasionally the Crab will move with a speed of 3 // MOB_VAR keeps track of how long it's moving at 3 //------------------------------------------------------- if (mob_list[list_num][MOB_VAR1] == 0 && !random(50)) mob_list[list_num][MOB_VAR1] = 70; if (mob_list[list_num][MOB_VAR1] > 0) mob_list[list_num][MOB_VAR1]--; if (mob_list[list_num][MOB_VAR1]) MoveMob(list_num, MOB_WANDER, 3); else MoveMob(list_num, MOB_WANDER, 2); break; case BUTTERFLY1: //Butterflies are usually found in town //------------------------- // Flutters the butterfly //------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 2: DrawImage(MOB, BUTTERFLY1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 3 ... 4: DrawImage(MOB, BUTTERFLY2, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, BUTTERFLY1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } MoveMob(list_num, MOB_FLUTTER, 1); break; case DMOB1: //Shelled mob found in doungens //------------------------- // Flutters the butterfly //------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 2: DrawImage(MOB, DMOB1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 3 ... 4: DrawImage(MOB, DMOB2, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, DMOB1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } MoveMob(list_num, MOB_FOLLOW, 1); break; case SPIKE1: //SPIKED mob found in doungens //------------------------- // Flutters the butterfly //------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 2 : DrawImage(MOB, SPIKE1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, SPIKE1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } MoveMob(list_num, MOB_SPIKE, 1); break; case MONSTER1: //Classic Zelda Octapus-looking monster //------------------------------------------------------------------ // count1 temporarily store direction offsets, which point DrawImage // to the right picture to draw. I know I could plug this into a // formula, but doing it this way makes it much clearer. //------------------------------------------------------------------ count1=0; switch(mob_list[list_num][MOB_DIRECTION]) { case LEFT: count1 += 2; case DOWN: count1 += 2; case RIGHT: count1 += 2; case UP: break; } //----------------------------------------- // The monster occasionally stops moving. //----------------------------------------- if (mob_list[list_num][MOB_PAUSE] == 0 && !random(50)) mob_list[list_num][MOB_PAUSE] = 10; if (mob_list[list_num][MOB_PAUSE] > 0) { mob_list[list_num][MOB_PAUSE]--; DrawImage(MOB, MONSTER1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; } //----------------------------------------------------------------------------- // Draws mob, taking into account the direction its facing, and its shuffling //----------------------------------------------------------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 2: DrawImage(MOB, MONSTER1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 3 ... 4: DrawImage(MOB, MONSTER1+count1+1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, MONSTER1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } MoveMob(list_num, MOB_WANDER, 2); break; case GOBLIN1: //Classic Zelda Octapus-looking monster //------------------------------------------------------------------ // count1 temporarily store direction offsets, which point DrawImage // to the right picture to draw. I know I could plug this into a // formula, but doing it this way makes it much clearer. //------------------------------------------------------------------ count1=0; switch(mob_list[list_num][MOB_DIRECTION]) { case LEFT: count1 += 2; case DOWN: count1 += 2; case RIGHT: count1 += 2; case UP: break; } //----------------------------------------- // The monster occasionally stops moving. //----------------------------------------- if (mob_list[list_num][MOB_PAUSE] == 0 && !random(50)) mob_list[list_num][MOB_PAUSE] = 10; if (mob_list[list_num][MOB_PAUSE] > 0) { mob_list[list_num][MOB_PAUSE]--; DrawImage(MOB, GOBLIN1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; } //----------------------------------------------------------------------------- // Draws mob, taking into account the direction its facing, and its shuffling //----------------------------------------------------------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 2: DrawImage(MOB, GOBLIN1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 3 ... 4: DrawImage(MOB, GOBLIN1+count1+1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, GOBLIN1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } MoveMob(list_num, MOB_WANDER, 1); break; case URCHIN1: //Spikey creatures from the beach //------------------------------------------ // Just shows it moving. Thats all it does //------------------------------------------ switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 5: DrawImage(MOB, URCHIN1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 6 ... 10: DrawImage(MOB, URCHIN2, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 11 ... 15: DrawImage(MOB, URCHIN3, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 16 ... 20: DrawImage(MOB, URCHIN4, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, URCHIN1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } break; case DOG1: //Dogs are usually found in town //------------------------------------------------------------------ // count1 temporarily store direction offsets, which point DrawMob // to the right picture to draw. //------------------------------------------------------------------ count1=0; switch(mob_list[list_num][MOB_DIRECTION]) { case UP: case LEFT: count1 += 2; default: break; } //----------------------------------------------------------------------------- // Draws whichever direction he is facing. The mob_list[list_num][MOB_VAR1] // stores how high the dog is jumping, and is generated by MOB_HOP from MoveMob(). //----------------------------------------------------------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 2: DrawImage(MOB, DOG1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y] - mob_list[list_num][MOB_VAR1], A_NORMAL); break; case 3 ... 4: DrawImage(MOB, DOG2+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y] - mob_list[list_num][MOB_VAR1], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, DOG1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y] - mob_list[list_num][MOB_VAR1], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } //------------------------------------------------------------------------------------- // The dog is sometimes traveling in two directions. This routine makes it so // when the dog is facing left or right, it is still also traveling up and down, // and vice versa. MOB_VAR2 stores a number 0, 1 or 2, which is used to determine // whether the dog will go UP or DOWN, and is chosen randomly when he stops moving. // If the variable is 2, it wont travel in 2 directions. // // NOTE: If the dog is already moving UP or DOWN, it doesnt use MOB_VAR2; // it just moves LEFT or RIGHT according to which direction he is facing. //------------------------------------------------------------------------------------- if ((mob_list[list_num][MOB_DIRECTION] == LEFT || mob_list[list_num][MOB_DIRECTION] == RIGHT) && mob_list[list_num][MOB_PAUSE] == 0 && mob_list[list_num][MOB_VAR2] != 2) { if (mob_list[list_num][MOB_VAR2] == UP) { if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]-1, 16, 16)) mob_list[list_num][MOB_Y] -= 1; } else { if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]+1, 16, 16)) mob_list[list_num][MOB_Y] += 1; } } if ((mob_list[list_num][MOB_DIRECTION] == UP || mob_list[list_num][MOB_DIRECTION] == DOWN) && mob_list[list_num][MOB_PAUSE] == 0 && mob_list[list_num][MOB_VAR2] != 2) { if (mob_list[list_num][MOB_DIRECTION] == UP) { if (!CheckTerrainCollision(mob_list[list_num][MOB_X]-1, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] -= 1; } else { if (!CheckTerrainCollision(mob_list[list_num][MOB_X]+1, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] += 1; } } //-------------------------------------------------------------- // Makes the dog randomly stop moving. //-------------------------------------------------------------- if (mob_list[list_num][MOB_PAUSE] == 0 && !random(50)) { mob_list[list_num][MOB_PAUSE] = random(15)+10; mob_list[list_num][MOB_VAR2] = random(3); } //---------------------------------------------------- // If the dog resumes movement, change its direction //---------------------------------------------------- if (mob_list[list_num][MOB_PAUSE] > 0) { mob_list[list_num][MOB_PAUSE]--; if (mob_list[list_num][MOB_PAUSE] == 0) mob_list[list_num][MOB_DIRECTION] = random(4); break; } MoveMob(list_num, MOB_HOP, 1); break; case CHICKEN1: //------------------------------------------------------------------ // The chicken basically has the same program as the dog, but with // very minor tweaks, which graphically make alot of difference. //------------------------------------------------------------------ //------------------------------------------------------------------ // count1 temporarily store direction offsets, which point DrawMob // to the right picture to draw. //------------------------------------------------------------------ count1=0; switch(mob_list[list_num][MOB_DIRECTION]) { case UP: case LEFT: count1 += 2; default: break; } //------------------------------------------------------------------------ // Checks if the chicken resumes movement. This is different from the dog // in that it doesnt give the chicken a chance to animate when it is paused. // It also doesnt give him a new random direction. //------------------------------------------------------------------------ if (mob_list[list_num][MOB_PAUSE] > 0) { mob_list[list_num][MOB_PAUSE]--; DrawImage(MOB, CHICKEN1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y] - mob_list[list_num][MOB_VAR1], A_NORMAL); break; } //----------------------------------------------------------------------------- // Draws whichever direction the chicken is facing. The mob_list[list_num][MOB_VAR1] // stores how high the chicken is jumping, and is generated by MOB_HOP from MoveMob(). //----------------------------------------------------------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 1 ... 4: //Chicken's flapping wings doenst animate as fast as a dog walking DrawImage(MOB, CHICKEN1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y] - mob_list[list_num][MOB_VAR1], A_NORMAL); break; case 5 ... 8: DrawImage(MOB, CHICKEN2+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y] - mob_list[list_num][MOB_VAR1], A_NORMAL); break; default: //This causes mob_frame reset when it has reached its max DrawImage(MOB, CHICKEN1+count1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y] - mob_list[list_num][MOB_VAR1], A_NORMAL); mob_list[list_num][MOB_FRAME] = 0; } //------------------------------------------------------------------------------------- // The chicken is sometimes traveling in two directions. This routine makes it so // when the chicken is facing left or right, it is still also traveling up and down, // and vice versa. MOB_VAR2 stores a number 0, 1 or 2, which is used to determine // whether the chicken will go UP or DOWN, and is chosen randomly when he stops moving. // If the variable is 2, it wont travel in 2 directions. // // NOTE: If the chicken is already moving UP or DOWN, it doesnt use MOB_VAR2; // it just moves LEFT or RIGHT according to which direction he is facing. //------------------------------------------------------------------------------------- if ((mob_list[list_num][MOB_DIRECTION] == LEFT || mob_list[list_num][MOB_DIRECTION] == RIGHT) && mob_list[list_num][MOB_PAUSE] == 0 && mob_list[list_num][MOB_VAR2] != 2) { if (mob_list[list_num][MOB_VAR2] == UP) { if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]-1, 16, 16)) mob_list[list_num][MOB_Y] -= 1; } else { if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]+1, 16, 16)) mob_list[list_num][MOB_Y] += 1; } } if ((mob_list[list_num][MOB_DIRECTION] == UP || mob_list[list_num][MOB_DIRECTION] == DOWN) && mob_list[list_num][MOB_PAUSE] == 0 && mob_list[list_num][MOB_VAR2] != 2) { if (mob_list[list_num][MOB_DIRECTION] == UP) { if (!CheckTerrainCollision(mob_list[list_num][MOB_X]-1, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] -= 1; } else { if (!CheckTerrainCollision(mob_list[list_num][MOB_X]+1, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] += 1; } } //-------------------------------------------------------------- // Makes the chicken randomly stop moving. // // The chicken randomly stops alot more than the dog, but for // shorter periods of time. //-------------------------------------------------------------- if (mob_list[list_num][MOB_PAUSE] == 0 && !random(20)) { mob_list[list_num][MOB_PAUSE] = 10; mob_list[list_num][MOB_VAR2] = 3; } MoveMob(list_num, MOB_HOP, 1); break; case SANDMOB1: //Creatures that come up from the ground, twirl a bit, then digs itself back into the sand //------------------------------------------------------------ // MOB_VAR1 stores how long hes in the ground. 0 if hes not. //------------------------------------------------------------ if (mob_list[list_num][MOB_VAR1]) { mob_list[list_num][MOB_VAR1]--; //------------------------------------------------------------- // Once the SandMob is ready to come back up, reset his frame //------------------------------------------------------------- if (mob_list[list_num][MOB_VAR1] == 0) { mob_list[list_num][MOB_FRAME] = 0; //--------------------------------------- // Occasionally, rise from Link's feet. //--------------------------------------- if(!random(3)) { mob_list[list_num][MOB_X] = link_x; mob_list[list_num][MOB_Y] = link_y; } } break; } //------------------------------------------------------------- // Frames 0 - 15, and 80-90 show it rising from the sand. // Anything inbetween just shows the mob spinning. At frame // 91 the mob goes back into the ground, and the frames reset //------------------------------------------------------------- switch(mob_list[list_num][MOB_FRAME]) { case 0 ... 5: DrawImage(MOB, SANDMOB1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 6 ... 10: DrawImage(MOB, SANDMOB2, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 11 ... 15: DrawImage(MOB, SANDMOB3, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 80 ... 85: DrawImage(MOB, SANDMOB2, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 86 ... 90: DrawImage(MOB, SANDMOB1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); break; case 91: mob_list[list_num][MOB_VAR1] = 40; break; default: //If the mob is above the ground, twirl it, and move it. if (mob_list[list_num][MOB_FRAME] % 2) DrawImage(MOB, SANDMOB3, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); else DrawImage(MOB, SANDMOB4, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); MoveMob(list_num, MOB_FOLLOW, 1); } break; } mob_list[list_num][MOB_FRAME]++; //Move to the next frame. } } /*===========================================================================*/ /* MoveMob works with AnimateMob to define a mobs behavior. MoveMob defines */ /* general movements patterns (such as MOB_WANDER and MOB_FLUTTER), which is */ /* modified by AnimateMob to create a mobs specific behavior. */ /* */ /* Takes in the list number from mob_list, the mobs general move type, */ /* and the mobs movement speed. */ /*===========================================================================*/ void MoveMob(int list_num, short move_type, short ani_speed) { switch (move_type) { //----------------------------------------------------------------------------- // Constantly moves; if hit a wall, turn the opposite way - (example: CRAB1) //----------------------------------------------------------------------------- case MOB_WANDER: switch (mob_list[list_num][MOB_DIRECTION]) { case RIGHT: //---------------------------------------------- // If the mob wont run into anything, move him //---------------------------------------------- if (!CheckTerrainCollision(mob_list[list_num][MOB_X]+ani_speed, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] += ani_speed; else //---------------------------------------------- // Otherwise move him in the other direction //---------------------------------------------- mob_list[list_num][MOB_DIRECTION] = LEFT; break; case LEFT: if (!CheckTerrainCollision(mob_list[list_num][MOB_X]-ani_speed, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] -= ani_speed; else mob_list[list_num][MOB_DIRECTION] = RIGHT; break; case UP: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]-ani_speed, 16, 16)) mob_list[list_num][MOB_Y] -= ani_speed; else mob_list[list_num][MOB_DIRECTION] = DOWN; break; case DOWN: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]+ani_speed, 16, 16)) mob_list[list_num][MOB_Y] += ani_speed; else mob_list[list_num][MOB_DIRECTION] = UP; break; } //--------------------------------------------- // Randomly change directions once in a while //--------------------------------------------- if(!random(100)) { mob_list[list_num][MOB_DIRECTION]--; if (mob_list[list_num][MOB_DIRECTION] < UP) mob_list[list_num][MOB_DIRECTION] = LEFT; } break; //--------------------------------------------------------------------- // Move randomly - doesnt check for collision - (example: BUTTERFLY1) //--------------------------------------------------------------------- case MOB_FLUTTER: switch (mob_list[list_num][MOB_DIRECTION]) { //------------------------------------------------------------------------------------ // These cases make the mob flutter towards a certain direction // 2-random(5) means the range of numbers is: -2 -1 0 1 2, meaning there is an equal opportunity to go any direction. // 2-random(2) means the range of numbers is: 1 2, meaning it moves toward a direction //------------------------------------------------------------------------------------ case UP: mob_list[list_num][MOB_Y] -= 2-random(2); mob_list[list_num][MOB_X] += 2-random(5); break; case RIGHT: mob_list[list_num][MOB_Y] += 2-random(5); mob_list[list_num][MOB_X] += 2-random(2); break; case DOWN: mob_list[list_num][MOB_Y] += 2-random(2); mob_list[list_num][MOB_X] += 2-random(5); break; case LEFT: mob_list[list_num][MOB_Y] += 2-random(5); mob_list[list_num][MOB_X] -= 2-random(2); break; } //--------------------------------------------- // Randomly change directions once in a while //--------------------------------------------- if(!random(20)) { mob_list[list_num][MOB_DIRECTION]--; if (mob_list[list_num][MOB_DIRECTION] < UP) mob_list[list_num][MOB_DIRECTION] = LEFT; } break; case MOB_HOP: //------------------------------------------------------------------------------ // **NOTE**: To use this movement-type, MOB_VAR1 must be free. // // MOB_HOP uses MOB_VAR1 to keep track of how many pixels a mob hops. To use // the hop, you actually have to add it to your mob defined in AnimateMob(). // // This routine just constantly scrolls through MOB_VAR1, and draws a shadow // under the mob when it is high in the air (when MOB_VAR1 is 2) //------------------------------------------------------------------------------ switch (mob_list[list_num][MOB_VAR1]) { case 2: DrawImage(OBJECT, SHADOW1, mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y], A_NORMAL); case 0: case 1: mob_list[list_num][MOB_VAR1]++; break; default: mob_list[list_num][MOB_VAR1] = 0; } //-------------------------------------------------------------- // Moves the mob (while hopping). It cannot // move below pixel 2 since it is hopping 2 pixels each round. //-------------------------------------------------------------- switch (mob_list[list_num][MOB_DIRECTION]) { case RIGHT: //---------------------------------------------- // If the mob wont run into anything, move him //---------------------------------------------- if (!CheckTerrainCollision(mob_list[list_num][MOB_X]+ani_speed, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] += ani_speed; break; case LEFT: if (!CheckTerrainCollision(mob_list[list_num][MOB_X]-ani_speed, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] -= ani_speed; break; case UP: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]-ani_speed-2, 16, 16)) mob_list[list_num][MOB_Y] -= ani_speed; break; case DOWN: if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]+ani_speed, 16, 16)) mob_list[list_num][MOB_Y] += ani_speed; break; } //--------------------------------------------- // Randomly change directions once in a while //--------------------------------------------- if(!random(40)) { mob_list[list_num][MOB_DIRECTION]--; if (mob_list[list_num][MOB_DIRECTION] < UP) mob_list[list_num][MOB_DIRECTION] = LEFT; } break; //--------------------------------------------------- // Follow makes the mob move towards where Link is. //--------------------------------------------------- case MOB_SPIKE: //-------------------------------------------------------------------- // These routines are pretty simple. Move the mob toward link, while // checking if it hit anything in its path. //-------------------------------------------------------------------- if (mob_list[list_num][MOB_Y] > link_y) { mob_list[list_num][MOB_DIRECTION] = UP; if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]-ani_speed-2, 16, 16)) mob_list[list_num][MOB_Y] -= ani_speed; } else { mob_list[list_num][MOB_DIRECTION] = DOWN; if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]+ani_speed, 16, 16)) mob_list[list_num][MOB_Y] += ani_speed; } break; case MOB_FOLLOW: //-------------------------------------------------------------------- // These routines are pretty simple. Move the mob toward link, while // checking if it hit anything in its path. //-------------------------------------------------------------------- if (mob_list[list_num][MOB_X] > link_x) { mob_list[list_num][MOB_DIRECTION] = LEFT; if (!CheckTerrainCollision(mob_list[list_num][MOB_X]-ani_speed, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] -= ani_speed; } else { mob_list[list_num][MOB_DIRECTION] = RIGHT; if (!CheckTerrainCollision(mob_list[list_num][MOB_X]+ani_speed, mob_list[list_num][MOB_Y], 16, 16)) mob_list[list_num][MOB_X] += ani_speed; } if (mob_list[list_num][MOB_Y] > link_y) { mob_list[list_num][MOB_DIRECTION] = UP; if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]-ani_speed-2, 16, 16)) mob_list[list_num][MOB_Y] -= ani_speed; } else { mob_list[list_num][MOB_DIRECTION] = DOWN; if (!CheckTerrainCollision(mob_list[list_num][MOB_X], mob_list[list_num][MOB_Y]+ani_speed, 16, 16)) mob_list[list_num][MOB_Y] += ani_speed; } break; } //--------------------------------------------------------- // In all cases, the mob must not go out of screen bounds // If the mob reaches edge of screen, walk other way //--------------------------------------------------------- if (mob_list[list_num][MOB_X] > 160-16) { mob_list[list_num][MOB_X] = 160-16; mob_list[list_num][MOB_DIRECTION] = LEFT; } if (mob_list[list_num][MOB_X] < 0) { mob_list[list_num][MOB_X] = 0; mob_list[list_num][MOB_DIRECTION] = RIGHT; } if (mob_list[list_num][MOB_Y] < 0) { mob_list[list_num][MOB_Y] = 0; mob_list[list_num][MOB_DIRECTION] = DOWN; } if (mob_list[list_num][MOB_Y] > 8*16-16) { mob_list[list_num][MOB_Y] = 8*16-16; mob_list[list_num][MOB_DIRECTION] = UP; } } //------------------------------------------------------------------------- // SlashMob takes in an area, and determines if any mob lies in that area //------------------------------------------------------------------------- void SlashMob(short x, short y, short width, short height) { int count1; for (count1=0;count1<5;count1++) { //------------------------------------------------------ // Special mob cases //------------------------------------------------------ switch (mob_list[count1][MOB_NUMBER]) { //Butterfly is immune to hits case BUTTERFLY1: continue; //Sandmob is immune inside the ground. case SANDMOB1: if (mob_list[count1][MOB_VAR1] > 0) continue; break; } //------------------------------------------------------------------------------------------ // If Link hits the mob, make mob reel back for 3 rounds. (this is explained in AnimateMob) //------------------------------------------------------------------------------------------ if ( CheckAreaCollision(x,y,width,height, mob_list[count1][MOB_X], mob_list[count1][MOB_Y], 16, 16) && mob_list[count1][MOB_NUMBER] >= 0) { mob_list[count1][MOB_PAUSE] = -3; } } }