// put.js
(function () {
/*global adventurejs A*/
/**
* @augments {adventurejs.Verb}
* @class put
* @ajsnode game.dictionary.verbs.put
* @ajsconstruct MyGame.createVerb({ "name": "put", [...] });
* @ajsconstructedby adventurejs.Dictionary#createVerb
* @hideconstructor
* @ajsinstanceof Verb
* @ajsnavheading ManipulationVerbs
* @summary Verb meaning put, as in 'put sword' or 'put sword in scabbard'.
* @ajssynonyms put
* @tutorial Scripting_VerbSubscriptions
* @tutorial Verbs_VerbAnatomy
* @tutorial Verbs_VerbProcess
* @tutorial Verbs_ModifyVerbs
* @tutorial Verbs_WriteVerbs
* @classdesc
* <pre class="display border outline">
* <span class="input">> put paper behind painting</span>
* You put the slip of paper on which is written the Illuminati
* password behind the painted portrait of Grover Cleveland.
* </pre>
* <pre class="display border outline">
* <span class="input">> put sword in stone</span>
* You put the sword in the stone. The stone begins to glow
* with a soft purple light. The glow brightens slowly,
* growing gradually into incandescence. You shield your eyes
* with your hands. There is a loud WHUMPF followed by cool
* darkness. You lower your hands. The sword and the stone are gone.
* </pre>
* <pre class="display border outline">
* <span class="input">> put syrup on pancakes</span>
* You can't put anything on the pancakes.
*
* Kidding! The game understands that you actually meant
* "pour syrup on pancakes". The game is not cruel or dumb
* or inflexible (not on purpose, at least). The game loves you,
* and validates you, and only wants you to enjoy a healthy
* nutritious breakfast. You pour some syrup on the pancakes. Mmmm.
* </pre>
* <pre class="display border outline">
* <span class="input">> put lizard under rock</span>
* You put the lizard back under the hot rock. It wriggles its
* legs and burrows in contentedly.
* </pre>
* <p>
* <strong>Put</strong> one
* {@link adventurejs.Tangible|Tangible}
* {@link adventurejs.Asset|Asset} behind/in/on/under another Tangible Asset.
* Requires that the destination Asset has a
* {@link adventurejs.Aspect|Aspect}
* there.
* To learn about Aspects, see
* <a href="/doc/Tangibles_Aspects.html">How to Use Aspects</a>.
* </p>
* @ajsverbreactions doRemoveThisFromThat, doRemoveThatFromThis, doMoveThisToThat, doMoveThatToThis
* @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
*/
A.Preverbs.put = {
name: "put",
prettyname: "put",
past_tense: "put",
synonyms: ["put", "place", "set"],
enqueue_collections: true,
gerund: "putting",
/**
* @ajsverbstructures
* @memberof put
*/
accepts_structures: [
"verb noun", // put lantern
"verb noun preposition", // put clothes on
"verb preposition noun", // put down lantern
"verb noun preposition noun", // put lantern on chest
],
/**
* @memberof put
* @ajsverbphrase
* phrase1:
* {
* accepts_noun: true,
* requires_noun: true,
* accepts_plural_noun: true,
* noun_must_be:
* {
* in_inventory: true,
* not_worn_if_all: true,
* not_nested_inventory_if_all: true,
* },
* },
*/
phrase1: {
accepts_noun: true,
requires_noun: true,
accepts_plural_noun: true,
noun_must_be: {
known: true,
present: true,
reachable: true,
visible: true,
// in_inventory: true,
takeable: true,
not_worn_if_all: true,
not_nested_inventory_if_all: true,
},
},
/**
* @memberof put
* @ajsverbphrase
* phrase2:
* {
* accepts_noun: true,
* noun_must_be:
* {
* tangible: true,
* present: true,
* visible: true,
* reachable: true,
* known: true,
* not_in_prior_plural: true,
* },
* accepts_preposition: true,
* requires_preposition: true,
* },
*/
phrase2: {
accepts_noun: true,
noun_must_be: {
tangible: true,
present: true,
visible: true,
reachable: true,
known: true,
not_in_prior_plural: true,
},
accepts_preposition: true,
requires_preposition: true,
},
/**
* @memberof put
* @ajsverbparams
* with_params: {},
*/
with_params: {},
doTry: function () {
var input = this.game.getInput();
var subject = input.getSubject();
var verb_phrase = input.verb_phrase;
var direct_object = input.getAsset(1);
var indirect_object = input.getAsset(2);
var direct_preposition = input.getPreposition(1);
var indirect_preposition = input.getPreposition(2);
var indirect_aspect;
var room = this.game.getCurrentRoom();
var msg = "";
var results;
if (input.hasStructure("verb noun") && direct_object.isDOV("drop")) {
// we've arrived here without an indirect_object, which is legit,
// subject can "put thing", in which case we just want to drop
this.game.log(
"L1337",
"log",
"high",
`${this.name}.js > no indirect object, doVerb drop`,
"Verbs"
);
return this.game.dictionary.doVerb("drop");
}
// can be direct object of verb?
if (!direct_object.isDOV(this.name)) {
this.game.debug(
`D1722 | ${this.name}.js | ${direct_object.id}.dov.${this.name}.enabled is unset `
);
msg += `${direct_object.Articlename} can't be ${this.past_tense}. `;
this.handleFailure(msg);
return null;
}
if (subject.getNestId() === direct_object.id) {
this.game.debug(
`D1181 | ${this.name}.js | subject is nested on ${direct_object.id}`
);
msg += `$(We) can't ${this.name} ${direct_object.articlename} ${
indirect_preposition ? indirect_preposition : ""
} ${
indirect_object ? indirect_object.articlename : ""
} while $(we're) ${subject.getPostureGerund()} ${subject.getNestPreposition()} it. `;
this.handleFailure(msg);
return null;
}
if (input.hasStructure("verb noun preposition")) {
if (["on", "down"].includes(indirect_preposition)) {
input.setPreposition(1, indirect_preposition);
input.deletePhrase(2);
input.setStructure("verb preposition noun");
} else {
this.game.debug(
`D1925 | ${this.name}.js | ${this.name} ${indirect_preposition} not handled `
);
msg += `$(We) $(don't) know how to ${this.name} ${direct_object.articlename} ${indirect_preposition}. `;
this.handleFailure(msg);
return null;
}
}
if (input.hasStructure("verb preposition noun")) {
if (direct_preposition === "down" && this.game.hasVerb("drop")) {
this.game.debug(`D1926 | ${this.name}.js | put down, doVerb drop `);
return this.game.dictionary.doVerb("drop");
}
if (direct_preposition === "on" && direct_object.isDOV("wear")) {
this.game.debug(`D1891 | ${this.name}.js | put on, doVerb wear `);
return this.game.dictionary.doVerb("wear");
}
// @TODO what about "put in key"? prompt for indirect object? assume from context?
this.game.debug(
`D1927 | ${this.name}.js | ${this.name} ${direct_preposition} not handled `
);
msg += `$(We) $(don't) know how to ${this.name} ${direct_preposition} ${direct_object.articlename}. `;
this.handleFailure(msg);
return null;
}
if (input.hasStructure("verb noun preposition noun")) {
if (direct_object === indirect_object) {
this.game.debug(
`D1154 | ${this.name}.js | direct_object ${direct_object.id} is indirect_object ${indirect_object.id} `
);
msg += `$(We) can't put ${direct_object.articlename} ${indirect_preposition} itself. `;
this.handleFailure(msg);
return null;
}
// direct_object.canRemoveThatFromThis(subject)
// can be direct object of verb?
if (!indirect_object.isIOV(this.name)) {
this.game.debug(
`D1026 | ${this.name}.js | ${indirect_object.id}.iov.${this.name}.enabled is unset `
);
msg += `Nothing can be ${this.past_tense} ${indirect_preposition} ${indirect_object.articlename}. `;
this.handleFailure(msg);
return null;
}
if (indirect_object instanceof adventurejs.Floor) {
if (!room.has_floor) {
this.game.debug(
`D1678 | ${this.name}.js | ${room.id}.has_floor is false `
);
msg += `$(We) can't see a floor here. `;
this.handleFailure(msg);
return null;
}
if (indirect_preposition !== "on") {
// @TODO what if there's a hole in the floor?
this.game.debug(
`D1685 | ${this.name}.js | ${this.name} ${indirect_preposition} floor is not handled `
);
msg += `$(We) $(don't) know how to ${this.name} anything ${indirect_preposition} the floor. `;
this.handleFailure(msg);
return null;
}
// @TODO handle this instead of deferring
this.game.debug(
`D1162 | ${this.name}.js | indirect_object is floor, doVerb drop `
);
return this.game.dictionary.doVerb("drop");
}
// in some cases "put on" can mean "attach to"
// ex "put cap on pen"
// so see if we can attach these things
if (
indirect_preposition === "on" &&
!indirect_object.hasAspectAt(indirect_preposition) &&
(direct_object.canBePut("attached", indirect_object) ||
indirect_object.canBePut("attached", direct_object)) &&
this.game.hasVerb("attach")
) {
input.setPreposition(2, "attached");
this.game.debug(
`D1155 | ${this.name}.js | ${direct_object.id} and ${indirect_object.id} can attach, doVerb attach `
);
return this.game.dictionary.doVerb("attach");
}
if (!indirect_object.hasAspectAt(indirect_preposition)) {
this.game.debug(
`D1156 | ${this.name}.js | ${indirect_object.id} has no ${indirect_preposition} aspect `
);
msg += `$(We) can't put anything ${indirect_preposition} ${indirect_object.articlename}. `;
this.handleFailure(msg);
return null;
}
if (
direct_object.getPlacePreposition() === indirect_preposition &&
direct_object.getPlaceAssetId() === indirect_object.id
) {
this.game.debug(
`D1163 | ${this.name}.js | ${indirect_object.id} is ${indirect_preposition} ${indirect_object.id}`
);
msg += `${direct_object.Articlename_is} already ${indirect_preposition} ${indirect_object.articlename}. `;
this.handleFailure(msg);
return null;
}
if (
"in" === indirect_preposition &&
indirect_object.isDOV("close") &&
indirect_object.is.closed
) {
// @TODO automatically open the thing, if context allows it
this.game.debug(
`D1157 | ${this.name}.js | ${indirect_object.id}.is.closed `
);
msg += `${indirect_object.Articlename_is} closed. `;
this.handleFailure(msg);
return false;
}
results = this.tryToPutThisInThatAspect(
direct_object,
indirect_preposition,
indirect_object
);
if (results.fail) {
msg = results.msg;
this.handleFailure(msg);
if (results.end_turn) return false;
return null;
}
} // verb noun preposition noun
return true;
},
doSuccess: function () {
var input = this.game.getInput();
var subject = input.getSubject();
var verb_phrase = input.verb_phrase;
var direct_object = input.getAsset(1);
var indirect_object = input.getAsset(2);
var indirect_preposition = input.getPreposition(2);
var msg = "";
var results;
var moved = false;
if (direct_object.is.worn) {
results = direct_object.unfasten();
msg += results ? `$(We) ${results} and remove ` : `$(We) remove `;
msg += `${direct_object.articlename} first. `;
direct_object.incrementDoVerbCount("remove", "dov");
direct_object.is.worn = false;
}
// sentence structure: verb noun preposition noun
if (input.hasStructure("verb noun preposition noun")) {
msg += `$(We)`;
if (direct_object.getPlaceAssetId() !== subject.id) {
msg += ` take ${direct_object.articlename} from ${
direct_object.getPlaceAsset().articlename
} and `;
// remove direct object from current location
results = direct_object
.getPlaceAsset()
.onRemoveThatFromThis(direct_object);
if ("undefined" !== typeof results) return results;
// subject has to pick this up
// set direct object's temporary location to subject
results = subject.onMoveThatToThis(direct_object);
if ("undefined" !== typeof results) return results;
moved = true;
}
msg += ` put ${
moved ? direct_object.getPronoun("we") : direct_object.articlename
} ${indirect_preposition} ${indirect_object.articlename}. `;
// remove noun1 from subject
results = subject.onRemoveThatFromThis(direct_object);
if ("undefined" !== typeof results) return results;
// set noun1's new location to noun2
// add noun1 to noun2's contents
results = indirect_object.onMoveThatToThis(
direct_object,
indirect_preposition
);
if ("undefined" !== typeof results) return results;
if (
input.parsedNoun1.matches.qualified.length > 1 &&
-1 === input.output_class.indexOf("concatenate_output")
) {
input.output_class += " concatenate_output";
}
}
// print output
return this.handleSuccess(msg, direct_object);
},
};
})(); // put