| | 1 | #charset "us-ascii" |
| | 2 | |
| | 3 | /* |
| | 4 | * Copyright (c) 2000, 2006 Michael J. Roberts. All Rights Reserved. |
| | 5 | * |
| | 6 | * TADS 3 Library - module ID's |
| | 7 | * |
| | 8 | * This module defines a framework for "module ID's." The module ID |
| | 9 | * mechanism allows library modules to identify themselves. The module |
| | 10 | * ID framework is modular, in that several libraries can be linked |
| | 11 | * together without any prior knowledge of one another, and the module ID |
| | 12 | * framework will be able to find all of their ID's. |
| | 13 | */ |
| | 14 | |
| | 15 | /* include the library header */ |
| | 16 | #include "adv3.h" |
| | 17 | |
| | 18 | /* we also require file access */ |
| | 19 | #include <file.h> |
| | 20 | |
| | 21 | |
| | 22 | /* ------------------------------------------------------------------------ */ |
| | 23 | /* |
| | 24 | * Module ID. Each library add-in can define one of these, so that the |
| | 25 | * "credits" command and the like can automatically show the version of |
| | 26 | * each library module included in the finished game, without the game's |
| | 27 | * author having to compile a list of the module versions manually. |
| | 28 | * |
| | 29 | * An easy way to implement a CREDITS command is to define a ModuleID |
| | 30 | * object for the game itself, and override the showCredit() method to |
| | 31 | * display the text of the game's credits. The module object for the |
| | 32 | * game itself should usually have a listingOrder of 1, because the |
| | 33 | * author usually will want the game's information to be displayed first |
| | 34 | * in any listing that shows each included library module (such as the |
| | 35 | * VERSION command's output). |
| | 36 | */ |
| | 37 | class ModuleID: object |
| | 38 | /* my name */ |
| | 39 | name = '' |
| | 40 | |
| | 41 | /* the "byline" for the module, in plain text and HTML versions */ |
| | 42 | byline = '' |
| | 43 | htmlByline = '' |
| | 44 | |
| | 45 | /* my version number string */ |
| | 46 | version = '' |
| | 47 | |
| | 48 | /* |
| | 49 | * Show my library credit. By default won't show anything. |
| | 50 | * Libraries should generally not override this, because we want to |
| | 51 | * leave it up to the author to determine how the credits are |
| | 52 | * displayed. If a library overrides this, then the author won't be |
| | 53 | * able to control the formatting of the library credit, which is |
| | 54 | * undesirable. |
| | 55 | */ |
| | 56 | showCredit() { } |
| | 57 | |
| | 58 | /* |
| | 59 | * Show version information. By default, we show our name and |
| | 60 | * version number, then start a new line. The main game's module ID |
| | 61 | * should generally override this to show an appropriate version |
| | 62 | * message for the game, and any library add-ins that want to |
| | 63 | * display their version information can override this to do so. |
| | 64 | */ |
| | 65 | showVersion() |
| | 66 | { |
| | 67 | gLibMessages.showVersion(name, version); |
| | 68 | "\n"; |
| | 69 | } |
| | 70 | |
| | 71 | /* |
| | 72 | * Show the "about this game" information. By default, we show |
| | 73 | * nothing here. Typically, only the game's module ID object will |
| | 74 | * override this; in the game's module ID object, this method should |
| | 75 | * display any desired background information about the game that |
| | 76 | * the author wants the player to see on typing the ABOUT command. |
| | 77 | * |
| | 78 | * The ABOUT command conventionally displays information about the |
| | 79 | * game and its author - the kind of thing you'd find in an author's |
| | 80 | * notes section in a book - along with any special instructions to |
| | 81 | * the player, such as notes on unusual command syntax. Information |
| | 82 | * that players will find especially helpful include: |
| | 83 | * |
| | 84 | * - A list of any unusual command phrasings that the game uses. |
| | 85 | * Ideally, you will disclose here every verb that's required to |
| | 86 | * complete the game, beyond the basic set common to most games |
| | 87 | * (LOOK, INVENTORY, NORTH, SOUTH, TAKE, DROP, PUT IN, etc). By |
| | 88 | * disclosing every necessary verb and phrasing, you can be certain |
| | 89 | * to avoid "guess the verb" puzzles. (Note that it's possible to |
| | 90 | * disclose every *required* verb without disclosing every |
| | 91 | * *accepted* verb - some verbs might be so suggestive of a |
| | 92 | * particular puzzle solution that you wouldn't want to disclose |
| | 93 | * them, but as long as you disclose less suggestive alternatives |
| | 94 | * that can be used to solve the same puzzles, you have a valid |
| | 95 | * defense against accusations of using "guess the verb" puzzles.) |
| | 96 | * |
| | 97 | * - A quick overview of the NPC conversation system, if any. |
| | 98 | * Conversation systems have been slowly evolving as authors |
| | 99 | * experiment with different styles, and at least three or four |
| | 100 | * different conventions have emerged. The default that experienced |
| | 101 | * players will expect is the traditional ASK/TELL system, so it's |
| | 102 | * especially important to mention your system if you're using |
| | 103 | * something else. |
| | 104 | * |
| | 105 | * - An indication of the "cruelty" level of the game. In |
| | 106 | * particular, many experienced players find it helpful to know from |
| | 107 | * the outset how careful they have to be about saving positions |
| | 108 | * throughout play, so it's helpful to point out whether or not it's |
| | 109 | * possible for the player character to be killed; whether it's |
| | 110 | * possible to get into situations where the game becomes |
| | 111 | * "unwinnable"; and if the game can become unwinnable, whether or |
| | 112 | * not this will become immediately clear. The kindest games never |
| | 113 | * kill the PC and are always winnable, no matter what actions the |
| | 114 | * player takes; it's never necessary to save these games except to |
| | 115 | * suspend a session for later resumption. The cruelest games kill |
| | 116 | * the PC without warning (although if they offer an UNDO command |
| | 117 | * from a "death" prompt, then even this doesn't constitute true |
| | 118 | * cruelty), and can become unwinnable in ways that aren't readily |
| | 119 | * and immediately apparent to the player, which means that the |
| | 120 | * player could proceed for quite some time (and thus invest |
| | 121 | * substantial effort) after the game is already lost. |
| | 122 | * |
| | 123 | * - A description of any special status line displays or other |
| | 124 | * on-screen information whose meaning might not be immediately |
| | 125 | * apparent. |
| | 126 | */ |
| | 127 | showAbout() { } |
| | 128 | |
| | 129 | /* |
| | 130 | * My listing order. When we compile a list of modules, we'll sort |
| | 131 | * the modules first by ascending listing order; any modules with |
| | 132 | * the same listing order will be sorted alphabetically by name with |
| | 133 | * respect to the other modules with the same listing order. |
| | 134 | * |
| | 135 | * The value 1 is reserved for the game's own ID object. Note that |
| | 136 | * the TADS 3 library defines a module ID with listing order 50, |
| | 137 | * which is chosen so that the main library credit will appear after |
| | 138 | * the game credits but before any extension credits using the |
| | 139 | * default order value 100 that we define here. Extensions are |
| | 140 | * free, however, to use a number lower than 5 if they wish to |
| | 141 | * appear before the main library credit. |
| | 142 | */ |
| | 143 | listingOrder = 100 |
| | 144 | |
| | 145 | /* |
| | 146 | * get a list of all of the modules that are part of the game, |
| | 147 | * sorted in listing order |
| | 148 | */ |
| | 149 | getModuleList() |
| | 150 | { |
| | 151 | local lst; |
| | 152 | |
| | 153 | /* compile a list of all of the modules */ |
| | 154 | lst = new Vector(10); |
| | 155 | forEachInstance(ModuleID, { obj: lst.append(obj) }); |
| | 156 | lst = lst.toList(); |
| | 157 | |
| | 158 | /* |
| | 159 | * sort the list by listing order (and alphabetically by name |
| | 160 | * where listing orders are the same) |
| | 161 | */ |
| | 162 | lst = lst.sort(SortAsc, new function(a, b) { |
| | 163 | |
| | 164 | /* if the listings order differ, sort by listing order */ |
| | 165 | if (a.listingOrder != b.listingOrder) |
| | 166 | return a.listingOrder - b.listingOrder; |
| | 167 | |
| | 168 | /* the listing orders are the same; sort by name */ |
| | 169 | if (a.name < b.name) |
| | 170 | return -1; |
| | 171 | else if (a.name > b.name) |
| | 172 | return 1; |
| | 173 | else |
| | 174 | return 0; |
| | 175 | }); |
| | 176 | |
| | 177 | /* return the sorted list */ |
| | 178 | return lst; |
| | 179 | } |
| | 180 | ; |
| | 181 | |
| | 182 | /* ------------------------------------------------------------------------ */ |
| | 183 | /* |
| | 184 | * A module ID with metadata. During pre-initialization, we'll |
| | 185 | * automatically write out a file with the metadata for each of these |
| | 186 | * objects. This is an abstract base class; a subclass must be created |
| | 187 | * for each specific metadata format. |
| | 188 | */ |
| | 189 | class MetadataModuleID: ModuleID, PreinitObject |
| | 190 | /* execute pre-initialization */ |
| | 191 | execute() |
| | 192 | { |
| | 193 | /* write out our metadata */ |
| | 194 | writeMetadataFile(); |
| | 195 | } |
| | 196 | |
| | 197 | /* |
| | 198 | * write our metadata file - this must be overridden by each |
| | 199 | * subclass to carry out the specific steps needed to create and |
| | 200 | * write the metadata file in the appropriate format for the |
| | 201 | * subclass |
| | 202 | */ |
| | 203 | writeMetadataFile() { } |
| | 204 | ; |
| | 205 | |
| | 206 | /* |
| | 207 | * A module ID with GameInfo metadata. The GameInfo metadata format is |
| | 208 | * the standard TADS format for descriptive data about the game. The |
| | 209 | * usual way to use GameInfo metadata is to create a file called |
| | 210 | * "gameinfo.txt" for a game, then embed this file directly in the |
| | 211 | * game's .t3 file using the TADS 3 resource bundler (t3res). Once the |
| | 212 | * gameinfo.txt is embedded in the .t3 file, tools will be able to read |
| | 213 | * the game's descriptive data directly from the .t3 file. For example, |
| | 214 | * HTML TADS on Windows can read the information into its Game Chest, |
| | 215 | * which allows the interpreter to show the full name of the game, the |
| | 216 | * author, and a blurb describing the game, among other things. |
| | 217 | */ |
| | 218 | class GameInfoModuleID: MetadataModuleID |
| | 219 | /* |
| | 220 | * The IFID - this is a UUID uniquely identifying the game, using the |
| | 221 | * standard UUID format (xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, where |
| | 222 | * each 'x' is a hexadecimal digit). You should pick an IFID when |
| | 223 | * you start each game project, and then keep the same IFID |
| | 224 | * throughout the game's entire existence, *including* version |
| | 225 | * updates. Each new version release of the same game - even major |
| | 226 | * new versions - should use the same IFID, so that the versions can |
| | 227 | * all be related to one another as the same game. |
| | 228 | */ |
| | 229 | IFID = '' |
| | 230 | |
| | 231 | /* |
| | 232 | * The game's headline. It's become an IF tradition to use a |
| | 233 | * quasi-subtitle of the sort that Infocom used, of the form "An |
| | 234 | * Interactive Mystery." This can be used to define that subtitle. |
| | 235 | */ |
| | 236 | headline = '' |
| | 237 | |
| | 238 | /* |
| | 239 | * If this game is part of a series, such as a trilogy, these can be |
| | 240 | * used to identify the name of the series and the position in the |
| | 241 | * series. The series name should be something like "The Enchanter |
| | 242 | * Trilogy"; the series number, if provided, should be a simple |
| | 243 | * integer string ('1', '2', etc) giving the position in the series. |
| | 244 | * Note that the series number isn't required even if a series name |
| | 245 | * is specified, since some series are just groups of works without |
| | 246 | * any particular ordering. |
| | 247 | */ |
| | 248 | seriesName = '' |
| | 249 | seriesNumber = '' |
| | 250 | |
| | 251 | /* |
| | 252 | * The genre of the game. Some games don't fit any particular genre, |
| | 253 | * and some authors just don't like the idea of having to pigeonhole |
| | 254 | * their games, so feel free to leave it out. If there's a good fit |
| | 255 | * to a well-established genre, though, you can specify it here. We |
| | 256 | * recommend you keep this short - one word, maybe two - and use a |
| | 257 | * genre name that's generally recognized as such. You might want to |
| | 258 | * use Baf's Guide as a reference (http://www.wurb.com/if/genre). |
| | 259 | */ |
| | 260 | genreName = '' |
| | 261 | |
| | 262 | /* |
| | 263 | * The forgiveness level, according to the Zarfian scale propounded |
| | 264 | * by Andrew Plotkin on rec.arts.int-fiction. This must be one of |
| | 265 | * these terms, using the exact capitalization shown: Merciful, |
| | 266 | * Polite, Tough, Nasty, Cruel. |
| | 267 | */ |
| | 268 | forgivenessLevel = '' |
| | 269 | |
| | 270 | /* |
| | 271 | * The names and email addresses of the authors, in GameInfo format. |
| | 272 | * This list must use the following format: |
| | 273 | * |
| | 274 | * author one <email>; author two <email> <email>; ... |
| | 275 | * |
| | 276 | * In other words, list the first author's name, followed by one or |
| | 277 | * more email addresses, in angle brackets, for the first author. |
| | 278 | * If more than one author is to be listed, add a semicolon, |
| | 279 | * followed by the name of the second author, followed by the second |
| | 280 | * author's email address or addresses, enclosing each in angle |
| | 281 | * brackets. Repeat as needed for additional authors. The list |
| | 282 | * does not need to end with a semicolon; semicolons are merely used |
| | 283 | * to separate entries. |
| | 284 | */ |
| | 285 | authorEmail = '' |
| | 286 | |
| | 287 | /* |
| | 288 | * The game's web site, if any. If specified, this must be an |
| | 289 | * absolute URL with http protocol - that is, it must be of the form |
| | 290 | * "http://mydomain.com/...". |
| | 291 | */ |
| | 292 | gameUrl = '' |
| | 293 | |
| | 294 | /* |
| | 295 | * Descriptive text for the game, in plain text format. This is a |
| | 296 | * short description that can be used, for example, in a catalog of |
| | 297 | * games. This should be a couple of sentences or so. |
| | 298 | */ |
| | 299 | desc = '' |
| | 300 | |
| | 301 | /* |
| | 302 | * Descriptive text for the game, as an HTML fragment. This should |
| | 303 | * have the same information as the 'desc', but this version can use |
| | 304 | * HTML markups (including tags and character entities) to embellish |
| | 305 | * the display of the text. Any HTML markups should be "in-line" |
| | 306 | * body elements only, not "block" or head elements, so that this |
| | 307 | * text can be inserted into a larger HTML document. For example, |
| | 308 | * markups like <i> and <b> are fine, but <p> and <table> should not |
| | 309 | * be used. |
| | 310 | */ |
| | 311 | htmlDesc = '' |
| | 312 | |
| | 313 | /* |
| | 314 | * The release date. By default, we compute this statically to be |
| | 315 | * today's date. This means this will be set to the date of |
| | 316 | * compilation. If the game wishes to override this, note that the |
| | 317 | * GameInfo format requires this to be of the form YYYY-MM-DD. For |
| | 318 | * example, December 9, 2001 would be '2001-12-09'. |
| | 319 | */ |
| | 320 | releaseDate = static getGameInfoToday() |
| | 321 | |
| | 322 | /* |
| | 323 | * The date of first publication. This can be just a year in YYYY |
| | 324 | * format, or a full YYYY-MM-DD date. This is the original release |
| | 325 | * date of the original version of the game, which is often of |
| | 326 | * interest to archivists. This should *not* be updated when a new |
| | 327 | * release is made - it's always the date of *original* publication. |
| | 328 | */ |
| | 329 | firstPublished = '' |
| | 330 | |
| | 331 | /* |
| | 332 | * The language in which this game's text is written. This is the |
| | 333 | * RFC3066 language code for the main language of the work. For |
| | 334 | * example, games written in US English would use 'en-US', while |
| | 335 | * games written in British English would use 'en-GB'. Note that |
| | 336 | * each language-specific library module should use 'modify' to set |
| | 337 | * this to the default for the library. |
| | 338 | */ |
| | 339 | languageCode = '' |
| | 340 | |
| | 341 | /* |
| | 342 | * The license type for this game. Most text IF games these days |
| | 343 | * are released as freeware, so we use this as the default. The |
| | 344 | * GameInfo metadata format defines several other standard license |
| | 345 | * types, including Public Domain, Shareware, Commercial Demo, |
| | 346 | * Commercial, and Other. Authors should change this if they plan |
| | 347 | * to release under a licensing model other than freeware. |
| | 348 | * |
| | 349 | * Note that the GameInfo metadata format documentation explicitly |
| | 350 | * states that the license type indicated here is advisory only and |
| | 351 | * cannot be considered definitive. This means that this setting |
| | 352 | * does not take away any of the author's rights to set specific |
| | 353 | * license terms. Even so, we recommend that you pick an |
| | 354 | * appropriate value here to avoid any confusion. |
| | 355 | */ |
| | 356 | licenseType = 'Freeware' |
| | 357 | |
| | 358 | /* |
| | 359 | * The copying rules for this game. Most text games these days are |
| | 360 | * released as freeware with minimal restrictions on copying, so we |
| | 361 | * use a default of "nominal cost only." Other values defined in the |
| | 362 | * GameInfo format include Prohibited, No Restrictions, No-Cost Only, |
| | 363 | * At-Cost Only, and Other. A modifier indicates whether or not the |
| | 364 | * game may be included in compilations (such as those "10,001 great |
| | 365 | * games" CD-R's that people like to sell on auction sites); we |
| | 366 | * indicate that inclusion in compilations is allowed by default. |
| | 367 | * You can change this to "Compilations Prohibited" if you prefer not |
| | 368 | * to allow your game to be distributed in that fashion. |
| | 369 | * |
| | 370 | * Note that the restrictions specified here aren't enforced by any |
| | 371 | * sort of copy-protection or DRM (digital rights management) |
| | 372 | * technology. This information is entirely for the benefit of |
| | 373 | * conscientious users who want to abide by your wishes and thus need |
| | 374 | * to know what your wishes are. |
| | 375 | * |
| | 376 | * The GameInfo bundle is mostly for the benefit of software that can |
| | 377 | * extract the information from the compiled game. So, we recommend |
| | 378 | * that you also put a full notice and explanation of your license |
| | 379 | * restrictions somewhere that users can easily find it, such as in a |
| | 380 | * separate LICENSE.TXT file that you distribute with your game, or |
| | 381 | * in the text of the game itself (displayed by a LICENSE or |
| | 382 | * COPYRIGHT command, for example). |
| | 383 | */ |
| | 384 | copyingRules = 'Nominal cost only; compilations allowed' |
| | 385 | |
| | 386 | /* |
| | 387 | * The recommended "presentation profile" for the game. 'Default' |
| | 388 | * means that the interpreter's default profile should be used. |
| | 389 | * (Some interpreters let the user select which profile to use as the |
| | 390 | * default, in which case 'Default' means we'll use that profile.) |
| | 391 | */ |
| | 392 | presentationProfile = 'Default' |
| | 393 | |
| | 394 | /* write our metadata file */ |
| | 395 | writeMetadataFile() |
| | 396 | { |
| | 397 | local f; |
| | 398 | |
| | 399 | /* |
| | 400 | * open the file - note that the GameInfo.txt resource is |
| | 401 | * required to be encoded in UTF-8, so open the file with the |
| | 402 | * UTF-8 character set |
| | 403 | */ |
| | 404 | f = File.openTextFile(gameInfoFilename, FileAccessWrite, 'utf-8'); |
| | 405 | |
| | 406 | /* scan our list of metadata keys and write each one */ |
| | 407 | for (local i = 1, local len = metadataKeys.length() ; |
| | 408 | i + 1 <= len ; i += 2) |
| | 409 | { |
| | 410 | local key; |
| | 411 | local prop; |
| | 412 | local val; |
| | 413 | |
| | 414 | /* get the key name and value property for this entry */ |
| | 415 | key = metadataKeys[i]; |
| | 416 | prop = metadataKeys[i+1]; |
| | 417 | val = self.(prop); |
| | 418 | |
| | 419 | /* turn any '\ ' characters into ' ' characters */ |
| | 420 | val = val.findReplace('\ ', ' ', ReplaceAll); |
| | 421 | |
| | 422 | /* write out this key if there's a value defined for it */ |
| | 423 | if (val != nil && val != '') |
| | 424 | f.writeFile(key + ': ' + val + '\n'); |
| | 425 | } |
| | 426 | |
| | 427 | /* done with the file - close it */ |
| | 428 | f.closeFile(); |
| | 429 | } |
| | 430 | |
| | 431 | /* |
| | 432 | * the GameInfo filename - by default, we write the standard |
| | 433 | * gameinfo.txt file |
| | 434 | */ |
| | 435 | gameInfoFilename = 'GameInfo.txt' |
| | 436 | |
| | 437 | /* |
| | 438 | * The metadata key mappings. This is a list of key/property pairs. |
| | 439 | * The key in each pair is a string giving a standard GameInfo key |
| | 440 | * name, and the property gives the property (of self) that we |
| | 441 | * evaluate to get the string value for that key. |
| | 442 | */ |
| | 443 | metadataKeys = |
| | 444 | [ |
| | 445 | 'IFID', &IFID, |
| | 446 | 'Name', &name, |
| | 447 | 'Headline', &headline, |
| | 448 | 'Byline', &byline, |
| | 449 | 'HtmlByline', &htmlByline, |
| | 450 | 'AuthorEmail', &authorEmail, |
| | 451 | 'Url', &gameUrl, |
| | 452 | 'Desc', &desc, |
| | 453 | 'HtmlDesc', &htmlDesc, |
| | 454 | 'Version', &version, |
| | 455 | 'ReleaseDate', &releaseDate, |
| | 456 | 'FirstPublished', &firstPublished, |
| | 457 | 'Series', &seriesName, |
| | 458 | 'SeriesNumber', &seriesNumber, |
| | 459 | 'Genre', &genreName, |
| | 460 | 'Forgiveness', &forgivenessLevel, |
| | 461 | 'Language', &languageCode, |
| | 462 | 'LicenseType', &licenseType, |
| | 463 | 'CopyingRules', ©ingRules, |
| | 464 | 'PresentationProfile', &presentationProfile |
| | 465 | ] |
| | 466 | |
| | 467 | /* |
| | 468 | * get today's date, using the GameInfo standard date format |
| | 469 | * (YYYY-MM-DD) |
| | 470 | */ |
| | 471 | getGameInfoToday() |
| | 472 | { |
| | 473 | local dt; |
| | 474 | local mm, dd; |
| | 475 | |
| | 476 | /* get the current date */ |
| | 477 | dt = getTime(GetTimeDateAndTime); |
| | 478 | |
| | 479 | /* get the month, and add a leading zero if it's only one digit */ |
| | 480 | mm = (dt[2] < 10 ? '0' : '') + dt[2]; |
| | 481 | |
| | 482 | /* get the day, and add a leading zero if it's only one digit */ |
| | 483 | dd = (dt[3] < 10 ? '0' : '') + dt[3]; |
| | 484 | |
| | 485 | /* build and return the full YYYY-MM-DD date string */ |
| | 486 | return toString(dt[1]) + '-' + mm + '-' + dd; |
| | 487 | } |
| | 488 | ; |
| | 489 | |
| | 490 | |
| | 491 | /* ------------------------------------------------------------------------ */ |
| | 492 | /* |
| | 493 | * Base class for the game's module ID. This merely sets the listing |
| | 494 | * order to 1 so that the game's credit is listed first. Normally, |
| | 495 | * exactly one GameID object, called 'versionInfo', is defined in a game, |
| | 496 | * to provide the game's identifying information. |
| | 497 | * |
| | 498 | * Note that this class is based on GameInfoModuleID, so the library will |
| | 499 | * automatically write out a gameinfo.txt file based on this object's |
| | 500 | * settings. For full GameInfo data, the game should minimally define the |
| | 501 | * following properties (see GameInfoModuleID and ModuleID for details on |
| | 502 | * these properties): |
| | 503 | * |
| | 504 | *. IFID - a random 32-digit hex number to uniquely identify the game; |
| | 505 | *. you can generate one with http://www.tads.org/ifidgen/ifidgen.pl |
| | 506 | *. name - the name of the game |
| | 507 | *. byline - the main author credit: "by so and so" |
| | 508 | *. htmlByline - the main author credit as an HTML fragment |
| | 509 | *. authorEmail - the authors' names and email addresses (in GameInfo format) |
| | 510 | *. desc - a short blurb describing the game, in plain text format |
| | 511 | *. htmlDesc - the descriptive blurb as an HTML ragment |
| | 512 | *. version - the game's version string |
| | 513 | * |
| | 514 | * In addition, you can override the following settings if you don't like |
| | 515 | * the defaults inherited from GameInfoModuleID: |
| | 516 | * |
| | 517 | *. releaseDate - the release date string (YYYY-MM-DD) |
| | 518 | *. licenseType - freeware, shareware, etc. |
| | 519 | *. copyingRules - summary rules on copying |
| | 520 | *. presentationProfile - Multimedia, Plain Text |
| | 521 | */ |
| | 522 | class GameID: GameInfoModuleID |
| | 523 | /* always list the game's credits before any library credits */ |
| | 524 | listingOrder = 1 |
| | 525 | |
| | 526 | /* |
| | 527 | * Show the game's credits. By default, we'll just show our name and |
| | 528 | * by-line. |
| | 529 | * |
| | 530 | * Typically, authors will want to override this to display the full |
| | 531 | * credits for the game. Most authors like to show the author or |
| | 532 | * authors, along with notes of thanks to important contributors. |
| | 533 | * |
| | 534 | * Note that libraries generally will not show anything automatically |
| | 535 | * in the credits, to allow the author full control over the |
| | 536 | * formatting of the credits. Authors are encouraged to give credit |
| | 537 | * where it's due for any libraries they use. |
| | 538 | */ |
| | 539 | showCredit() |
| | 540 | { |
| | 541 | /* by default, just show the game's name and by-line */ |
| | 542 | gLibMessages.showCredit(name, htmlByline); |
| | 543 | } |
| | 544 | |
| | 545 | /* |
| | 546 | * show a blank line after the game's version information, to make |
| | 547 | * it stand apart from the list of library and VM version numbers |
| | 548 | */ |
| | 549 | showVersion() |
| | 550 | { |
| | 551 | inherited(); |
| | 552 | "\b"; |
| | 553 | } |
| | 554 | ; |
| | 555 | |
| | 556 | /* ------------------------------------------------------------------------ */ |
| | 557 | /* |
| | 558 | * The main TADS 3 library ID. |
| | 559 | */ |
| | 560 | moduleAdv3: ModuleID |
| | 561 | name = 'TADS 3 Library' |
| | 562 | byline = 'by Michael J.\ Roberts' |
| | 563 | htmlByline = 'by <a href="mailto:mjr_@hotmail.com">' |
| | 564 | + 'Michael J.\ Roberts</a>' |
| | 565 | version = '3.0.18.1' |
| | 566 | |
| | 567 | /* |
| | 568 | * We use a listing order of 50 so that, if all of the other credits |
| | 569 | * use the defaults, we appear after the game's own credits |
| | 570 | * (conventionally at listing order 1) and before any extension |
| | 571 | * credits (which inherit the default order 100), but so that |
| | 572 | * there's room for extensions that want to appear before us, or |
| | 573 | * after us but before any default-ordered extensions. |
| | 574 | */ |
| | 575 | listingOrder = 50 |
| | 576 | ; |
| | 577 | |
| | 578 | |
| | 579 | /* ------------------------------------------------------------------------ */ |
| | 580 | /* |
| | 581 | * An ID module not for the library but for the T3 VM itself. This |
| | 582 | * doesn't display any credit information, but displays version number |
| | 583 | * information for the VM so that the "version" command shows what |
| | 584 | * version of the interpreter is in use. |
| | 585 | */ |
| | 586 | ModuleID |
| | 587 | showVersion() |
| | 588 | { |
| | 589 | local vsn = t3GetVMVsn(); |
| | 590 | |
| | 591 | /* |
| | 592 | * show the version information - note that we must decompose |
| | 593 | * the version number into the standard 3-part dotted string |
| | 594 | */ |
| | 595 | gLibMessages.showVersion('T3 VM (' + t3GetVMID() + ')', |
| | 596 | '' + (vsn >> 16) + '.' |
| | 597 | + ((vsn >> 8) & 0xFF) + '.' |
| | 598 | + (vsn & 0xFF)); |
| | 599 | "\n"; |
| | 600 | } |
| | 601 | |
| | 602 | /* |
| | 603 | * Use a very high listing order so that we're the last thing shown. |
| | 604 | */ |
| | 605 | listingOrder = 10000 |
| | 606 | ; |
| | 607 | |