| ! physics.h | |
| ! Version 1.1 | |
| ! by Sam Hulick <shulick@indiana.edu> | |
| ! This is a slight revision (not by much) of the old physics.inf example | |
| ! I released quite awhile ago. Please read through these comments here | |
| ! so you know exactly how it works. | |
| ! P.S.: I give Graham Nelson complete permission to add this into | |
| ! his next library release. | |
| ! When creating a game using physics.h, you must define a new player | |
| ! object, or directly modify the one in parser.h so it includes | |
| ! a 'max_space 100', in it, preferably near the 'capacity 100'. | |
| ! So if you make your own player obj, be sure to do this as the | |
| ! first line in Initialise(): | |
| ! | |
| ! ChangePlayer(newself); | |
| ! followed by.. | |
| ! player.max_weight = max_weight_carried; | |
| ! player.max_space = max_space_carried; | |
| ! | |
| ! Note that max_weight and max_space do NOT work on an object-by-object | |
| ! basis, but by weight #'s. That's the whole point of physics.h. | |
| ! Inform's capacity handling routines aren't very detailed, in that you | |
| ! could put three large rocks in a bag, and the bag will be full, but | |
| ! if you put three small pebbles in the bag, it is strangely full as | |
| ! well. This file will remedy that problem. When you define objects, | |
| ! give it a 'weight' and 'size', i.e. | |
| ! | |
| ! Object skull "human skull" | |
| ! with name "human" "skull", | |
| ! weight 8, | |
| ! size 6, | |
| ! ... | |
| ! | |
| ! Just figure a decent weight/size scale for your game, and think of | |
| ! what size or weight you would give it. I would give a shovel a | |
| ! weight of 10 or 13, perhaps, and a size of 15-20, maybe. It's | |
| ! just estimating. I give very small objects (pebbles, M&M's, etc.) | |
| ! a weight and size of 0, usually, because they're so small. Or | |
| ! you could up-scale your system, making M&M's size/weight both 1, | |
| ! then your shovel would more likely have a weight of 30, since you've | |
| ! up-scaled your values to compensate for the M&M's. There are no | |
| ! rights or wrongs: it's your game. I'm just providing the medium | |
| ! to control these weights and sizes. | |
| ! Now, on to more technical things. max_weight and max_space are | |
| ! used for containers and supporters. They can be values or | |
| ! routines (maybe for magical containers that expand). I think | |
| ! that is self-explanatory. | |
| ! too_big and too_heavy are a bit more complicated. They can simply | |
| ! be a string to print to the user when an object is too heavy or | |
| ! big to carry, or it can be a routine if you wish. But on a supporter | |
| ! or container, it really MUST be a routine. When too_heavy or too_big | |
| ! is called, 'action' contains either ##Take, ##PutOn, or ##Insert. | |
| ! Let's give an example: | |
| ! Object mcont "magic container" | |
| ! with description "You can put things on or in it, ooh.", | |
| ! name "magic" "container", | |
| ! size 5, | |
| ! weight 10, | |
| ! max_weight 30, | |
| ! max_size 30, | |
| ! too_heavy [; | |
| ! switch (action) | |
| ! { | |
| ! ##Take: "The container contains too many heavy things \ | |
| ! for you to handle it."; | |
| ! ##PutOn: "However magical it is, it can't support the \ | |
| ! weight of that."; | |
| ! ##Insert: "That object is too heavy, the magical \ | |
| ! container would rip trying to carry that."; | |
| ! } | |
| ! ], | |
| ! ..... | |
| ! | |
| ! And too_big works the same way, only it deals with the fact that | |
| ! the container can't handle the size of an object. If these things | |
| ! are unclear to you, you can skim through this file and read the | |
| ! source code. If you do not provide a too_heavy/too_big routine | |
| ! or string for an object, default messages will be printed, and | |
| ! you don't have to handle examining the 'action' variable. But | |
| ! you will most likely want to handle it yourself, since the default | |
| ! messages are.. well.. rather bland. | |
| ! IF YOU FIND ANY BUGS, or have any questions, e-mail me at | |
| ! shulick@indiana.edu. Thanks! Enjoy the code. Hope it adds some | |
| ! interesting depth to your games. | |
| ! P.S.: Don't forget to REPLACE RTakeSub, InsertSub, and PutOnSub, | |
| ! and include this file after parser and verblib. | |
| Property max_weight alias capacity; ! max weight something can hold | |
| Property max_space; ! max space..... | |
| Property weight; ! can be a routine. so can max_weight/max_space | |
| Property size; ! same for this one | |
| Property too_heavy "That's too heavy for you to carry right now."; | |
| Property too_big "That's too big for you to carry right now."; | |
| ! can the carrier take on the weight of obj? true/false return value | |
| [ OkWeight carrier obj w; | |
| w = ValueOrRun(obj, weight); | |
| if ((WeightCarried(carrier) + w) > ValueOrRun(carrier, max_weight)) rfalse; | |
| rtrue; | |
| ]; | |
| ! can the carrier take on the size of obj? | |
| [ OkSize carrier obj s; | |
| s = ValueOrRun(obj, size); | |
| if ((SpaceCarried(carrier) + s) > ValueOrRun(carrier, max_space)) rfalse; | |
| rtrue; | |
| ]; | |
| [ WeightCarried obj o total; | |
| objectloop (o in obj) | |
| { | |
| total = total + ValueOrRun(o, weight); | |
| if (child(o) ~= 0) | |
| total = total + WeightCarried(o); | |
| } | |
| return total; | |
| ]; | |
| [ SpaceCarried obj o total; | |
| objectloop (o in obj) | |
| total = total + ValueOrRun(o, size); | |
| return total; | |
| ]; | |
| !! The reason SpaceCarried() isn't recursive is because it merely doesn't | |
| ! have to be. WeightCarried() must be recursive, because if you put a | |
| ! huge heavy steel ball into a light sack and carry the sack, this doesn't | |
| ! mean the sack relieves your weight. However, if you can manage to fit a | |
| ! very large object into a small sack, then your troubles are reduced. (a | |
| ! good example would be a huge Nerf(TM) beachball that is tough to carry | |
| ! around, but if you find a small, light box, you can open the box, stuff | |
| ! the Nerf(TM) ball into it, and close the box. The weight carried is | |
| ! still the box plus the ball, but now your space carried has reduced. | |
| [ AdviseMoveIt obj; | |
| print "Try moving some things off ", (the) obj; "."; | |
| ]; | |
| [ AdvisePullIt obj; | |
| print "Try removing some things from ", (the) obj; "."; | |
| ]; | |
| [ RTakeSub fromobj i j k postonobj a rval; | |
| if (noun==player) return L__M(##Take,2); | |
| if (noun has animate) return L__M(##Take,3,noun); | |
| if (parent(player)==noun) return L__M(##Take,4,noun); | |
| i=parent(noun); | |
| if (i==player) return L__M(##Take,5); | |
| if (i has container || i has supporter) | |
| { postonobj=i; | |
| k=action; action=##LetGo; | |
| if (RunRoutines(i,before)~=0) { action=k; rtrue; } | |
| action=k; | |
| } | |
| while (i~=fromobj && i~=0) | |
| { if (i hasnt container && i hasnt supporter) | |
| { if (i has animate) return L__M(##Take,6,i); | |
| if (i has transparent) return L__M(##Take,7,i); | |
| return L__M(##Take,8); | |
| } | |
| if (i has container && i hasnt open) | |
| return L__M(##Take,9,i); | |
| i=parent(i); | |
| if (i==player) i=fromobj; | |
| } | |
| if (noun has scenery) return L__M(##Take,10); | |
| if (noun has static) return L__M(##Take,11); | |
| ! If it's too heavy, don't even bother with SACK_OBJECT. just because | |
| ! we put something in a sack doesn't make it any lighter. | |
| if (OkWeight(player, noun) == 0) | |
| { | |
| a = action; | |
| action = ##Take; | |
| rval = PrintOrRun(noun, too_heavy, 0); | |
| action = a; | |
| return rval; | |
| } | |
| if (OkSize(player, noun) == 0) | |
| { | |
| if (SACK_OBJECT~=0) | |
| { if (parent(SACK_OBJECT)~=player) | |
| return ObjTooBig(noun); | |
| j=0; | |
| objectloop (k in player) | |
| if (k~=SACK_OBJECT && k hasnt worn && k hasnt light) j=k; | |
| if (j~=0) | |
| { L__M(##Take,13,j); | |
| keep_silent = 1; <Insert j SACK_OBJECT>; keep_silent = 0; | |
| if (j notin SACK_OBJECT) rtrue; | |
| } | |
| else return ObjTooBig(noun); | |
| } | |
| else return ObjTooBig(noun); | |
| } | |
| move noun to player; | |
| if (postonobj~=0) | |
| { k=action; action=##LetGo; | |
| if (RunRoutines(postonobj,after)~=0) { action=k; rtrue; } | |
| action=k; | |
| } | |
| rfalse; | |
| ]; | |
| [ ObjTooBig obj a rval; | |
| a = action; | |
| action = ##Take; | |
| rval = PrintOrRun(obj, too_big, 0); | |
| action = a; | |
| return rval; | |
| ]; | |
| [ PutOnSub a; | |
| receive_action=##PutOn; | |
| if (second==d_obj) { <Drop noun>; rfalse; } | |
| if (parent(noun)~=player) return L__M(##PutOn,1,noun); | |
| if (second>1) | |
| { action=##Receive; | |
| if (RunRoutines(second,before)~=0) { action=##PutOn; rtrue; } | |
| action=##PutOn; | |
| } | |
| if (IndirectlyContains(noun,second)==1) return L__M(##PutOn,2); | |
| if (second hasnt supporter) return L__M(##PutOn,3,second); | |
| if (parent(second)==player) return L__M(##PutOn,4); | |
| if (noun has worn) | |
| { L__M(##PutOn,5); | |
| <Disrobe noun>; | |
| if (noun has worn) rtrue; | |
| } | |
| if (OkSize(second, noun) == 0) | |
| { | |
| a = action; | |
| action = ##PutOn; | |
| if (RunRoutines(second, too_big) == 0) | |
| { | |
| ! default message | |
| print_ret (The) noun, " won't fit on ", (the) second, "."; | |
| } | |
| action = a; | |
| if (ValueOrRun(noun, size) <= ValueOrRun(second, max_space)) | |
| return AdviseMoveIt(second); | |
| rtrue; | |
| } | |
| if (OkWeight(second, noun) == 0) | |
| { | |
| a = action; | |
| action = ##PutOn; | |
| if (RunRoutines(second, too_heavy) == 0) | |
| { | |
| print_ret "You feel ", (the) second, " begin to give as you start to put ", | |
| (the) noun, " on it. Maybe this isn't such a good idea."; | |
| } | |
| action = a; | |
| if (ValueOrRun(noun, weight) <= ValueOrRun(second, max_weight)) | |
| return AdviseMoveIt(second); | |
| rtrue; | |
| } | |
| move noun to second; | |
| if (AfterRoutines()==1) rtrue; | |
| if (second>1) | |
| { action=##Receive; | |
| if (RunRoutines(second,after)~=0) { action=##PutOn; rtrue; } | |
| action=##PutOn; | |
| } | |
| if (keep_silent==1) rtrue; | |
| if (multiflag==1) return L__M(##PutOn,7); | |
| L__M(##PutOn,8,noun); | |
| ]; | |
| [ InsertSub a; | |
| receive_action = ##Insert; | |
| if (second==d_obj ) <<Drop noun>>; | |
| if (parent(noun)~=player) return L__M(##Insert,1); | |
| if (second>1) | |
| { action=##Receive; | |
| if (RunRoutines(second,before)~=0) { action=##Insert; rtrue; } | |
| action=##Insert; | |
| } | |
| if (second hasnt container) return L__M(##Insert,2); | |
| if (second hasnt open) return L__M(##Insert,3); | |
| if (IndirectlyContains(noun,second)==1) return L__M(##Insert,5); | |
| if (noun has worn) | |
| { L__M(##Insert,6); | |
| <Disrobe noun>; if (noun has worn) rtrue; | |
| } | |
| if (OkSize(second, noun) == 0) | |
| { | |
| a = action; | |
| action = ##Insert; | |
| if (RunRoutines(second, too_big) == 0) | |
| { | |
| print_ret "There's not enough room inside ", (the) second, " for ", | |
| (the) noun, "."; | |
| } | |
| action = a; | |
| if (ValueOrRun(noun, size) <= ValueOrRun(second, max_space)) | |
| return AdvisePullIt(second); | |
| rtrue; | |
| } | |
| if (OkWeight(second, noun) == 0) | |
| { | |
| a = action; | |
| action = ##Insert; | |
| if (RunRoutines(second, too_heavy) == 0) | |
| { | |
| print_ret (The) second, " won't hold anymore weight."; | |
| } | |
| action = a; | |
| if (ValueOrRun(noun, weight) <= ValueOrRun(second, max_weight)) | |
| return AdvisePullIt(second); | |
| rtrue; | |
| } | |
| move noun to second; | |
| if (AfterRoutines()==1) rtrue; | |
| if (second>1) | |
| { action=##Receive; | |
| if (RunRoutines(second,after)~=0) { action=##Insert; rtrue; } | |
| action=##Insert; | |
| } | |
| if (keep_silent==1) rtrue; | |
| if (multiflag==1) return L__M(##Insert,8); | |
| L__M(##Insert,9,noun); | |
| ]; | |
Xet Storage Details
- Size:
- 11.2 kB
- Xet hash:
- 082c8e287ae1f519baf2559c251eb3be7fd7836e90616dd213d0b01d4c35f56c
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.