// write.js
(function () {
/*global adventurejs A*/
"use strict";
/**
* @augments {adventurejs.Verb}
* @class write
* @ajsnode game.dictionary.verbs.write
* @ajsconstruct MyGame.createVerb({ "name": "write", [...] });
* @ajsconstructedby adventurejs.Dictionary#createVerb
* @hideconstructor
* @ajsinstanceof Verb
* @ajsnavheading CompositionVerbs
* @summary Verb that means write, as in "write on blackboard".
* @tutorial Scripting_VerbSubscriptions
* @tutorial Verbs_VerbAnatomy
* @tutorial Verbs_VerbProcess
* @tutorial Verbs_ModifyVerbs
* @tutorial Verbs_WriteVerbs
* @classdesc
* <pre class="display border outline">
* <span class="input">> write on blackboard with chalk</span>
* You scribble a hasty formula on the blackboard with the chalk.
* Hmm, no, that doesn't look right.
* </pre>
* <p>
* <strong>Write on</strong> a {@link adventurejs.Tangible|Tangible}
* {@link adventurejs.Asset|Asset}.
* Requires that the writing Asset has
* <code>.iov.write.enabled</code>
* set to true and that the target has
* <code>asset.dov.write.enabled</code>
* set to true.
* <strong>Write on</strong> saves a record
* of things written on an Asset to its
* <a class="code" href="/doc/adventurejs.Tangible.html#property_written_strings">written_strings</a>
* property, which can be appended to the Asset's description.
* </p>
* @ajsverbreactions
* @ajsverbphases doBeforeTry, doAfterTry, doBeforeSuccess, doAfterSuccess
*/
A.Preverbs.write = {
name: "write",
prettyname: "write on",
past_tense: "wrote",
synonyms: ["write"],
// write on x
//verb_prep_noun: [ "write on" ],
// write on x with y
//verb_prep_noun_prep_noun: [ "write on with" ],
/**
* @ajsverbstructures
* @memberof write
*/
accepts_structures: [
"verb noun",
"verb preposition noun",
"verb noun preposition noun",
"verb preposition noun preposition noun",
"verb noun preposition noun preposition noun",
],
/**
* @memberof write
* @ajsverbphrase
* phrase1:
* {
* accepts_noun: true,
* requires_noun: true,
* accepts_preposition: true,
* noun_must_be:
* {
* known: true,
* //tangible: true, // @todo write idea on thing
* present: true,
* visible: true,
* reachable: true,
* },
* },
*/
phrase1: {
accepts_noun: true,
requires_noun: true,
accepts_preposition: true,
noun_must_be: {
known: true,
present: true,
visible: true,
reachable: true,
},
},
/**
* @memberof write
* @ajsverbphrase
* phrase2:
* {
* accepts_noun: true,
* noun_must_be:
* {
* known: true,
* //tangible: true,
* present: true,
* visible: true,
* reachable: true,
* },
* accepts_preposition: true,
* //requires_preposition: true,
* //accepts_these_prepositions: [ 'with' ], // @todo
* },
*/
phrase2: {
accepts_noun: true,
noun_must_be: {
known: true,
present: true,
visible: true,
reachable: true,
},
accepts_preposition: true,
},
/**
* @memberof write
* @ajsverbphrase
* phrase3:
* {
* accepts_noun: true,
* noun_must_be:
* {
* known: true,
* //tangible: true,
* present: true,
* visible: true,
* reachable: true,
* },
* accepts_preposition: true,
* //requires_preposition: true,
* //accepts_these_prepositions: [ 'with' ], // @todo
* },
*/
phrase3: {
accepts_noun: true,
noun_must_be: {
known: true,
present: true,
visible: true,
reachable: true,
},
accepts_preposition: true,
},
/**
* @memberof write
* @ajsverbparams
* with_params: {},
*/
with_params: {},
doTry: function () {
var input = this.game.getInput();
var player = this.game.getPlayer();
var msg = "";
var allow = true;
var information_object, writing_object, surface_object;
var results;
/**
* 'write' doesn't follow an easy directObject/indirectObject
* pattern. Player can input "write 'foo'" or "write 'foo' on board"
* or "write 'foo' on board with chalk"
* or "write with chalk" or "write on board"
* We need to do some extra work to figure out what's what
* and save the results in the verb_params object for doSuccess to use.
* All we're saving is the phrase number, not the actual phrase.
*/
input.verb_params.surface_phrase = 0;
input.verb_params.writing_phrase = 0;
input.verb_params.information_phrase = 0;
for (var i = 0; i <= 3; i++) {
var asset = input.getAsset(i);
var preposition = input.getPreposition(i);
if (asset && asset.class === "GlobalString") {
// need to expand this to handle abtractions
// like "type password" or "write name"
information_object = asset;
input.verb_params.information_phrase = i;
} else if (preposition === "with") {
// it's our writing implement
writing_object = input.getAsset(i);
input.verb_params.writing_phrase = i;
if (!writing_object.isIOV("write")) {
this.game.debug(
`F1528 | ${this.name}.js | ${writing_object.id}.iov.write.enabled is false `,
);
msg += `${writing_object.Articlename} can't be written with. `;
this.handleFailure(msg);
return false;
}
} else if (preposition === "on" || preposition === "in") {
// it's our writing surface
// write on paper is different from write in book
// maybe need to add a "quirks.write_on_means_write_in" property?
surface_object = input.getAsset(i);
input.verb_params.surface_phrase = i;
//if( !surface_object["can_be_written_"+preposition] )
if (!surface_object.isDOV("write")) {
this.game.debug(
`F1527 | ${this.name}.js | ${surface_object.id}.dov.write.enabled is false `,
);
msg += `${surface_object.Articlename} doesn't offer a good writing surface. `;
this.handleFailure(msg);
return false;
}
} else if (preposition) {
// we don't know any other prepositions
this.game.debug(
`F1535 | ${this.name}.js | received a preposition we don't know how to handle `,
);
msg += `$(We) can't write ${preposition} ${asset.articlename}. `;
this.handleFailure(msg);
return false;
}
}
if (!surface_object) {
// because we don't know which noun,
// maybe don't do a soft prompt?
var phrase = input.getPhraseCount() + 1;
input.setPreposition(phrase, "on");
input.setSoftPrompt({
["noun" + phrase]: true,
// ["preposition"+phrase]: "on",
// verb: 'write'
});
this.game.debug(
`F1525 | ${this.name}.js | soft prompt for surface object `,
);
msg += `What would $(we) like to write on? `;
this.handleFailure(msg);
return null;
}
// is player holding the writing implement?
// in most verbs would be handled by NounMustBe,
// but write's noun_must_be is a little more complicated
// because the order of words can vary
if (
writing_object &&
!this.game.parser.selectInHands([writing_object.id]).length
) {
this.game.debug(
`F1549 | ${this.name}.js | ${writing_object.id}.place is not ${player.id} `,
);
msg += `$(We're) not holding ${writing_object.articlename}. `;
this.handleFailure(msg);
return null;
}
// can writing object write on surface object?
if (
writing_object &&
(!writing_object.isDOV(this.name) ||
!writing_object.DOVallowWithAsset(this.name, surface_object))
) {
this.game.debug(
`F1517 | ${this.name}.js | neither ${writing_object.id} nor ${surface_object.id} lists the other in .assets_this_can_${this.name}, .assets_that_can_${this.name}_this, .classes_this_can_${this.name}, .classes_that_can_${this.name}_this `,
);
msg += `${surface_object.Articlename} doesn't present a good writing surface for ${writing_object.articlename}. `;
this.handleFailure(msg);
return null;
}
// can we infer a writing object?
if (!writing_object && this.game.settings.try_to_infer_indirect_objects) {
results = this.tryToInferIndirectObject(surface_object);
if (results.fail) {
/* do nothing */
} else if (results.prompt) {
/* do nothing here, we'll handle later */
} else if (results.success) {
writing_object = results.indirect_object;
var index = input.setNewPhrase({
asset: writing_object,
preposition: "with",
});
input.verb_params.writing_phrase = index;
}
}
// no writing object after all
if (!writing_object) {
var index = input.hasPhrase(2) ? 3 : 2;
// we're implying an indirect object so restructure sentence for next turn
input.setSoftPrompt({
["noun" + index]: true,
structure: input.getStructure() + " preposition noun",
});
input.setPreposition(index, "with");
this.game.debug(`F1759 | ${this.name}.js | soft prompt for noun2 `);
msg += `What would $(we) like to write with? `;
this.handleFailure(msg);
return false;
}
return true;
},
doSuccess: function () {
var input = this.game.getInput();
var information_object = input.getAsset(0);
var surface_object = input.getAsset(input.verb_params.surface_phrase);
var surface_preposition = input.getPreposition(
input.verb_params.surface_phrase,
);
var writing_object = input.getAsset(input.verb_params.writing_phrase);
var writing_preposition = input.getPreposition(
input.verb_params.writing_phrase,
);
var information_object = input.getAsset(
input.verb_params.information_phrase,
);
var results;
var msg = "";
if (information_object) {
/* *
* at the moment, the only information object we're handling is GlobalString
* which is basically an Asset that's used as a placeholder for a string.
* The string itself is stored in input.strings. This is probably not ideal,
* and eventually we'll want to handle things like passwords and other
* abstractions that can be written on a surface.
* That's all @TODO
*/
}
this.game.debug(`F1529 | ${this.name}.js | print doSuccess `);
if (
input.verb_params.writing_phrase &&
input.getAssumed(input.verb_params.writing_phrase)
) {
msg += `<span class='inference'>(with ${writing_object.articlename})</span>`;
}
msg += "$(We) write ";
if (surface_object) {
if (input.strings.length) {
msg += input.strings[0] + " ";
surface_object.written_strings.push(input.strings[0]);
} else {
msg += " a few scribbles ";
}
msg += surface_object.quirks.write_on_means_write_in ? "in " : "on ";
msg += surface_object.articlename;
} else {
msg += " a few scribbles in the air";
}
if (writing_object) {
msg += " with " + writing_object.articlename;
}
msg += ". ";
// print output
this.handleSuccess(msg, surface_object);
return true;
},
};
})(); // write