<?php
/**
* An object which is "alive", common code shared between users and NPCs
*
* DutchPIPE version 0.4; PHP version 5
*
* LICENSE: This source file is subject to version 1.0 of the DutchPIPE license.
* If you did not receive a copy of the DutchPIPE license, you can obtain one at
* http://dutchpipe.org/license/1_0.txt or by sending a note to
* hide@address.com, in which case you will be mailed a copy immediately.
*
* @package DutchPIPE
* @subpackage dpuniverse_std
* @author Lennert Stock <hide@address.com>
* @copyright 2006, 2007 Lennert Stock
* @license http://dutchpipe.org/license/1_0.txt DutchPIPE License
* @version Subversion: $Id: DpLiving.php 311 2007-09-03 12:48:09Z ls $
* @link http://dutchpipe.org/manual/package/DutchPIPE
* @see DpObject
*/
/**
* Builts upon the standard DpObject class
*/
inherit(DPUNIVERSE_STD_PATH . 'DpObject.php');
/**
* An object which is "alive", common code shared between users and NPCs
*
* Creates the following DutchPIPE properties:<br />
*
* - boolean <b>isLiving</b> - Set to TRUE
* - string <b>displayMode</b> - "graphical" or "abstract"
* - integer <b>sessionAge</b> - Age in seconds of this object
* - integer <b>weightCarry</b> - Combined weight of objects in our inventory
* - integer <b>maxWeightCarry</b> - Maximum weight this object can carry
* - integer <b>volumeCarry</b> - Combined volume of objects in our inventory
* - integer <b>maxVolumeCarry</b> - Maximum volume this object can carry
* - string <b>actionFailure</b> - Last action error message, "Read what?"
* - string <b>actionDefaultFailure</b> - Default action error message, "What?"
* - int <b>lastActionTime</b> - UNIX time stamp of last action performed
* - string <b>inputMode</b> - Input area mode, 'say' or 'cmd'
*
* @package DutchPIPE
* @subpackage dpuniverse_std
* @author Lennert Stock <hide@address.com>
* @copyright 2006, 2007 Lennert Stock
* @license http://dutchpipe.org/license/1_0.txt DutchPIPE License
* @version Release: 0.2.1
* @link http://dutchpipe.org/manual/package/DutchPIPE
* @see DpObject
*/
class DpLiving extends DpObject
{
/**
* Creates this living object
*
* Called by DpObject when this object is created. Adds standard actions
* which can be performed by this object, usually a user or a computer
* controlled character.
*
* Calls {@link createDpLiving()} in the inheriting class.
*
* Starts a "heartbeat", see {@link timeoutHeartBeat()}.
*
* @access private
* @see createDpLiving(), timeoutHeartBeat()
*/
final function createDpObject()
{
$this->isLiving = new_dp_property(TRUE);
$this->displayMode = new_dp_property('graphical');
$this->sessionAge = new_dp_property(0, FALSE);
$this->inputMode = new_dp_property('cmd');
$this->isDraggable = FALSE;
if (WEIGHT_TYPE_NONE !== WEIGHT_TYPE) {
$this->weightCarry = new_dp_property(0, FALSE);
$this->coinherit(DPUNIVERSE_STD_PATH . 'mass.php');
if (WEIGHT_TYPE_ABSTRACT === WEIGHT_TYPE) {
$this->weight = 7;
$this->maxWeightCarry = new_dp_property(7);
} elseif (WEIGHT_TYPE_METRIC === WEIGHT_TYPE) {
$this->weight = 70000; /* Grams */
$this->maxWeightCarry = new_dp_property(30000);
} elseif (WEIGHT_TYPE_USA === WEIGHT_TYPE) {
$this->weight = 2458; /* Ounces */
$this->maxWeightCarry = new_dp_property(1054);
}
}
if (VOLUME_TYPE_NONE !== VOLUME_TYPE) {
$this->volumeCarry = new_dp_property(0, FALSE);
$this->coinherit(DPUNIVERSE_STD_PATH . 'mass.php');
if (VOLUME_TYPE_ABSTRACT === VOLUME_TYPE) {
$this->volume = 7;
$this->maxVolumeCarry = new_dp_property(5);
} elseif (VOLUME_TYPE_METRIC === VOLUME_TYPE) {
$this->volume = 70000;
$this->maxVolumeCarry = new_dp_property(30000);
} elseif (VOLUME_TYPE_USA === VOLUME_TYPE) {
$this->volume = 2458;
$this->maxVolumeCarry = new_dp_property(1054);
}
}
/**
* Sets the message shown to the user when an action fails
*
* Call this method from action methods, for example actionFoo(). When the
* user performs an action but the action fails, there are two ways for the
* method implementing the action to communicate the failure to the user.
*
* <ol>
* <li>
* Call {@link DpUser:tell()} in the user and return TRUE, for
* example:<br><br>
* <code>
*$user->tell('Action foo failed because of bar.');
*return TRUE;
* </code>
* <br>
* The action system will stop looking for other ways to perform the
* action.<br><br>
* </li>
* <li>
* Call this setActionFailure method in the user and return FALSE. This
* failure setup is used when different objects can have the same actions
* implemented with addAction - if one fails, another might still
* succeed. Example:<br><br>
* <code>
*$user->setActionFailure('Action foo failed because of bar.');
*return FALSE;
* </code>
* <br>
* The action system will continue looking for other ways to perform
* the action. If it doesn't find any, the previously set failure message
* is communicated to the user. Otherwise, the next method implementing
* the action takes over. The action system will continue looking for
* object/methods implementing the action, until TRUE is returned or no
* more implementations are found. In that case, the last set action
* failure is returned. If no action failure was set, the default failure
* message is shown, see {@link setActionDefaultFailure()}.
* </li>
* </ol>
*
* @param string $actionFailure message to be shown when an action fails
* @example /websites/dutchpipe.org/dpuniverse/obj/note.php A readable note
* @see getActionFailure(), setActionDefaultFailure(),
* getActionDefaultFailure()
*/
$this->actionFailure = new_dp_property(DPUNIVERSE_ACTION_DEFAULT_FAILURE);
/**
* Sets the default message shown to the user when an action fails
*
* Used when no message was set with setActionFailure, for example "What?".
*
* @param string $actionDefaultFailure default message to be shown when
* an action fails
* @see setActionFailure(), getActionFailure(),
* getActionDefaultFailure()
*/
$this->actionDefaultFailure = new_dp_property(DPUNIVERSE_ACTION_DEFAULT_FAILURE);
$this->setBody(dp_text("This description hasn't been set yet.<br />"));
/* Actions for both NPCs and users */
$this->addAction(dp_text('take'), explode('#', dp_text('take#get')), 'actionTake', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_OBJENV, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(dp_text('drop'), dp_text('drop'), 'actionDrop', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_OBJINV, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(dp_text('inventory'), explode('#', dp_text('inventory#inv#i')), 'actionInventory', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(dp_text('examine'), explode('#', dp_text('examine#exam#exa#x#look#l')), 'actionExamine', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_SELF | DP_ACTION_TARGET_LIVING | DP_ACTION_TARGET_OBJINV | DP_ACTION_TARGET_OBJENV, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
//$this->addAction(array($this, 'getMenuGiveLabel'), dp_text('give'), 'actionGive', DP_ACTION_OPERANT_METHOD_MENU, DP_ACTION_TARGET_OBJINV, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(dp_text('give to...'), dp_text('give'), 'actionGive', DP_ACTION_OPERANT_METHOD_MENU, DP_ACTION_TARGET_OBJINV, array($this, 'getMenuGiveAuth'), DP_ACTION_SCOPE_SELF);
$this->addAction(dp_text('<div style="width: 81px; margin: 0px"><div style="float: left">page chat</div> <div style="float: right">TAB</div></div>'), dp_text('say'), 'actionSay', DP_ACTION_OPERANT_COMPLETE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('emotions'), dp_text('smile')), dp_text('smile'), 'actionSmile', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('emotions'), dp_text('grin')), dp_text('grin'), 'actionGrin', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('emotions'), dp_text('laugh')), dp_text('laugh'), 'actionLaugh', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array($this, 'getEmotionsMenu'), dp_text('cheer'), 'actionCheer', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_SELF | DP_ACTION_TARGET_LIVING, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('emotions'), dp_text('nod')), dp_text('nod'), 'actionNod', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('emotions'), dp_text('shrug')), dp_text('shrug'), 'actionShrug', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array($this, 'getEmotionsMenu'), dp_text('pat'), 'actionPat', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_LIVING, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array($this, 'getEmotionsMenu'), dp_text('high5'), 'actionHighFive', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_LIVING, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array($this, 'getEmotionsMenu'), dp_text('hug'), 'actionHug', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_LIVING, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array($this, 'getEmotionsMenu'), dp_text('kiss'), 'actionKiss', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_LIVING, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array($this, 'getEmotionsMenu'), dp_text('dance'), 'actionDance', DP_ACTION_OPERANT_MENU, DP_ACTION_TARGET_LIVING, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('emotions'), dp_text('emote...')), dp_text('emote'), 'actionEmote', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('send message to...')), dp_text('tell'), 'actionTell', DP_ACTION_OPERANT_METHOD_MENU, DP_ACTION_TARGET_SELF, array($this, 'getMenuTellAuth'), DP_ACTION_SCOPE_SELF);
$this->addAction(dp_text('send message...'), dp_text('tell'), 'actionTell', array($this, "getTellOperant"), DP_ACTION_TARGET_USER, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->addAction(array(dp_text('more chat'), dp_text('shout to site...')), dp_text('shout'), 'actionShout', DP_ACTION_OPERANT_NONE, DP_ACTION_TARGET_SELF, DP_ACTION_AUTHORIZED_ALL, DP_ACTION_SCOPE_SELF);
$this->setTimeout('timeoutHeartBeat', 2);
$this->createDpLiving();
}
/**
* Sets this living object up at the time it is created
*
* An empty function which can be redefined by the living class extending
* on DpLiving. When the object is created, it has no title, HTML body, et
* cetera, so in this method methods like {@link DpObject::setTitle()} are
* called. Building blocks extending on DpLiving may define their own create
* function. For example, DpNpc defines {@link DpNpc:createDpNpc}.
*
* @see resetDpLiving()
*/
function createDpLiving()
{
}
/**
* Resets this living object
*
* Called by DpObject at regular intervals as defined in dpuniverse-ini.php.
* Calls the method 'resetDpLiving' in this living object. You can redefine
* that function to periodically do stuff such as alter the state of this
* living object.
*
* @access private
* @see resetDpLiving()
*/
final function resetDpObject()
{
$this->resetDpLiving();
}
/**
* Resets this living object
*
* Called by this living object at regular intervals as defined in
* dpuniverse-ini.php. An empty function which can be redefined by the
* living class extending on DpLiving. To be used to periodically do stuff
* such as alter the state of the living object.
*
* @see createDpLiving()
*/
function resetDpLiving()
{
}
/**
* Reports an event
*
* Called when certain events occur, given with $name.
*
* Calls the method 'eventDpLiving' in this living object.
*
* @param object $name Name of event
* @param mixed $args One or more arguments, depends on event
* @since DutchPIPE 0.2.0
*/
final function eventDpObject($name)
{
$args = func_get_args();
call_user_func_array(array($this, 'eventDpLiving'), $args);
}
/**
* Reports an event
*
* Called when certain events occur, given with $name.
*
* @param object $name Name of event
* @param mixed $args One or more arguments, depends on event
* @since DutchPIPE 0.2.0
*/
function eventDpLiving($name)
{
}
/**
* Calls itself every "heartbeat"
*
* Redefine this method to make timed stuff happen.
*/
function timeoutHeartBeat()
{
$this->setTimeout('timeoutHeartBeat', 2);
}
/**
* Gets the livings's age since it was created as an object in a string
*
* Returns the livings's age in a format like "6 hours and 14 minutes".
*
* @return string livings's age
* @see DpUser::getInactive(), DpUser::isInactive(), DpUser::getStatus()
*/
function getSessionAge()
{
return get_age2string(time() - $this->creationTime);
}
/**
* Tries to perform the action given by the living object
*
* Called by the system to handle both actions performed by clicking on
* menus and actions from the input area. The first method will result in an
* $action parameter such as "take object_242" (using an unique object id).
* With the second method, $action will contain what the user typed, such as
* "take beer".
*
* Searches and calls for the right method linked to the action, which could
* be in another object. Handles failure messages when the action failed.
*
* This method can also be used to force living objects to perform actions.
*
* @param string $action the action given by the living object
* @return boolean TRUE for success, FALSE for unsuccessful action
* @see setActionFailure(), getActionFailure(), setActionDefaultFailure(),
* getActionDefaultFailure(), DpObject::addAction(),
* DpObject::getActionData(), DpObject::getActionsMenu(),
* DpObject::getTargettedActions(),
* DpObject::performActionSubject()
*/
public function performAction($action)
{
global $grCurrentDpObject;
$this->lastActionTime = !isset($this->lastActionTime)
? new_dp_property(time()) : time();
$action = trim($action);
$grCurrentDpObject = $this;
echo sprintf(dp_text("Action by %s: %s\n"), $this->getTitle(), $action);
$rval = (bool)$this->performActionSubject($action, $this);
if (TRUE !== $rval) {
if (dp_strlen($action) && $action !== dp_text('look')
&& $action !== dp_text('l')) {
$action_failure = $this->getActionFailure();
if (!isset($this->_GET['menuaction'])) {
$this->tell($action_failure);
if ($this->isUser && $this === get_current_dpuser()) {
get_current_dpuniverse()->setToldSomething();
}
}
$this->setActionFailure($this->getActionDefaultFailure());
}
}
$grCurrentDpObject = FALSE;
return $rval;
}
function getWeightCarry()
{
$inv = $this->getInventory();
$weight = 0;
foreach ($inv as &$ob) {
if (isset($ob->weight)) {
$weight += $ob->weight;
}
}
return $weight;
}
function getVolumeCarry()
{
$inv = $this->getInventory();
$volume = 0;
foreach ($inv as &$ob) {
if (isset($ob->volume)) {
$volume += $ob->volume;
}
}
return $volume;
}
/**
* Makes this living object examine an object
*
* @param string $verb the action, "examine"
* @param string $noun what to examine, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionExamine($verb, $noun)
{
if ($verb == dp_text('look') || $verb == dp_text('l')) {
$at = dp_text('at');
$at_len = dp_strlen($at);
if (dp_strlen($noun) >= $at_len
&& dp_substr($noun, 0, $at_len) == $at) {
$noun = $noun == $at ? '' : trim(dp_substr($noun, $at_len));
}
}
if (!dp_strlen($noun)) {
$this->setActionFailure($verb == dp_text('look')
|| $verb == dp_text('l')
? dp_text('Look at what?<br />')
: dp_text('Examine what?<br />'));
return FALSE;
}
if (FALSE === ($env = $this->getEnvironment())) {
return FALSE;
}
if (!($ob = $this->isPresent($noun))
&& !($description = $this->getItemDescription($noun))) {
if (!($ob = $env->isPresent($noun))
&& !($description = $env->getItemDescription($noun))) {
$this->setActionFailure(sprintf(
dp_text('There is no %s here.<br />'), $noun));
return FALSE;
}
}
if ($ob) {
$description = $ob->getAppearance(0, TRUE, NULL, $this->displayMode,
FALSE, 'dpexamine');
}
$this->tell("<window>$description</window>");
return TRUE;
}
/**
* Makes this living object take an object
*
* @param string $verb the action, "take"
* @param string $noun what to take, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionTake($verb, $noun)
{
if (FALSE === ($env = $this->getEnvironment())) {
return FALSE;
}
if (!dp_strlen($noun)) {
$this->setActionFailure(ucfirst(sprintf(dp_text('%s what?<br />'),
$noun)));
return FALSE;
}
if ($noun == dp_text('all')) {
$inv = $env->getInventory();
$picked_up = FALSE;
foreach ($inv as &$ob) {
if (!isset($ob->isLiving) || TRUE !== $ob->isLiving) {
$result = $ob->moveDpObject($this);
$picked_up = TRUE;
if (TRUE !== $result) {
if (E_MOVEOBJECT_HEAVY === $result) {
$this->tell(dp_text("You can't carry more weight, drop something first.<br />"));
}
if (E_MOVEOBJECT_VOLUME === $result) {
$this->tell(dp_text("You can't carry more volume, drop something first.<br />"));
}
continue;
}
$this->tell(dp_text('You take %s.<br />',
$ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
$env->tell(ucfirst(sprintf(dp_text('%s takes %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE))),
$this);
}
}
if (FALSE === $picked_up) {
$this->tell(dp_text('There is nothing to pick up here.<br />'));
}
return TRUE;
}
if (FALSE === ($ob = $env->isPresent($noun))) {
$this->setActionFailure(sprintf(
dp_text('There is no %s here.<br />'), $noun));
return FALSE;
}
if (isset($ob->isLiving) && TRUE === $ob->isLiving) {
$this->tell(ucfirst(sprintf(
dp_text('%s refuses to be taken.<br />'), $ob->getTitle())));
return TRUE;
}
if ($ob->isHeap && ((!DPSERVER_ENABLE_MBSTRING
&& preg_match(dp_text('/^(\d+) /'), $noun, $matches))
|| (DPSERVER_ENABLE_MBSTRING && mb_ereg(dp_text('^([0-9]+) '),
$noun, $matches))) && $matches[1] > 0
&& $matches[1] < $ob->amount) {
$result = $ob->moveDpObject($this, FALSE, $matches[1]);
$title_definite = $title_indefinite = $noun;
} else {
$result = $ob->moveDpObject($this);
$title_definite = $ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE);
$title_indefinite = $ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE);
}
if (TRUE !== $result) {
if (E_MOVEOBJECT_HEAVY === $result) {
$this->tell(ucfirst(
dp_text("You can't carry more weight, drop something first.<br />")));
}
if (E_MOVEOBJECT_VOLUME === $result) {
$this->tell(ucfirst(
dp_text("You can't carry more volume, drop something first.<br />")));
}
return TRUE;
}
$this->tell(sprintf(dp_text('You take %s.<br />'),
$title_definite));
$env->tell(ucfirst(sprintf(dp_text('%s takes %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$title_indefinite)),
$this);
return TRUE;
}
/**
* Drops an object in the user's environment
*
* @param string $verb the action, "drop"
* @param string $noun what to drop, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionDrop($verb, $noun, $silently = FALSE)
{
if (!dp_strlen($noun)) {
if (FALSE === $silently) {
$this->setActionFailure(dp_text('Drop what?<br />'));
}
return FALSE;
}
if (FALSE === ($env = $this->getEnvironment())) {
return FALSE;
}
if ($noun == dp_text('all')) {
$inv = $this->getInventory();
if (sizeof($inv) == 0) {
if (FALSE === $silently) {
$this->tell(dp_text('You have nothing to drop.<br />'));
}
return TRUE;
}
foreach ($inv as &$ob) {
$ob->moveDpObject($env);
if (FALSE === $silently) {
$this->tell(sprintf(dp_text('You drop %s.<br />'),
$ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
}
$env->tell(ucfirst(sprintf(dp_text('%s drops %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE))),
$this);
}
return TRUE;
}
if (FALSE === ($ob = $this->isPresent($noun))) {
if (FALSE === $silently) {
$this->setActionFailure(sprintf(
dp_text('There is no %s here.<br />'), $noun));
}
return FALSE;
}
if ($ob->isHeap && ((!DPSERVER_ENABLE_MBSTRING
&& preg_match(dp_text('/^(\d+) /'), $noun, $matches))
|| (DPSERVER_ENABLE_MBSTRING && mb_ereg(dp_text('^([0-9]+) '),
$noun, $matches))) && $matches[1] > 0
&& $matches[1] < $ob->amount) {
$ob->moveDpObject($env, FALSE, $matches[1]);
$title_definite = $title_indefinite = $noun;
} else {
$ob->moveDpObject($env);
$title_definite = $ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE);
$title_indefinite = $ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE);
}
if (FALSE === $silently) {
$this->tell(sprintf(dp_text('You drop %s.<br />'),
$title_definite));
}
$env->tell(ucfirst(sprintf(dp_text('%s drops %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$title_indefinite)), $this);
return TRUE;
}
/**
* Shows this living object a list of objects it is carrying
*
* @param string $verb the action, "inventory"
* @param string $noun empty string
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionInventory($verb, $noun)
{
$inventory = $this->getAppearance(0, TRUE, NULL,
$this->displayMode, -1, 'dpobinv');
/* :KLUDGE: */
$carrying_str = dp_text('You are carrying:');
$inventory = str_replace($carrying_str, "<b>$carrying_str</b>",
$inventory);
$this->tell("<window name=\"inventory\">$inventory</window>");
return TRUE;
}
/**
* Makes this living object say something
*
* @param string $verb the action, "say"
* @param string $noun what to say, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionSay($verb, $noun)
{
if (empty($noun)) {
$this->tell(dp_text('Say what?<br />'));
return TRUE;
}
if (FALSE === ($env = $this->getEnvironment())) {
return FALSE;
}
$env->tell(ucfirst(sprintf(dp_text('%s says: %s<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE), $noun)), $this);
$this->tell(sprintf(dp_text('You say: %s<br />'), $noun));
return TRUE;
}
function getEmotionsMenu($verb, &$defined_by, &$target, &$performer)
{
//echo "$verb: THIS: {$this->title} DEFINED: {$defined_by->title}; TARGET: " . $target->title . "; PERFORMER: " . $performer->title . "\n";
return $defined_by === $performer
? array(dp_text('more chat'), dp_text('emotions'), $verb)
: array(dp_text('emotions'), $verb);
}
function getTellOperant($verb, &$defined_by, &$target, &$performer)
{
return $defined_by->title;
}
/**
* Completes the give action performed by clicking on an object
*
* Called by the action system when someone clicks on an object and selects
* "give...". Returns something like "beer to", which allows the system to
* fill the input area with "give beer to " using the title of the object
* which was clicked on.
*
* @param string $verb the action, "give"
* @return string a string such as "beer to "
* @see actionGive()
*/
function getActionOperantMenu($verb, &$menuobj)
{
$user = get_current_dpuser();
if ($verb === dp_text('give')) {
$ob_title = dp_strtolower($menuobj->getTitle());
$rval = dp_text('give %s to %s');
if (FALSE !== ($env = $this->getEnvironment())) {
$menu = array();
$inv = $env->getInventory();
foreach ($inv as &$ob) {
if ($ob->isLiving && $ob !== $user) {
$to_title = dp_strtolower($ob->getTitle());
$menu[$to_title] = sprintf($rval, $ob_title, $to_title);
}
}
}
return !count($menu) ? FALSE : $menu;
} elseif ($verb === dp_text('tell')) {
$rval = dp_text('tell %s');
$users = get_current_dpuniverse()->getUsers();
if (sizeof($users)) {
$menu = array();
foreach ($users as &$u) {
if ($u !== $user) {
$to_title = dp_strtolower($u->getTitle());
$menu[$to_title] = sprintf($rval, $to_title);
}
}
}
return !count($menu) ? FALSE : $menu;
}
return FALSE;
}
function getMenuGiveAuth()
{
if (FALSE !== ($env = $this->getEnvironment())) {
$inv = $env->getInventory();
foreach ($inv as &$ob) {
if ($ob->isLiving && $ob !== get_current_dpuser()) {
return DP_ACTION_AUTHORIZED_ALL;
}
}
}
return DP_ACTION_AUTHORIZED_DISABLED;
}
function getMenuTellAuth()
{
if (1 < get_current_dpuniverse()->getNrOfUsers()) {
return DP_ACTION_AUTHORIZED_ALL;
}
return DP_ACTION_AUTHORIZED_DISABLED;
}
function getMenuGiveLabel()
{
if (FALSE !== ($env = $this->getEnvironment())) {
$inv = $env->getInventory();
foreach ($inv as &$ob) {
if ($ob->isLiving && $ob !== get_current_dpuser()) {
return dp_text('give...');
}
}
}
return dp_text("<span style='color: #999'>give to...</span>");
}
/**
* Makes this living object give an object to another living object
*
* @param string $verb the action, "give"
* @param string $noun what and who to give, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
* @see actionGiveOperant()
*/
function actionGive($verb, $noun)
{
if (empty($noun)) {
return FALSE;
}
$to = ' ' . dp_text('to') . ' ';
$to_len = dp_strlen($to);
if (FALSE === ($pos = dp_strpos($noun, $to))
|| $pos > dp_strlen($noun) - $to_len) {
$this->Tell(dp_text('Give what to who?<br />'));
return TRUE;
}
$what = dp_substr($noun, 0, $pos);
$who = dp_substr($noun, $pos + $to_len);
if (!($what_ob = $this->isPresent($what))) {
$this->tell(sprintf(dp_text('You have no %s.<br />'), $what));
return TRUE;
}
$env = $this->getEnvironment();
if (!is_object($env) || !($who_ob = $env->isPresent($who))) {
$this->tell(ucfirst(sprintf(dp_text('%s is not here.<br />'),
$who)));
return TRUE;
}
$env->tell(ucfirst(sprintf(dp_text('%s gives %s to %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$what_ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE),
$who_ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE))),
$this, $who_ob);
$who_ob->tell(ucfirst(sprintf(dp_text('%s gives %s to you.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$what_ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE))));
$what_ob->moveDpObject($who_ob);
$this->tell(sprintf(dp_text('You give %s to %s.<br />'),
$what_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$who_ob->getTitle(DPUNIVERSE_TITLE_TYPE_INDEFINITE)));
return TRUE;
}
/**
* Makes this living object tell something to another user object
*
* @param string $verb the action, "tell"
* @param string $noun who and what to tell, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionTell($verb, $noun)
{
if (empty($noun)) {
return FALSE;
}
if (FALSE === ($pos = dp_strpos($noun, ' '))) {
$this->Tell(dp_text('Tell who what?<br />'));
return TRUE;
}
$who = dp_substr($noun, 0, $pos);
$what = dp_substr($noun, $pos + 1);
if (FALSE === ($who_ob = get_current_dpuniverse()->findUser($who))) {
$this->tell(sprintf(dp_text('User %s was not found.<br />'), $who));
return TRUE;
}
$who_ob->tell(ucfirst(sprintf(dp_text('%s tells you: %s<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE), $what)));
$this->tell(sprintf(dp_text('You tell %s: %s<br />'),
$who_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE), $what));
return TRUE;
}
/**
* Makes this living object shout something to everyone on the site
*
* @param string $verb the action, "shout"
* @param string $noun what to shout, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionShout($verb, $noun)
{
if (is_null($noun)) {
return FALSE;
}
$users = get_current_dpuniverse()->getUsers();
if (sizeof($users)) {
$msg = FALSE === ($env = $this->getEnvironment())
? ucfirst(sprintf(dp_text('%s shouts from nowhere: %s<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE), $noun))
: ucfirst(sprintf(dp_text('%s shouts from %s: %s<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$env->getTitle(), $noun));
foreach ($users as &$u) {
if ($u !== $this) {
$u->tell($msg);
}
}
}
$this->tell(sprintf(dp_text('You shout: %s<br />'), $noun));
return TRUE;
}
/**
* Makes this living object smile happily
*
* @param string $verb the action, "smile"
* @param string $noun empty string
* @return boolean TRUE
*/
function actionSmile($verb, $noun)
{
$this->tell(dp_text('You smile happily.<br />'));
if (FALSE !== ($env = $this->getEnvironment())) {
$env->tell(ucfirst(sprintf(dp_text('%s smiles happily.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))), $this);
}
return TRUE;
}
/**
* Makes this living object grin evilly
*
* @param string $verb the action, "grin"
* @param string $noun empty string
* @return boolean TRUE
*/
function actionGrin($verb, $noun)
{
$this->tell(dp_text('You grin evilly.<br />'));
if (FALSE !== ($env = $this->getEnvironment())) {
$env->tell(ucfirst(sprintf(dp_text('%s grins evilly.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))), $this);
}
return TRUE;
}
/**
* Makes this living object fall down on the floor laughing
*
* @param string $verb the action, "laugh"
* @param string $noun empty string
* @return boolean TRUE
*/
function actionLaugh($verb, $noun)
{
$this->tell(dp_text('You fall down on the floor laughing.<br />'));
if (FALSE !== ($env = $this->getEnvironment())) {
$env->tell(ucfirst(sprintf(
dp_text('%s falls down on the floor laughing.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))), $this);
}
return TRUE;
}
/**
* Makes this living object cheer wildly
*
* @param string $verb the action, "cheer"
* @param string $noun who to cheer on, could be empty
* @return boolean TRUE
*/
function actionCheer($verb, $noun)
{
if (!dp_strlen($noun) || $this->isId($noun)) {
$this->tell(dp_text('You jump up and down cheering.<br />'));
if (FALSE !== ($env = $this->getEnvironment())) {
$env->tell(ucfirst(sprintf(
dp_text('%s jumps up and down cheering.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))), $this);
}
return TRUE;
}
if (FALSE === ($env = $this->getEnvironment()) ||
($noun && !($dest_ob = $env->isPresent($noun)))) {
$this->setActionFailure(sprintf(dp_text("Couldn't find: %s<br />"),
$noun));
return FALSE;
}
if (!isset($dest_ob)) {
$this->setActionFailure(dp_text('Cheer on who?<br />'));
return FALSE;
}
$this->tell(sprintf(
dp_text('You jump up and down cheering on %s.<br />'),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
$env->tell(ucfirst(sprintf(
dp_text('%s jumps up and down cheering on %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))),
$this, $dest_ob);
$dest_ob->tell(ucfirst(sprintf(
dp_text('%s jumps up and down cheering you on.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))));
return TRUE;
}
/**
* Makes this living object nod solemnly
*
* @param string $verb the action, "nod"
* @param string $noun empty string
* @return boolean TRUE
*/
function actionNod($verb, $noun)
{
$this->tell(dp_text('You nod solemnly.<br />'));
if (FALSE !== ($env = $this->getEnvironment())) {
$env->tell(ucfirst(sprintf(dp_text('%s nods solemnly.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))), $this);
}
return TRUE;
}
/**
* Makes this living object shrug
*
* @param string $verb the action, "laugh"
* @param string $noun empty string
* @return boolean TRUE
*/
function actionShrug($verb, $noun)
{
$this->tell(dp_text('You shrug.<br />'));
if (FALSE !== ($env = $this->getEnvironment())) {
$env->tell(ucfirst(sprintf(dp_text('%s shrugs.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))), $this);
}
return TRUE;
}
/**
* Makes this living object pat another living object on the head
*
* @param string $verb the action, "pat"
* @param string $noun who to pat, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionPat($verb, $noun)
{
if (FALSE === ($env = $this->getEnvironment()) ||
($noun && !($dest_ob = $env->isPresent($noun)))) {
$this->setActionFailure(sprintf(dp_text("Couldn't find: %s<br />"),
$noun));
return FALSE;
}
if (!isset($dest_ob)) {
$this->setActionFailure(dp_text('Pat who?<br />'));
return FALSE;
}
$this->tell(sprintf(
dp_text('You pat %s on the head with a bone-crushing sound.<br />'),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
$env->tell(ucfirst(sprintf(
dp_text('%s pats %s on the head with a bone-crushing sound.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))),
$this, $dest_ob);
$dest_ob->tell(ucfirst(sprintf(
dp_text('%s pats you on the head with a bone-crushing sound.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))));
return TRUE;
}
/**
* Makes this living object slap a high-five with another living object
*
* @param string $verb the action, "high5"
* @param string $noun who to high5, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionHighFive($verb, $noun)
{
if (FALSE === ($env = $this->getEnvironment()) ||
($noun && !($dest_ob = $env->isPresent($noun)))) {
$this->setActionFailure(sprintf(dp_text("Couldn't find: %s<br />"),
$noun));
return FALSE;
}
if (!isset($dest_ob)) {
$this->setActionFailure(dp_text('High5 who?<br />'));
return FALSE;
}
$this->tell(sprintf(
dp_text('You jump up, and slap a thundering high-five with %s.<br />'),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
$env->tell(ucfirst(sprintf(
dp_text('%s jumps up, and slaps a thundering high-five with %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))),
$this, $dest_ob);
$dest_ob->tell(ucfirst(sprintf(
dp_text('%s jumps up, and slaps a thundering high-five with you.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))));
return TRUE;
}
/**
* Makes this living object hug another living object
*
* @param string $verb the action, "hug"
* @param string $noun who to hug, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionHug($verb, $noun)
{
if (FALSE === ($env = $this->getEnvironment()) ||
($noun && !($dest_ob = $env->isPresent($noun)))) {
$this->setActionFailure(sprintf(dp_text("Couldn't find: %s<br />"),
$noun));
return FALSE;
}
if (!isset($dest_ob)) {
$this->setActionFailure(dp_text('Hug who?<br />'));
return FALSE;
}
$this->tell(sprintf(dp_text('You hug %s.<br />'),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
$env->tell(ucfirst(sprintf(dp_text('%s hugs %s.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))),
$this, $dest_ob);
$dest_ob->tell(ucfirst(sprintf(dp_text('%s hugs you.<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))));
return TRUE;
}
/**
* Makes this living object give another living object a passionate kiss
*
* @param string $verb the action, "kiss"
* @param string $noun who to kiss, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionKiss($verb, $noun)
{
if (FALSE === ($env = $this->getEnvironment()) ||
($noun && !($dest_ob = $env->isPresent($noun)))) {
$this->setActionFailure(sprintf(dp_text("Couldn't find: %s<br />"),
$noun));
return FALSE;
}
if (!isset($dest_ob)) {
$this->setActionFailure(dp_text('Kiss who?<br />'));
return FALSE;
}
$this->tell(sprintf(
dp_text('You give %s a deep and passionate kiss... It seems to last forever...<br />'),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
$env->tell(ucfirst(sprintf(
dp_text('%s gives %s a deep and passionate kiss... It seems to last forever...<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))),
$this, $dest_ob);
$dest_ob->tell(ucfirst(sprintf(
dp_text('%s gives you a deep and passionate kiss... It seems to last forever...<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))));
return TRUE;
}
/**
* Makes this living object take another living object for a dance
*
* @param string $verb the action, "dance"
* @param string $noun who to dance with, could be empty
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionDance($verb, $noun)
{
if (FALSE === ($env = $this->getEnvironment()) ||
($noun && !($dest_ob = $env->isPresent($noun)))) {
$this->setActionFailure(sprintf(dp_text("Couldn't find: %s<br />"),
$noun));
return FALSE;
}
if (!isset($dest_ob)) {
$this->setActionFailure(dp_text('Dance with who?<br />'));
return FALSE;
}
$this->tell(sprintf(
dp_text('You take %s for a dance... The tango!<br />'),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE)));
$env->tell(ucfirst(sprintf(
dp_text('%s takes %s for a dance... The tango!<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE),
$dest_ob->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))),
$this, $dest_ob);
$dest_ob->tell(ucfirst(sprintf(
dp_text('%s takes you for a dance... The tango!<br />'),
$this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))));
return TRUE;
}
/**
* Makes this living object communicate a custom message to its environment
*
* @param string $verb the action, "emote"
* @param string $noun string to "emote"
* @return boolean TRUE for action completed, FALSE otherwise
*/
function actionEmote($verb, $noun)
{
if (FALSE === ($env = $this->getEnvironment())) {
return FALSE;
}
if (!dp_strlen($noun)) {
$this->setActionFailure(dp_text('Try: emote <i>text</i><br />'));
return FALSE;
}
$this->tell(ucfirst($this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))
. " $noun<br />");
$env->tell(ucfirst($this->getTitle(DPUNIVERSE_TITLE_TYPE_DEFINITE))
. " $noun<br />", $this);
return TRUE;
}
}
?>