From a2e35698fe94fbe0c784d59cb845f6b1ae829585 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 17 Oct 2021 16:22:09 +0200 Subject: [PATCH] add judgement skill, improve anim format --- CMakeLists.txt | 21 +++++------ assets-cg/converters.py | 9 ++++- assets-cg/skillicons.png | Bin 707 -> 769 bytes assets-cg/skills/fxconv-metadata.txt | 50 +++++++++++++++----------- assets-cg/skills/hit.png | Bin 181 -> 0 bytes assets-cg/skills/impale_down.png | Bin 213 -> 0 bytes assets-cg/skills/impale_left.png | Bin 176 -> 0 bytes assets-cg/skills/impale_right.png | Bin 181 -> 0 bytes assets-cg/skills/impale_up.png | Bin 217 -> 0 bytes assets-cg/skills/judgement.aseprite | Bin 0 -> 2128 bytes assets-cg/skills/swing_down.png | Bin 256 -> 0 bytes assets-cg/skills/swing_left.png | Bin 295 -> 0 bytes assets-cg/skills/swing_right.png | Bin 274 -> 0 bytes assets-cg/skills/swing_up.png | Bin 262 -> 0 bytes assets-cg/skills/teleport.aseprite | Bin 972 -> 944 bytes assets-cg/skills/teleport.png | Bin 341 -> 0 bytes src/anim.c | 4 +-- src/anim.h | 9 ++--- src/entities.c | 51 +++++++++++++++++++-------- src/entities.h | 9 +++-- src/game.c | 4 +-- src/main.c | 9 +++++ src/render.c | 5 +-- 23 files changed, 108 insertions(+), 63 deletions(-) delete mode 100644 assets-cg/skills/hit.png delete mode 100644 assets-cg/skills/impale_down.png delete mode 100644 assets-cg/skills/impale_left.png delete mode 100644 assets-cg/skills/impale_right.png delete mode 100644 assets-cg/skills/impale_up.png create mode 100644 assets-cg/skills/judgement.aseprite delete mode 100644 assets-cg/skills/swing_down.png delete mode 100644 assets-cg/skills/swing_left.png delete mode 100644 assets-cg/skills/swing_right.png delete mode 100644 assets-cg/skills/swing_up.png delete mode 100644 assets-cg/skills/teleport.png diff --git a/CMakeLists.txt b/CMakeLists.txt index f819758..2be051b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,16 +47,17 @@ set(ASSETS assets-cg/player/player_down.aseprite assets-cg/player/player_left.aseprite # Skill animations - assets-cg/skills/swing_up.png - assets-cg/skills/swing_right.png - assets-cg/skills/swing_down.png - assets-cg/skills/swing_left.png - assets-cg/skills/impale_up.png - assets-cg/skills/impale_right.png - assets-cg/skills/impale_down.png - assets-cg/skills/impale_left.png - assets-cg/skills/hit.png - assets-cg/skills/teleport.png + assets-cg/skills/swing_up.aseprite + assets-cg/skills/swing_right.aseprite + assets-cg/skills/swing_down.aseprite + assets-cg/skills/swing_left.aseprite + assets-cg/skills/impale_up.aseprite + assets-cg/skills/impale_right.aseprite + assets-cg/skills/impale_down.aseprite + assets-cg/skills/impale_left.aseprite + assets-cg/skills/hit.aseprite + assets-cg/skills/judgement.aseprite + assets-cg/skills/teleport.aseprite assets-cg/skills/shock.aseprite # Enemies: Slime assets-cg/enemies/slime_idle_left.png diff --git a/assets-cg/converters.py b/assets-cg/converters.py index 5a6e6ab..6d34461 100644 --- a/assets-cg/converters.py +++ b/assets-cg/converters.py @@ -215,7 +215,8 @@ def convert_aseprite_anim(input, output, params): print(f"{os.path.basename(input)} ({ase.header.width}x{ase.header.height})", f"has {len(tags)} animations:") for (name, from_, to) in tags: - print(f" '{name}': Frames {from_} to {to}", end="") + name = f"'{name}'" if name else "(untagged)" + print(f" {name}: Frames {from_} to {to}", end="") durations = [ase.frames[i].frame_duration for i in range(from_, to+1)] print(" (" + ", ".join(f"{d} ms" for d in durations) + ")") @@ -232,6 +233,12 @@ def convert_aseprite_anim(input, output, params): if chunk.chunk_type == 0x2005: # Cel # Render only visible layers if ase.layers[chunk.layer_index].flags & 1: + # Resolve linked cells + if chunk.cel_type == 1: # Linked cel + x = ase.frames[chunk.data['link'][0]].chunks + x = [c for c in x if c.chunk_type == 0x2005] + chunk = x[chunk.layer_index] + cel = _aseprite_render_cel(chunk) img.paste(cel, (chunk.x_pos, chunk.y_pos)) diff --git a/assets-cg/skillicons.png b/assets-cg/skillicons.png index 2eb8e1f66eff9351e096fc887e971e5b4e39b59c..4008c86f24f3a8cc1dbaa591083e3d38ed8be153 100644 GIT binary patch literal 769 zcmV+c1OEJpP)Px%yGcYrRA_3Bo|;Qfb3 zGU<5~8{G3VR>Vc;GAl3BMOOa#?R!=ZqBy%hh+-ns7PTSLlxZKy<4(sT`sN44tNv>M zpuA~CRedt)c~mzdw_%0?uo6idLxq2k4MI~!va-qc zc-=bsj;RhD8ruUdGN5VP@+$uqHY0M|FupCip^1JJ;fP)hOkhh_#`b{Pf@~=Jt!efq z&GIJNG_=gHT^efD%qF9rA4J=$OB?k~;8fWpP{Ee23|pzL?h2XJYueDgNwYkZ!-Uo@ z@2|t&nQ8i!K{wKyoI@Rc)7&JsbahdQ+PZ18$&CvhtC1=C`msx0ov5vAjH;1EeX7#e zy-TyA_dh^ykm}S|P3tUM6g>ol5K@*=oPRBPOh7nn=!*tbXTilxtnv=aOch<vNd=xW)?lsss^YIc$pT{5$TmJtehZ<$ueEQA9$*L$>9$?EYk&oC?-J^ zlVP`GM3*t_c9f5e6wRlq$Oc|Ti=P)ol%-;4Iv&y6>l-{LiMFBaJLc{64W{D}Wgn*d z?Ut4Px%eMv+?RA_4c;(lG#7%%%hYA3xo* z`Oqb#*ym?F#D#O2#hYZE#ZNzeX0abeS${u_Se~|Q44G!0b{nx5vnjp#MR+xO4FDt> zt75N>5YGWxo}6Y{_W2pUd`|%UF`mbJY+BC?l9{25S09bj+JcLUpSYw%;tDw7mslaKa2o?DKlG> zQNNdI=d~juVvHGI1y#pk^Px+1Gy4#3IshXXnVK$rNFpKtcrLSfTy{Lm+;qB)XtwOP z3cI*TyD*vAho*{SQA*J~EZMfK2~6qcarn@tU@1k{WOSyah(?<~D!5 zqMF2%Ze4V;Kd(fn#t{377|n3mSHJ(MTPORgX1a18UPYu0$o9v8+T5mgA7$@b$Cian zzywU_%Suw&GS#_Pdz0k7${*fW(YcbMLS=^TDo~ZKA}l|Q*d|%S8@oE={)0Dmu}RkO z!-)A|#3lo$5naw?;AkJQ>6%oeS4GEK%%*gEeS^n1u5CL14t{%mgT-u0{P1Da@72=f z@RK8cPO3xG^}VW&4FC_p3h$;K-hcaC%k)jM#`5G855Wp}@pm4BwcegCSD^~C@H002ovPDHLkV1nElTnPXG diff --git a/assets-cg/skills/fxconv-metadata.txt b/assets-cg/skills/fxconv-metadata.txt index 999b46b..2e67ad6 100644 --- a/assets-cg/skills/fxconv-metadata.txt +++ b/assets-cg/skills/fxconv-metadata.txt @@ -1,24 +1,34 @@ -*.png: - custom-type: animation - name_regex: (.*)\.png anim_\1 - center: 0, 0 - profile: p8 - -swing_*.png: - frame_duration: 30, 60, 30, 30, 30, 60, 30 - -impale_*.png: - frame_duration: 60, 60, 60, 60, 60 - -hit.png: - frame_duration: 60, 90, 90, 60, 90 - -teleport.png: - frame_duration: 90, 90, 90, 60, 60 - *.aseprite: custom-type: aseprite-anim name_regex: (.*)\.aseprite anims_skill_\1 - center: 0, 0 - profile: p8 + profile: p4 +hit.aseprite: + center: 3, 3 + +impale_up.aseprite: + center: 4, 10 +impale_right.aseprite: + center: 0, 4 +impale_left.aseprite: + center: 10, 4 +impale_down.aseprite: + center: 4, 0 + +judgement.aseprite: + center: 10, 26 + +teleport.aseprite: + center: 8, 19 + +shock.aseprite: + center: 18, 18 + +swing_up.aseprite: + center: 9, 8 +swing_right.aseprite: + center: 0, 9 +swing_left.aseprite: + center: 8, 9 +swing_down.aseprite: + center: 9, 0 diff --git a/assets-cg/skills/hit.png b/assets-cg/skills/hit.png deleted file mode 100644 index bc22dfdf420f9f170e91e1e369d7bc7726ebba39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^%0SG{!3HFoo_whUQjEnx?oJHr&dIz4a`HW0978lF zE)6~?c0hrn>)-$RcT?Y4%0=YPnIdAE-6P-85m5Gv$L?{=8xaYv|CvlK&puM5`nd^cHG`+CpUXO@geCyezh~J9q!^2X+?^QKos)S9zcR+!ICHDXS^s0+32b6AII*w7fBQu-E=3k zI-h$}U0KbH{-bH-heLnmmzb9KyKu(GNxbdfb@1BsJw}qE_F^9y-aY;7v{$kw59l-o MPgg&ebxsLQ0ObW$O#lD@ diff --git a/assets-cg/skills/impale_left.png b/assets-cg/skills/impale_left.png deleted file mode 100644 index 9f8c2e7ac36b61b5da18d83cccb873a3a60b5170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^=0MEJ!3HF!t==*lNHG=%xjQkeJ16rJ$jS0_aSXBO zy*p*2&;bPw=fnT&OLmnc2y`x;Hz)rK6H7qjvJXoaZT_G8G>zfFnYOKaFM2F~5@}>I zTS+#)*k#rWpU(MZbA1D6emc=HYxSdC9LgD*%%5M3s>%Sn! b>ay)so5y8AcYG6pwla9S`njxgN@xNATG2-o diff --git a/assets-cg/skills/impale_right.png b/assets-cg/skills/impale_right.png deleted file mode 100644 index a9d590f59eed87f25fdf800e4170ebcf74553b25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^=0MEJ!3HF!t==*lNHG=%xjQkeJ16rJ$jSF~aSXBO zy&K}lcR+!s>A!u|ZXNICZ-YwGdhhfEYzS*?vd}y8>1Xbm8!`+Y%l_uvShMbP;O-RD z#a5~Im-bxU#h)pDVAs1{$&WK`z3We7p0zRL@T3&8EzcKLr0(qBW&G%s`S$;_qkHey go$d-)uJmYr;mXHlryPGz2U^YG>FVdQ&MBb@02=pAHUIzs diff --git a/assets-cg/skills/impale_up.png b/assets-cg/skills/impale_up.png deleted file mode 100644 index 42d46a09befef277802dd9004731e9684af11af1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^xzh~J9q!^2X+?^QKos)S9~{CFMdv zk_>D37_Q`TzvP*=K-KKBZNcP?OCpQ>*F9f;wddU0yX!A$-&?J2CAE8wb@3GTy7#p= zPnGb@_u9;u^;WiHO>31HZ?H)G(>J}#_q)5b-8}Q6T6{KB_TPyK_0K(bFe*wOpS5^@ RIycaH44$rjF6*2UngGacR%`$O diff --git a/assets-cg/skills/judgement.aseprite b/assets-cg/skills/judgement.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..66f0667adc0e9741a85d635808d5205039d7918a GIT binary patch literal 2128 zcmcJQc~FvR9LHZH)68RXC$&N$H;*o_v4aF`Hp326vr(zgGz*UuuT0b|D-DZQtdtZ{ zYs)Uf$`!>9ZI{#v&8-xNQasU&%rno5{o&ZwxV!CN`@HjhczJnVzMt>=3@@(g2-1?L zf#@Mv*i;Y%p~L=lz&YhfL>;#OW0b5SpaKShWbsOXiH8}$z@Q-D4i7ir!Jke6 zZ`#-ZC7yo3hPb;x*7?oAQ=wLhASf_XdEc>c041OS=z}|mgEc6FFUW!^Xo4dMf*q)V z7f68-=qOzj3a|hL$cJ!9hFHjiKuCiqj4}y}0)82wfT$r(zA^hEu+~=aMir}E==q3Z z#+NCx5EMe^`uX_yjIw4K+)i#ihdQZ(4DnY#35F@-{VJ0Sr(7-y?8@s^ks04yuZf^1 zuYWjGaTH-%Irm{SNcGzt2~Ijo-UiMly+nn_23*h4Yq8f(a4}qj+apX#&3+_EH{g$c z+;plu{5lFz+qq!q@w6<#RF+cntE(>DLprzT+#Rh1E6tgbBPdf}b<%}PSMt_tMD+U{ zGqf|+-RfP4-S)X7!{6WlZ`bDg8jek;&6)VpwO!)-=-JDwGlq@P-j~(Y9whXS99mmd zJ2sGO%y^6u&vj;^BSM*DLwNfNg05QO$C%+F{-bllspWVk$3-5=9TqX8V|R|Eu4!c5 zkcF`;`=m8)fnuYasNqlUq8r^3IYFgpk1H}Vtw+~X4|w^ehw`UL=gQKzY6#b~1|cQuAs~wYWacwCJ5(_&IiUR#vc-?c%Yt_i1c^t`BPFzxK^~_hSseVPeEq1fO~x7Lid7B4}QO8)WN8N zVo&Mr`oycOr6a*!EjMqXI>Rgk_U*pT8}t|CJJkqp8rkYppL`a6ue^LXAimhV{O;jL zsQ)3I^6{`}^wtR}BwQsvXO`*F9({up<$itY{;{Pa~0L4ocTKJQU zK6To&0-CA8iO|Cww+oNg1-~FKi?3ko9$Qg0|I(GD+f;AMBetu}j&%LrC8JFkn%GI+ zxfC`SRLD#$akXh6`16~Ba5bGx~pvX_PQQUZR>t8rWw-9c%owqfjV`AxQ5L!(wFV2DW2QN}gQ`OfhKlG^NbO&AC z0c&h0{*gWOq_|?3xN|#kC(T6lRbi&5Od257M=^E6&c<@lVr!SY=n8S^L3B zn*Zh)?m--WxYqu>pLhQFIMKYIG&7b{8|El&C-IX<-v-y+d)~OWm-lQhZ@_SeSZ63` zG3)uXuD?xn{pTle#t`Tu>2y4vAz6-};;L$bfJqVw3#~Ja9 zx4pcICdPFJ;6rL`{Kc}j6tTR%-7AMrwAGfM;i0KA1F)wg(BxxW`COkID#*XhoBX@@YaW9938E1sKmY&$ literal 0 HcmV?d00001 diff --git a/assets-cg/skills/swing_down.png b/assets-cg/skills/swing_down.png deleted file mode 100644 index 4211fc8caeddab617675c0d1ed2a8f7fc327220c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmV+b0ssDqP)Px#x=BPqR9J=Om%$EzAPhsD@&A8$UL^4VVWW?T+Pjasl^VAVkY6HLe-b%2l69y? z2orafnVGx0nHj;N{MGo>8I<2LJC!AwAcj*57Qt#UR`#rL3X2G-)D)`JrfEGNy)nJ> zGXqw`Ry-?i*(QS9JnQ-LwQSMr9iS0000Px#;Ymb6R9J=GmrD-AFbD;CRquagy0U~&C}3>kc6Lb+@_>H<{Ta;6L_`4K#k@}q zs=^p7ku4=-yj%dl%xqTY7PQopd?ZH413+8nXQaO68Qsi`;gtzqMMg?ubySLbU6(P( z!Ca=Y^q8)6V_LTxu)^e09*1Tr-bRV?I zM+J8lA}w!iYAbf^)08@2J+r%uv2@x;HmUJGb0gcuqr7)s>sa|L<+P}d=_cLz%-WU( tn8~vnSKj-YP)Px#%t=H+R9J=8SV0cJAP5t)|9^SA%*2=oMQy;It62*rxbpre1`y6|kWrL~$c)^$ z8mI9rP6kx;BYTr(U4U>hp{^d(3}}XCkCUr4k%;usKw^SMiGk(HTd*Q9ijL?2mw2Q) zo(e|K1$X78gXdhv{L|VVg(aA2NVs?pP8&fHe`<2G_Xb+!M*}i$d=K+-uizPGwHF|_)2sQIFoSFrt?7a diff --git a/assets-cg/skills/swing_up.png b/assets-cg/skills/swing_up.png deleted file mode 100644 index 2b79c2771814c012f4a9fee182928db6461925f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262 zcmV+h0r~!kP)Px#z)3_wR9J=WmfH@1APhsD@&A9hzPN;#pmK zK~rr$Dxj;jkXNi$<`sJ;qpeRTP^yw5vRSP$BLgt=S4-wzb&Ef%l<%zc|2sZ2cSgsE z_P~?`%50zM0pyCuZ1cT*5$^#sB~S diff --git a/assets-cg/skills/teleport.aseprite b/assets-cg/skills/teleport.aseprite index 4499d909750110400b71b6be7568b26da1794c75..d5751f5d5a0655fe81c08dfaff78a798a042a531 100644 GIT binary patch delta 314 zcmX@ZzJZ-_!$ih<#wQyaI~WY5MTdVYUw<<=|{yu{6*e%uaArjQ9zmzhN*C;tYo@#o5vs7#Mzi zWMqf}(u_bH4#cbqAT|rbeQVYu z5?8HPO_$kwE9bYCYxvi?d@O8pt{j49;BaAOxWnzfcpII6WGzZxpZy+CJ4>JQ3 zl0DoEA`pAH{w0eaTgBJ*QJaNH!*xoOghZ(IrmO#sGZm~nxP1NutD0BR9~p!0ax=s? zbFhQV0-0?Cq(OeLo~+I+r_13>G*4WrQ>w&$H!}G^N>>nBZH~DM<0FIJ^H~;_u diff --git a/assets-cg/skills/teleport.png b/assets-cg/skills/teleport.png deleted file mode 100644 index 7887195e198c858fef1238b9e4c5d94cab8437e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341 zcmV-b0jmCqP)Px$4@pEpR9J=Wmg^3KAPh#^W$*vW-JfZY75K_cVLb`if)v^#qC}1rDGhkd$YLi% zicXi3TCQf!97R@NMa|2jEhTw0@^LmAKRa zxYPmsl~m+B?6S`B2l@W`309J{%!3rE%{NOud8YVe{W n>MNvlE~D$Li22dmT}Tf;`A^gOzIEgF00000NkvXXu0mjfHLaB) diff --git a/src/anim.c b/src/anim.c index 9d47132..cddcbca 100644 --- a/src/anim.c +++ b/src/anim.c @@ -24,8 +24,8 @@ prefix ## _left_ ## suffix, \ }; -DIRECTIONAL_ANIM(anim_swing); -DIRECTIONAL_ANIM(anim_impale); +DIRECTIONAL_ANIM(anims_skill_swing); +DIRECTIONAL_ANIM(anims_skill_impale); ANIM_4DIRECTIONAL(anims_player, Idle); ANIM_4DIRECTIONAL(anims_player, Walking); diff --git a/src/anim.h b/src/anim.h index 9ac7055..bfe3882 100644 --- a/src/anim.h +++ b/src/anim.h @@ -48,9 +48,10 @@ void anim_state_update(anim_state_t *state, fixed_t dt); /* List of animations. */ /* Basic animations. */ -extern anim_frame_t anim_hit[]; -extern anim_frame_t anim_teleport[]; +extern anim_frame_t anims_skill_hit[]; +extern anim_frame_t anims_skill_teleport[]; extern anim_frame_t anims_skill_shock[]; +extern anim_frame_t anims_skill_judgement[]; /* Enemy animations (bidirectional). */ @@ -73,5 +74,5 @@ extern anim_frame_t *anims_player_Idle[4]; extern anim_frame_t *anims_player_Walking[4]; extern anim_frame_t *anims_player_Attack[4]; extern anim_frame_t *anims_player_Hit[4]; -extern anim_frame_t *anim_swing[4]; -extern anim_frame_t *anim_impale[4]; +extern anim_frame_t *anims_skill_swing[4]; +extern anim_frame_t *anims_skill_impale[4]; diff --git a/src/entities.c b/src/entities.c index e74bd6e..ebbde8f 100644 --- a/src/entities.c +++ b/src/entities.c @@ -192,30 +192,45 @@ effect_area_t *effect_area_new_attack(uint16_t type, entity_t *e, int facing) if(!area) return NULL; frect_t hitbox = { 0 }; - fixed_t distance = fix(0.75); + fixed_t distance = fix(0.625); fpoint_t dir = fdir(facing); + fpoint_t anchor = rect_center(entity_sprite(e)); anim_frame_t *anim = NULL; + bool rotate = true; if(type == EFFECT_ATTACK_HIT) { - anim = anim_hit; + anim = anims_skill_hit; hitbox = (frect_t){ -fix(4)/16, fix(3)/16, -fix(4)/16, fix(3)/16 }; } else if(type == EFFECT_ATTACK_SLASH) { - anim = anim_swing[facing]; - hitbox = (frect_t){ -fix(10)/16, fix(10)/16, -fix(4)/16, fix(4)/16 }; + anim = anims_skill_swing[facing]; + hitbox = (frect_t){ -fix(10)/16, fix(10)/16, -fix(8)/16, 0 }; + if(facing == UP || facing == DOWN) + anchor = entity_pos(e); } else if(type == EFFECT_ATTACK_IMPALE) { - anim = anim_impale[facing]; - hitbox = (frect_t){ -fix(4)/16, fix(4)/16, -fix(5)/16, fix(5)/16 }; + anim = anims_skill_impale[facing]; + hitbox = (frect_t){ -fix(4)/16, fix(4)/16, -fix(10)/16, 0 }; + if(facing == UP || facing == DOWN) + anchor = entity_pos(e); } else if(type == EFFECT_ATTACK_SHOCK) { anim = anims_skill_shock; - hitbox = (frect_t){ -fix(18)/16, fix(18)/16, -fix(19)/16, fix(19)/16 }; + hitbox = (frect_t){ -fix(17)/16, fix(18)/16, -fix(17)/16, fix(18)/16 }; + anchor = entity_pos(e); distance = fix(0); + rotate = false; + } + else if(type == EFFECT_ATTACK_JUDGEMENT) { + anim = anims_skill_judgement; + hitbox = (frect_t){ -fix(10)/16, fix(11)/16, -fix(6)/16, fix(6)/16 }; + anchor = entity_pos(e); + distance = fix(1.5); + rotate = false; } - area->sprite = rect_rotate(hitbox, UP, facing); - area->anchor = rect_center(entity_sprite(e)); + area->sprite = rotate ? rect_rotate(hitbox, UP, facing) : hitbox; + area->anchor = anchor; area->anchor.x += fmul(distance, dir.x); area->anchor.y += fmul(distance, dir.y); area->lifetime = anim_duration(anim); @@ -224,9 +239,10 @@ effect_area_t *effect_area_new_attack(uint16_t type, entity_t *e, int facing) if(type == EFFECT_ATTACK_HIT || type == EFFECT_ATTACK_SLASH - || type == EFFECT_ATTACK_IMPALE) { - area->data.slash.strength = e->ATK; - area->data.slash.dir = facing; + || type == EFFECT_ATTACK_IMPALE + || type == EFFECT_ATTACK_JUDGEMENT) { + area->data.generic.strength = e->ATK; + area->data.generic.dir = facing; } else if(type == EFFECT_ATTACK_SHOCK) { area->data.shock.strength = e->ATK; @@ -275,8 +291,8 @@ static bool attack_apply(game_t *game, effect_area_t *ea, entity_t *e) if(ea->type == EFFECT_ATTACK_HIT || ea->type == EFFECT_ATTACK_SLASH || ea->type == EFFECT_ATTACK_IMPALE) { - dir = fdir(ea->data.slash.dir); - damage = ea->data.slash.strength; + dir = fdir(ea->data.generic.dir); + damage = ea->data.generic.strength; } else if(ea->type == EFFECT_ATTACK_SHOCK) { dir.x = e->movement.x - ea->data.shock.origin.x; @@ -284,6 +300,10 @@ static bool attack_apply(game_t *game, effect_area_t *ea, entity_t *e) dir = fnormalize(dir); damage = ea->data.shock.strength * 3 / 2; } + else if(ea->type == EFFECT_ATTACK_JUDGEMENT) { + r = fix(0); + damage = ea->data.generic.strength * 5; + } /* Inflict damage */ damage = entity_damage(e, damage); @@ -316,7 +336,8 @@ void effect_area_apply(game_t *game, effect_area_t *ea, entity_t *e) if(ea->type == EFFECT_ATTACK_HIT || ea->type == EFFECT_ATTACK_SLASH || ea->type == EFFECT_ATTACK_IMPALE - || ea->type == EFFECT_ATTACK_SHOCK) + || ea->type == EFFECT_ATTACK_SHOCK + || ea->type == EFFECT_ATTACK_JUDGEMENT) was_hit = attack_apply(game, ea, e); if(!was_hit) return; diff --git a/src/entities.h b/src/entities.h index 9a1bef4..dcf6dae 100644 --- a/src/entities.h +++ b/src/entities.h @@ -130,8 +130,9 @@ enum { EFFECT_ATTACK_SLASH, /* Impaling attack using a slashing weapon */ EFFECT_ATTACK_IMPALE, - /* Shock attack */ + /* Skills */ EFFECT_ATTACK_SHOCK, + EFFECT_ATTACK_JUDGEMENT, /* Monster spawning */ EFFECT_SPAWN, }; @@ -166,10 +167,8 @@ typedef struct effect_area { uint16_t type; /* Effect data (type-dependent) */ union { - /* EFFECT_ATTACK_HIT: source and ATK strength */ - struct { int strength; int dir; } hit; - /* EFFECT_ATTACK_SLASH: source and ATK strength */ - struct { int strength; int dir; } slash; + /* Generic attacks: source and ATK strength */ + struct { int strength; int dir; } generic; /* EFFECT_ATTACK_SHOCK: origin and ATK strength */ struct { int strength; fpoint_t origin; } shock; } data; diff --git a/src/game.c b/src/game.c index 1392627..0dda918 100644 --- a/src/game.c +++ b/src/game.c @@ -112,10 +112,10 @@ void game_spawn_entity(game_t *g, entity_t *e, fpoint_t pos) effect_area_t *area = effect_area_new(EFFECT_SPAWN); area->sprite = hitbox; area->anchor = entity_pos(e); - area->lifetime = anim_duration(anim_teleport); + area->lifetime = anim_duration(anims_skill_teleport); area->repeat_delay = 0; area->origin = e; - effect_area_set_anim(area, anim_teleport); + effect_area_set_anim(area, anims_skill_teleport); game_add_effect_area(g, area); e->current_attack = area; diff --git a/src/main.c b/src/main.c index 9412d81..2e05254 100644 --- a/src/main.c +++ b/src/main.c @@ -459,6 +459,15 @@ int main(void) player->current_attack = area; player->attack_follows_movement = true; } + if(player->HP > 0 && keydown(KEY_F3) && !player->current_attack) { + effect_area_t *area = effect_area_new_attack( + EFFECT_ATTACK_JUDGEMENT, player, player->movement.facing); + game_add_effect_area(&game, area); + + entity_set_anim(player, anims_player_Attack, 2); + player->current_attack = area; + player->attack_follows_movement = false; + } /* Remove dead entities first as it will kill their attack areas */ game_remove_dead_entities(&game); diff --git a/src/render.c b/src/render.c index f32631f..c6b6ec0 100644 --- a/src/render.c +++ b/src/render.c @@ -145,10 +145,7 @@ static void render_effect_area(effect_area_t const *ea, camera_t const *c, ipoint_t anchor = camera_map2screen(c, ea->anchor); if(ea->anim.frame) { - fpoint_t top_left = { - ea->anchor.x + ea->sprite.l, - ea->anchor.y + ea->sprite.t }; - ipoint_t p = camera_map2screen(c, top_left); + ipoint_t p = camera_map2screen(c, ea->anchor); anim_frame_render(p.x, p.y, ea->anim.frame); } if(!ea->anim.frame || show_hitboxes) {