44
55#include < maxmod9.h>
66#include < cstdlib>
7+ #include < cstdio>
78#include " spider.h"
89#include " ../../globals_declarations.h"
910#include " ../animations/blood.h"
1213#include " ../../collisions/collisions.h"
1314#include " ../../tiles/map_utils.h"
1415#include " ../../../build/soundbank.h"
16+ #include " ../sprite_utils.h"
1517
1618#define SPIDER_HITPOINTS 1
1719#define SPIDER_POS_INC_DELTA 30
@@ -30,58 +32,54 @@ void Spider::draw() {
3032 return ;
3133
3234 set_position ();
33-
34- subSpriteInfo->entry ->hFlip = true ;
35- mainSpriteInfo->entry ->hFlip = true ;
36- mainSpriteInfo->entry ->isHidden = false ;
37- subSpriteInfo->entry ->isHidden = false ;
35+ sprite_utils::set_visibility (true , mainSpriteInfo, subSpriteInfo);
36+ sprite_utils::set_vertical_flip (false , mainSpriteInfo, subSpriteInfo);
37+ sprite_utils::set_horizontal_flip (false , mainSpriteInfo, subSpriteInfo);
3838
3939 if (!hunting)
40+ // Check if main dude is direcly under the spider - intentionally not checking for terrain obstacles,
41+ // like in the original game. Also check if main dude is in certain range
4042 hunting = abs (y - global::main_dude->y ) < 9 * TILE_H && global::main_dude->x + MAIN_DUDE_PHYSICAL_WIDTH > x &&
4143 global::main_dude->x < x + physical_width && global::main_dude->y > y;
42- else
44+ else {
45+ time_since_last_big_jump += *global::timer;
46+ time_since_last_jump += *global::timer;
4347 animFrameTimer += *global::timer;
48+ }
4449
4550 if (animFrameTimer > SPIDER_ANIM_FRAME_DELTA) {
51+
52+ animFrameTimer = 0 ;
4653 animFrame++;
4754
4855 if (jumping && animFrame >= 4 ) {
56+ // done jumping, now still
4957 animFrame = 0 ;
5058 jumping = false ;
5159 }
5260
5361 if (hanging && hunting && animFrame >= 7 ) {
62+ // done rotating animation, now still
5463 animFrame = 0 ;
5564 hanging = false ;
5665 }
5766
58- if (hanging && !hunting)
59- set_sprite_hanging ();
60- else if (hanging && hunting)
61- set_sprite_flipping ();
62- else if (!hanging && hunting && jumping)
63- set_sprite_jumping ();
64- else
65- set_sprite_falling ();
66-
67- animFrameTimer = 0 ;
67+ match_animation ();
6868 }
6969
70+ if (hunting && bottomCollision && !hanging)
71+ jump_to_main_dude ();
7072
7173 kill_if_whip (1 );
7274 kill_if_main_dude_jumped_on_you (1 );
7375 deal_damage_main_dude_on_collision (1 );
74-
75- if (hunting && bottomCollision && !hanging) {
76- jump_to_main_dude ();
77- }
7876}
7977
8078
8179void Spider::init () {
82- initSprite ();
83- random_speed = 0 ;
8480 hanging = true ;
81+ random_speed = 0 ;
82+ initSprite ();
8583}
8684
8785void Spider::updateSpeed () {
@@ -94,8 +92,12 @@ void Spider::updateSpeed() {
9492
9593 if (pos_inc_timer > SPIDER_POS_INC_DELTA) {
9694 update_position ();
95+
9796 if (hunting)
98- apply_gravity (GRAVITY_DELTA_SPEED * 0.8 );
97+ if (previously_collided)
98+ apply_gravity (GRAVITY_DELTA_SPEED * 1 );
99+ else
100+ apply_gravity (GRAVITY_DELTA_SPEED * 0.8 );
99101
100102 pos_inc_timer = 0 ;
101103 }
@@ -105,101 +107,90 @@ void Spider::updateSpeed() {
105107
106108void Spider::updateCollisionsMap (int x_current_pos_in_tiles, int y_current_pos_in_tiles) {
107109
108- MapTile *tiles [9 ] = {};
109- Collisions::getNeighboringTiles (global::level_generator->map_tiles , x_current_pos_in_tiles,
110- y_current_pos_in_tiles, tiles );
110+ MapTile *t [9 ] = {};
111+ Collisions::getNeighboringTiles (global::level_generator->map_tiles ,
112+ x_current_pos_in_tiles, y_current_pos_in_tiles, t );
111113
112- standingOnLeftEdge = Collisions::isStandingOnLeftEdge (tiles , x, physical_width, x_current_pos_in_tiles);
113- standingOnRightEdge = Collisions::isStandingOnRightEdge (tiles , x, physical_width, x_current_pos_in_tiles);
114- bottomCollision = Collisions::checkBottomCollision (tiles , &x, &y, &ySpeed, physical_width, physical_height, false , 0 );
115- leftCollision = Collisions::checkLeftCollision (tiles , &x, &y, &xSpeed, physical_width, physical_height, false , 0 );
116- rightCollision = Collisions::checkRightCollision (tiles , &x, &y, &xSpeed, physical_width, physical_height, false , 0 );
117- upperCollision = Collisions::checkUpperCollision (tiles , &x, &y, &ySpeed, physical_width, false , 0 );
114+ standingOnLeftEdge = Collisions::isStandingOnLeftEdge (t , x, physical_width, x_current_pos_in_tiles);
115+ standingOnRightEdge = Collisions::isStandingOnRightEdge (t , x, physical_width, x_current_pos_in_tiles);
116+ bottomCollision = Collisions::checkBottomCollision (t , &x, &y, &ySpeed, physical_width, physical_height, false , 0 );
117+ leftCollision = Collisions::checkLeftCollision (t , &x, &y, &xSpeed, physical_width, physical_height, false , 0 );
118+ rightCollision = Collisions::checkRightCollision (t , &x, &y, &xSpeed, physical_width, physical_height, false , 0 );
119+ upperCollision = Collisions::checkUpperCollision (t , &x, &y, &ySpeed, physical_width, false , 0 );
118120
119- }
121+ if (bottomCollision)
122+ random_speed = 0 ;
120123
121- void Spider::apply_dmg (int dmg_to_apply) {
122124
123- // spider has only 1 dmg point, always kill if any dmg_apply
125+ if (!previously_collided && (leftCollision || rightCollision)) {
124126
125- subSpriteInfo-> entry -> isHidden = true ;
126- mainSpriteInfo-> entry -> isHidden = true ;
127+ xSpeed = 0 ;
128+ previously_collided = true ;
127129
128- spawn_blood ();
130+ if (leftCollision)
131+ previous_collision_side = SpriteState::W_LEFT;
132+ else
133+ previous_collision_side = SpriteState::W_RIGHT;
134+
135+ }
129136
137+ }
138+
139+ // !>spider has only 1 dmg point, always kill if any dmg_apply
140+ void Spider::apply_dmg (int dmg_to_apply) {
141+
142+ sprite_utils::set_visibility (false , mainSpriteInfo, subSpriteInfo);
143+ global::killed_npcs.push_back (SpriteType::S_SPIDER);
144+ spawn_blood ();
130145 killed = true ;
131146 ready_to_dispose = true ;
132- global::killed_npcs.push_back (SpriteType::S_SPIDER);
133147
134148}
135149
136150void Spider::initSprite () {
137151
138152 subSpriteInfo = global::sub_oam_manager->initSprite (gfx_spider_skeletonPal, gfx_spider_skeletonPalLen,
139- nullptr , sprite_width * sprite_height , 16 , SKELETON_SPIDER, true , false ,
140- LAYER_LEVEL::MIDDLE_TOP);
153+ nullptr , SPIDER_SPRITE_SIZE , 16 , SKELETON_SPIDER, true ,
154+ false , LAYER_LEVEL::MIDDLE_TOP);
141155 mainSpriteInfo = global::main_oam_manager->initSprite (gfx_spider_skeletonPal, gfx_spider_skeletonPalLen,
142- nullptr , sprite_width * sprite_height, 16 , SKELETON_SPIDER, true ,
143- false ,
144- LAYER_LEVEL::MIDDLE_TOP);
145-
146- frameGfx = (u8 *) gfx_spider_skeletonTiles + sprite_width * sprite_height * 4 / 2 ;
147- subSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
148- mainSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
149-
150-
151-
152- subSpriteInfo->entry ->isHidden = false ;
153- mainSpriteInfo->entry ->isHidden = false ;
154-
155- subSpriteInfo->entry ->vFlip = false ;
156- subSpriteInfo->entry ->hFlip = false ;
156+ nullptr , SPIDER_SPRITE_SIZE, 16 , SKELETON_SPIDER, true ,
157+ false , LAYER_LEVEL::MIDDLE_TOP);
158+ match_animation ();
159+ set_position ();
160+ sprite_utils::set_visibility (true , mainSpriteInfo, subSpriteInfo);
161+ sprite_utils::set_vertical_flip (false , mainSpriteInfo, subSpriteInfo);
162+ sprite_utils::set_horizontal_flip (false , mainSpriteInfo, subSpriteInfo);
157163
158- mainSpriteInfo->entry ->vFlip = false ;
159- mainSpriteInfo->entry ->hFlip = false ;
160164}
161165
162166void Spider::set_sprite_hanging () {
163- frameGfx = (u8 *) gfx_spider_skeletonTiles + (sprite_width * sprite_height * (4 ) / 2 );
164- subSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
165- mainSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
167+ frameGfx = sprite_utils::get_frame ((u8 *) gfx_spider_skeletonTiles, SPIDER_SPRITE_SIZE, 4 );
166168}
167169
168170void Spider::set_sprite_flipping () {
169- frameGfx = (u8 *) gfx_spider_skeletonTiles + (sprite_width * sprite_height * (animFrame + 4 ) / 2 );
170- subSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
171- mainSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
171+ frameGfx = sprite_utils::get_frame ((u8 *) gfx_spider_skeletonTiles, SPIDER_SPRITE_SIZE, animFrame + 4 );
172172}
173173
174174void Spider::set_sprite_jumping () {
175- frameGfx = (u8 *) gfx_spider_skeletonTiles + (sprite_width * sprite_height * (animFrame) / 2 );
176- subSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
177- mainSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
175+ frameGfx = sprite_utils::get_frame ((u8 *) gfx_spider_skeletonTiles, SPIDER_SPRITE_SIZE, animFrame);
178176}
179177
180178void Spider::set_sprite_falling () {
181- frameGfx = (u8 *) gfx_spider_skeletonTiles + (sprite_width * sprite_height * (0 ) / 2 );
182-
183- subSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
184- mainSpriteInfo->updateFrame (frameGfx, sprite_width * sprite_height);
179+ frameGfx = sprite_utils::get_frame ((u8 *) gfx_spider_skeletonTiles, SPIDER_SPRITE_SIZE, 0 );
185180}
186181
187-
188182void Spider::set_position () {
189183
190184 int main_x, main_y, sub_x, sub_y;
191185 get_x_y_viewported (&main_x, &main_y, &sub_x, &sub_y);
192186
193- mainSpriteInfo->entry ->x = main_x;
194- subSpriteInfo->entry ->x = sub_x;
195-
196187 if (!hanging) {
197- mainSpriteInfo->entry ->y = main_y - SPIDER_HANGING_OFFSET;
198- subSpriteInfo->entry ->y = sub_y - SPIDER_HANGING_OFFSET;
199- } else {
200- mainSpriteInfo->entry ->y = main_y;
201- subSpriteInfo->entry ->y = sub_y;
188+ main_y -= SPIDER_HANGING_OFFSET;
189+ sub_y -= SPIDER_HANGING_OFFSET;
202190 }
191+
192+ sprite_utils::set_entry_xy (mainSpriteInfo, main_x, main_y);
193+ sprite_utils::set_entry_xy (subSpriteInfo, sub_x, sub_y);
203194}
204195
205196Spider::Spider () {
@@ -209,26 +200,96 @@ Spider::Spider() {
209200 sprite_width = SPIDER_SPRITE_WIDTH;
210201 hitpoints = SPIDER_HITPOINTS;
211202 spritesheet_type = SpritesheetType::SKELETON_SPIDER;
212- sprite_type = SpriteType ::S_SPIDER;
203+ sprite_type = SpriteType::S_SPIDER;
213204}
214205
215206void Spider::jump_to_main_dude () {
207+
208+ if (!bottomCollision || time_since_last_jump < (200 + jump_delay))
209+ return ;
210+
211+ time_since_last_jump = 0 ;
212+
216213 int diff = global::main_dude->x - x > 0 ;
217214
218- if (diff > 40 )
219- diff = 40 ;
215+ bool additional_jump_speed = false ;
216+
217+ if (diff) {
218+
219+ if (previously_collided && time_since_last_big_jump > 2500 ) {
220220
221- if (diff)
222- random_speed = 1.1 + ((rand () % diff) / 10 );
221+ if (previous_collision_side == SpriteState::W_RIGHT) {
222+ random_speed = 0 .3f ;
223+ xSpeed = 0 .3f ;
224+ } else {
225+ random_speed = -0 .3f ;
226+ xSpeed = -0 .3f ;
227+ }
228+
229+ additional_jump_speed = true ;
230+ time_since_last_big_jump = 0 ;
231+
232+ } else {
233+ if (jump_delay >= 400 )
234+ random_speed = 1.5 + ((rand () % diff) / 10 );
235+ else
236+ random_speed = 1.1 + ((rand () % diff) / 10 );
237+ }
238+
239+ } else {
240+ if (previously_collided && time_since_last_big_jump > 2500 ) {
241+
242+ if (previous_collision_side == SpriteState::W_RIGHT) {
243+ random_speed = 0 .3f ;
244+ xSpeed = 0 .3f ;
245+ } else {
246+ random_speed = -0 .3f ;
247+ xSpeed = -0 .3f ;
248+ }
249+
250+ xSpeed = -0 .3f ;
251+ random_speed = -0 .3f ;
252+ additional_jump_speed = true ;
253+ time_since_last_big_jump = 0 ;
254+ } else {
255+ if (jump_delay >= 400 )
256+ random_speed = -1.5 + ((rand () % 3 ) / 10 );
257+ else
258+ random_speed = -1.1 + ((rand () % 3 ) / 10 );
259+ }
260+ }
261+
262+ if (additional_jump_speed)
263+ jump_delay = rand () % 700 ;
223264 else
224- random_speed = - 1.1 - (( rand () % diff) / 10 ) ;
265+ jump_delay = rand () % 500 ;
225266
226267 jumping = true ;
227268 animFrame = 0 ;
228- ySpeed = -1.5 - ((rand () % diff) / 5 );
269+ previously_collided = false ;
270+
271+ if (additional_jump_speed) {
272+ ySpeed = -3.5 ;
273+ } else
274+ ySpeed = -1.6 - ((rand () % 3 ) / 10 );
275+
229276}
230277
231278Spider::Spider (int x, int y) : Spider() {
232279 this ->x = x;
233280 this ->y = y;
234281}
282+
283+ void Spider::match_animation () {
284+
285+ if (hanging && !hunting)
286+ set_sprite_hanging ();
287+ else if (hanging && hunting)
288+ set_sprite_flipping ();
289+ else if (!hanging && hunting && jumping)
290+ set_sprite_jumping ();
291+ else
292+ set_sprite_falling ();
293+
294+ sprite_utils::update_frame (frameGfx, SPIDER_SPRITE_SIZE, mainSpriteInfo, subSpriteInfo);
295+ }
0 commit comments