// AdvInit.cpp : Initialization and cleanup functions
//

#include "stdafx.h"
#include "malloc.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "time.h"

#include "AdvDef.h"
#include "AdvDatabase.h"
#include "AdvInit.h"
#include "AdvIO.h"
#include "AdvUtil.h"
#include "Encode.h"

/////////////////////
// Forward references
void initLocationProps
  (AdvGlobalContext&  gc);

void initObjectProps
  (AdvGlobalContext&  gc);

///////////////////
// Public functions

void cleanupAndExit
  (AdvGlobalContext& gc)   // global context
//
//  Frees memory used by databases and exits game.
//
{
  unloadDescriptionArray (& (gc.m_messages[0]), gc.m_nMessages);
  unloadDescriptionArray (& (gc.m_shortp[0]), gc.m_nPlaces);
  unloadDescriptionArray (& (gc.m_longp[0]), gc.m_nPlaces);
  unloadDescriptionArray (& (gc.m_vocab[0]), gc.m_nVocab);
  unloadObjectDescriptions (& (gc.m_objects[0]), gc.m_nObjects);

  exit (0);
}

bool init
  (AdvGlobalContext&  gc,             // global context
   char*              szExeFilespec)  // program filespec
//
//  Initializes the game:
//    - initializes game context
//    - initializes location properties
//    - initializes object properties
//    - loads databases
//
//  Returns true on success, false otherwise.
//
{
  // Zero out everything
  memset (&gc, sizeof (AdvGlobalContext), 0);

  // Get version information
  strcpy (gc.m_szSignature, SIGNATURE);
  gc.m_nVerMajor = MAJOR;
  gc.m_nVerMinor = MINOR;

  // Save program directory
  strcpy (gc.m_szExeDir, szExeFilespec);
  char* pSlash = strrchr (gc.m_szExeDir, '\\');
  if (pSlash != NULL)
     *pSlash = '\0';
  strcat (gc.m_szExeDir, "\\");

  // Initialize command state
  gc.m_nCmdWords = 0;
  gc.m_nContext = null;
  gc.m_nArg1 = null;
  gc.m_nArg2 = null;
  strcpy (gc.m_szArg1, "");
  strcpy (gc.m_szArg2, "");

  // Kick the random number generator
  srand ((unsigned) time (NULL));

  // Initialize game context
  gc.m_bMoved = true;
  gc.m_bOk2Describe = true;
  gc.m_bJustDied = false;
  gc.m_bExtendedVersion = false;

  gc.m_nHere = road;
  gc.m_nPrevLoc = road;
  gc.m_nDwarfCount = random (3) + 3;
  gc.m_nClockTick = random(10) + 15;
  gc.m_nInventory = 0;
  gc.m_nStrength = 7;
  gc.m_nLampLife = 300;

  // Initialize location and object properties
  initLocationProps (gc);
  initObjectProps (gc);

  // Load databases
  if (!loadDescriptionArray (gc, &(gc.m_messages[0]), MAXMESSAGES, MSGFILE, gc.m_nMessages))
     return (false);
  if (!loadDescriptionArray (gc, &(gc.m_shortp[0]), MAXPLACES, SHORTFILE, gc.m_nPlaces))
     return (false);
  if (!loadDescriptionArray (gc, &(gc.m_longp[0]), MAXPLACES, LONGFILE, gc.m_nPlaces))
     return (false);
  if (!loadDescriptionArray (gc, &(gc.m_vocab[0]), MAXVOCAB, VOCABFILE, gc.m_nVocab))
     return (false);
  if (!loadObjectDescriptions (gc, &(gc.m_objects[0]), MAXOBJECTS, OBJFILE, gc.m_nObjects))
     return (false);

  // Remember time he started playing
  time (&gc.m_nTimeStart);

  return (true);
}

////////////////////
// Private functions

void initLocationProps
  (AdvGlobalContext& gc)   // global context
//
//  Initializes location properties
//
{
long  nIndex;   // generic index

  // Underground locations that are out of limits for dwarves
  gc.m_noDwarf [incave] = true;
  gc.m_noDwarf [cobbles] = true;
  gc.m_noDwarf [alcove] = true;
  gc.m_noDwarf [plover] = true;
  gc.m_noDwarf [dark] = true;
  gc.m_noDwarf [swofchasm] = true;
  gc.m_noDwarf [neofchasm] = true;
  gc.m_noDwarf [corridor] = true;
  gc.m_noDwarf [fork] = true;
  gc.m_noDwarf [warmjunction] = true;
  gc.m_noDwarf [breathtaker] = true;
  gc.m_noDwarf [boulders] = true;
  gc.m_noDwarf [limestone] = true;
  gc.m_noDwarf [barren] = true;
  gc.m_noDwarf [bearhere] = true;
  gc.m_noDwarf [mazea_26] = true;   // treasure chest here
  gc.m_noDwarf [eastpit] = true;
  gc.m_noDwarf [westpit] = true;
  gc.m_noDwarf [streampit] = true;
  gc.m_noDwarf [faces] = true;
  gc.m_noDwarf [by_figure] = true;
  gc.m_noDwarf [plain_1] = true;
  gc.m_noDwarf [plain_2] = true;
  gc.m_noDwarf [plain_3] = true;
  gc.m_noDwarf [nondescript] = true;
  gc.m_noDwarf [pentagram] = true;
  gc.m_noDwarf [chimney] = true;
  gc.m_noDwarf [tube] = true;
  gc.m_noDwarf [tube_slide] = true;
  gc.m_noDwarf [basque_1] = true;
  gc.m_noDwarf [basque_2] = true;
  gc.m_noDwarf [basque_fork] = true;
  gc.m_noDwarf [peelgrunt] = true;
  gc.m_noDwarf [on_steps] = true;
  gc.m_noDwarf [steps_exit] = true;
  gc.m_noDwarf [storage] = true;
  gc.m_noDwarf [fake_y2] = true;
  gc.m_noDwarf [fake_jumble] = true;
  for (nIndex = catacombs_1; (nIndex <= catacombs_9); nIndex++)
      gc.m_noDwarf [nIndex] = true;
  gc.m_noDwarf [audience] = true;
  gc.m_noDwarf [audience_e] = true;
  gc.m_noDwarf [banshee_1] = true;
  gc.m_noDwarf [golden] = true;
  gc.m_noDwarf [arabesque] = true;
  gc.m_noDwarf [translucent] = true;
  gc.m_noDwarf [reservoir_n] = true;
  gc.m_noDwarf [warm] = true;
  gc.m_noDwarf [balcony] = true;
  gc.m_noDwarf [insafe] = true;
  gc.m_noDwarf [belowtrap] = true;
  gc.m_noDwarf [emergency] = true;
  gc.m_noDwarf [southend] = true;

  // All the rooms in the mazes are "no back" types to give the adventurer heartburn
  // and a possible ulcer, with the exception of mazea_1 and mazed_107, which are
  // the entrances to the mazes.  This way, if he accidentally wanders into a maze
  // he can escape quickly by saying "GO BACK".

  for (nIndex=mazea_2; (nIndex <= mazea_26); nIndex++)
      gc.m_noBack [nIndex] = true;
  for (nIndex=mazed_131; (nIndex <= mazed_140); nIndex++)
      gc.m_noBack [nIndex] = true;
  gc.m_noBack [incline] = true;
  gc.m_noBack [stalact] = true;
  gc.m_noBack [swofchasm] = true;
  gc.m_noBack [neofchasm] = true;
  gc.m_noBack [wittsend] = true;
  gc.m_noBack [alcove] = true;
  gc.m_noBack [plover] = true;
  gc.m_noBack [dark] = true;
  gc.m_noBack [nscanyonwide] = true;
  for (nIndex=icecave_1; (nIndex <= icecave_21); nIndex++)
      gc.m_noBack [nIndex] = true;
  gc.m_noBack [slide] = true;
  gc.m_noBack [ice] = true;
  for (nIndex=catacombs_1; (nIndex <= catacombs_19); nIndex++)
      gc.m_noBack [nIndex] = true;
  gc.m_noBack [faces] = true;
  gc.m_noBack [plain_1] = true;
  gc.m_noBack [plain_2] = true;
  gc.m_noBack [basque_1] = true;
  gc.m_noBack [cylinderical] = true;
  gc.m_noBack [platform] = true;
  gc.m_noBack [mirrorroom] = true;

  // So that he can't sneak out with the clam
  gc.m_noBack [shell] = true;

  // So that he can't retreat over quicksand
  gc.m_noBack [arch_cor_1] = true;
  gc.m_noBack [arch_cor_2] = true;

  // These places are outside the cave
  gc.m_notInCave [road] = true;
  gc.m_notInCave [hill] = true;
  gc.m_notInCave [building] = true;
  gc.m_notInCave [valley] = true;
  gc.m_notInCave [forest] = true;
  gc.m_notInCave [forest2] = true;
  gc.m_notInCave [slit] = true;
  gc.m_notInCave [depression] = true;
  gc.m_notInCave [fake_slit] = true;
  gc.m_notInCave [nearstove] = true;
  gc.m_notInCave [hill_extended] = true;
  gc.m_notInCave [hayfield] = true;

  // Self-illuminated rooms
  for (nIndex=road; (nIndex < limbo); nIndex++)
      if (gc.m_notInCave [nIndex])
         gc.m_lit [nIndex] = true;
  gc.m_lit [incave] = true;
  gc.m_lit [cobbles] = true;
  gc.m_lit [plover] = true;
  gc.m_lit [breathtaker] = true;
  gc.m_lit [shelf] = true;
  gc.m_lit [beach] = true;
  gc.m_lit [plain_2] = true;
  gc.m_lit [plain_3] = true;
  gc.m_lit [faces] = true;
  gc.m_lit [by_figure] = true;
  gc.m_lit [audience] = true;
  gc.m_lit [audience_e] = true;
  gc.m_lit [translucent] = true;
  gc.m_lit [platform] = true;
  gc.m_lit [cylinderical] = true;
  gc.m_lit [treasureroom] = true;
  gc.m_lit [balcony] = true;
  gc.m_lit [belowtrap] = true;
  gc.m_lit [emergency] = true;

  // Hints are available here
  for (nIndex=mazea_1; (nIndex <= mazea_26); nIndex++)
      gc.m_hintable [nIndex] = true;
  for (nIndex=mazed_107; (nIndex <= mazed_140); nIndex++)
      gc.m_hintable [nIndex] = true;
  for (nIndex=icecave_1; (nIndex <= icecave_30); nIndex++)
      gc.m_hintable [nIndex] = true;
  gc.m_hintable [birdchamber] = true;
  gc.m_hintable [depression] = true;
  gc.m_hintable [mtking] = true;
  gc.m_hintable [wittsend] = true;
  gc.m_hintable [plover] = true;
  gc.m_hintable [alcove] = true;
  gc.m_hintable [dark] = true;
  gc.m_hintable [slide] = true;
  gc.m_hintable [plain_2] = true;
  gc.m_hintable [mirrorroom] = true;
  gc.m_hintable [nearstove] = true;

  // There are watering holes
  gc.m_waterHere [building] = true;
  gc.m_waterHere [road] = true;
  gc.m_waterHere [valley] = true;
  gc.m_waterHere [slit] = true;
  gc.m_waterHere [streampit] = true;
  gc.m_waterHere [cavern] = true;
  gc.m_waterHere [reservoir] = true;
  gc.m_waterHere [reservoir_n] = true;

  // Locations inside mazes
  for (nIndex=mazea_1; (nIndex <= mazea_26); nIndex++)
      gc.m_inMaze [nIndex] = true;
  for (nIndex=mazed_107; (nIndex <= mazed_140); nIndex++)
      gc.m_inMaze [nIndex] = true;
  for (nIndex=icecave_1; (nIndex <= icecave_30); nIndex++)
      gc.m_inMaze [nIndex] = true;
  gc.m_inMaze [slide] = true;

  // Rooms with single exits
  gc.m_oneExit [goldroom] = true;
  gc.m_oneExit [southside] = true;
  gc.m_oneExit [sandstone] = true;
  gc.m_oneExit [window] = true;
  gc.m_oneExit [window2] = true;
  gc.m_oneExit [mazea_5] = true;
  gc.m_oneExit [mazea_6] = true;
  gc.m_oneExit [mazea_7] = true;
  gc.m_oneExit [mazea_13] = true;
  gc.m_oneExit [mazea_15] = true;
  gc.m_oneExit [mazea_17] = true;
  gc.m_oneExit [mazea_19] = true;
  gc.m_oneExit [mazea_20] = true;
  gc.m_oneExit [mazea_24] = true;
  gc.m_oneExit [mazea_25] = true;
  gc.m_oneExit [mazea_26] = true;
  gc.m_oneExit [deadend1] = true;
  gc.m_oneExit [deadend2] = true;
  gc.m_oneExit [deadend3] = true;
  gc.m_oneExit [soft] = true;
  gc.m_oneExit [culdesac] = true;
  gc.m_oneExit [reservoir] = true;
  gc.m_oneExit [balcony] = true;
  gc.m_oneExit [mazed_140] = true;
  gc.m_oneExit [insafe] = true;
  gc.m_oneExit [tool] = true;
  gc.m_oneExit [cubicle] = true;
  gc.m_oneExit [spherical] = true;
  gc.m_oneExit [icecave_1] = true;
  gc.m_oneExit [icecave_3] = true;
  gc.m_oneExit [icecave_7] = true;
  gc.m_oneExit [icecave_8] = true;
  gc.m_oneExit [icecave_13] = true;
  gc.m_oneExit [icecave_14] = true;
  gc.m_oneExit [crack_4] = true;
  gc.m_oneExit [beach] = true;
  gc.m_oneExit [southend] = true;

  // Throwing objects here sends them elsewhere
  gc.m_thrower [pit] = true;
  gc.m_thrower [eastoffissur] = true;
  gc.m_thrower [westoffissur] = true;
  gc.m_thrower [wend2pit] = true;
  gc.m_thrower [eend2pit] = true;
  gc.m_thrower [lownspassage] = true;
  gc.m_thrower [window] = true;
  gc.m_thrower [window2] = true;
  gc.m_thrower [brink] = true;
  gc.m_thrower [dusty] = true;
  gc.m_thrower [mazea_16_pit] = true;
  gc.m_thrower [secretnscyn] = true;
  gc.m_thrower [secretnspas] = true;
  gc.m_thrower [secretew_tite] = true;
  gc.m_thrower [incline] = true;
  gc.m_thrower [cavern] = true;
  gc.m_thrower [misty] = true;
  gc.m_thrower [reservoir] = true;
  gc.m_thrower [reservoir_n] = true;
  gc.m_thrower [stalact] = true;
  gc.m_thrower [balcony] = true;
  gc.m_thrower [swofchasm] = true;
  gc.m_thrower [neofchasm] = true;
  gc.m_thrower [breathtaker] = true;
  gc.m_thrower [faces] = true;
  gc.m_thrower [tube] = true;
  gc.m_thrower [tube_slide] = true;
  gc.m_thrower [basque_fork] = true;
  gc.m_thrower [on_steps] = true;
  gc.m_thrower [steps_exit] = true;
  gc.m_thrower [brink_1] = true;
  gc.m_thrower [brink_2] = true;
  gc.m_thrower [brink_3] = true;
  gc.m_thrower [ice] = true;
  gc.m_thrower [shelf] = true;
  gc.m_thrower [platform] = true;
  gc.m_thrower [nslope] = true;
}

void initObjectProps
  (AdvGlobalContext& gc)   // global context
//
//  Initializes location properties
//
{
long  nIndex;   // generic index

  // General initialization
  for (nIndex=0; (nIndex <= MAXOBJECTS); nIndex++)
    {
      gc.m_portable [nIndex] = true;
      gc.m_seen [nIndex] = false;
      gc.m_valued [nIndex] = false;
      gc.m_mortal [nIndex] = false;
      gc.m_openable [nIndex] = false;
      gc.m_invisible [nIndex] = false;
      gc.m_weightless [nIndex] = false;
      gc.m_special1 [nIndex] = false;
      gc.m_special2 [nIndex] = false;
      gc.m_firstDesc [nIndex] = false;
      gc.m_nState [nIndex] = 0;
      gc.m_nWhereIs [nIndex] = limbo;
    }

  // All objects execept these are portable
  gc.m_portable [basilisk] = false;
  gc.m_portable [blob] = false;
  gc.m_portable [chasm] = false;
  gc.m_portable [dinghy] = false;
  gc.m_portable [djinn] = false;
  gc.m_portable [door] = false;
  gc.m_portable [dragon] = false;
  gc.m_portable [drawing] = false;
  gc.m_portable [dwarf] = false;
  gc.m_portable [fissure] = false;
  gc.m_portable [fog] = false;
  gc.m_portable [glow] = false;
  gc.m_portable [goblins] = false;
  gc.m_portable [gong] = false;
  gc.m_portable [wheatstone] = false;
  gc.m_portable [grate] = false;
  gc.m_portable [machine] = false;
  gc.m_portable [message] = false;
  gc.m_portable [mirror] = false;
  gc.m_portable [ogre] = false;
  gc.m_portable [pirate] = false;
  gc.m_portable [plant] = false;
  gc.m_portable [plant2] = false;
  gc.m_portable [quicksand] = false;
  gc.m_portable [safe] = false;
  gc.m_portable [shadow] = false;
  gc.m_portable [skeleton] = false;
  gc.m_portable [slime] = false;
  gc.m_portable [snake] = false;
  gc.m_portable [stalactite] = false;
  gc.m_portable [statue] = false;
  gc.m_portable [steps] = false;
  gc.m_portable [tablet] = false;
  gc.m_portable [throne] = false;
  gc.m_portable [tree] = false;
  gc.m_portable [troll] = false;
  gc.m_portable [troll2] = false;
  gc.m_portable [volcano] = false;
  gc.m_portable [_pentagram] = false;
  gc.m_portable [stove] = false;
  gc.m_portable [trapdoor] = false;
  gc.m_portable [mirror2] = false;
  gc.m_portable [sign] = false;
  gc.m_portable [turtle] = false;

  // Mark the treasures
  for (nIndex=MINTREASURES; (nIndex <= MAXTREASURES); nIndex++)
      gc.m_valued [nIndex] = true;

  // These are killable things
  for (nIndex=MINMORTALS; (nIndex <= MAXMORTALS); nIndex++)
      gc.m_mortal [nIndex] = true;
  gc.m_mortal [turtle] = true;

  // These objects can be opened/closed/unlocked/locked
  gc.m_openable [grate] = true;
  gc.m_openable [door] = true;
  gc.m_openable [clam] = true;
  gc.m_openable [oyster] = true;
  gc.m_openable [flask] = true;
  gc.m_openable [chain] = true;
  gc.m_openable [safe] = true;
  gc.m_openable [vial] = true;
  gc.m_openable [_pentagram] = true;
  gc.m_openable [stove] = true;
  gc.m_openable [trapdoor] = true;

  // These are invisible objects
  gc.m_invisible [fissure] = true;
  gc.m_invisible [pirate] = true;
  gc.m_invisible [knife] = true;
  gc.m_invisible [fog] = true;
  gc.m_invisible [plant2] = true;
  gc.m_invisible [wheatstone] = true;
  gc.m_invisible [goblins] = true;
  gc.m_invisible [scroll] = true;
  gc.m_invisible [trapdoor] = true;
  gc.m_invisible [needle] = true;

  // These objects are never described
  gc.m_noDesc [tree] = true;
  gc.m_noDesc [mirror] = true;
  gc.m_noDesc [quicksand] = true;
  gc.m_noDesc [throne] = true;
  gc.m_noDesc [dwarf] = true;
  gc.m_noDesc [_pentagram] = true;
  gc.m_noDesc [fog] = true;
  gc.m_noDesc [glow] = true;
  gc.m_noDesc [statue] = true;
  gc.m_noDesc [blob] = true;
  gc.m_noDesc [volcano] = true;
  gc.m_noDesc [turtle] = true;
  gc.m_noDesc [carpet] = true;
  gc.m_noDesc [treasure] = true;
  gc.m_noDesc [wheatstone] = true;    // initially - changed later in code
  gc.m_noDesc [mirror2] = true;
  gc.m_noDesc [drawing] = true;
  gc.m_noDesc [stalactite] = true;

  // These objects can be carried without affecting the adventurer's capacity
  gc.m_weightless [bird] = true;
  gc.m_weightless [oil] = true;
  gc.m_weightless [water] = true;
  gc.m_weightless [bear] = true;
  gc.m_weightless [knife] = true;

  // These objects should be described first
  gc.m_firstDesc [slime] = true;
  gc.m_firstDesc [flask] = true;
  gc.m_firstDesc [grate] = true;
  gc.m_firstDesc [glow] = true;
  gc.m_firstDesc [snake] = true;
  gc.m_firstDesc [dragon] = true;
  gc.m_firstDesc [basilisk] = true;
  gc.m_firstDesc [steps] = true;
  gc.m_firstDesc [fissure] = true;
  gc.m_firstDesc [bear] = true;
  gc.m_firstDesc [shadow] = true;
  gc.m_firstDesc [door] = true;
  gc.m_firstDesc [tablet] = true;
  gc.m_firstDesc [plant] = true;
  gc.m_firstDesc [plant2] = true;
  gc.m_firstDesc [chasm] = true;
  // gc.m_firstdesc [troll] = true;     // chasm should be described before troll
  gc.m_firstDesc [volcano] = true;
  gc.m_firstDesc [machine] = true;
  // gc.firstdesc [carpet] = true;      // since it's nodesc[]
  gc.m_firstDesc [safe] = true;
  gc.m_firstDesc [quicksand] = true;
  gc.m_firstDesc [gong] = true;
  gc.m_firstDesc [mirror] = true;
  gc.m_firstDesc [statue] = true;
  gc.m_firstDesc [skeleton] = true;
  gc.m_firstDesc [dinghy] = true;
  gc.m_firstDesc [stove] = true;
  gc.m_firstDesc [scroll] = true;
  gc.m_firstDesc [trapdoor] = true;
  gc.m_firstDesc [mirror2] = true;
  gc.m_firstDesc [sign] = true;

  // These objects' initial states are not zero
  gc.m_nState [chain] = 1;
  gc.m_nState [fog] = 8;
  gc.m_nState [flask] = 1;
  gc.m_nState [sculpture] = 2 * random (3);

  // Move objects to their starting places
  apport (keys, building);
  apport (lamp, building);
  apport (grate, depression);
  apport (cage, cobbles);
  apport (rod, debris);
  apport (steps, pit);
  apport (bird, birdchamber);
  apport (door, immensenspass);
  apport (pillow, soft);
  apport (snake, mtking);
  apport (fissure, eastoffissur);
  apport (tablet, dark);
  apport (clam, shell);
  apport (magazines, anteroom);
  apport (food, building);
  apport (bottle, building);
  apport (plant, westpit);
  apport (plant2, wend2pit);
  apport (stalactite, stalact);
  apport (shadow, window);
  apport (drawing, oriental);
  apport (dragon, secretnscyn);
  apport (rug, secretnscyn);
  apport (chasm, swofchasm);
  apport (troll, swofchasm);
  apport (bear, bearhere);
  apport (volcano, breathtaker);
  apport (machine, mazed_140);
  apport (carpet, soft);
  apport (gold, goldroom);
  apport (diamonds, westoffissur);
  apport (silver, lownspassage);
  apport (jewelry, southside);
  apport (coins, westside);
  apport (eggs, giant);
  apport (trident, cavern);
  apport (vase, oriental);
  apport (emerald, plover);
  apport (pyramid, dark);
  apport (spices, boulders);
  apport (chain, bearhere);
  apport (spyglass, in_jonah);
  apport (bag, beach);
  apport (dinghy, beach);
  apport (helmet, morion);
  apport (vial, spherical);
  apport (mushroom, cubicle);
  apport (sculpture, icecave_20);
  apport (casket, crack_4);
  apport (safe, vault);
  apport (quicksand, arch_cor_1);
  apport (slime, crack_2);
  apport (sword, sandstone);
  apport (ogre, glassy);
  apport (throne, audience_e);
  apport (skeleton, audience_e);
  apport (sceptre, audience_e);
  apport (crown, insafe);
  apport (statue, by_figure);
  apport (fog, plain_2);
  apport (yacht, nondescript);
  apport (bracelet, translucent);
  apport (flask, arabesque);
  apport (basilisk, basque_1);
  apport (plate, storage);
  apport (beads, balcony);
  apport (gong, reservoir_n);
  apport (mirror, mirrorcnyn);
  apport (_pentagram, pentagram);
  apport (wheatstone, breathtaker);
  apport (stove, nearstove);
  apport (scroll, nearstove);
  apport (trapdoor, nearstove);
  apport (mirror2, mirrorroom);
  apport (shovel, deadend1);
  apport (sign, belowtrap);
  apport (needle, hayfield);

  // Set up cameo appearance
  gc.m_nCameoTime = (chance(40) ? random(400) + 100 : 0);
}
