package iageserver;
/**
* Game class. Used to store designer's preferences, game
* level information and custom events.
*/
public class game {
/** Maximum number of items any player can carry */
public long MaxItemsCanCarry = 0;
/** Maximum weight of combined items any player can carry */
public long MaxWeightCanCarry = 0;
/** Maximum size of combined items any player can carry */
public long MaxSizeCanCarry = 0;
/** Location all players start in (or -1 for random) */
public long StartingLocation = 1;
/** Flag to determine whether descriptions should be repeated
* to players who have already visited a location. Basically the
* default for verbosity for all players
*/
public boolean RepeatDescription = true;
/** If set, an extra line of text will be appended to location
* descriptions, listing the available exits.
*/
public boolean ShowAvailableExits = true;
/**
* If set, MUD players can save and load their states
* in a special server area. Note that objects cannot be persisted with
* players because of how they are tied together - besides it really isn't
* fair is it! Basically all the custom properties for that player are
* persisted, along with their alias, their score, turns taken and currentlocation.
* Combat properties are included in the custom properties.
* Players can password protect their save games.
*/
public boolean AllowPersist = false;
/** If this option is set, more detailed player saves are allowed*/
public boolean SinglePlayerGame = false;
/** Number of simultaneous maximum users on server for this game */
public int MaxUsers = 128;
/** Turn based NPCs instead of real time? */
public boolean RealTimeNPCs = true;
/** If Wide display is on */
public static boolean WideDisplay = true;
/** Password for IDE */
public String IDEPassword = "";
/** Set if you want to use IAGE inbuilt combat system. The properties can still be used
* if you write your own.*/
public boolean UsingIAGECombat = false;
/** Set if you want to use IAGE money. Money is an abstract entity which has no
* object references. IAGE will take care of giving money to killers etc. if you switch
* this on. */
public boolean UsingIAGEMoney = false;
/** Default number of hit points each player starts the game with */
public long DefaultHitPoints = 50;
/** Default maximum damage a player can do with a single hit */
public long DefaultDamage = 5;
/** Initial amount of money the player is carrying */
public long DefaultMoney = 0;
/** Default percentage chance of a player hitting their target in an attack */
public long DefaultChanceOfHitting = 60;
/** Amount to increment hit chance by after killing a player */
public long ChanceOfHittingIncrementForKill = 2;
/** Amount to increment barefist damage indicator by after a kill */
public long DamageIndicatorIncrementForKill = 1;
/** Players stay dead once killed and have to reconnect */
public boolean PlayersStayDead = false;
/** NPCs stay dead once killed - if this is set to false, they are
* resurrected in a random location */
public boolean NPCsStayDead = false;
/*** Media base path - is automatically put on the front of URLs */
public String MediaBase = "";
/*** List of verbs to trigger overriding checks of secondary nouns */
public String OverrideSecondaryNouns = "";
/*** Name of the loaded game */
public String Name = "";
/** Code collection, fires immediately after input */
public iagecode OnAfterInputImmediate = new iagecode();
/** Code collection, fires when any player quits */
public iagecode OnQuit = new iagecode();
/** Code collection, fires when a new player enters the game */
public iagecode OnStart = new iagecode();
/** Code collection, runs when the score banner is displayed at the top-right */
public iagecode OnDisplayBanner = new iagecode();
/** Code collection, runs when a player requests their score with SCORE (or equivalent) */
public iagecode OnScore = new iagecode();
/** Code collection, runs when server is first started */
public iagecode OnInitialise = new iagecode();
/**
* Selects a location at random and returns the ID.
*/
public static long getRandomLocation() {
int i = data.olocations.getCount(); // Total number of locations
long retl = Math.round(Math.random() * i) + 1; // Generate random range from number of locations
int retloc = (int) retl;
location l = (location) data.olocations.get(retloc); // Fetch location with this idx into temp object
return l.ID; // Finally, return the location ID
}
/**
* Main location display routine. Outputs NPCs, players, items, descriptions, handles
* darkness and lightsources etc.
*/
public static void displaylocation(player tp) {
int i = 1;
int z = 1;
int x = 1;
String IName = "";
String S = "";
String s = "";
iagecollection vExits = new iagecollection();
boolean havelight = false;
boolean dispcontainer = false;
location l = null;
player p = null;
item im = null;
character c = null;
// If we are in wide mode, pass control to that
if (game.WideDisplay) { displaylocationwide(tp); return; }
// Displays the current location to the user.
// Show the location description
while (i <= data.olocations.getCount()) {
// Find our location
l = (location) data.olocations.get(i);
if (l.ID == tp.CurrentLocation) {
havelight = true;
// First determine if the location is dark.
if (l.IsDark) {
havelight = false;
// Determine if a light source is available:
z = 1;
while (z <= data.oitems.getCount()) {
im = (item) data.oitems.get(z);
// Check if this item is in current location or carried by our player
if (im.CurrentLocation == tp.CurrentLocation || im.CurrentLocation == (location.PLAYERBASE + tp.Index)) {
havelight = havelight | im.IsLit;
}
// Check if the item is being held by another player in the same location
x = 1;
while (x <= data.oplayers.getCount()) {
p = (player) data.oplayers.get(x);
if (p.CurrentLocation == tp.CurrentLocation && im.CurrentLocation == (location.PLAYERBASE + x)) {
havelight = havelight | im.IsLit;
}
x++;
}
z++;
}
}
// If we can see, display the location
if (havelight) {
// Sort any stuff that needs doing with images now:
if (l.ImagePath.length() > 1) {
//vdu.Transmit("IMAGE: " + data.ogame.MediaBase + l.ImagePath + "|", tp);
vdu.Transmit("", tp);
}
else
{
vdu.Transmit("IMAGE: NONE|", tp);
}
// Work out location modifiers (if the player is sat, stood etc.)
String locmod = "";
if (tp.State != player.ST_NORMAL) {
if (tp.State == player.ST_LYING) {locmod = processor.smake(message.getMessage(constant.MSG_LAIDONTHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
if (tp.State == player.ST_STOODON) {locmod = processor.smake(message.getMessage(constant.MSG_STOODONTHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
if (tp.State == player.ST_SITTING) {locmod = processor.smake(message.getMessage(constant.MSG_SATONTHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
if (tp.State == player.ST_INSIDE) {locmod = processor.smake(message.getMessage(constant.MSG_INSIDETHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
}
// Set overhead bar
vdu.Transmit("TITLE: " + l.Name + " " + locmod + "|", tp);
// Send the location description proper
if (!tp.TextOnly) {
vdu.Transmit("" + l.Name + " " + locmod + "", tp);
}
else
{
vdu.Transmit("** " + l.Name + " " + locmod + " **", tp);
}
// Only transmit the location description if the player
// hasn't seen it already or verbose mode is on.
if (!tp.HasSeenLocation(l.ID) || tp.VerboseMode) {
// Run any before_display procedure if we have one for this location
// and change it if necessary.
String locname = l.Description;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(l.OnDisplay, "Location(" + l.Name + ").OnDisplay", "before_display", new String[4], 0, "Internal.DisplayLocation", 0, 0);
if (befdisp.cancelled) {
locname = befdisp.returnvalue;
}
vdu.Transmit(locname, tp);
// Flag location as seen by player
tp.MarkLocationAsSeen(l.ID);
}
}
else
{
// No image:
vdu.Transmit("IMAGE: NONE|", tp);
// Send the location name as dark
vdu.Transmit("TITLE: Dark|", tp);
// Send the location itself as the dark message
vdu.Transmit("" + message.getMessage(constant.MSG_DARK) + "", tp);
vdu.Transmit(message.getMessage(constant.MSG_DARKLOCATION), tp);
}
// Flag whether the player can see anything
tp.CanSee = havelight;
break;
}
i++;
}
// If the player can't see, don't display objects/NPCs or run
// display code and just drop out now.
if (!tp.CanSee) return;
// Run the location's OnDisplay code:
interpreter it = new interpreter(tp, null);
it.runcode(l.OnDisplay, "Location(" + l.ID + ").OnDisplay");
// If the option is set, show available exits:
if (data.ogame.ShowAvailableExits) {
S = message.getMessage(constant.MSG_EXITSLEAD) + " ";
if (l.N > 0) {vExits.add(new String(message.getMessage(constant.MSG_NORTH)));}
if (l.S > 0) {vExits.add(new String(message.getMessage(constant.MSG_SOUTH)));}
if (l.E > 0) {vExits.add(new String(message.getMessage(constant.MSG_EAST)));}
if (l.W > 0) {vExits.add(new String(message.getMessage(constant.MSG_WEST)));}
if (l.U > 0) {vExits.add(new String(message.getMessage(constant.MSG_UP)));}
if (l.D > 0) {vExits.add(new String(message.getMessage(constant.MSG_DOWN)));}
if (l.NE > 0) {vExits.add(new String(message.getMessage(constant.MSG_NORTHEAST)));}
if (l.NW > 0) {vExits.add(new String(message.getMessage(constant.MSG_NORTHWEST)));}
if (l.SE > 0) {vExits.add(new String(message.getMessage(constant.MSG_SOUTHEAST)));}
if (l.SW > 0) {vExits.add(new String(message.getMessage(constant.MSG_SOUTHWEST)));}
// Display them nicely
if (vExits.getCount() == 0) {
S = S + message.getMessage(constant.MSG_NOWHERE);
}
else
{
z = 1;
while (z <= vExits.getCount()) {
s = (String) vExits.get(z);
if (z < vExits.getCount() - 1) {S = S + s + ", ";}
if (z == vExits.getCount() - 1) {S = S + s + " " + message.getMessage(constant.MSG_AND) + " ";}
if (z == vExits.getCount()) {S = S + s + ".";}
z++;
}
}
vdu.Transmit(S, tp);
}
// Now display any items
i = 1;
while (i <= data.oitems.getCount()) {
im = (item) data.oitems.get(i);
// Is it in location and not invisible?
if (im.CurrentLocation == tp.CurrentLocation && im.Invisible == false) {
if (im.MovedFromOriginalLocation || im.Description.length() < 2) {
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
IName = im.Name;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Item(" + im.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
// Perform any modifiers
IName = IName + item.getModifiers(im);
vdu.Transmit(message.getMessage(constant.MSG_THEREIS) + " " + IName + " " + message.getMessage(constant.MSG_HERE), tp);
}
else
{
// Run any before_displayinitial procedure if we have one for this item
// and change it's name if necessary.
IName = im.Description;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Item(" + im.Name + ").OnAction", "before_displayinitial", new String[4], 0, "DisplayItemInitial", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
vdu.Transmit(IName, tp);
}
// Containing other objects, but only if the container is
// open if it can be open/closed or transparent
if (im.CanOpenClose) {
if (im.OpenCloseState || im.Transparent) {
displaycontainerinventory(im, tp, 1);
}
}
else
{
// Show the container inventory if it is a container that
// has no open/close state (like a plastic bag for example)
displaycontainerinventory(im, tp, 1);
}
// Has other objects on it's surface?
if (im.HasSurface) {
displaysurfaceinventory(im, tp, 1);
}
}
// If the object is invisible, still show it's contents
// if it is a container
if (im.CurrentLocation == tp.CurrentLocation && im.Invisible == true) {
// Containing other objects, but only if the container is
// open if it can be open/closed or transparent
if (im.CanOpenClose) {
if (im.OpenCloseState || im.Transparent) {
displaycontainerinventory(im, tp, 1);
}
}
else
{
// Show the container inventory if it is a container that
// has no open/close state (like a plastic bag for example)
displaycontainerinventory(im, tp, 1);
}
// Has other objects on it's surface?
if (im.HasSurface) {
displaysurfaceinventory(im, tp, 1);
}
}
i++;
}
// Now display characters (NPC):
i = 1;
while (i <= data.ocharacters.getCount()) {
c = (character) data.ocharacters.get(i);
if (c.CurrentLocation == tp.CurrentLocation) {
if (c.MovedFromOriginalLocation || c.Description.length() < 2) {
// Run any before_display procedure if we have one for this npc
// and change it's name if necessary.
IName = c.Name;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Character(" + c.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
vdu.Transmit(IName + " " + message.getMessage(constant.MSG_ISHERE), tp);
}
else
{
// Run any before_displayinitial procedure if we have one for this npc
// and change it's name if necessary.
IName = c.Description;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Character(" + c.Name + ").OnAction", "before_displayinitial", new String[4], 0, "DisplayItemInitial", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
vdu.Transmit(IName, tp);
}
}
i++;
}
// Now display any other players:
i = 1;
while (i <= data.oplayers.getCount()) {
p = (player) data.oplayers.get(i);
if (p.CurrentLocation == tp.CurrentLocation && (p.Index != tp.Index)) {
// Check player state
String pmod = "";
if (p.State != player.ST_NORMAL) {
if (p.State == player.ST_LYING) {pmod = processor.smake(message.getMessage(constant.MSG_LAIDONTHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
if (p.State == player.ST_STOODON) {pmod = processor.smake(message.getMessage(constant.MSG_STOODONTHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
if (p.State == player.ST_SITTING) {pmod = processor.smake(message.getMessage(constant.MSG_SATONTHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
if (p.State == player.ST_INSIDE) {pmod = processor.smake(message.getMessage(constant.MSG_INSIDETHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
pmod = pmod + " ";
}
vdu.Transmit(p.DisplayName + " " + pmod + message.getMessage(constant.MSG_ISHERE), tp);
}
i++;
}
// Check to see if any NPCs are following us around. If
// they are, bring them in.
// Also, check to see if there are any NPCs on auto-attack
// mode so we can set them off attacking the player if they are
// in the same location
i = 1;
while (i <= data.ocharacters.getCount()) {
c = (character) data.ocharacters.get(i);
if (c.AIMode == character.FOLLOWPLAYER) {
if (c.CurrentLocation != p.CurrentLocation) {
// Tell everyone in the other location where NPC is going.
vdu.TransmitAllInLocation(c.Name + " " + message.getMessage(constant.MSG_FOLLOWS) + " " + tp.Name + ".", tp, c.CurrentLocation);
// Move it.
c.CurrentLocation = tp.CurrentLocation;
// Tell everyone in new location it's here.
vdu.TransmitAllInLocation(c.Name + " " + message.getMessage(constant.MSG_ENTERS), null, tp.CurrentLocation);
}
}
if (c.AutoAttack && c.CurrentLocation == tp.CurrentLocation) {
c.AIMode = character.ATTACKING;
c.AttackingWho = tp.Index;
}
i++;
}
}
/**
* Main location display routine.
* Outputs NPCs, players, items, descriptions, handles
* darkness and lightsources etc. This does it in wide format.
*/
public static void displaylocationwide(player tp) {
int i = 1;
int z = 1;
int x = 1;
String IName = "";
String S = "";
String s = "";
iagecollection vExits = new iagecollection();
boolean havelight = false;
boolean dispcontainer = false;
location l = null;
player p = null;
item im = null;
character c = null;
// Displays the current location to the user.
// Show the location description
while (i <= data.olocations.getCount()) {
// Find our location
l = (location) data.olocations.get(i);
if (l.ID == tp.CurrentLocation) {
havelight = true;
// First determine if the location is dark.
if (l.IsDark) {
havelight = false;
// Determine if a light source is available:
z = 1;
while (z <= data.oitems.getCount()) {
im = (item) data.oitems.get(z);
// Check if this item is in current location or carried by our player
if (im.CurrentLocation == tp.CurrentLocation || im.CurrentLocation == (location.PLAYERBASE + tp.Index)) {
havelight = havelight | im.IsLit;
}
// Check if the item is being held by another player in the same location
x = 1;
while (x <= data.oplayers.getCount()) {
p = (player) data.oplayers.get(x);
if (p.CurrentLocation == tp.CurrentLocation && im.CurrentLocation == (location.PLAYERBASE + x)) {
havelight = havelight | im.IsLit;
}
x++;
}
z++;
}
}
// If we can see, display the location
if (havelight) {
// Sort any stuff that needs doing with images now:
if (l.ImagePath.length() > 1) {
//vdu.Transmit("IMAGE: " + data.ogame.MediaBase + l.ImagePath + "|", tp);
vdu.Transmit("", tp);
}
else
{
vdu.Transmit("IMAGE: NONE|", tp);
}
// Work out location modifiers (if the player is sat, stood etc.)
String locmod = "";
if (tp.State != player.ST_NORMAL) {
if (tp.State == player.ST_LYING) {locmod = processor.smake(message.getMessage(constant.MSG_LAIDONTHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
if (tp.State == player.ST_STOODON) {locmod = processor.smake(message.getMessage(constant.MSG_STOODONTHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
if (tp.State == player.ST_SITTING) {locmod = processor.smake(message.getMessage(constant.MSG_SATONTHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
if (tp.State == player.ST_INSIDE) {locmod = processor.smake(message.getMessage(constant.MSG_INSIDETHEX), tp.StateItem.Name.substring(tp.StateItem.Name.indexOf(" ") + 1, tp.StateItem.Name.length()));}
}
// Set overhead bar
vdu.Transmit("TITLE: " + l.Name + " " + locmod + "|", tp);
// Send the location description proper
if (!tp.TextOnly) {
vdu.Transmit("" + l.Name + " " + locmod + "", tp);
}
else
{
vdu.Transmit("** " + l.Name + " " + locmod + " **", tp);
}
// Only transmit the location description if the player
// hasn't seen it already or verbose mode is on.
if (!tp.HasSeenLocation(l.ID) || tp.VerboseMode) {
// Run any before_display procedure if we have one for this location
// and change it if necessary.
String locname = l.Description;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(l.OnDisplay, "Location(" + l.Name + ").OnDisplay", "before_display", new String[4], 0, "Internal.DisplayLocation", 0, 0);
if (befdisp.cancelled) {
locname = befdisp.returnvalue;
}
vdu.Transmit(locname, tp);
// Flag location as seen by player
tp.MarkLocationAsSeen(l.ID);
}
}
else
{
// No image:
vdu.Transmit("IMAGE: NONE|", tp);
// Send the location name as dark
vdu.Transmit("TITLE: Dark|", tp);
// Send the location itself as the dark message
vdu.Transmit("" + message.getMessage(constant.MSG_DARK) + "", tp);
vdu.Transmit(message.getMessage(constant.MSG_DARKLOCATION), tp);
}
// Flag whether the player can see anything
tp.CanSee = havelight;
break;
}
i++;
}
// If the player can't see, don't display objects/NPCs or run
// display code and just drop out now.
if (!tp.CanSee) return;
// Run the location's OnDisplay code:
interpreter it = new interpreter(tp, null);
it.runcode(l.OnDisplay, "Location(" + l.ID + ").OnDisplay");
// If the option is set, show available exits:
if (data.ogame.ShowAvailableExits) {
S = message.getMessage(constant.MSG_EXITSLEAD) + " ";
if (l.N > 0) {vExits.add(new String(message.getMessage(constant.MSG_NORTH)));}
if (l.S > 0) {vExits.add(new String(message.getMessage(constant.MSG_SOUTH)));}
if (l.E > 0) {vExits.add(new String(message.getMessage(constant.MSG_EAST)));}
if (l.W > 0) {vExits.add(new String(message.getMessage(constant.MSG_WEST)));}
if (l.U > 0) {vExits.add(new String(message.getMessage(constant.MSG_UP)));}
if (l.D > 0) {vExits.add(new String(message.getMessage(constant.MSG_DOWN)));}
if (l.NE > 0) {vExits.add(new String(message.getMessage(constant.MSG_NORTHEAST)));}
if (l.NW > 0) {vExits.add(new String(message.getMessage(constant.MSG_NORTHWEST)));}
if (l.SE > 0) {vExits.add(new String(message.getMessage(constant.MSG_SOUTHEAST)));}
if (l.SW > 0) {vExits.add(new String(message.getMessage(constant.MSG_SOUTHWEST)));}
// Display them nicely
if (vExits.getCount() == 0) {
S = S + message.getMessage(constant.MSG_NOWHERE);
}
else
{
z = 1;
while (z <= vExits.getCount()) {
s = (String) vExits.get(z);
if (z < vExits.getCount() - 1) {S = S + s + ", ";}
if (z == vExits.getCount() - 1) {S = S + s + " " + message.getMessage(constant.MSG_AND) + " ";}
if (z == vExits.getCount()) {S = S + s + ".";}
z++;
}
}
vdu.Transmit(S, tp);
}
// Now display any items
// Now display any items
i = 1;
iagecollection obsinloc = new iagecollection();
while (i <= data.oitems.getCount()) {
im = (item) data.oitems.get(i);
// Is it in location and not invisible?
if (im.CurrentLocation == tp.CurrentLocation && im.Invisible == false) {
if (im.MovedFromOriginalLocation || im.Description.length() < 2) {
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
IName = im.Name;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Item(" + im.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
// Perform any modifiers
IName = IName + item.getModifiers(im);
}
else
{
// Run any before_displayinitial procedure if we have one for this item
// and change it's name if necessary.
IName = im.Description;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Item(" + im.Name + ").OnAction", "before_displayinitial", new String[4], 0, "DisplayItemInitial", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
vdu.Transmit(IName, tp);
}
// Containing other objects, but only if the container is
// open if it can be open/closed or transparent
if (im.CanOpenClose) {
if (im.OpenCloseState || im.Transparent) {
// Display the contents on a new line if it is an initial
String continv = retrievecontainerinventorywide(im, 1);
if (im.MovedFromOriginalLocation || im.Description.length() < 2) {
if (!continv.equals("")) {
IName = IName + "(containing " + continv + ")";
}
}
else
{
if (!continv.equals("")) {
vdu.Transmit("The " + im.Name.substring(im.Name.indexOf(" ")+1, im.Name.length()) + " contains " + continv + ".", tp);
}
}
}
}
else
{
// Show the container inventory if it is a container that
// has no open/close state (like a plastic bag for example)
// Display the contents on a new line if it is an initial
String continv = retrievecontainerinventorywide(im, 1);
if (im.MovedFromOriginalLocation || im.Description.length() < 2) {
if (!continv.equals("")) {
IName = IName + " (containing " + continv + ")";
}
}
else
{
if (!continv.equals("")) {
vdu.Transmit ("The " + im.Name.substring(im.Name.indexOf(" ")+1, im.Name.length()) + " contains " + continv + ".", tp);
}
}
}
// Has other objects on it's surface?
if (im.HasSurface) {
String surfinv = retrievesurfaceinventorywide(im, 1);
if (im.MovedFromOriginalLocation || im.Description.length() < 2) {
if (!surfinv.equals("")) {
IName = IName + " (on which, there is " + surfinv + ")";
}
}
else
{
if (!surfinv.equals("")) {
vdu.Transmit("On the " + im.Name.substring(im.Name.indexOf(" ")+1, im.Name.length()) + ", there is " + surfinv + ".", tp);
}
}
}
// Add this object to our collection of objects to output:
if (im.MovedFromOriginalLocation || im.Description.length() < 2) {
obsinloc.add(IName);
}
}
// If our object is invisible, see if it has anything in it or on it's
// surface to show them anyway. Use the Initial type display.
if (im.CurrentLocation == tp.CurrentLocation && im.Invisible == true) {
if (im.CanOpenClose) {
if (im.OpenCloseState || im.Transparent) {
String continv = retrievecontainerinventorywide(im, 1);
if (!continv.equals("")) {
vdu.Transmit("The " + im.Name.substring(im.Name.indexOf(" ")+1, im.Name.length()) + " contains " + continv + ".", tp);
}
}
}
else
{
// Show the container inventory if it is a container that
// has no open/close state (like a plastic bag for example)
// Display the contents on a new line if it is an initial
String continv = retrievecontainerinventorywide(im, 1);
if (!continv.equals("")) {
vdu.Transmit ("The " + im.Name.substring(im.Name.indexOf(" ")+1, im.Name.length()) + " contains " + continv + ".", tp);
}
}
// Has other objects on it's surface?
if (im.HasSurface) {
String surfinv = retrievesurfaceinventorywide(im, 1);
if (!surfinv.equals("")) {
vdu.Transmit("On the " + im.Name.substring(im.Name.indexOf(" ")+1, im.Name.length()) + ", there is " + surfinv + ".", tp);
}
}
}
i++;
}
// Perform our output
i = 1;
String sout = "";
while (i <= obsinloc.getCount()) {
if (!sout.equals("") && i < obsinloc.getCount())
sout = sout + ", ";
if (!sout.equals("") && i == obsinloc.getCount())
sout = sout + " and ";
sout = sout + (String) obsinloc.get(i);
i++;
}
// Send it
if (!sout.equals(""))
vdu.Transmit("There is " + sout + " here.", tp);
// Now display characters (NPC):
i = 1;
while (i <= data.ocharacters.getCount()) {
c = (character) data.ocharacters.get(i);
if (c.CurrentLocation == tp.CurrentLocation) {
if (c.MovedFromOriginalLocation || c.Description.length() < 2) {
// Run any before_display procedure if we have one for this npc
// and change it's name if necessary.
IName = c.Name;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Character(" + c.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
vdu.Transmit(IName + " " + message.getMessage(constant.MSG_ISHERE), tp);
}
else
{
// Run any before_displayinitial procedure if we have one for this npc
// and change it's name if necessary.
IName = c.Description;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Character(" + c.Name + ").OnAction", "before_displayinitial", new String[4], 0, "DisplayItemInitial", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
vdu.Transmit(IName, tp);
}
}
i++;
}
// Now display any other players:
i = 1;
while (i <= data.oplayers.getCount()) {
p = (player) data.oplayers.get(i);
if (p.CurrentLocation == tp.CurrentLocation && (p.Index != tp.Index)) {
// Check player state
String pmod = "";
if (p.State != player.ST_NORMAL) {
if (p.State == player.ST_LYING) {pmod = processor.smake(message.getMessage(constant.MSG_LAIDONTHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
if (p.State == player.ST_STOODON) {pmod = processor.smake(message.getMessage(constant.MSG_STOODONTHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
if (p.State == player.ST_SITTING) {pmod = processor.smake(message.getMessage(constant.MSG_SATONTHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
if (p.State == player.ST_INSIDE) {pmod = processor.smake(message.getMessage(constant.MSG_INSIDETHEX), p.StateItem.Name.substring(p.StateItem.Name.indexOf(" ") + 1, p.StateItem.Name.length()));}
pmod = pmod + " ";
}
vdu.Transmit(p.DisplayName + " " + pmod + message.getMessage(constant.MSG_ISHERE), tp);
}
i++;
}
// Check to see if any NPCs are following us around. If
// they are, bring them in.
// Also, check to see if there are any NPCs on auto-attack
// mode so we can set them off attacking the player if they are
// in the same location
i = 1;
while (i <= data.ocharacters.getCount()) {
c = (character) data.ocharacters.get(i);
if (c.AIMode == character.FOLLOWPLAYER) {
if (c.CurrentLocation != p.CurrentLocation) {
// Tell everyone in the other location where NPC is going.
vdu.TransmitAllInLocation(c.Name + " " + message.getMessage(constant.MSG_FOLLOWS) + " " + tp.Name + ".", tp, c.CurrentLocation);
// Move it.
c.CurrentLocation = tp.CurrentLocation;
// Tell everyone in new location it's here.
vdu.TransmitAllInLocation(c.Name + " " + message.getMessage(constant.MSG_ENTERS), null, tp.CurrentLocation);
}
}
if (c.AutoAttack && c.CurrentLocation == tp.CurrentLocation) {
c.AIMode = character.ATTACKING;
c.AttackingWho = tp.Index;
}
i++;
}
}
/**
* Outputs the game version to the player - not to be confused with
* the IAGE server version.
*/
public static void displayversion(player tp) {
vdu.Transmit(message.getMessage(constant.MSG_VERSION), tp);
}
/**
* Checks all items for a -1 currentlocation (starting value) and scatters
* them around the map.
*/
public static void randomizeobjects() {
// Enumerates all items and if any have a current location of -1, sends
// them to a random location.
int i = 1;
item im = null;
while (i <= data.oitems.getCount()) {
im = (item) data.oitems.get(i);
if (im.CurrentLocation == -1) {
im.CurrentLocation = getRandomLocation();
}
i++;
}
}
/**
* Recursive routine which shows the contents of a container, then checks each
* item within the container to see if that is a container and to display that
* container's contents.
*/
public static void displaycontainerinventory(item thecontainer, player tp, int level) {
boolean dispcontainer = false;
item i = null;
String iname = "";
String spcs = "";
int z = 1;
int xs = 0;
while (z <= data.oitems.getCount()) {
i = (item) data.oitems.get(z);
if (i.CurrentLocation == location.CONTAINERBASE + thecontainer.ID) {
if (!dispcontainer) {
iname = thecontainer.Name.substring(thecontainer.Name.indexOf(" ") + 1, thecontainer.Name.length());
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(thecontainer.OnAction, "Item(" + thecontainer.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
// Modifiers
iname = iname + item.getModifiers(thecontainer);
xs = 0;
spcs = "";
while (xs < (level * 2)) {
spcs = spcs + " ";
xs++;
}
vdu.Transmit(spcs + processor.smake(message.getMessage(constant.MSG_THEXCONTAINS), iname), tp);
dispcontainer = true;
}
iname = i.Name;
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(i.OnAction, "Item(" + i.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
vdu.Transmit(spcs + " " + iname + item.getModifiers(i), tp);
// Recursive check to keep displaying items in containers.
if (i.CanOpenClose) {
if (i.OpenCloseState || i.Transparent) {
displaycontainerinventory(i, tp, (level + 1));
}
}
else displaycontainerinventory(i, tp, (level + 1));
}
z++;
}
}
/**
* Recursive routine which shows the contents of a surface, then checks each
* item within the container to see if that has a surface and to display that
* surface's contents.
*/
public static void displaysurfaceinventory(item thecontainer, player tp, int level) {
boolean dispcontainer = false;
item i = null;
String iname = "";
String spcs = "";
int z = 1;
int xs = 0;
while (z <= data.oitems.getCount()) {
i = (item) data.oitems.get(z);
if (i.CurrentLocation == location.SURFACEBASE + thecontainer.ID) {
if (!dispcontainer) {
iname = thecontainer.Name.substring(thecontainer.Name.indexOf(" ") + 1, thecontainer.Name.length());
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(thecontainer.OnAction, "Item(" + thecontainer.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
// Modifiers
iname = iname + item.getModifiers(thecontainer);
xs = 0;
spcs = "";
while (xs < (level * 2)) {
spcs = spcs + " ";
xs++;
}
vdu.Transmit(spcs + processor.smake(message.getMessage(constant.MSG_ONTHEXIS), iname), tp);
dispcontainer = true;
}
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
iname = i.Name;
interpreter befdisp = new interpreter(tp, new parsestring("!,!", new player(), ","));
befdisp.runcode(i.OnAction, "Item(" + i.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
vdu.Transmit(spcs + " " + iname + item.getModifiers(i), tp);
// Recursive check to keep displaying items on surfaces
displaysurfaceinventory(i, tp, (level + 1));
}
z++;
}
}
/*** Displays a player's inventory */
public static void displayplayerinventory(player thisplayer) {
boolean HasSomething = false;
boolean DispContainer = false;
int z = 1;
int i = 1;
String IName = "";
item im = null;
if (!game.WideDisplay) {
vdu.Transmit(message.getMessage(constant.MSG_INVENTORY), thisplayer);
thisplayer.OutputToPlayer = false;
vdu.Transmit(getinventory(thisplayer.Index + location.PLAYERBASE), thisplayer);
if (!thisplayer.OutputToPlayer)
vdu.Transmit(message.getMessage(constant.MSG_NOTHING), thisplayer);
}
else
{
String output = "You have ";
String getinv = getinventory(thisplayer.Index + location.PLAYERBASE);
if (getinv.equals(""))
output = output + "nothing.";
else
output = output + getinventory(thisplayer.Index + location.PLAYERBASE) + ".";
vdu.Transmit(output, thisplayer);
}
// Display money carried if it is enabled
if (data.ogame.UsingIAGEMoney) {
vdu.Transmit(processor.smake(message.getMessage(constant.MSG_YOUHAVEMONEY), Long.toString(thisplayer.Money)), thisplayer);
}
}
/*** Generic way of returning an inventory for any container */
public static String getinventory(long locationid) {
String output = "";
item im = null;
String IName = "";
// Submit to wide display if in wide mode
if (game.WideDisplay) {return getinventorywide(locationid);}
int i = 1;
while (i <= data.oitems.getCount()) {
im = (item) data.oitems.get(i);
// Is it in location and not invisible?
if (im.CurrentLocation == locationid && im.Invisible == false) {
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
IName = im.Name;
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Item(" + im.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
// Perform any modifiers
IName = IName + item.getModifiers(im);
output = output + " " + IName + "
";
// Containing other objects, but only if the container is
// open if it can be open/closed
if (im.CanOpenClose) {
if (im.OpenCloseState || im.Transparent) {
output = output + retrievecontainerinventory(im, 1);
}
}
else
{
// Show the container inventory if it is a container that
// has no open/close state (like a plastic bag for example)
output = output + retrievecontainerinventory(im, 1);
}
// Has other objects on it's surface?
if (im.HasSurface) {
output = output + retrievesurfaceinventory(im, 1);
}
}
i++;
}
return output;
}
/*** Generic way of returning an inventory for any container */
public static String getinventorywide(long locationid) {
String output = "";
item im = null;
String IName = "";
int i = 1;
iagecollection objsin = new iagecollection();
while (i <= data.oitems.getCount()) {
im = (item) data.oitems.get(i);
// Is it in location and not invisible?
if (im.CurrentLocation == locationid && im.Invisible == false) {
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
IName = im.Name;
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(im.OnAction, "Item(" + im.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
IName = befdisp.returnvalue;
}
// Perform any modifiers
IName = IName + item.getModifiers(im);
// Containing other objects, but only if the container is
// open if it can be open/closed
if (im.CanOpenClose) {
if (im.OpenCloseState || im.Transparent) {
String continv = retrievecontainerinventorywide(im, 1);
if (!continv.equals(""))
IName = IName + " (containing " + continv + ")";
}
}
else
{
// Show the container inventory if it is a container that
// has no open/close state (like a plastic bag for example)
String continv = retrievecontainerinventorywide(im, 1);
if (!continv.equals(""))
IName = IName + " (containing " + continv + ")";
}
// Has other objects on it's surface?
if (im.HasSurface) {
String continv = retrievesurfaceinventorywide(im, 1);
if (!continv.equals(""))
IName = IName + " (on which, there is " + continv + ")";
}
objsin.add(IName);
}
i++;
}
i = 1;
output = "";
while (i <= objsin.getCount()) {
if (!output.equals("") && i < objsin.getCount())
output = output + ", ";
if (!output.equals("") && i == objsin.getCount())
output = output + " and ";
output = output + (String) objsin.get(i);
i++;
}
return output;
}
/**
* Recursive routine which returns the contents of a surface, then checks each
* item within the container to see if that has a surface and return that
* surface's contents.
*/
public static String retrievesurfaceinventory(item thecontainer, int level) {
String output = "";
boolean dispcontainer = false;
item i = null;
String iname = "";
String spcs = "";
int z = 1;
int xs = 0;
while (z <= data.oitems.getCount()) {
i = (item) data.oitems.get(z);
if (i.CurrentLocation == location.SURFACEBASE + thecontainer.ID) {
if (!dispcontainer) {
iname = thecontainer.Name.substring(thecontainer.Name.indexOf(" ") + 1, thecontainer.Name.length());
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(thecontainer.OnAction, "Item(" + thecontainer.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
// Modifiers
iname = iname + item.getModifiers(thecontainer);
xs = 0;
spcs = "";
while (xs < (level * 2)) {
spcs = spcs + " ";
xs++;
}
output = output + spcs + processor.smake(message.getMessage(constant.MSG_ONTHEXIS), iname) + "
";
dispcontainer = true;
}
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
iname = i.Name;
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(i.OnAction, "Item(" + i.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
output = output + spcs + " " + iname + item.getModifiers(i) + "
";
// Recursive check to keep displaying items on surfaces
output = output + retrievesurfaceinventory(i, (level + 1));
}
z++;
}
return output;
}
/**
* Recursive routine which returns the contents of a container, then checks each
* item within the container to see if that has a contained objects and return that
* container's contents.
*/
public static String retrievecontainerinventory(item thecontainer, int level) {
String output = "";
boolean dispcontainer = false;
item i = null;
String iname = "";
String spcs = "";
int z = 1;
int xs = 0;
while (z <= data.oitems.getCount()) {
i = (item) data.oitems.get(z);
if (i.CurrentLocation == location.CONTAINERBASE + thecontainer.ID) {
if (!dispcontainer) {
iname = thecontainer.Name.substring(thecontainer.Name.indexOf(" ") + 1, thecontainer.Name.length());
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(thecontainer.OnAction, "Item(" + thecontainer.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
// Modifiers
iname = iname + item.getModifiers(thecontainer);
xs = 0;
spcs = "";
while (xs < (level * 2)) {
spcs = spcs + " ";
xs++;
}
output = output + spcs + processor.smake(message.getMessage(constant.MSG_THEXCONTAINS), iname) + "
";
dispcontainer = true;
}
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
iname = i.Name;
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(i.OnAction, "Item(" + i.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
output = output + spcs + " " + iname + item.getModifiers(i) + "
";
// Recursive check to keep displaying items in containers
if (i.CanOpenClose) {
if (i.OpenCloseState || i.Transparent) {
output = output + retrievecontainerinventory(i, (level + 1));
}
}
else
{
output = output + retrievecontainerinventory(i, (level + 1));
}
}
z++;
}
return output;
}
/**
* Recursive routine which returns the contents of a container, then checks each
* item within the container to see if that has a contained objects and return that
* container's contents.
*/
public static String retrievecontainerinventorywide(item thecontainer, int level) {
String output = "";
item i = null;
String iname = "";
int z = 1;
iagecollection objsin = new iagecollection();
while (z <= data.oitems.getCount()) {
i = (item) data.oitems.get(z);
if (i.CurrentLocation == location.CONTAINERBASE + thecontainer.ID) {
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
iname = i.Name;
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(i.OnAction, "Item(" + i.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
// Recursive check to keep displaying items in containers
if (i.CanOpenClose) {
if (i.OpenCloseState || i.Transparent) {
String continv = retrievecontainerinventorywide(i, (level + 1));
if (!continv.equals(""))
iname = iname + " (containing " + continv + ")";
}
}
else
{
String continv = retrievecontainerinventorywide(i, (level + 1));
if (!continv.equals(""))
iname = iname + " (containing " + continv + ")";
}
objsin.add(iname);
}
z++;
}
z = 1;
output = "";
while (z <= objsin.getCount()) {
if (!output.equals("") && z < objsin.getCount())
output = output + ", ";
if (!output.equals("") && z == objsin.getCount())
output = output + " and ";
output = output + objsin.get(z);
z++;
}
return output;
}
/**
* Recursive routine which returns the surface of a container, then checks each
* item within the container to see if that has a contained objects and return that
* container's contents.
*/
public static String retrievesurfaceinventorywide(item thecontainer, int level) {
String output = "";
item i = null;
String iname = "";
int z = 1;
iagecollection objsin = new iagecollection();
while (z <= data.oitems.getCount()) {
i = (item) data.oitems.get(z);
if (i.CurrentLocation == location.SURFACEBASE + thecontainer.ID) {
// Run any before_display procedure if we have one for this item
// and change it's name if necessary.
iname = i.Name;
interpreter befdisp = new interpreter(new player(), new parsestring("!,!", new player(), ","));
befdisp.runcode(i.OnAction, "Item(" + i.Name + ").OnAction", "before_display", new String[4], 0, "DisplayItem", 0, 0);
if (befdisp.cancelled) {
iname = befdisp.returnvalue;
}
// Recursive check to keep displaying items in containers
if (i.CanOpenClose) {
if (i.OpenCloseState || i.Transparent) {
String continv = retrievesurfaceinventorywide(i, (level + 1));
if (!continv.equals(""))
iname = iname + " (on which, there is " + continv + ")";
}
}
else
{
String continv = retrievesurfaceinventorywide(i, (level + 1));
if (!continv.equals(""))
iname = iname + " (on which, there is " + continv + ")";
}
objsin.add(iname);
}
z++;
}
z = 1;
output = "";
while (z <= objsin.getCount()) {
if (!output.equals("") && z < objsin.getCount())
output = output + ", ";
if (!output.equals("") && z == objsin.getCount())
output = output + " and ";
output = output + objsin.get(z);
z++;
}
return output;
}
}