From e600723a95b646c9b8237d65bf72c813234a4199 Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Mon, 6 Mar 2023 17:11:11 -0800 Subject: [PATCH] Bullet deflection with sword, combat improve --- assets.mdesk | 4 ++ assets/bullet.png | Bin 0 -> 1085 bytes assets/drop_shadow.png | Bin 0 -> 755 bytes assets/level0.json | 4 +- main.c | 135 +++++++++++++++++++++++++++-------------- 5 files changed, 95 insertions(+), 48 deletions(-) create mode 100644 assets/bullet.png create mode 100644 assets/drop_shadow.png diff --git a/assets.mdesk b/assets.mdesk index 73c9f43..d589535 100644 --- a/assets.mdesk +++ b/assets.mdesk @@ -50,6 +50,10 @@ { filepath: "white square.png", } +@image bullet: +{ + filepath: "bullet.png", +} @image shift_icon: { filepath: "shift_icon.png", diff --git a/assets/bullet.png b/assets/bullet.png new file mode 100644 index 0000000000000000000000000000000000000000..ca9038ba05a65a9381da45415d27619381aa0707 GIT binary patch literal 1085 zcmV-D1j74?P)8?2pf}Zlt)VvK%?IZBy~#=kIr`*7+?h2D$EFgpAIo!nh9&HF7 zq!>yIx<%p1i!T~mODS-CSFI10$Y%$_(b&}wlh^0u> zb8Db>pcH`^_=H*$Gu~F;fwj-grmQ{d%$9V=0B>P9hacv!{iyGO8HNL;2!Qm?gq84; z2APB@t2;DE-Jz}Pt^vj|n&i}K8K}zPibOuri9mJf0`PXK!JxokW7|?g?h*DKCxWbC zo)Kh@VAn31Q#j|1QU!^k6oH(<_TfA@Wncx==#Cl`rVTrK^z;zR%^W7KnW+=0Bmw4W zpmqUTKT><@CkOXZt5Ta3aY2;004ft!m2m>kG(?C>Dj?I?NMXA-LK)l;wE!~@#R$M%E0xkosSHP|@+t^wD=KuMryoogmoR@fSs zBM_pDm})|cNQfOl#2L8NE;1Q>Vb7X^g0ViHk|a+%5$IS6kL|9H1G0zQ|Kca0RXc8% z*(FatGui>j3%yDccixw*gti#sDN1pa^4u$$%qyY_Xg?Qir@s5NZcnNM`WwRXDlOAG z-Uq%<%}#8ucNK`8U6fLqb6|6hPRfa&f-O}^OJ7YA&r+=1zyG0eb2$Pl-Up8Dseglo z9gc4YjU6)jQCs@#hW1xhznm4WY7amD<$XZgvoBNlSRVMnBv#``W z$lZxy-8q?;Kn_c~qpu?a!^VE@KZ&di3``xKE{-7;jBju6%@%Q#Irh=rx64|ki!t6H zQ|FS#B)32Ry&YM&xz}$nP~w{RV&QZpv3G~hP0}d8)3tx@+`E749voM@e%Ho)_vX(^ zj6l<|0iTPeyvO50Kd<7uR65UY{?bi7zPdT5H!oa)OPUoCj28Sjy6Y4iP&vFdP$^CJQK z6?~hf3;gCdr#LsGA~E-|T*Wf06FEh!*T3l9=S!DT|GsDYDUpP}2Y=2~E&9mzZMzO* zndF>itE&}xo&Qgr-*5ivg=B^E-2(mUxU0Ut)A#>wUUe<>Z^#C{rq2f+uiW)Jkf$>~ zTW;C@>0Barcc`!Ypl+}CC+WYh<2voWbaRf}-N(6V?zyvl_qp*j#BouR^`(-w-~SKi zmMmciJSfYZ+qxw*q=4NiS}|8tG$wQNPgU;B)hiz8wQO^`rKPpwk(d;>*rl+*gL63{ zD(7*=bMM~K>lDVT6n_B7+!He4#LiP`$FIaDPIe8I7ged6v~#A*+*eX}%(_DocSTfv z{M731xBckvx$hm;uc}&~5W9Bf-+;YLZ~jgUj`jJ<|D%;@deOR58=oJUyejV9%xo!} zqA$~0&%X*d_qH;be}m+!{lRUyZ))GHE@_yjD1Uk1sn(|LYHuz*_e)#vdpBJ6(Ssentence_to_say = new_sentence; } -// from_point is for knockback -void request_do_damage(Entity *to, Vec2 from_point, float damage) -{ - if(to == NULL) return; - if(to->npc_kind != DEATH) - { - to->damage += damage; - to->aggressive = true; - to->vel = MulV2F(NormV2(SubV2(to->pos, from_point)), 5.0f); - } -} - #include "prompts.gen.h" void begin_text_input(); // called when player engages in dialog, must say something and fill text_input_buffer @@ -1349,13 +1344,19 @@ void dbgline(Vec2 from, Vec2 to) { #ifdef DEVTOOLS if(!show_devtools) return; - line(from, to, 2.0f, RED); + line(from, to, 0.5f, RED); #else (void)from; (void)to; #endif } +void dbgvec(Vec2 from, Vec2 vec) +{ + Vec2 to = AddV2(from, vec); + dbgline(from, to); +} + // in world space void dbgrect(AABB rect) { @@ -1373,6 +1374,29 @@ void dbgrect(AABB rect) #endif } +// from_point is for knockback +void request_do_damage(Entity *to, Vec2 from_point, float damage) +{ + if(to == NULL) return; + if(to->is_bullet) + { + Vec2 norm = NormV2(SubV2(to->pos, from_point)); + dbgvec(from_point, norm); + to->vel = ReflectV2(to->vel, norm); + dbgprint("deflecitng\n"); + } + else if(to->npc_kind != DEATH) + { + to->damage += damage; + to->aggressive = true; + to->vel = MulV2F(NormV2(SubV2(to->pos, from_point)), 15.0f); + } + else + { + Log("Can't do damage to npc...\n"); + } +} + typedef struct TextParams { @@ -1632,8 +1656,6 @@ float draw_wrapped_text(bool dry_run, Vec2 at_point, float max_width, char *text void draw_dialog_panel(Entity *talking_to) { - // talking to them feedback - draw_quad((DrawParams){true, quad_centered(talking_to->pos, V2(TILE_SIZE, TILE_SIZE)), image_dialog_circle, full_region(image_dialog_circle), WHITE}); float panel_width = 250.0f; float panel_height = 150.0f; float panel_vert_offset = 30.0f; @@ -1960,15 +1982,16 @@ void frame(void) it->shotgun_timer = 0.0f; const float spread = (float)PI/4.0f; // shoot shotgun - for(int i = 0; i < 3; i++) + int num_bullets = 5; + for(int i = 0; i < num_bullets; i++) { Vec2 dir = to_player; - float theta = Lerp(-spread/2.0f, ((float)i / 2.0f), spread/2.0f); + float theta = Lerp(-spread/2.0f, ((float)i / (float)(num_bullets - 1)), spread/2.0f); dir = RotateV2(dir, theta); Entity *new_bullet = new_entity(); new_bullet->is_bullet = true; new_bullet->pos = AddV2(it->pos, MulV2F(dir, 20.0f)); - new_bullet->vel = MulV2F(dir, 10.0f); + new_bullet->vel = MulV2F(dir, 15.0f); it->vel = AddV2(it->vel, MulV2F(dir, -3.0f)); } } @@ -2000,12 +2023,15 @@ void frame(void) else if (it->is_bullet) { it->pos = AddV2(it->pos, MulV2F(it->vel, pixels_per_meter * dt)); - draw_quad((DrawParams){true, quad_aabb(entity_aabb(it)), image_white_square, full_region(image_white_square), WHITE}); + dbgvec(it->pos, it->vel); + AABB normal_aabb = entity_aabb(it); + Quad drawn = quad_centered(aabb_center(normal_aabb), MulV2F(aabb_size(normal_aabb), 1.5f)); + draw_quad((DrawParams){true, drawn, IMG(image_bullet), WHITE}); Overlapping over = get_overlapping(cur_level, entity_aabb(it)); Entity *from_bullet = it; BUFF_ITER(Overlap, &over) if(it->e != from_bullet) { - if(!it->is_tile && !(it->e->npc_kind == DEATH)) + if(!it->is_tile && !(it->e->npc_kind == DEATH) && !(it->e->is_bullet)) { // knockback and damage request_do_damage(it->e, from_bullet->pos, 0.2f); @@ -2069,7 +2095,9 @@ void frame(void) // if somebody, show their dialog panel if(talking_to) { - draw_dialog_panel(talking_to); + // talking to them feedback + draw_quad((DrawParams){true, quad_centered(talking_to->pos, V2(TILE_SIZE, TILE_SIZE)), image_dialog_circle, full_region(image_dialog_circle), WHITE}); +draw_dialog_panel(talking_to); } // process dialog and display dialog box when talking to NPC @@ -2105,32 +2133,8 @@ void frame(void) if(attack && (player->state == CHARACTER_IDLE || player->state == CHARACTER_WALKING)) { player->state = CHARACTER_ATTACK; + BUFF_CLEAR(&player->done_damage_to_this_swing); player->swing_progress = 0.0; - AABB weapon_aabb = {0}; - if(player->facing_left) - { - weapon_aabb = (AABB){ - .upper_left = AddV2(player->pos, V2(-40.0, 25.0)), - .lower_right = AddV2(player->pos, V2(0.0, -25.0)), - }; - } - else - { - weapon_aabb = (AABB){ - .upper_left = AddV2(player->pos, V2(0.0, 25.0)), - .lower_right = AddV2(player->pos, V2(40.0, -25.0)), - }; - } - dbgrect(weapon_aabb); - Overlapping overlapping_weapon = get_overlapping(cur_level, weapon_aabb); - BUFF_ITER(Overlap, &overlapping_weapon) - { - if(!it->is_tile && it->e != player) - { - request_do_damage(it->e, player->pos, 0.2f); - } - } - } @@ -2199,6 +2203,45 @@ void frame(void) } else if(player->state == CHARACTER_ATTACK) { + AABB weapon_aabb = {0}; + if(player->facing_left) + { + weapon_aabb = (AABB){ + .upper_left = AddV2(player->pos, V2(-40.0, 25.0)), + .lower_right = AddV2(player->pos, V2(0.0, -25.0)), + }; + } + else + { + weapon_aabb = (AABB){ + .upper_left = AddV2(player->pos, V2(0.0, 25.0)), + .lower_right = AddV2(player->pos, V2(40.0, -25.0)), + }; + } + dbgrect(weapon_aabb); + Overlapping overlapping_weapon = get_overlapping(cur_level, weapon_aabb); + BUFF_ITER(Overlap, &overlapping_weapon) + { + if(!it->is_tile && it->e != player) + { + bool done_damage = false; + Entity *looking_for = it->e; + BUFF_ITER(Entity*, &player->done_damage_to_this_swing) + { + if(*it == looking_for) done_damage = true; + } + if(!done_damage) + { + if(!BUFF_HAS_SPACE(&player->done_damage_to_this_swing)) + { + BUFF_REMOVE_FRONT(&player->done_damage_to_this_swing); + Log("Too many things to do damage to...\n"); + } + BUFF_APPEND(&player->done_damage_to_this_swing, looking_for); + request_do_damage(it->e, player->pos, 0.2f); + } + } + } player->swing_progress += dt; draw_animated_sprite(&knight_attack, player->swing_progress, player->facing_left, character_sprite_pos, WHITE);