Script Specific to Object in Inventory

Enpherdaen
21 Feb 2020, 01:53Currently the player has every single obtainable object in their inventory, which are all invisible. This way when the player "picks up" a clone of that object (really just decreases the value of the clone, making it invisible if the value = 0), the value of the object in the inventory increases by the amount taken.
How do I set it so that when the player "takes" the object, this happens? Currently, it's hard fooling around with "take" since it interferes with the take function.

Enpherdaen
22 Feb 2020, 16:47):
mrangel
22 Feb 2020, 17:10I'm not sure I understand the question.
You're using a stacking system with a value
being the number in that location. That seems pretty standard.
I've seen a lot of variations of this system with the original object being placed somewhere inaccessible, and an object cloning itself where necessary.
Do you mean that the original objects are all in the player's inventory, set to invisible until they are picked up? I've not come across that, but it seems like it would make the system easier because you know that the prototype is the player's copy.
You'd give these items a take script like:
this.prototype.value = this.prototype.value + this.value
this.prototype.visible = true
destroy (this.name)
and the drop script would be:
CloneObjectAndMove (this, destination)
this.value = 0
this.visible = false
Or if you want it to work with containers which have scripts attached:
newClone = CloneObject (this)
if (HasScript (destination, "addscript")) {
do (destination, "addscript", QuickParams ("destination", destination, "object", this))
}
else {
newClone.parent = destination
}
if (newClone.parent = this.parent) {
destroy (newClone.name)
}
else {
this.value = 0
this.visible = false
}
But…
It might make more sense to modify the changedparent
script instead (which I believe is the more common way to handle scripts like this). This guarantees that moving the object around using scripts will continue to work correctly.

Enpherdaen
23 Feb 2020, 05:01Mrangel you genius, spot on again in determining my intentions. Those scripts do seem very clever, and should work if I understand them correctly. What do you mean by modifying the changedparent script though?
mrangel
23 Feb 2020, 09:36If an object has a changedparent
script attribute, this will be run every time the object moves for any reason. This could be used to check the new location for an existing clone of the same object and combine them if necessary. This works if an object is taken, dropped, put into a container, or moved by any other script or command.
The changedparent
script would look something like:
if (HasObject (this, "prototype") and not this = this.prototype) {
// Moving a clone
if (this.parent = game.pov) {
// Into the inventory
this.prototype.value = this.prototype.value + this.value
this.prototype.visible = true
destroy (this.name)
}
else {
// check if the destination already has a clone of the same object
foreach (sibling, GetDirectChildren (this.parent)) {
if (sibling.prototype = this.prototype and not sibling = this) {
this.value = this.value + sibling.value
destroy (sibling.name)
}
}
}
}
else if (not this.parent = game.pov) {
// this is the original; so force it to stay in the inventory
destination = this.parent
this.parent = game.pov
CloneObjectAndMove (this, destination)
this.value = 0
this.visible = false
}
This could be coupled with a changedvalue
script, also meaning that you can change an object's value in script whenever you want, and trust Quest to make it visible or invisible as appropriate. If you use this, the "visible" lines in the above script are unnecessary
this.visible = (this.value > 0)
This method means that you don't need to write a different script for every situation in which an object might change in location or number; these scripts cover every situation, so don't need a custom take/drop script.

Enpherdaen
11 Mar 2020, 18:27The problem with that take script is that it's only good for all or nothing. But I need a script that allows the player to select a value from the cloned object (ex: "take 3 sticks" when there are 10 sticks) rather than just destroying the clone and adding it's value to the prototype value.
mrangel
11 Mar 2020, 19:20Not hard to do. If you have a command with the pattern ^take (?<text_count>\d+) (?<object>.+)$
then you have a variable with the number. The scripts can be easily adapted.

Enpherdaen
11 Mar 2020, 19:27Would this work?
msg ("How much do you want to take?")
get input {
if (this.value > result) {
this.prototype.value = this.prototype.value + result
this.prototype.visible = true
this.value = this.value - result
}
else if (this.value = 0) {
this.visible = false
}
else if (this.value < result) {
msg ("There aren't that many sticks here.")
}
}