lib/vhyl-rpg-expanded.t

Reference index ยท View on GitHub

   1  /* Include after core, progression and the Lite umbrella. */
   2  
   3  /** Expanded configuration error with a stable, author-readable reason. */
   4  class RpgExpandedError: RpgError
   5      reason = 'invalid-expanded-configuration'
   6  ;
   7  
   8  /** Raise an expanded configuration error before committing an operation. */
   9  rpgExpandedReject(reason)
  10  {
  11      local error = new RpgExpandedError(); error.reason = reason; throw error;
  12  }
  13  
  14  /** Per-campaign options. Merely including a module never enables these options. */
  15  class RpgExpandedRules: object
  16      exceptionalCharacteristics = nil
  17      wildcardSkills = nil
  18      cinematicInstantTasks = nil
  19  ;
  20  
  21  /** Expanded profile; keeps the inherited injury, fatigue, inventory and point ledgers.
  22   * Profiles may share immutable campaign rules; contribution instances are owned. */
  23  class RpgExpandedProfile: RpgLiteProfile
  24      rules = nil
  25      contributions = []
  26      /* Character module supplies creation-budget assessment for cash exchanges. */
  27      creationMoneyReason(points) { return 'creation-money-accounting-unavailable'; }
  28      validateFeatures() { return nil; }
  29      hpAdjustment = 0
  30      fpAdjustment = 0
  31      willAdjustment = 0
  32      perceptionAdjustment = 0
  33      speedQuarterAdjustment = 0
  34      moveAdjustment = 0
  35      maxHP = (st + hpAdjustment)
  36      maxEnergy = (ht + fpAdjustment)
  37      will = (iq + willAdjustment)
  38      perception = (iq + perceptionAdjustment)
  39      basicSpeedQuarters() { return self.dx + self.ht + self.speedQuarterAdjustment; }
  40      basicMove() { return self.basicSpeedQuarters() / 4 + self.moveAdjustment; }
  41  ;
  42  
  43  /** Owned point contribution from an optional subsystem; cost queries are pure. */
  44  class RpgExpandedContribution: object
  45      id = nil
  46      owner = nil
  47      amounts(profile) { return []; }
  48      wealthStatusBonus() { return 0; }
  49      validate(profile) { return nil; }
  50  ;
  51  
  52  /** Operation receipt. Blocked operations have a reason and spend nothing. */
  53  class RpgExpandedResult: object
  54      status = 'blocked'
  55      reason = nil
  56      points = 0
  57      seconds = 0
  58      check = nil
  59      modifier = 0
  60  ;
  61  
  62  /** Validate the foundation contract without requiring any optional module. */
  63  rpgExpandedValidate(profile)
  64  {
  65      if (profile == nil || !profile.ofKind(RpgExpandedProfile)
  66          || profile.rules == nil || !profile.rules.ofKind(RpgExpandedRules))
  67          rpgExpandedReject('profile-or-rules');
  68      profile.validateFeatures();
  69      local ids = [];
  70      foreach (local contribution in profile.contributions)
  71      {
  72          if (!contribution.ofKind(RpgExpandedContribution) || contribution.owner != profile
  73              || contribution.id == nil || holds(ids, contribution.id))
  74              rpgExpandedReject('contribution-ownership');
  75          ids = ids + [contribution.id]; contribution.validate(profile);
  76      }
  77      return true;
  78  }