How can I let the player refer to something that isn't present? - inform7

I’ve got a book drop, into which you can drop things:
The garage is a room. The book drop is fixed in place in the garage.
The player is carrying a persimmon.
Instead of inserting something into the book drop:
say "Thunk."; move the noun to the book drop.
This much works:
garage
You can see a book drop here.
>PUT PERSIMMON IN BOOK DROP
Thunk.
However:
>TAKE PERSIMMON
You can't see any such thing.
I want to respond more meaningfully here. I tried this:
Instead of taking something which is in the book drop, say "You can't fit your hand through the slot."
but it seems we never get that far. The parser won’t let the player attempt any action referencing the persimmon.
Adding “The book drop is a transparent container.”, unsurprisingly, has various unwanted consequences (it lets you EXAMINE THE PERSIMMMON and even tells you about the persimmon when you LOOK).
Update: Adding “After deciding the scope of the player: place the contents of the book drop in scope.” also makes it so that the player “can see” the persimmon.
What’s the right way to fix this?

I think this does only what you want without any unexpected side effects:
The garage is a room. The book drop is a fixed in place open container.
It is scenery in the garage. The studio is north of the garage.
The player is carrying a persimmon.
Instead of inserting something into the book drop:
say "Thunk."; move the noun to the book drop.
Instead of taking something which is in the book drop:
say "You can't fit your hand through the slot."
Instead of doing something to something which is in the book drop:
say "You can't see any such thing."
Instead of examining the book drop:
say "It's a book drop."
Test me with "open drop / close drop / put persimmon in drop / get persimmon / x persimmon / x drop / n / get persimmon / x persimmon / x drop"

Related

AzerothCore: does rate.drop.item.quality from the worldserver.conf affect world drops?

I want to modify world drop rates, but I'm not sure how the rate.drop.item works. It seems to not affect all drops as I would have expected.
I've done some testing using various values from 200 all the way up to 10,000,000 and the results seem strange. Normal enemies don't seem to drop world blues any higher than normal, unless it's something normally on their drop table, like a blueprint or something (I tested this on many enemies across a few different zones). Enemies in dungeons drop many more BoE blues, but it would appear to be BoE drops specific to the instance, not world drops.
Oddly, chests seem to act as I would expect, if I have the rate.drop.item.rare set to a very high value, I will receive several world drop rares from the chest. It just doesn't seem to affect creatures.
I don't think this matters, but I was testing this with GM privileges.
Can anyone clarify more precisely how this configuration option works, and if it doesn't affect world drops, is there a config that does, or will I have to edit some tables to achieve this?
Thanks.
UPDATE
I ended up modifying the database directly. Here's the update I ran
UPDATE acore_world.creature_loot_template INNER JOIN reference_loot_template ON creature_loot_template.reference = reference_loot_template.entry
INNER JOIN item_template ON reference_loot_template.item = item_template.entry
SET creature_loot_template.Chance = creature_loot_template.Chance*5
WHERE creature_loot_template.Reference != 0 AND creature_loot_template.Chance < 1 AND (item_template.quality = 3 OR item_template.quality = 4)
AND creature_loot_template.GroupId != 0 AND (reference_loot_template.comment NOT LIKE '%ReferenceTable%')
The way Loots are managed in AzerothCore is more complex than it seems: it is not only about the drop chance of every single item but there are also other factors for example Groups etc...
I recommend reading:
https://www.azerothcore.org/wiki/loot_template
To understand how the core reads the loot tables.

Prevent automatically entering the room on startup

I want to give the player a chance to select a few options on game startup, such as their name.
The only problem is that the game insists on putting the player into the first room immediately and print the room name and description. That's not interesting for the player yet, though.
How can I prevent Inform 7 from automatically putting the player into the first room, or at least suppress the room name and description printing at startup?
The solution I found:
The initial room is a room.
The first rule for printing the name of a room:
if the player is in the initial room:
do nothing;
otherwise:
continue the action.

Inform 7 error using If player consents

I'm trying to write a piece of interactive fiction using inform 7, I want to put a choice in there for the player and I want a simple yes or no I used the following code:
if the player consents say "You get a better view of the stranger."
Otherwise:
say "You can't make out what's happening clearly, however, you notice the stranger walking out of the pub"
I then get this useless error message:
You wrote 'if the player consents say "You get a better view of the stranger."' : but I can't find a verb that I know how to deal with. This looks like an 'if' phrase which has slipped its moorings, so I am ignoring it. ('If' phrases, like all other such instructions, belong inside definitions of rules or phrases - not as sentences which have no context. Maybe a full stop or a skipped line was accidentally used instead of semicolon, so that you inadvertently ended the last rule early?)
Any help would be greatly appreciated.
The punctuation is off. Phrases should end with a semicolon, and if phrases should use either begin..end blocks, or the "colon-and-indentation" style. So either:
if the player consents begin;
say "You get a better view of the stranger.";
otherwise;
say "You can't make out what's happening clearly, however, you notice the stranger walking out of the pub";
end if;
or
if the player consents:
say "You get a better view of the stranger.";
otherwise:
say "You can't make out what's happening clearly, however, you notice the stranger walking out of the pub";
Note the colons and semicolons and tabs in the second example.
Also, as the error message says, you need to specify when that question should be asked. If phrases must be inside rules or phrases. For example, if the question should be asked as a result of an action:
After examining the stranger for the first time:
say "Move closer?";
if the player consents begin;
say "You get a better view of the stranger.";
otherwise;
say "You can't make out what's happening clearly, however, you notice the stranger walking out of the pub";
end if;

Prolog: Recursion and splitting lists

I'm trying to write a game in which the program reads through a database, grabs attributes and asks the player if the Movie that the player is thinking of will have that attribute. The user will answer either yes or no and if yes, the game will ask about the next attribute until either the user has said yes to every attribute, at that point the program will output the name of the movie. Or if the user says no, the game will then move along to the next movie in the database and start asking about those attributes.
The game ends when either it finds a movie with all the attributes or there are no more movies in the database in which the program could ask about.
Here is the database file.
object_properties(crocodile_dundee,[comedy,australian,paul_hogan_movie]).
object_properties(flipper,[action_movie,australian, paul_hogan_movie,
-comedy]).
object_properties(jackass,[comedy,-australian]).
object_properties(the_godfather,[drama,crime,-character_batman]).
object_properties(the_dark_knight,[drama,crime,character_batman]).
object_properties(the_living_planet, [documentary,director_attenborough]).
object_properties(the_code, [documentary,nerds_love_it]).
object_properties(the_russian_revolution, [documentary,about_history]).
Here is my game file.
go():-
guess_object(0,[]).
guess_object(Obj,[A|As]) :-
object_categories(Obj,A).
guess_object(1).
guess_object(2).
guess_object(3).
guess_object(4).
guess_object(5). %how do i do this specifically for the current Obj attributes?
guess(X) :- guess_object(_, X),
writeln('Does your object have the attribute '(X)'?'),
read(Input), Input=('yes') -> assert(object(X)) ; retractall(X), guess(X).
writeln('I guess that the film is: 'guess_object(Obj,_).
The main questions I have:
How do I split the object attributes in to a list like I'm trying to do on guess_object(1) through to guess_object(5) depending on whether the object has 2 attributes or 4 attributes, etc.
How do I make my guess(A) predicate recursive so once the user says no it will then go to the next object in the database file?
I'm not too great at prolog but any advice or pointers would be greatly appreciated, even if it's just pointing out a stupid mistake I may have made. I will also answer any questions anyone has to the best of my ability.

After Effects Expressions - controling comps from main comp using an "Expressions Layer"

THE GOAL I WANT TO ACHEIVE:
Control AE timelines using ONE EXPRESSION LAYER (much like using Actionscript) to trigger frequently used comps such as blinking, walking, flying etc... for cartoon animation.
I want animate a the blinking of a cartoon character. (and other actions, explained below) Rather than "re posting" the comp or key frames movements every time I want a blink or a particular action, I want to create a script where I can trigger the Blink comp to play. Is this possible? (Sidenote: A random blink through entire movie would be nice) but I still want to know how to do this for the reasons below.
Ideally: I would like to create an "Expressions layer" in the main comp to TRIGGER other comps to play. At certain points I would like to add triggers to call frequently used comps that contain actions like.. Blinking, Walking, Flying, Look Left and Right etc...
IT WOULD BE AMAZING IF somehow we could trigger other comps to begin, repeat, stop, maybe reverse, and do this all from one Main Comp using an expression layer.
WHY DO IT THIS WAY?
Why not just paste a comp in the spot you want it to play every time you want such action? Well in after effects if you wanted a "blink comp" to play 40 times in two minutes you would have to create 40 layers, or pate the key frames on that comp 40 times. Wouldn't it be awesome to trigger or call it from one one layer when you wanted it from one expressions layer?
We do something like this in Flash using Actionscript all the time. It would be awesome if there was a method out there to achieve this effect. This would be an OUTSTANDING tutorial and I believe it would be very popular if someone did it. It could be used for a MULTITUDE of amazing effects and could save a ton of time for everyone. Heck, help me figure this out and perhaps I will make a tutorial.
Thank you all ye "overflowing Stackers" who contribute! :)
I found the answer and that is...
IT'S NOT POSSIBLE.
After Effects expressions can not control other timelines. Unfortunately you have to put an expression on each layer you want to affect.
The next best solution, and to achieve something close to what I was asking can be found on this link: motionscript.com/design-guide/marker-sync.html
We can only hope that Adobe will someday give the power to expressions like they did with action-script.
HOPEFULLY SOON! Anyone reading this who works for Adobe please plead our case. Thanks
Part 1: Reference other layers in pre-Comps
Simply replace "thisComp" with "comp("ComName")"
To reference Effect-Controllers between compositions, follow the below formula:
comp("ComName").layer("LayerWithExpression").effect("EffectControlerName")("EffectControllerType")
More In-depth Answer: Adobe's Docs - Skip to the Layer Sub-objects part
As I understand the Adobe documentation, only Layers can be accessed,
not footage. What this means is that you will need to create your
expression link utilizing a pre-Comp. Footage can not access this so
that also means no nulls, adjustment layers, etc.
As an added bonus, if you use the essential graphics panel, you can put all the controllers in one pre-comp, but have the controls available no matter which comp you are in. Just select it in the Essential-Graphics dropdown.
Part 2: Start/End based on other layers within pre-comps:
Regarding the next part where you want the expressions to activate based on other compositions, I recommend using the in-out Point expression.
inPoint | Return type: Number. Returns the In point of the layer, in seconds.
outPoint | Return type: Number. Returns the Out point of the layer, in seconds.
If you utilize the start time overrides you can pull this from:
startTime | Return type: Number. Returns the start time of the layer, in seconds.
Alternate Option:
I would recommend avoiding this as the keyframes are basically referenced as an index, so things can get messed up if you add one ahead of a keyframe you were already using - def incorporate some error handling.
Refer to the Key attributes and methods (expression reference) Here
Part 3: Interpolation & Time Reversal
You can time reverse the layer in the rightclick->time, otherwise this is all interpolation expressions like loop out etc - you can loopOut("FOO") a pre-comp if you not only cut it correctly, but also enable time remapping.
then use this to loop those keyframes;
try{ timeStart = thisProperty.key(1).time; duration = thisProperty.key(thisProperty.numKeys).time-timeStart; pingPong =
false; //change to true value if you want to loop animationn back &
forth quant=Math.floor((time-timeStart)/duration);
if(quant<0) quant = 0
if(quant%2 == 1 && pingPong == true){
t = 2*timeStart+ (quant+1)*duration - time;
}
else{
t = time-quant*duration;
}
}
catch(err){
t = time;
}
thisProperty.valueAtTime(t)

Resources