From 57e5b0975764603f09f4656a782f83bf88ec2f8e Mon Sep 17 00:00:00 2001 From: AJ Fontaine Date: Tue, 22 Mar 2022 23:35:53 -0400 Subject: [PATCH] Midterm time --- README.md | 34 +-- config/catalog.json | 7 + config/texts.json | 5 + gfc | 2 +- images/battlers/Egglet/front.png | Bin 0 -> 573 bytes images/battlers/Mukchuk/front.png | Bin 0 -> 634 bytes images/battlers/Pyruff/front.png | Bin 0 -> 1035 bytes images/battlers/Sappurr/front.png | Bin 764 -> 781 bytes images/battlers/Squoink/front.png | Bin 1293 -> 634 bytes images/objects/HatKid.png | Bin 1047 -> 1149 bytes images/tiles/kt01.png | Bin 6041 -> 9195 bytes include/k_battle.h | 3 +- include/k_entity.h | 18 +- include/k_field.h | 17 +- include/k_item.h | 11 +- include/k_local.h | 8 + include/k_menu.h | 9 + include/k_monster.h | 15 +- include/k_save.h | 3 + include/k_species.h | 2 +- maps/map1.bin.bak | Bin 6400 -> 0 bytes maps/testfield.json | 170 ++++++++++++++- maps/testfield/coll.bin | Bin 0 -> 1640 bytes maps/testfield/coll.bin.bak | Bin 0 -> 3200 bytes maps/testfield/layer1.bin | Bin 0 -> 3200 bytes maps/testfield/layer1.bin.bak | Bin 0 -> 3200 bytes maps/testfield/layer2.bin | Bin 0 -> 3200 bytes maps/testfield/layer2.bin.bak | Bin 0 -> 3200 bytes maps/{map1.bin => testfield/map1.bin.bak} | Bin 3200 -> 3200 bytes saves/save1.json | 1 + saves/save1.sav | 2 +- src/game.c | 157 +++++++++----- src/k_battle.c | 24 ++- src/k_entity.c | 78 +++++++ src/k_field.c | 116 ++++++++-- src/k_hud.c | 19 ++ src/k_item.c | 44 ++++ src/k_local.c | 12 +- src/k_monster.c | 247 +++++++++++++++++++++- src/k_player.c | 13 +- src/k_save.c | 7 +- 41 files changed, 879 insertions(+), 145 deletions(-) create mode 100644 images/battlers/Egglet/front.png create mode 100644 images/battlers/Mukchuk/front.png create mode 100644 images/battlers/Pyruff/front.png delete mode 100644 maps/map1.bin.bak create mode 100644 maps/testfield/coll.bin create mode 100644 maps/testfield/coll.bin.bak create mode 100644 maps/testfield/layer1.bin create mode 100644 maps/testfield/layer1.bin.bak create mode 100644 maps/testfield/layer2.bin create mode 100644 maps/testfield/layer2.bin.bak rename maps/{map1.bin => testfield/map1.bin.bak} (86%) create mode 100644 src/k_item.c diff --git a/README.md b/README.md index 26649e9..57fd53e 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,8 @@ -# gameframework2d (GF2D) -a collection of utlitity functions designed to facilitate creating 2D games with SDL2 -This project is specifically intended to function as an educational tool for my students taking 2D Game Programming. +# Keystone -Currently the project is in a WIP state, however it is functional with sample projects showcasing rudimentary scrolling shooters, -platformers, and adventure games. +Pokemon-like RPG -The master branch is kept deliberately minimal to allow students to build out systems as they are learning. -Other branches have more complete system: Collisions, menus, input abstraction. - -# Build Process - -Before you can build the example code we are providing for you, you will need to obtain the libraries required -by the source code - - SDL2 - - SDL2_image - - SDL2_mixer - - SDL2_ttf -There are additional sub modules that are needed for this project to work as well, but they can be pulled right from within the project. -Performable from the following steps from the root of the cloned git repository within a terminal. - -Make sure you fetch submodules: `git submodule update --init --recursive` -Go into each submodule's src directory and type: -`make` -`make static` - -Once each submodule has been made you can go into the base project src folder anre simply type: -`make` - -You should now have a `gf2d` binary within the root of your git repository. Executing this will start your game. +- WASD to move +- You can't move through trees or other people +- Press enter to interact with people +- Be careful you might start sliding weeee diff --git a/config/catalog.json b/config/catalog.json index e69de29..b2a82c0 100644 --- a/config/catalog.json +++ b/config/catalog.json @@ -0,0 +1,7 @@ +{ + "sappurr": + { + "entry1":"It taps into trees with its root-like fangs, drinking the sap from within.", + "entry2":"If you invite one in your home, expect to find holes in your furniture soon." + } +} \ No newline at end of file diff --git a/config/texts.json b/config/texts.json index e69de29..d5a37cf 100644 --- a/config/texts.json +++ b/config/texts.json @@ -0,0 +1,5 @@ +{ + "hatkid_show_egglet" : { + "english":"Hey, can you show me an Egglet?" + } +} \ No newline at end of file diff --git a/gfc b/gfc index 47fc3a3..7d0aed3 160000 --- a/gfc +++ b/gfc @@ -1 +1 @@ -Subproject commit 47fc3a3a3d854d61f46a5da05bd07fc18d792fcb +Subproject commit 7d0aed3fd98bb76b2a348a223218d74c039f5498 diff --git a/images/battlers/Egglet/front.png b/images/battlers/Egglet/front.png new file mode 100644 index 0000000000000000000000000000000000000000..eb62a2981eae2b4f97ba94571063ad31f1974395 GIT binary patch literal 573 zcmV-D0>b@?P)Px#Cs0gOMVaMLo2|ELYHIfU|LXGh`|>uqvoU5lF~x>xk5)UFk{jCP>QX8r$?$S7 z0000DbW%=J0RR90|NsC0|NsC0|1AVTtpET4t4TybR9J=WmdkR(FbG8r!j`b||KHmS zD2>uCD!k|>W+t+e$vHws4{zHYcieHue+7}X%zPCug@Bh*t{4n26!-<+aqx~4#aOa< z1lt#plwranB$t8nBI0fEx%`XR!1KPYTZ)Hp=xXaP7`>o)DwnEKzIa5e52kI1`=n~8Yi7!7ZA2Dkl2Kjq>G`wXAEqH zZsW%du0S6MUOpXI1GGQ_0$4G)+y`+VC`5Zo24MsDEMXu@U&{+ z!8bFY|G*86`MqH9IzRx^qfNb&EB+RE>M(dF{N6jQ91&3j8pYt)S%9t|5yK!+P1JuV z*3Z~cLFbL)^;z`GfFo+(&&*P?;2qOHRx>s@+vBqQe#8P|;PyF_yipi>XY|h9d>MmN zkp&+I-cRsLN`U{fx3~cJhEg?{sd1m&*JsM>pMJ~pX>;-I^yA_SmFNz8*!jh=00000 LNkvXXu0mjfwpbAe literal 0 HcmV?d00001 diff --git a/images/battlers/Mukchuk/front.png b/images/battlers/Mukchuk/front.png new file mode 100644 index 0000000000000000000000000000000000000000..6504e89fe69d9bc73bab8b32be2aca183400a6fe GIT binary patch literal 634 zcmV-=0)_pFP)Px#Bv4FLMgRZ*FkpgXoBvyG;a|<0001KYHFLUxAJA3F#rGn z40KXXQvm<}|NsC0|NsC0{|UrUCIA2d>`6pHR9J=Wl-sg{APhwf7!3CR|Mw&TB!PPA z>lt^aouaG-LS$Lqym|Bg0&v~FI987NFAW%Iz2f;A39!5IZjo zHiV}J6&$z!5IV(2C#P|3YOz-}4^(M*DF1j!2kz)yk_O@gfsYz0!@Tu>kh#z5SIJkO85 zZDk3z;}L=rl={XpesXib)h>QB2_LZW&46Y6WaogvZ+|4ngRto0)n1OMyXj0)_`H0?${0 zWT)UFf;xF47$;B-J7?x&TfVZEd_=Hdag0V#dA^uw;@h#R6k;D<-k)lyxCmxk z4Cuy2Yyqn*56 zU>8ZdTnk!%t>I`chycz7hanGbBLKJ(EIDU)b2Q!xio>;r?)i@YCLEN*g*R^`fB)AN U?zz_2AOHXW07*qoM6N<$f>VSTGynhq literal 0 HcmV?d00001 diff --git a/images/battlers/Pyruff/front.png b/images/battlers/Pyruff/front.png new file mode 100644 index 0000000000000000000000000000000000000000..b04cf7a62298c9f8ae9e801d105d7072d131f773 GIT binary patch literal 1035 zcmV+m1oZofP)Px&#Ysd#RCt{2nZHXLVHn51mvpIQkw6oN4wekI#nN0A8X9ntpi7rR*Gvf%F$EW) ziyZ_Pp|MiXDSv=Vm)MX=usEo(MAS?Ub-6&Z6r)pm9j?#$=FR;|^sIsB1L3`U@4fTB z&yV+g-V2PRlZfk?L|m8qCr6U{vP$0I@Q;A z4ivx;pHD{s0J*}I5z4h~#fSIw4ab+2!~+0kmW}}ctMgAf#<#Qva)o+d8NoFI0H9br zLa}OSl7%m??E(Pivf~Iw!&sdUV`d3D&>zv@%>Y#e`E&%qXt=F^d2JUIA>y%^8h70Y z0jG=WI|mAR*hxHKL;#KLCtSTVIg-?^@|`FakIdtfvkS~+$I;RnX5U?(6C5MJir=rk zU}~Xao=;CdZEO1tM+3NdpExIy;8LmAww}fV~(i+{Vh+^J$~a73x@rVSxRukmtYW726aL z*Y~s7ean8r&HLRLiU>x-2u8!mrz6O0J}|}Kr1t@b2uLn&q4;3}fU(At@Z{na@co@R z&S}zfLQEeg3?ukgP}x4vOAX-Uc>uQFw-WDW5WjYswh>USZ7VZNurz|*Y){anXD6sz z@qXes36c>2V;d~j_#$3rdOO^rq}Md_g6D9O3luRF>6%r@&nz9c^;0N2O^$Lz__?|A z^gRHu|G1G!#P!Dy4ci#P+#?{LjyR6B6YmGX>)f14#P#>DA0ajrLTo66z@Kw`E;W&g z1)!f_LO;Lk=p&|{hmb4Ok%|Qn2n|?1-%9+qA5EP8`uXuX?=9jv0%S-$V0f&hHIP!H z05s$Zbxc3IUg_?)=ZUU2LoyVu)TY!Zh6kG{Ru%I*q8*e9Ev?bT~clwVvc1;}&M0>G!Qr=WkH5arso zBG(P__2I!LQfk!v4G%UuY7IZ=DFXfp)B)h+>=a@viIB literal 0 HcmV?d00001 diff --git a/images/battlers/Sappurr/front.png b/images/battlers/Sappurr/front.png index 69c81cffc81bb3c8ff43496156a6f5965cc09983..6b469cf192a83de4147957cfb001b8e23cc8a8d8 100644 GIT binary patch delta 701 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 literal 1047 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSjKx9jP7LeL$-HD>V7}<-;uumf z=j|L@59vgShWKu087oos=nF+6F(TsZ|M@uIK9IPO7aMce#kHiMquF9diMC!I-`kY# zkSI<;O~(~nlT=ll&IV*Y=i`cRpI~C|UbOSh@x=Sj8y$-3&mS+0)9d`+0kjhY8pL)r zt$AX>8EmgR{kK3y^pC|~%h?6Lf3^KSBYIYPvHJu5`|qn0k9$hw7wR5Ox_8R&K>qRf z*^c@@4>SZ<#%VmUl4AMy;!l4Q&x)vbUvHWHIQ)6Ljn|)fRj)W-uV>gFTfe~AA##FW z{gfm_`4VB-Mthn1)65T^J)6G#&&TA64<9<7e7<>J^M@#X4xq)SXT6>kk+bTPg-`mK zKLP7Ik1jiN!sF19q~Nr=71w2!8JnJ7yEE@_dgvei^YM~Lp5|S;Ggo%TYNv~D&h*aS zy}9{Ra(dpK7}2h0@7^4Ud8c-G>f`ON@?Uo^cyn|o4`275h`6;g_ifmt_38KS6#a9z zZ^qmP`R%n*f$`K=x9(f7;#pMX@b&!n?|mu8Q@Or&3;g-^XP;Qi&8qBW$K6!-?o&}x zT7Q2}PQ)^s11FzslbN5ElAWr!Wp2a$dHbI_rB<3gZ45D@{EzUB7?L^uWhV zH=tJOl&_z28|`cAFEb~cEj{bDCw||bm2>~S$&5d|$v&^kbp7OybuY_eFQ5FaSogaw zUcB++ylBt$`de*woq8V(WZTdF%3D|cZ&`Z7*^pJ(+z6XV&ECUA*RBN$|5DCd%*c*G`Sm+tcs(6K-V5{ri8I zACgjlB){k{hEspPFi!dXl3C;XW%ht~%lQ}F@t1elIp40K$i9~0&)Lpj|4RORVf=8J z{XqU{B$=mmxV19W{dcLYw*snw0|6G?%7>aw0&4Y)lRCU6&G0_h5AvX=tDnm{r-UW| DX2t`k diff --git a/images/tiles/kt01.png b/images/tiles/kt01.png index 4508c7d0382dda15439d5bb1cbd8a76856ecce9e..91ab6f5428e2a310a17c56ac00e5514fbcbd7070 100644 GIT binary patch literal 9195 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

wq{u|Lv>tg$NeJiza3%~ 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 f|D^vXUBC?EGp5{hy&$OrpuwB|G@n=r3DM z#XQ(GE9K#Q_1qoB#j- literal 0 HcmV?d00001 diff --git a/maps/testfield/coll.bin.bak b/maps/testfield/coll.bin.bak new file mode 100644 index 0000000000000000000000000000000000000000..ff870fa25bf6df16d7c9eb0b977fff3b0a2737e5 GIT binary patch literal 3200 zcmeH_T@k`C5QH!Mw9lu2K>>q=O27eiKplVtBp?9^NI(J-a6o{vd!)xq7+!eDtxII73#0}k)-s)*Z1DB#yhD|d48tH`Stu{ z-`KyYYV0(}>-b2GN+SLFbw~-7nvK+`B+~P%u@WwhmDH#t&hv9f36+|S)Tku#Q+_Y? C;$V9K literal 0 HcmV?d00001 diff --git a/maps/testfield/layer1.bin.bak b/maps/testfield/layer1.bin.bak new file mode 100644 index 0000000000000000000000000000000000000000..ff870fa25bf6df16d7c9eb0b977fff3b0a2737e5 GIT binary patch literal 3200 zcmeH_T@k`C5QH!Mw9lu2K>>q=O27eiKplVtBp?9^NI(J-a6o{vd!)xq7+!eDYwAz<`0zzyJ(@00961 literal 0 HcmV?d00001 diff --git a/maps/testfield/layer2.bin.bak b/maps/testfield/layer2.bin.bak new file mode 100644 index 0000000000000000000000000000000000000000..ff870fa25bf6df16d7c9eb0b977fff3b0a2737e5 GIT binary patch literal 3200 zcmeH_T@k`C5QH!Mw9lu2K>>q=O27eiKplVtBp?9^NI(J-a6o{vd!)xq7+!eD=D~%k0PyI5A-^kaC=u;L8rAKyZTCL@g`H1i?hX0>MH-1|Vb-WENxrLN-Bm zLB@%SvKwbDV$^1nXVYg;WH1D331moQC}e14n8+x|u#jOR!$F3N3=bJU0<|%+2(k*Y RO>8e^VV7su-?cXz@oqbBobHvAj1Rg diff --git a/saves/save1.json b/saves/save1.json index e69de29..dd125e7 100644 --- a/saves/save1.json +++ b/saves/save1.json @@ -0,0 +1 @@ +{"time":"0","map":"maps/testfield.json","player_name":"Ben","player_id":"8454","gender":"false","player_x":"0","player_y":"0"} \ No newline at end of file diff --git a/saves/save1.sav b/saves/save1.sav index d7dd505..7b27bcc 100644 --- a/saves/save1.sav +++ b/saves/save1.sav @@ -1 +1 @@ -{"time":"0","map":"maps/testfield.json","player_name":"Ben","player_id":"19791","gender":"false","player_x":"0","player_y":"0"} \ No newline at end of file +{"time":"0","map":"maps/testfield.json","player_name":"Ben","player_id":"54000","gender":"false","player_x":"0","player_y":"0"} \ No newline at end of file diff --git a/src/game.c b/src/game.c index 95807c8..2f31d97 100644 --- a/src/game.c +++ b/src/game.c @@ -6,20 +6,23 @@ #include "k_player.h" #include "k_save.h" +#include "k_menu.h" +#include "k_local.h" +#include "k_battle.h" int main(int argc, char * argv[]) { /*variable declarations*/ int done = 0; const Uint8 * keys; - Sprite *sprite; + //Sprite *sprite; //save1 = LoadSave("save/save00.sav"); - int mx,my; - float mf = 0; - Sprite *mouse; - Vector4D mouseColor = {255,100,255,200}; + //int mx,my; + //float mf = 0; + //Sprite *mouse; + //Vector4D mouseColor = {255,100,255,200}; Sprite* hatkid; @@ -38,10 +41,10 @@ int main(int argc, char * argv[]) gf2d_sprite_init(1024); SDL_ShowCursor(SDL_DISABLE); SetUpTilesets(); - NewSave("saves/save1.sav"); + NewSave("saves/save1.json"); /*demo setup*/ - sprite = gf2d_sprite_load_image("images/backgrounds/bg_flat.png"); - mouse = gf2d_sprite_load_all("images/pointer.png", 32, 32, 16); + //sprite = gf2d_sprite_load_image("images/backgrounds/bg_flat.png"); + //mouse = gf2d_sprite_load_all("images/pointer.png", 32, 32, 16); hatkid = gf2d_sprite_load_all("images/objects/HatKid.png", 32, 32, 4); @@ -58,10 +61,50 @@ int main(int argc, char * argv[]) player_init(); ent_free(&HatKid); + GiveDemoParty(); boy = ent_new(); boy->sprite = hatkid; boy->position = vector2d(128, 128); - //PrintLayout(save1.map); + boy->cellPos = cell(8, 8); + boy->OnTalk = talk_showme_egglet; + Edict* frankid, * farmer, * tree, * mukchuk, * treehugger, * riddler; + frankid = ent_new(); + frankid->sprite = fran; + frankid->position = vector2d(80, 80); + frankid->cellPos = cell(5, 5); + frankid->OnTalk = talk_give_restorade; + + farmer = ent_new(); + farmer->sprite = hatkid; + farmer->position = vector2d(192, 160); + farmer->cellPos = cell(12, 10); + farmer->OnTalk = talk_find_mukchuk; + + + treehugger = ent_new(); + treehugger->sprite = hatkid; + treehugger->position = vector2d(128, 192); + treehugger->cellPos = cell(8, 12); + treehugger->OnTalk = talk_treehugger; + + + riddler = ent_new(); + riddler->sprite = hatkid; + riddler->position = vector2d(176, 176); + riddler->cellPos = cell(11, 11); + riddler->OnTalk = talk_riddler; + + tree = ent_new(); + tree->position = vector2d(448, 256); + tree->cellPos = cell(27, 16); + tree->OnCollide = coll_tree; + + mukchuk = ent_new(); + mukchuk->position = vector2d(256, 256); + mukchuk->cellPos = cell(16, 16); + mukchuk->OnCollide = coll_mukchuk; + + game_init(); /*main game loop*/ while(!done) { @@ -70,54 +113,68 @@ int main(int argc, char * argv[]) SDL_Event keyEvent; SDL_PollEvent(&keyEvent); /*update things here*/ - SDL_GetMouseState(&mx,&my); + /*SDL_GetMouseState(&mx, &my); mf+=0.1; if (mf >= 16.0)mf = 0; - - if (keys[SDL_SCANCODE_W]) { - player_move(player, cell(0,-1)); - player->facing = DIR_N; - } - else if (keys[SDL_SCANCODE_S]) { - player_move(player, cell(0, 1)); - player->facing = DIR_S; - } - else if (keys[SDL_SCANCODE_A]) { - player_move(player, cell(-1, 0)); - player->facing = DIR_W; - } - else if (keys[SDL_SCANCODE_D]) { - player_move(player, cell(1, 0)); - player->facing = DIR_E; - } - if (keyEvent.type==SDL_KEYDOWN&&keys[SDL_SCANCODE_M]) { - if (boy->inUse) { - slog("Free the boy"); - ent_free(boy); - boy->inUse = 0; + */ + switch (game.state) { + case GAMESTATE_FIELD: + if (keys[SDL_SCANCODE_W]) { + player_move(player, cell(0, -1)); + player->facing = DIR_N; } - else { - slog("New boy"); - boy = ent_new(); - boy->sprite = hatkid; - boy->position = vector2d(128, 128); + else if (keys[SDL_SCANCODE_S]) { + player_move(player, cell(0, 1)); + player->facing = DIR_S; } - - } + else if (keys[SDL_SCANCODE_A]) { + player_move(player, cell(-1, 0)); + player->facing = DIR_W; + } + else if (keys[SDL_SCANCODE_D]) { + player_move(player, cell(1, 0)); + player->facing = DIR_E; + } + if (keyEvent.type == SDL_KEYDOWN && keys[SDL_SCANCODE_M]) { + if (boy->inUse) { + slog("Free the boy"); + ent_free(boy); + boy->inUse = 0; + } + else { + slog("New boy"); + boy = ent_new(); + boy->sprite = hatkid; + boy->position = vector2d(128, 128); + } + + } + + ent_manager_think_all(); + + gf2d_graphics_clear_screen();// clears drawing buffers + // all drawing should happen betweem clear_screen and next_frame + //backgrounds drawn first + //gf2d_sprite_draw_image(sprite, vector2d(0, 0)); + RenderMap(save1.map); - ent_manager_think_all(); - - gf2d_graphics_clear_screen();// clears drawing buffers - // all drawing should happen betweem clear_screen and next_frame - //backgrounds drawn first - //gf2d_sprite_draw_image(sprite, vector2d(0, 0)); - RenderMap(save1.map); - + ent_manager_draw_all(); + + RenderMapLayer2(save1.map); - ent_manager_draw_all(); + DrawHUD(); + break; + case GAMESTATE_BATTLE: + gf2d_graphics_clear_screen();// clears drawing buffers + // all drawing should happen betweem clear_screen and next_frame + //backgrounds drawn first + //gf2d_sprite_draw_image(sprite, vector2d(0, 0)); + + RenderBattlefield(); + } //UI elements last - gf2d_sprite_draw( + /*gf2d_sprite_draw( mouse, vector2d(mx,my), NULL, @@ -125,7 +182,7 @@ int main(int argc, char * argv[]) NULL, NULL, &mouseColor, - (int)mf); + (int)mf);*/ gf2d_grahics_next_frame();// render current draw frame and skip to the next frame if (keys[SDL_SCANCODE_ESCAPE])done = 1; // exit condition diff --git a/src/k_battle.c b/src/k_battle.c index 6d374b1..63d0c31 100644 --- a/src/k_battle.c +++ b/src/k_battle.c @@ -3,6 +3,8 @@ #include "k_monster.h" #include "k_technique.h" +#include "k_save.h" +#include "k_local.h" @@ -72,9 +74,27 @@ void RenderBattlefield() { Sprite* field; Sprite *participants[4]; int i = 0; - field = gf2d_sprite_load_image(battlefieldbgs[gBattle.battleType]); + field = gf2d_sprite_load_image(battlefieldbgs[gBattle.fieldtype]); for (; i < gBattle.numMons; i++) { - participants[i] = gf2d_sprite_load_image(gBattlerSprites[gBattle.participants[i]->species]); + participants[i] = gf2d_sprite_load_image(gBaseStats[gBattle.participants[i]->species].spritefile); } + for (i = 0; i < gBattle.numMons; i++) { + gf2d_sprite_draw_image(participants[i], vector2d(gBattle.participants[i]->x*64, gBattle.participants[i]->y*64+128)); + } +} +void StartWildBattle(u16 species, u8 level, u8 bg) { + MonDict* wild = monster_set_dict(monster_new(species, level, 0, Random32())); + gBattle.fieldsizex = 7; + gBattle.fieldsizey = 4; + gBattle.battleType = BATTLE_TYPE_WILD; + gBattle.fieldtype = bg; + gBattle.numMons = 2; + gBattle.turnCount = 0; + gBattle.participants[0] = &party.party[0]; + gBattle.participants[1] = wild; + gBattle.participants[0]->x = 3; + gBattle.participants[0]->y = 2; + gBattle.participants[1]->x = 5; + gBattle.participants[1]->y = 2; } \ No newline at end of file diff --git a/src/k_entity.c b/src/k_entity.c index 332c1b5..1fd9ea8 100644 --- a/src/k_entity.c +++ b/src/k_entity.c @@ -1,5 +1,9 @@ #include "simple_logger.h" +#include "gf2d_graphics.h" +#include "k_monster.h" +#include "k_local.h" +#include "k_item.h" #include "k_entity.h" #include "k_field.h" #include "k_save.h" @@ -20,6 +24,7 @@ Edict* ent_new() { entity_manager.entities[i].draw_scale.y = 1; entity_manager.entities[i].draw_offset = vector2d(-8, 0); entity_manager.entities[i].Think = ent_think_generic; + entity_manager.entities[i].OnCollide = ent_collide_generic; slog("New entity created"); return &entity_manager.entities[i]; } @@ -99,6 +104,24 @@ void ent_think_generic(Edict* ent) { } +void ent_collide_generic(Edict* ent, Direction dir) { + switch (dir) { + case DIR_N: + ent->facing = DIR_S; + break; + case DIR_S: + ent->facing = DIR_N; + break; + case DIR_E: + ent->facing = DIR_W; + break; + case DIR_W: + ent->facing = DIR_E; + } + + ent->OnTalk(ent, dir); +} + void ent_manager_think_all() { u32 i; for (i = 0; i < entity_manager.maxEnts; i++) { @@ -151,10 +174,65 @@ void ent_move(Edict* ent) { } } +void coll_mukchuk(Edict* ent, Direction dir) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION,"","You found a Mukchuk!",NULL); + party.partyPersonal[4] = *monster_new(SPECIES_MUKCHUK, 10, 0, Random32()); + party.party[4] = *monster_set_dict(party.partyPersonal + 4); + ent_free(ent); +} +void coll_tree(Edict* ent, Direction dir) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "", "You found a Sappurr!", NULL); + party.partyPersonal[1] = *monster_new(SPECIES_SAPPURR, 5, 0, Random32()); + party.party[1] = *monster_set_dict(party.partyPersonal + 1); + ent_free(ent); +} + +void talk_showme_egglet(Edict* ent, Direction dir) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Kid", "Can you show me an Egglet?", NULL); + if (party.partyPersonal[2].species == SPECIES_EGGLET) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Kid", "Oh, that's it! Here, take this!", NULL); + GiveItem("Restorade"); + } +} +void talk_treehugger(Edict* ent, Direction dir) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Tree Guy", "Hey man, go touch that tree.", NULL); +} +void talk_find_mukchuk(Edict* ent, Direction dir) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Farmer", "There's a monster scurrying around underground. Try and find it for me.", NULL); +} +void talk_riddler(Edict* ent, Direction dir) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Other Kid", "Hey, what type is Egglet?",NULL); + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Other Kid", "That's right, Air!", NULL); + party.partyPersonal[2] = *monster_new(SPECIES_EGGLET, 5, 0, Random32()); + party.party[2] = *monster_set_dict(party.partyPersonal + 2); +} +void talk_give_restorade(Edict* ent, Direction dir) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Fran", "Hey, my Squoink's low on health. Can you give me a Restorade?", NULL); + if (RemoveItem("Restorade")) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Fran", "Oh, thanks man, I owe you one! Here, have a Pyruff.", NULL); + party.partyPersonal[3] = *monster_new(SPECIES_PYRUFF, 5, 0, Random32()); + party.party[3] = *monster_set_dict(party.partyPersonal + 3); + } +} + + int Colliding(Rect a, Rect b) { return SDL_HasIntersection(&a, &b); } +u16 CheckEntCollision(Point8 pt, Direction dir) { + unsigned int i; + for (i = 0; i < entity_manager.maxEnts; i++) { + if (entity_manager.entities[i].inUse && entity_manager.entities[i].cellPos.x == pt.x && entity_manager.entities[i].cellPos.y == pt.y) { + entity_manager.entities[i].OnCollide(entity_manager.entities+i,dir); + return i; + } + } + return SDL_FALSE; +} + + Point8 cell(s8 x, s8 y) { Point8 c= { x, y }; return c; diff --git a/src/k_field.c b/src/k_field.c index 54de456..d2ed823 100644 --- a/src/k_field.c +++ b/src/k_field.c @@ -1,6 +1,6 @@ -#include #include "gf2d_graphics.h" #include "gf2d_sprite.h" +#include "gfc_text.h" #include "simple_logger.h" #include "simple_json.h" @@ -47,7 +47,7 @@ Block TallGrass = { void SetUpTilesets() { gTilesets[0].sheet = gf2d_sprite_load_all("images/tiles/kt01.png", 16, 16, 16); //16 tiles wide 64 tiles tall - strcpy(gTilesets[0].filename, "images/tiles/kt01.png"); + gfc_line_cpy(gTilesets[0].filename, "images/tiles/kt01.png"); } static Vector2D tileScale = { 1, 1 }; @@ -65,40 +65,89 @@ Map* map_new() { } Map *LoadMap(const char* jsonfile) { - FILE* file; - u16* buff; - long length; - - SJson* json; + SJson *json, *r, *c, *e; char* spriteFile = NULL; - char* mapFile = NULL; - Map *map; - map = map_new(); - slog(jsonfile); + Map *map = NULL; + int row, col, t; + MapTile tile=0; + TileCollision coll=0; int height, width; + + map = map_new(); + if (!map)return NULL; + slog("attempting to load json file %s", jsonfile); if (!jsonfile) return NULL; json = sj_load(jsonfile); if (!json) { - slog("Couldn't load map file"); + slog("Couldn't load map file %s",jsonfile); return NULL; } map->name = jsonfile; spriteFile = sj_get_string_value(sj_object_get_value(json, "tileset")); - mapFile = sj_get_string_value(sj_object_get_value(json, "layout")); sj_get_integer_value(sj_object_get_value(json, "height"), &height); sj_get_integer_value(sj_object_get_value(json, "width"), &width); - map->height=height; + map->height = height; map->width = width; + map->layout = (MapTile*)calloc(height*width,sizeof(MapTile)); + map->layer2 = (MapTile*)calloc(height*width,sizeof(MapTile)); + map->collision = (TileCollision*)calloc(height*width,sizeof(TileCollision)); + + for (t = 0, row = 0; row < height; row++) { + r = sj_array_get_nth(sj_object_get_value(json, "layer_1"), row); + for (col = 0; col < width; col++) { + sj_get_integer_value(sj_array_get_nth(r,col), map->layout+t++); + } + } + for (t = 0, row = 0; row < height; row++) { + r = sj_array_get_nth(sj_object_get_value(json, "layer_2"), row); + for (col = 0; col < width; col++) { + sj_get_integer_value(sj_array_get_nth(r, col), map->layer2+t++); + } + } + for (t = 0, row = 0; row < height; row++) { + r = sj_array_get_nth(sj_object_get_value(json, "collisions"), row); + for (col = 0; col < width; col++) { + sj_get_integer_value(sj_array_get_nth(r, col), map->collision+t++); + } + } + + /*FILE* file; + u16 *buff, *buff2; + u8 *buffc; + long length; + file = fopen(mapFile, "rb"); fseek(file, 0, SEEK_END); length = ftell(file); - slog("%d", length); + slog("Read %d bytes for layout", length); rewind(file); buff = (u16*)malloc(length * sizeof(u16)); if (buff) fread(buff, length, 1, file); fclose(file); - map->layout = (MapTile*) buff; + map->layout = buff; + + mapFile = sj_get_string_value(sj_object_get_value(json, "layer2")); + file = fopen(mapFile, "rb"); + fseek(file, 0, SEEK_END); + length = ftell(file); + slog("Read %d bytes for layer 2", length); + rewind(file); + buff2 = (u16*)malloc(length * sizeof(u16)); + if (buff2) fread(buff2, length, 1, file); + fclose(file); + map->layer2 = buff2; + + mapFile = sj_get_string_value(sj_object_get_value(json, "collision")); + file = fopen(mapFile, "rb"); + fseek(file, 0, SEEK_END); + length = ftell(file); + slog("Read %d bytes for collision", length); + rewind(file); + buffc = (u8*)malloc(length * sizeof(u8)); + if (buffc) fread(buffc, length, 1, file); + fclose(file); + map->collision = (TileCollision*)buffc;*/ map->tileset = gTilesets[0]; @@ -107,11 +156,32 @@ Map *LoadMap(const char* jsonfile) { } void RenderMap(Map* map) { + int y, x, t; + if (!map) return; + for (t=0, y = 0; y < map->height; y++) { + for (x = 0; x < map->width; x++) { + gf2d_sprite_draw( + map->tileset.sheet, + vector2d(16 * x, 16 * y), + &tileScale, + NULL, + NULL, + NULL, + NULL, + map->layout[t++]); + } + } +} + +void RenderMapLayer2(Map* map) { + int x, y, t; if (!map) return; - for (int y = 0; y < map->height; y++) { - for (int x = 0; x < map->width; x++) { - MapTile* block = &map->layout[y*map->width+x]; - u16 collisions = block->collision; + for (t=0, y = 0; y < map->height; y++) { + for (x = 0; x < map->width; x++) { + if (map->layer2[t] == 0) { + t++; + continue; + } gf2d_sprite_draw( map->tileset.sheet, vector2d(16 * x, 16 * y), @@ -120,7 +190,7 @@ void RenderMap(Map* map) { NULL, NULL, NULL, - block->blockID-256); + map->layer2[t++]); } } } @@ -133,14 +203,14 @@ TileCollision GetCollisionAt(Map *map, Point8 position) { return COLL_IMPASSIBLE; } }*/ - return map->layout[position.y * map->width + position.x].collision; + return map->collision[position.y*map->width+position.x]; } void PrintLayout(Map* map) { int i, j; for (i = 0; i < map->height; i++) { for (j = 0; j < map->width; j++) { - slog("%d ",map->layout[i * map->width + j].collision); + slog("%d ",map->collision[i * map->width + j]); } } } diff --git a/src/k_hud.c b/src/k_hud.c index e69de29..60fff19 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -0,0 +1,19 @@ +#include "k_menu.h" +#include "k_entity.h" +#include "k_save.h" +#include "simple_logger.h" + +void DrawHUD() { + int i; + Vector2D drawpos = vector2d(8, 0); + Vector2D drawscale = vector2d(1, 1); + for (i = 0; i < 6; i++) { + u16 species = party.partyPersonal[i].species; + if (species == 0 || species > SPECIES_MAX) { + continue; + } + Sprite* sprite = gf2d_sprite_load_all(gBaseStats[species].spritefile,32,64,2); + gf2d_sprite_draw(sprite, drawpos, &drawscale, NULL, NULL, NULL, NULL, 0); + drawpos.x += 32; + } +} \ No newline at end of file diff --git a/src/k_item.c b/src/k_item.c new file mode 100644 index 0000000..89e0b21 --- /dev/null +++ b/src/k_item.c @@ -0,0 +1,44 @@ +#include "simple_json.h" + +#include "k_save.h" +#include "k_item.h" + +void item_use_heal(Item* item) { + +} + +void item_use_capsule(Item* item) { + +} + +int RemoveItem(char* name) { + if (SDL_strcmp(save1.inventory[0].name, name) == 0) + return 1; + else return 0; +} + +void GiveItem(char* name) { + save1.inventory[0] = GetItemFromJson(name); + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Item Get", name, NULL); +}; + +Item GetItemFromJson(char* name) { + SJson* json; + Item* i; + i = (Item*)malloc(sizeof(Item)); + if (i == NULL) return; + json = sj_object_new(); + json = sj_load("config/items.json"); + gfc_word_cpy(i->name,name); + json = sj_object_get_value(json, name); + sj_get_integer_value(sj_object_get_value(json, "id"), &i->id); + if (sj_object_get_value(json, "useInBattle")) i->useInBattle = true; + if (sj_object_get_value(json, "useOnField")) i->useOnField = true; + sj_get_integer_value(sj_object_get_value(json, "price"), &i->price); + sj_get_integer_value(sj_object_get_value(json, "args"), &i->useargs); + char* usefunc = sj_get_string_value(sj_object_get_value(json, "usefunc")); + + if (SDL_strcmp(usefunc, "use_heal")==0) i->Use = item_use_heal; + if (SDL_strcmp(usefunc, "use_capsule") == 0) i->Use = item_use_capsule; + return *i; +} \ No newline at end of file diff --git a/src/k_local.c b/src/k_local.c index 002f1da..2e2d614 100644 --- a/src/k_local.c +++ b/src/k_local.c @@ -8,6 +8,16 @@ u8 CoinFlip() { return game.random & 0x000F; } +u32 Random32() { + return (u32)(gfc_random()*SDL_MAX_UINT32); +} + void SeedRNG() { - game.randomSeed=(int)(gfc_random()*(2>>64)); + game.randomSeed=(int)(gfc_random()*SDL_MAX_UINT64); +} + +void game_init() { + game.steps = 0; + game.time = 0; + game.state = GAMESTATE_FIELD; } \ No newline at end of file diff --git a/src/k_monster.c b/src/k_monster.c index 29e2207..ee83279 100644 --- a/src/k_monster.c +++ b/src/k_monster.c @@ -1,13 +1,49 @@ #include "simple_logger.h" #include "simple_json.h" + #include "k_monster.h" #include "k_technique.h" +#include "k_save.h" +#include "k_local.h" typedef struct { MonDict *monsters; u8 monsternum; }MonsterManager; +typedef struct +{ + const char* name; + const char* spritefile; + int startinghealth; +}MONSTERDATA; + + +const MONSTERDATA _monster_data[] = +{ + {0}, + { + "sappurr", + "images/battlers/Sappurr/front.png", + 10 + }, + {0} +}; + +MONSTERDATA* monster_get_by_name(const char* name) +{ + MONSTERDATA* it = NULL; + for (it = _monster_data; it && it->name != 0; it++) + { + if (strcmp(name, it->name) == 0)return it; + } + return NULL; +} + +u8 GetLevel(PersonalDict pers) { + return (u8)SDL_sqrt(pers.exp); +} + MonsterManager monsterManager; const Technique gTechniques[NUM_TECHNIQUES] = { @@ -16,7 +52,11 @@ const Technique gTechniques[NUM_TECHNIQUES] = { }; const struct BaseStats gBaseStats[NUM_SPECIES] = { - [SPECIES_SAPPURR] = { + {0}, + { + "Sappurr", + "images/battlers/Sappurr/front.png", + .hp = 48, .attack = 60, .defense = 50, @@ -31,20 +71,206 @@ const struct BaseStats gBaseStats[NUM_SPECIES] = { .xpGrowth = GROWTH_MEDIUM, .atkYield = 1, + .genderParam = GENDER_MALE_7_8TH, + .catchrate = 45 + },{ + "Camofline", + "images/battlers/Sappurr/front.png", + + .hp = 48, + .attack = 60, + .defense = 50, + .m_attack = 40, + .m_defense = 42, + .agility = 72, + + + .type1 = T_PLANT, + + .xpYield = 80, + .xpGrowth = GROWTH_MEDIUM, + .atkYield = 1, + + .genderParam = GENDER_MALE_7_8TH, + .catchrate = 45 + },{ + "Vampiroot", + "images/battlers/Sappurr/front.png", + + .hp = 76, + .attack = 105, + .defense = 75, + .m_attack = 80, + .m_defense = 75, + .agility = 109, + + + .type1 = T_PLANT, + .type2 = T_MIND, + + .xpYield = 80, + .xpGrowth = GROWTH_MEDIUM, + .atkYield = 3, + .genderParam = GENDER_MALE_7_8TH, .catchrate = 45 }, - [SPECIES_PYRUFF] = { - 50, 62, 50, 45, 45, 60, + { + "Pyruff", + "images/battlers/Pyruff/front.png", + + .hp = 50, + .attack = 62, + .defense = 50, + .m_attack = 45, + .m_defense = 45, + .agility = 60, + + .type1 = T_FLAME, + .xpYield = 80, .atkYield = 1, .genderParam = GENDER_MALE_7_8TH, + .catchrate = 45 + }, + { + "Flarewolf", + "images/battlers/Pyruff/front.png", + + .hp = 50, + .attack = 62, + .defense = 50, + .m_attack = 45, + .m_defense = 45, + .agility = 60, + .type1 = T_FLAME, - .type2 = T_MYSTERY, + + .xpYield = 80, + .atkYield = 1, + .genderParam = GENDER_MALE_7_8TH, .catchrate = 45 - } + }, + { + "Lycarson", + "images/battlers/Pyruff/front.png", + + .hp = 83, + .attack = 102, + .defense = 80, + .m_attack = 94, + .m_defense = 80, + .agility = 95, + + .type1 = T_FLAME, + + .xpYield = 80, + .atkYield = 1, + .genderParam = GENDER_MALE_7_8TH, + .catchrate = 45 + }, + { + "Squoink", + "images/battlers/Squoink/front.png", + 58, + 50, + 50, + 58, + 52, + 44, + + T_AQUA + }, + { + "Woghash", + "images/battlers/Squoink/front.png", + 58, + 50, + 50, + 58, + 52, + 44, + + T_AQUA + }, + { + "Soluboar", + "images/battlers/Squoink/front.png", + 100, + 80, + 80, + 100, + 100, + 70, + + T_AQUA, + T_TOXIC + }, + { + "Egglet", + "images/battlers/Egglet/front.png", + 50, + 54, + 50, + 50, + 50, + 58, + + T_AIR + }, + { + "Reagle", + "images/battlers/Egglet/front.png", + 50, + 54, + 50, + 50, + 50, + 58, + + T_AIR + }, + { + "Reagalia", + "images/battlers/Egglet/front.png", + 80, + 110, + 80, + 80, + 80, + 100, + + T_AIR + }, + { + "Mukchuk", + "images/battlers/Egglet/front.png", + 40, + 50, + 35, + 20, + 25, + 55, + + T_BASIC + }, + {0} +}; + +const char* gBattlerSprites[NUM_SPECIES] = { + [SPECIES_SAPPURR] = "images/battlers/Sappurr/front.png", + [SPECIES_CAMOFLINE] = "images/battlers/Sappurr/front.png", + [SPECIES_VAMPIROOT] = "images/battlers/Sappurr/front.png", + [SPECIES_PYRUFF] = "images/battlers/Sappurr/front.png", + [SPECIES_FLAREWOLF] = "images/battlers/Sappurr/front.png", + [SPECIES_LYCARSON] = "images/battlers/Sappurr/front.png", + [SPECIES_SQUOINK] = "images/battlers/Squoink/front.png" }; +const char* GetBattleSprite(u16 species) { + return gBattlerSprites[species]; +} + u16 CalculateStat(PersonalDict pers, Stat stat) { switch (stat) { @@ -61,6 +287,7 @@ u16 CalculateStat(PersonalDict pers, Stat stat) { case STAT_AGILITY: return (gBaseStats[pers.species].agility + pers.agilityTV + GetLevel(pers)) / 50 + 5 - 5 * pers.agiReserves; } + return 0; } void monster_manager_init() { @@ -109,9 +336,19 @@ PersonalDict* monster_new(u16 species, u8 level, u8 form, u32 personality) { p->species = species; p->form = form; p->personality = personality; + p->exp = level * level; + return p; } void mondict_free(MonDict* mon) { free(mon); slog("%d monsters", --monsterManager.monsternum); +} + +void GiveDemoParty() { + party.partyPersonal[0] = *monster_new(SPECIES_SQUOINK, 5, 0, Random32()); + int i; + for (i = 0; i < 1; i++) { + party.party[i] = *monster_set_dict(party.partyPersonal + i); + } } \ No newline at end of file diff --git a/src/k_player.c b/src/k_player.c index e83dec0..55fa9d5 100644 --- a/src/k_player.c +++ b/src/k_player.c @@ -10,14 +10,14 @@ void player_init() { player = ent_new(); player->sprite = ben;//placeholder - player->position = vector2d(0,0); - player->targetPosition = vector2d(0,0); - player->cellPos = cell(0,0); - player->targetCell = cell(0, 0); + player->position = vector2d(160,160); + player->targetPosition = vector2d(160,160); + player->cellPos = cell(10,10); + player->targetCell = cell(10, 10); player->draw_offset = vector2d(-8, 0); player->Think = player_think; player->inUse = 1; - player->z = 1; + player->z = 0; slog("Player initialized"); } @@ -47,7 +47,8 @@ void player_think(Edict* self) { void player_move(Edict* ent, Point8 movement) { cell_add(ent->targetCell, ent->cellPos, movement); TileCollision coll = GetCollisionAt(save1.map, ent->targetCell); - if (coll == COLL_IMPASSIBLE || (coll != ent->z && coll != COLL_TRANSITION && ent->z != COLL_TRANSITION)) { + if (coll == COLL_IMPASSIBLE || (coll != ent->z && coll != COLL_TRANSITION && ent->z != COLL_TRANSITION) || + CheckEntCollision(ent->targetCell,ent->facing)) { ent->targetCell = ent->cellPos; //slog("%d, %d", ent->z, coll); } diff --git a/src/k_save.c b/src/k_save.c index 32106e7..a4a2106 100644 --- a/src/k_save.c +++ b/src/k_save.c @@ -48,6 +48,9 @@ void NewSave(char* filename) { slog(save1.map->tileset.filename); } + party.party = gfc_allocate_array(sizeof(MonDict),6); + party.partyPersonal = gfc_allocate_array(sizeof(PersonalDict), 6); + sj_object_insert(json, "time", sj_new_str("0")); sj_object_insert(json, "map", sj_new_str("maps/testfield.json")); sj_object_insert(json, "player_name", sj_new_str(save1.client.name)); @@ -68,7 +71,7 @@ void WriteSave(char* filename) { json = sj_load(filename); if (!json) return; - sj_string_set(str, SDL_lltoa(save1.playTime,buff,10)); + /*sj_string_set(str, SDL_lltoa(save1.playTime,buff,10)); sj_object_insert(json, "time", sj_string_to_value(str)); sj_string_set(str, save1.map->name); sj_object_insert(json, "map", sj_string_to_value(str)); @@ -82,6 +85,6 @@ void WriteSave(char* filename) { sj_save(json, filename); - sj_string_free(str); + sj_string_free(str);*/ sj_free(json); } \ No newline at end of file