'Give' changing an integer value with NPCs

benn
I've been messing with Quest for a few weeks & really like it. The GUI's fairly intuitive so for the most part, I've been able to set things up pretty easily without having to delve too deeply with coding. But I hit a snag. Keep looking through the documentation, but I think I might've missed it

So I have different object types set up for 'food' & 'npc's. I gave both a 'happiness' attribute. Through expressions, I set it up so eating certain foods makes the player character happier, & thus gets different descriptions & outcomes based on that variations of that integer value. What I'd like to do is set up something similar for npcs. Make it so if I give another character a food item instead of just eating it, it can apply that same value it already has to them instead of the player & thus alter your interactions with them. The part I'm running into trouble, since I'm doing this by expressions, is what to call that. Whereas just plain eating it alters "player.happiness," is there a nice way to apply that to all npcs as a base? Is there a way to set it up to make it work across the entire object type, but only work on the specific npc receiving an item? Or do I have to account for every npc's happiness value individually?

And if you'll allow me to piggyback another, since it's sort of related, I like how with certain verbs like give, you can get an automatic list of hyperlinks of who you can give things to/interact with. What's annoying is when I click 'apple > give' & among the list is like 'chair' 'npc' 'clock' 'etc' like every possible combo of item in the room & in the inventory. Is there a simple way of limiting the hyperlink options on something like that just to npcs? Or do I have to kill the autolist & just try to make a menu via script?

Thanks in advance!

HegemonKhan
over the versions, many Tabs have accumulated in the GUI~Editor, cluttering it up, and so, now many of the Tabs are hidden, until you toggle them on:

'game' Game Object -> 'Features' and~or the 'Room Descriptions' Tab -> toggle (via the check boxes) on~off various features~Tabs, as desired

'whatever' (for individual) Object(s) -> 'Objects' and~or 'Features' Tab -> toggle (via the check boxes) on~off various features~Tabs, as desired

http://docs.textadventures.co.uk/quest/ ... notes.html

so, first if you haven't already, is to toggle on the 'use~give' Tab for your Objects (the default 'player' Player Object and~or other desired Objects).

this provides you the built-in 'use~give' feature (shows~reveals the 'use~give' Tab now), which should then hopefully be intuitive... (if not let me~us know):

basicaly you want to 'run scripts', and to choose (add) the scripts that-or-to do what you want (usually you want the action~scripts to be local to that specific Object, so choose '[handle Objects individually]' if that is one of the choices).

I'm not that familiar with the GUI~Editor... and am too lazy to look it up, so hopefully you can figure out what scripts to add to do what you want...

----------------

unfortunately... yes, each Object, needs its own Attributes, though there's different methods of doing this to make it easier on you, the computer~cpu (processing: speed~performance), and~or on the computer's memory usage (not using up lots of your computer's memory~resources).

these various methods can be complex~advanced~confusing if you're not already a decent~good coder (such as using the 'Object Types' as I have done in my example below, but there's also via scripting, and etc advanced methods), but~so if you're interested, let me know.

hopefully this is intuitive... about why each object needs it's own attributes (if you don't mind a little code usage for a conceptual example):

'barbarian.strength' is his own strength amount, which needs to be tracked~stored (so it can be manipulated~used), which can be increased or decreased, and used for other game mechanics~formulas.

'paladin.strength' is his own strength amount, completely independant of the 'barbarian' Object's 'strength' Attribute, which needs to be tracked~stored (so it can be manipulated~used), which can be increased or decreased, and used for other game mechanics~formulas.

If the 'barbarian' Object gets his 'strength' Attribute increased, that should have no effect upon the 'paladin' Object's 'strength' Attribute, and thus why the 'paladin' needs his own 'strength' Attribute as well as the 'barbarian' needing~having his own 'strength' Attribute.

and by having two such attributes, they can be computed (added, subtracted, multiplied, divided, etc) and compared~contrasted too, to each other:

(ignore the lame-ness and~or impracticality of my examples below, lol)

if (barbarian.strength > paladin.strength) {
msg ("The barbarian has more strength than the paladin")
} else if (barbarian.strength < paladin.strength) {
msg ("The paladin has more strength than the barbarian")
} else {
msg ("The barbarian and paladin have the same strength")
}


team.strength = barbarian.strength + paladin.strength


player.damage = (player.weapon.damage + player.weapon.damage * (player.strength / 100)) - (monster.armor.resistance + monster.armor.resistance * (monster.endurance / 100))


player.current_life = player.current_life - monster.damage

monster.current_life = monster.current_life - player.damage


---------------

if you want to see, in code, an example, then here:

if the built-in 'give' doesn't work, you can create your own Command and~or Function (I don't know how to integrate the Command with a Verb --- I saw Pixie, or maybe it was someone else argh, doing it in one of his~her many guides, but can't remember where~what one, and at the time I couldn't understand it and probably still can't understand it, anyways, lol)

(there's a recent thread on using regular expressions, to handle all the different variations of words that people may use, but it was a bit over my head)

<object name="npc_1">
<inherit name="npc_type" />
<attr name="alias" type="string">tavern maid</attr>
</object>

<object name="apple">
<inherit name="food_type" />
</object>

<object name="banana">
<inherit name="food_type" />
<attr name="condition_integer" type="int">20</attr>
</object>

<object name="cyanide">
<inherit name="poison_type" />
</object>

<object name="ars_enic">
<inherit name="poison_type" />
<attr name="condition_integer" type="int">90</attr>
</object>

<type name="npc_type">
<attr name="type_of_object" type="string">npc</attr>
<attr name="condition_integer" type="int">50</attr>
<attr name="condition_string" type="string">normal</attr>
<attr name="changedcondition_integer" type="script">
if (this.condition_integer > 66) {
this.condition_string = "healthy"
} else if (this.condition_integer > 33) {
this.condition_string = "normal"
} else if (this.condition_integer > 0) {
this.condition_string = "unhealthy"
} else {
this.condition_string = "dead"
}
</attr>
</type>

<type name="food_type">
<attr name="type_of_object" type="string">food</attr>
<attr name="condition_integer" type="int">10</attr>
</type>

<type name="poison_type">
<attr name="type_of_object" type="string">poison</attr>
<attr name="condition_integer" type="int">60</attr>
</type>

<command name="give_item_to_npc_command">
<pattern>give #object_1# to #object_2#</pattern>
<script>
if (GetString (object_1, "type_of_object") = "food" and GetString (object_2, "type_of_object") = "npc") {
object_1.parent = object_2
object_2.condition_integer = object_2.condition_integer + object_1.condition_integer
msg ("You give the " + object_1.name + " and they eat it, (and magically the food is back or still in the npc's hand, lol), restoring " + object_1.condition_integer + "life.")
} else if (GetString (object_1, "type_of_object") = "poison" and GetString (object_2, "type_of_object") = "npc") {
object_1.parent = object_2
object_2.condition_integer = object_2.condition_integer - object_1.condition_integer
msg ("You give the " + object_1.name + " and they drink it, (and magically the poison is back or still in the npc's hand, lol), poisoning them, depleting" + object_1.condition_integer + "life.")
}
</script>
</command>

benn
Thanks, HK!
I don't know if I miscommunicated the question I had or if I'm just not following, but I definitely understand every npc requiring their own attribute. As a matter of fact they already do have them as a base. My question was about how to apply the change to that integer. To run with your example, say you have a potion that gives +5 strength. Barbarian's got 20 strength & the Paladin's got 15. How do I set up the expression so either one gets the same +5 strength? It seems like something I could run as a function, but don't know exactly what to put to make it work universal among each npc. Do I have to create a separate script for every possible npc under the food object type?
EDIT- though stupid me, i didn't realize that last code window had a scroll to it. i see how you coded it & while it's a lot more complicated than i was looking to go, but i get the general idea. if I do have to do it individually, at the very least i can copy the 'eat' scripts & just swap the player out for each npc. just thought there might've been an easier way

And with the other question, 'give' might've been a bad example, as I did eventually find how to limit the options for that. Where it's bugging me most at the moment, I have the custom verb 'confront with...' & have it set to 'require another object'. Problem is when I click it, I get this super long list of my whole inventory AND everything just hanging in the room & doesn't give me the 'handle Objects individually' option. I clicked through toggles & tabs but didn't see anything that really applied. I guess I might have to take the verb off the npc & put it on the item, but then I'm worried it'll still give me the option to confront the chair or something. Anyway, deeply sorry if I wasted any of your time but truly appreciate the help

The Pixie
The important part of what you are doing is raising the attribute in the script for GIVE; in code it just looks like this (click the seventh icon along over a script area of the GUI to see the code view):
this.happiness = this.happiness + 5

The "this" refers to the thing that has the script, so you can use the same code for any NPC.

For the verbs, you need to select from the list what you will confront the NPC with. Quest allows that to be any object or room in the game, so yes, that will potentially be a long list.

benn
Thanks, Pixie!

If it was just the one value of +5, that's probably how I would've gone about it. But since I have different food adding different values, I already have "this" applying to the food's happiness attribute in the eat expression (in the food object type). Like so:

player.happiness = player.happiness + this.happiness


Ok, so say I change the attribute in the food object type from happiness to like "hap" or something, to avoid any conflicts. Could I use "this" to apply to both a unique attribute in both the npc & the food in the same expression? Essentially:

this.happiness = this.happiness + this.hap


With "this.happiness" being the happiness of the npc & "this.hap" being how happy the food makes them? I'd try to just plug it in right now to test it myself, but I'd have to change it for "eat" then too & I'm already running a little late for work at the moment.

jaynabonne
(Testing my memory: that's the problem with only offering single lines of code instead of entire contexts to jar me.)

Two-object commands typically have "object" and "object2" variables (e.g. give %object to %object2). I'm not sure what the convention is for verbs, but there must be some way to access the "other" object within the script. I'd try "object" or "object2" as a first try.

HegemonKhan
Programming uses ASSIGNMENT, which is different than math's EQUALS:

math:

(x = 10) = (10 = x)

programming~coding:

(x = 10) =/= (10 = x): ERROR

the ASSIGNMENT OPERATOR (=) means that you're putting~storing the value_or_expression on the right side of the '=', into the VARIABLE on the left side of the '=', conceptually algebraic substitution:

x = 10
msg ("The value of x is: " + x)
// outputs: The value of x is: 10

player.strength = 10
msg ("The Player's strength is: " + player.strength)
// outputs: The Player's strength is: 10

----------

so, the syntax (in code) for the basic computations is:

// this is my own way of representing the syntax generically (an Attribute):

Object_name.Attribute_name = Value_or_Expression

~and for a conditional, an example using an 'if' Script ~

if (Object_name.Attribute_name OPERATOR Value_or_Expression) { scripts }

----------

OPERATORS:

Assignment or Comparison: =
// quest doesn't have the '==' (comparison operator), it can parse the '=' accurately, to whether to do an assignment or comparison

Addition or Concatenation (Concatenation: literally putting strings together, aka next to each other: "55" + "55" = "5555"): +

Subtraction: -

Multiplication: *

Division (getting the quotient, aka normal devision: 4/2 = 2): /

Modulus (devision, except you're getting~finding the REMAINDER, not the quotient: 5%2 = R1, 4%2 = R0, 5%3 = R2): %

Negation (Not) method A: not Object_name.Attribute_name = Value_or_Expression
// or for Boolean Attributes, the shorthand is: not Object_name.Attribute_name
~OR~

// if you're doing stuff directly in code (non-GUI~Editor), then you need to add the 'CDATA' tags to tell quest that the '<,>' are NOT html tags:

<![CDATA[ scripts ]]>

example:

<function name="student_grade_function" parameters="student"><![CDATA[
if (student.score > 90) {
student.grade = "A"
} else if (student.score > 80) {
student.grade = "B"
} else if (student.score > 70) {
student.grade = "C"
} else if (student.score > 60) {
student.grade = "D"
} else {
student.grade = "F"
}
]]></function>


so, this 'CDATA' tagging applies to all of these: again only if doing directly in code (if doing in the GUI~Editor, than it will automatically handle it for you, do NOT use the 'CDATA' tags if using the GUI~Editor):

Negation (Not) method B: Object_name.Attribute_name <> Value_or_Expression

Greater Than: >

Lesser Than: <

// the equals must be on the RIGHT side:

Greater Than or Equals To: >=

Lesser Than or Equals To: <=

etc etc etc (probably missing a few more operators... meh)

---------

Setting~Re-Setting~Alternating~Manipulating a VARIABLE's (usually using Attributes as your VARIABLES) Value:

player.strength = 0
player.strength = 100

monster.strength = 25
player.strength = monster.strength
// player.strength = 25

monster.strength = 25
monster.endurance = 75
player.strength = monster.strength + monster.endurance
// player.strength = 100

--------------

Addition (examples):

player.strength = player.strength + 5 // or whatever value you want

player.strength = player.strength + player.endurance + player.constitution

----------

*conceptual* example of how it works (using simple addition):

initial (old) value: player.strength = 0

player.strength (new) = player.strength (old:0) + 5
player.strength (new) = (0) + 5

new value: player.strength = 5

old value: player.strength = 5

player.strength (new) = player.strength (old:5) + 5
player.strength (new) = (5) + 5

new value: player.strength = 10

old value: player.strength = 10

player.strength (new) = player.strength (old:10) + 5
player.strength (new) = (10) + 5

new value: player.strength = 15

etc etc etc

---------------------

Subtraction:

player.strength = player.strength - 5

-------------------

Multiplication:

player.strength = player.strength * 5

-----------------

Division:

player.strength = player.strength / 5

----------------

Modulus:

game.seconds = game.seconds % 60

// remember this gets the REMAINDER of a division operation: making it good for cyclic things, such as time and dates (like seconds, minutes, hours, months, days, seasons, etc etc etc)
// 0,1,2,...,59,0,...,59,0,...,59, etc etc etc
// (0%60 = 60: you don't want this, lol), 1%60 = 1, 2%60 = 2, 59/60 = 59, 60%60 = 0, 61%60 = 1, 119%60 = 59, 120%60 = 0, 121%60 = 1, etc etc etc

game.minutes = game.minutes % 60

game.civilian_hours = game.civilian_hours % 12 // 0-11 am, 0-11 pm, 0 (0 or 12): am to pm (noon) or pm to am (midnight)

game.military_hours = game.military_hours % 24 // 0-23, 0 (0 or 24): from old day to new day (midnight)

game.months = game.months % 12

game.days = game.days % 7

game.seasons = game.seasons % 4

-------------------------

IN THE GUI~EDITOR:

Attributes (script that creates, sets, re-sets, changes, alters, manipulates, and~or etc Attributes):

run as script -> add new script -> variables -> 'set a variable or attribute' Script -> [expression], or choose the right option for what you want to do

if you choose the [expression] option, then you can type in the quasi-code (since I don't know the GUI~Editor's options, I like to cheat, choosing the [expression] option which lets me write in what I want the in it directly):

run as script -> add new script -> variables -> 'set a variable or attribute' Script -> [expression]: see below

set variable player.strength [expression] player.strength + 5

the 'if' Script:

or, if you want to use 'if' (or whatever conditional) Script:

run as script -> add new script -> scripts -> 'set a variable or attribute' Script -> [expression]: see below

if [expression] player.strength > monster.strength

-> then, -> add new script -> output -> 'print a message' Script -> print [message] The Player's strength is greater than the Monster's strength.

// choose the [expression] if you want to use VARIABLES or VARIABLES+TEXT, as the [message] is for TEXT only

------

the GUI~Editor's [increase~decrease to object's counter or whatever it is called] script option, only is able to do +1 or -1, which in code is, an example:

player.strength = player.strength + 1
player.strength = player.strength - 1

so, if you want to do~use values other than 1, or different operators (like multiply or divide or modulus), then you're going to have to choose the [expression] script option, and type in the quasi-code yourself.

jaynabonne
So, I looked through things a bit, and if I understand what you want, I think I have a solution.

If you want to be able to give (say) an apple to anyone and have a script update a happiness attribute on the receiver, then do this:
1) Go to the desired object that will be given, and on the "Features" tab, check "Use/Give". A new tab will appear with Use/Give on it.
2) Click on that Use/Give tab.
3) Where it says "Give this to (other object)", for the Action, choose "Handle objects individually".
4) An empty box will appear, but more importantly, a new choice will have appeared beneath that object list box that says "Give to any other object".
5) Choose "Add New Script"
6) Scroll down in the script choices to the Variables section, and choose "Set an object's attribute (named by an expression)". (Click OK or double click to add the script.)
7) Change "name" after "Set object" to "expression". In the type-in box after "expression", enter "object" (don't include the quotes).
8 ) Set attribute to "happiness" (include the quotes this time - you need it to be a string!)
9) In "Value" enter "object.happiness + this.happiness" (don't include the quotes).

That will do it for that object. Now, if you want all your objects to have that script, then it's easiest just to add a type with that setup. Then inherit the objects you want from that type. That would take quite a few steps, so I'm just going to include the source for a sample game here. Basically, I just went into code view and copied the give-related fields to the new type.

<!--Saved by Quest 5.6.5783.24153-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="giveitatest">
<gameid>43772fda-865d-49c8-a57c-7586a032eaf1</gameid>
<version>1.0</version>
<firstpublished>2016</firstpublished>
</game>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
<object name="apple">
<inherit name="editor_object" />
<inherit name="GivesHappiness" />
<happiness type="int">4</happiness>
</object>
</object>
<object name="henry">
<inherit name="editor_object" />
<happiness type="int">0</happiness>
</object>
</object>
<type name="GivesHappiness">
<feature_usegive />
<givetoanything type="script">
set (object, "happiness", object.happiness + this.happiness)
</givetoanything>
<giveto type="scriptdictionary" />
</type>
</asl>

This has a type called "GivesHappiness", which has the script to run when the object is given to anything. If you need to only allow some things to accept the object, then you'll need to include some code to reject being given to ineligible objects.

And if you want the "give" to actually transfer the object, then you can add this line to the "givetoanything" script:

this.parent = object

to make the target object the parent of what's being given.

If you run the game, you can type "give apple to henry". Since I didn't check the option to bring up a menu, it won't give you a list of objects to give to if you don't specify a target.

Note: the code the editor drops in for setting the variable is not what I would use personally, since I prefer to enter the script myself. Instead of:

set (object, "happiness", object.happiness + this.happiness)

you could simply have:

object.happiness = object.happiness + this.happiness

benn
Sorry I'm only back to respond now. I downloaded that the other night jaynabonne, but only got the chance to implement it today. That's pretty much exactly what I was looking for & I really appreciate you taking the time! And thank you everyone else as well. I'm sure I might have other questions moving forward but I appreciate the help on this & didn't want to make it seem like I forgot about you. Thanks.

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums