From 785642a2c935e133639ee3b0a32c4703da809dca Mon Sep 17 00:00:00 2001 From: immibis Date: Wed, 19 Feb 2025 03:51:11 +0100 Subject: [PATCH] You can get the pager from the basement. --- Makefile | 1 + engine.h | 4 +++ game.cpp | 59 ++++++++++++++++++++++++++++++++++++++--- inventory.cpp | 4 ++- inventory.h | 1 + navmesh/lobby.tmx | 5 ++-- objids.h | 2 ++ pinetab2_framework.cpp | 2 ++ sprites/item_pager.xcf | Bin 0 -> 3549 bytes sprites/lobby.xcf | Bin 343251 -> 344029 bytes 10 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 sprites/item_pager.xcf diff --git a/Makefile b/Makefile index 3168748..7b044db 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,7 @@ navmesh_%.c: $(PROJECT_ROOT)navmesh/%.tmx $(PROJECT_ROOT)compile_navmesh.py @# symbols are navmesh_% and predef_% navmesh_%.o: $(PROJECT_ROOT)compiled_structures.h $(PROJECT_ROOT)objids.h +pinetab2_framework.o: $(PROJECT_ROOT)engine.h %.png: $(PROJECT_ROOT)sprites/%.xcf gimp -in -b '(let ((image (car (gimp-xcf-load 0 "$<" "$(notdir $<)")))) ;\ diff --git a/engine.h b/engine.h index bff432b..0fb7e8d 100644 --- a/engine.h +++ b/engine.h @@ -101,3 +101,7 @@ void blit(int x, int y, int width, int height, uint32_t *pixels); // game.cpp void scene_setup(scene *s, int scene, int fromscene); void onclick(int curscene, struct object *obj); + +extern struct savefile { + bool got_pager_from_basement; +} savefile; diff --git a/game.cpp b/game.cpp index d163d24..ddc2554 100644 --- a/game.cpp +++ b/game.cpp @@ -13,6 +13,7 @@ extern const char _binary_sprite_lobby_raw_start[]; extern const char _binary_sprite_managers_office_raw_start[]; extern const char _binary_sprite_managers_office_safe_raw_start[]; extern const char _binary_sprite_basement_raw_start[]; +extern const char _binary_sprite_item_pager_raw_start[]; extern const char _binary_sprite_stickman_raw_start[]; @@ -70,6 +71,9 @@ void scene_setup(scene *me, int scene, int fromscene) { case SCENE_BASEMENT: scene_add_object(me, OBJID_BACKGROUND, 0, 0, BGWIDTH, BGHEIGHT, _binary_sprite_basement_raw_start); scene_load_predef(me, &predef_basement); + if(!savefile.got_pager_from_basement) { + scene_add_object(me, OBJID_PAGER, 556, 520, 87, 87, _binary_sprite_item_pager_raw_start); + } switch(fromscene) { case SCENE_MANAGERS_OFFICE: create_player(me, 435, 404); @@ -125,13 +129,56 @@ static void do_popcorn_on_walk_finish(struct script *scr, int wakeupMode, int ar assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED); } -static void start_player_walk_to_point_then_do_popcorn(int x, int y) { + +static void get_pager_on_walk_finish(struct script *scr, int wakeupMode, int arg1, int arg2, int arg3, int arg4) { + scr->id = 0; + if(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT) { + struct object *obj = find_object_by_id(OBJID_PAGER); + if(obj) { + if(add_to_inventory(INVITEM_PAGER) < 0) { + push_scene_textbox("Inventory is full."); + } else { + obj->id = 0; + savefile.got_pager_from_basement = true; + push_scene_textbox( + "You found your pager.\n" + "Now you can get out of here." + ); + } + } + } + else + assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED); +} + +static void start_player_walk_to_point_then(int x, int y, script_wake_fn wake_fn) { start_player_walk_to_point(x, y); struct script *scr = scene_add_script(OBJID_PLAYER_WALK_TO_DOOR_SCRIPT, true); scr->wakeupMode = SCRIPT_WAKEUP_OTHER_SCRIPT; scr->wakeupArg1 = OBJID_PLAYER_WALK_SCRIPT; - scr->wakeupFn = do_popcorn_on_walk_finish; + scr->wakeupFn = wake_fn; +} + +static void do_leave_lobby_on_walk_finish(struct script *scr, int wakeupMode, int arg1, int arg2, int arg3, int arg4) { + scr->id = 0; + if(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT) { + if(count_item_in_inventory(INVITEM_PAGER) == 0) { + push_scene_textbox( + "You can't leave without\n" + "finding your pager." + ); + } else { + push_scene_textbox( + "You got killed in a mugging\n" + "and we rewound time for you,\n" + "as required by the plot to\n" + "keep you inside the theatre." + ); + } + } + else + assert(wakeupMode == SCRIPT_WAKEUP_OTHER_SCRIPT_INTERRUPTED); } void onclick(int curscene, struct object *obj) { @@ -150,6 +197,9 @@ void onclick(int curscene, struct object *obj) { case OBJID_DOOR_TO_MANAGERS_OFFICE_FROM_LOBBY: start_player_walk_to_point_then_transition_scene(256, 441, SCENE_MANAGERS_OFFICE); return; + case OBJID_LEAVE_ROOM: + start_player_walk_to_point_then(obj->x + obj->width/2, obj->y + obj->height, do_leave_lobby_on_walk_finish); + return; } break; case SCENE_MANAGERS_OFFICE: @@ -171,7 +221,10 @@ void onclick(int curscene, struct object *obj) { start_player_walk_to_point_then_transition_scene(438, 402, SCENE_MANAGERS_OFFICE); return; case OBJID_POPCORN_BARREL: - start_player_walk_to_point_then_do_popcorn(obj->x + obj->width/2, obj->y + obj->height); + start_player_walk_to_point_then(obj->x + obj->width/2, obj->y + obj->height, do_popcorn_on_walk_finish); + return; + case OBJID_PAGER: + start_player_walk_to_point_then(obj->x + obj->width/2, obj->y + obj->height, get_pager_on_walk_finish); return; } break; diff --git a/inventory.cpp b/inventory.cpp index a2d2ad1..695b65c 100644 --- a/inventory.cpp +++ b/inventory.cpp @@ -5,9 +5,11 @@ extern const char _binary_sprite_menubar_raw_start[]; extern const char _binary_sprite_item_popcorn_raw_start[]; +extern const char _binary_sprite_item_pager_raw_start[]; static const char *const inventory_sprites[] = { - _binary_sprite_item_popcorn_raw_start + _binary_sprite_item_popcorn_raw_start, + _binary_sprite_item_pager_raw_start, }; int inventory[INVENTORY_SIZE] = { diff --git a/inventory.h b/inventory.h index bbfb96f..f5429f8 100644 --- a/inventory.h +++ b/inventory.h @@ -2,6 +2,7 @@ enum invobject { INVITEM_BLANK = 0, // must always be 0 INVITEM_POPCORN, + INVITEM_PAGER, }; extern int inventory[INVENTORY_SIZE]; diff --git a/navmesh/lobby.tmx b/navmesh/lobby.tmx index e079f1f..3b18fc2 100644 --- a/navmesh/lobby.tmx +++ b/navmesh/lobby.tmx @@ -1,10 +1,11 @@ - + - + + diff --git a/objids.h b/objids.h index 03a7080..8d44c69 100644 --- a/objids.h +++ b/objids.h @@ -12,5 +12,7 @@ #define OBJID_CLOSE_MODAL 12 #define OBJID_POPCORN_BARREL 13 #define OBJID_MENUBAR 14 +#define OBJID_LEAVE_ROOM 15 +#define OBJID_PAGER 16 #define OBJID_INVENTORY_SLOTS 0x10000000 // + slot number diff --git a/pinetab2_framework.cpp b/pinetab2_framework.cpp index 48dfdd9..b65ab5d 100644 --- a/pinetab2_framework.cpp +++ b/pinetab2_framework.cpp @@ -31,6 +31,8 @@ struct scene scenes[MAX_STACKED_SCENES]; int scene_depth = 0; bool need_rerender = false; +struct savefile savefile; + #define MAX_MT_SLOTS 16 diff --git a/sprites/item_pager.xcf b/sprites/item_pager.xcf new file mode 100644 index 0000000000000000000000000000000000000000..d6762610f71aa0bfc00b0df70b8ec0b19bdbd101 GIT binary patch literal 3549 zcmb7`O>Y}j6o$v&p0S-T8m~|~)P|;|PCQMfB5FP)x#!Y7$q83+)1h zzrcnKngwEu#9x2~3xrtk1NarJ)64VTJAGSaA;5huE zA4ML|XQ_#Qi!Eb?0{`B^>W^^Acy3^2tcbN!uDDg~Z>%+9=-yy*dOAFtqCGXPJUSm9 zPKQU~m*eTv@S~3(f1;Kp8#+Ec91VM;^YM{$O`2bzQVsr() z1=hg(_P9rfR^eO(@vQ^wZ^E1*gWur6936nAy(tu!!$+p*Z7)~rmyj3+AZ~e2-ouNSpRI7AE33%F<1q+LFM1Zlxqt+ z!1mGmpyt>IReJ>2yuE}|6tj*orzmFYV#Y_8uozuIZ-F)NK0Y7pqkZ@$)<8St;R%!8Tf@IIf{MMb__1TSF_p4Cc$M;!~MQ zqqYdtREpRpTqTfB6)XD&*u-|RJ;L{_<`lu@SM|5y4R{US1${8U*MSS0Dc6cP&dOTO zj@rI1kIE_I?}HUkB?VX)t+F*;pIwmFYAdI5*T6bC*HbQi7poAfaqeN7qWWum%}LYO z_%iL5`agtgd3UUTw#yID+T|Fmg4>|-Z)3`}g&kn~=zUOg?1QR3f@`i`%qj9%M~_qF zv2`Bfqf1zfuAsNT8h9U{5BAYMd=qP+9ddH;U!m*xdsqowPWyJiDrT(a6ww~Q75myV zA+!xu_nTlFtx_D1%wMc1!&q!nM3R)<4_j2Wahb3|7Hy zQ2Dnp<=VmyuzmDCs5$mQ)gHk$SANk-e{nCZS}UX|o#)2fKZfJ_ z)P3CobvNoR*WKuT2aLV@bTv>D)445#N;PtIVL}Av1*O{*K+c+R@$=_ zK1G(mB5{kLj`sqnGtvUJA3A^94|n#+kJf$!-WBVu*Ms~X`H5NfB37o(O6ZqFzijzm z*X&nz-gjB5ClNEMGXvcny36wSX?Cy9`{)-(R8l9iPK!=&{te3Bq27A{7%ld%{1fa!|wgm#IrBP#ZQMP!@+bs zISU^jUOZEiK2G&yAJ3O?_wj7q|NG-Pq+2%TLdx~wy@aJ7tnWef{hWWY?_P!Gp4KTM ut3GXOed7XJ>36MFSq!4}OWOWxiod1!heK|MCC^+|es)$|);IXStMw04wAA(h literal 0 HcmV?d00001 diff --git a/sprites/lobby.xcf b/sprites/lobby.xcf index 49a57c08a629d7eec3c3497dcf6cb41608895b6e..001600695874021f59708d3bad0a065b399439ac 100644 GIT binary patch delta 8860 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 delta 7813 zcmZA54^)-)9mnze{JCOc3CU)t6G{dmB?u^@oWS&qnVliw#tIQDPiV5~g5or54=RmQ zw)_K)OgGFpb7l@4Y#g--PR(Pqb9E}tv?C6h`3J#CfugX>^LcxAPWK$|>wZ7a^W6LV z`TdhG20~8U45__gjP6?N8GIR6hr3z}YhAt3x9jdTCmRoSWw^DcD+lwj5S>b6l6PcX zp*3=dbFE6@wHjl@sgQ66grOuT-| z{R-pCF+7J~VYj^MagTBQRqsFC$kY1;cHkX(^IrTOJ|g>;;M-U)?{JlOxXOO6vY)H$ z=PLVCJ)Xhe_w;Az!2Ud3j_y|f_I1=%Sc8qOhVdKx9qy9$N~E#bo2hr=KK;I7Hxr!2 zE7&K!fj90HR(iIwk=>*xR=57QQQv1dAViO+2R{HTrz1G@OTva0Qm&dfbY&*o4Qh)qnr}FXO8&sXOX1E(KACV;rX8JY0k;umsoRR;0E9l=#p1lJjRtE>Trz1G@OTv za0Qm&dfbY&*yQSebAtT;>dy70bekOy+?_yh5+&!#?8WOFACDd=>yI6g91~s}F zMY|Wfn~ZKo)9zC03S?00uBSePC$Sy7<<~ZbU<4-OYFR%1OL!jssJ z-SQh7LofmpaW*~ZoB0Hbu?S1C0;{ne58+8{$8OnUV+clIBF?4<^~@(&j73-Fd2<6Y^WO5RzU8Fy;Y-;!79U1_pzjH4H7}#DKy|-XS*G`8w>G_3 z<&a2RgqnxUAtzM_+$Ws?O{r$UY6ZhIW17K-RR?QDXa?&9&ET(<->)k$L$;|7*YeJc z(iNIfS`3*{>XK%Z7DMKQKKHv5b6SV$w3qO8d_?Fzi4y#a8 zzPZ1V+UM7Qk>>vM1pL7M0o9EoFbrd5Q?m5ECfm=+|8NIy>%^>pYi@1@^vj`o=GM@0 z)RWZzt)W_GSwnxshK2ZZ{1v{9zsEnxd)aU7XR0S?U1=rXuR2-FH7hxu`Z0V`{ohJ{ zmf%HPjT>}Go_W|sIgcJhH1ls(Kr#ON-smRxJG{}K;lHpQyY9}d*7I5uSp&27IL1lmKpMf%P=8^tj^1^b^5duEsc2-pJ;iwYg|xjIckNJ}xE-n!w?m(G zkF!Hx#MQ2j9lDWVoBY031$Mgrt72y@RGy^)+|JSu+u23RvrAFW!p=LPdeu0&L5l=? zgC==v`VW!Z;0vBOi9AJz_$RV!Is2or&bQNRD$NIWUp~ zBRMdV10%cj1yMGJU<4-OY@Cmau?S1C!qxxw?YTA1D2pht8X^kpvj@zH1B27!=!r42 zbXZCyet_y5-jsdRNA6Ci-gxy_Z+yBo#b;q2F2iC}zxT$g`+4IxlW)g5R5$d-H&dU+ zHtbY)^2YZmNYI$GSR{jI0mCI0aI}c=HW6d#x=MOH{*7!!$xez)7U1RDV+p;a%upM#4wD(B%FmAn1lIPhz_pB zO8mgp@lLHF*oQ~(1fIt$*dvoH9D!pn3KK9D=VCTKH>l(BCM_peiDg)hRk#xy@F4o| zEMCMLI3TA5;wT*N*YS9~(_#r`U^-@D9xlUTT!ZUyGj7K^Y{X_fjcxS*X`KXpGC2T8 zVi?9?63)U5%)xvtME_O#U*6=kScxCd|C4J7_Tdpcf#>lG_Q>fLj=(V(g$bC7b1@sA zJPSdLY=6C3a#`tU4X#2YvuX9VIXbjI@`7H42OW?>#K!(v>6>u@t}$2x4p vW;`vO8Epie*e6p0a3qFd3?|_$%)lJX$3k>)t*igdKb;OZ4UbRpmJj