mirror of https://github.com/marrub--/zscript-doc
Compare commits
3 Commits
c7a56af98e
...
9025bda4ad
Author | SHA1 | Date |
---|---|---|
an | 9025bda4ad | |
an | 7e071b7622 | |
an | cd38527f4d |
|
@ -12,8 +12,10 @@ The user-defined stat numbers begin at `Thinker.STAT_USER` and end at
|
|||
`Thinker.STAT_USER_MAX`. Do not attempt to use normal integers as stat numbers
|
||||
except as relative to these two.
|
||||
|
||||
(Note to authors: These tables are not alphabetically organized as their
|
||||
ordering is meaningful.)
|
||||
<!--
|
||||
NOTE: These tables are not alphabetically organized as their ordering is
|
||||
meaningful.
|
||||
-->
|
||||
|
||||
Thinkers which do not think and are elided from many checks:
|
||||
|
||||
|
|
10
api.md
10
api.md
|
@ -22,12 +22,6 @@ sense to user code, but are fine to the engine. Because of this, the API shall
|
|||
be documented in pseudo-ZScript which gives an idea of how it works for the
|
||||
modder rather than for the engine.
|
||||
|
||||
Note to authors: Capitalization is normalized within this documentation to
|
||||
encourage consistent code, and does not follow ZScript's original
|
||||
capitalization exactly. Similarly, argument names in methods are sometimes
|
||||
renamed. Note well that *arguments with defaults MAY NOT be renamed* as they
|
||||
are part of the API.
|
||||
|
||||
# Actors
|
||||
|
||||
<!-- inter-toc actor -->
|
||||
|
@ -113,7 +107,9 @@ For legacy reasons, many intermission-related things may be prefixed with `WI`
|
|||
or `WB`. The abbreviation `WI` means *World Intermission* (the intermission
|
||||
screen was originally called "World Map" by Tom Hall) and `WB` meaning *World
|
||||
Buffer*, as this data was originally buffered into a specific memory address
|
||||
for [statistics drivers](https://doomwiki.org/wiki/Statistics_driver).
|
||||
for [statistics drivers][1].
|
||||
|
||||
[1]: https://doomwiki.org/wiki/Statistics_driver
|
||||
|
||||
# Level Data
|
||||
|
||||
|
|
71
entry.md
71
entry.md
|
@ -4,6 +4,7 @@
|
|||
|
||||
* [ACS](#acs)
|
||||
* [Actors](#actors)
|
||||
* [Examples: Actor Replacement](#examples-actor-replacement)
|
||||
* [Console Commands](#console-commands)
|
||||
* [CVARINFO](#cvarinfo)
|
||||
* [DECALDEF](#decaldef)
|
||||
|
@ -22,7 +23,7 @@ itself, many interactions with the engine are not defined in ZScript. This
|
|||
section describes all ZScript interactions with the engine, both inside and
|
||||
outside of ZScript itself.
|
||||
|
||||
# ACS
|
||||
## ACS
|
||||
|
||||
ACS has several functions for interfacing with ZScript: `SetUserVariable`
|
||||
(callfunc `24`,) `GetUserVariable` (callfunc `25`,) `SetUserArray` (callfunc
|
||||
|
@ -55,7 +56,7 @@ values, although more than one value will be ignored. The returned value may be
|
|||
`double` (converted to fixed-point,) `name`, `sound` or `string` (converted to
|
||||
ACS string.) If it is not one of these types, it will be ignored.
|
||||
|
||||
# Actors
|
||||
## Actors
|
||||
|
||||
Actor classes can be replaced by the `replaces` class flag, which during
|
||||
dynamic actor replacement will choose to spawn this class over its replaced
|
||||
|
@ -63,72 +64,94 @@ actor, unless the replaced actor is later replaced again by another class.
|
|||
Dynamic actor replacement can also be overridden with an event handler's
|
||||
`CheckReplacement` virtual function.
|
||||
|
||||
For example:
|
||||
### Examples: Actor Replacement
|
||||
|
||||
```
|
||||
class MyActor : Actor replaces OtherActor {} // OtherActor will be dynamically replaced with MyActor
|
||||
class MyOtherActor : Actor replaces OtherActor {} // OtherActor will now be replaced with MyOtherActor instead of MyActor
|
||||
// Some actor.
|
||||
class OtherActor : Actor
|
||||
{
|
||||
}
|
||||
|
||||
// OtherActor will be dynamically replaced with MyActor.
|
||||
class MyActor : Actor replaces OtherActor
|
||||
{
|
||||
}
|
||||
|
||||
// OtherActor will now be replaced with MyOtherActor instead of MyActor.
|
||||
class MyOtherActor : Actor replaces OtherActor
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
# Console Commands
|
||||
## Console Commands
|
||||
|
||||
While ZScript cannot be directly called by console commands, one can use the
|
||||
`event` and `netevent` console commands. `event` will dispatch a non-player
|
||||
network event, and `netevent` will dispatch a network event for the player that
|
||||
ran it.
|
||||
|
||||
# CVARINFO
|
||||
## CVARINFO
|
||||
|
||||
Any CVars declared as a server CVar in `CVARINFO` or by the engine will be
|
||||
accessible as a global variable in ZScript, which has a special type that can
|
||||
be implicitly cast to the type of the CVar. They cannot be set this way, only
|
||||
accessed.
|
||||
|
||||
# DECALDEF
|
||||
## DECALDEF
|
||||
|
||||
`DECALDEF` can set the decal generator for a specific `Actor` class with the
|
||||
`generator` keyword. An actor can also define its generator and inherited
|
||||
classes' generators with the `Decal` property.
|
||||
|
||||
# DECORATE
|
||||
## DECORATE
|
||||
|
||||
TODO: lots of things to note here
|
||||
|
||||
# LOCKDEFS
|
||||
## LOCKDEFS
|
||||
|
||||
Key and lock groups in `LOCKDEFS` are defined as groups of `Inventory` or `Key`
|
||||
descendants.
|
||||
|
||||
# GLDEFS
|
||||
## GLDEFS
|
||||
|
||||
Lights can be associated with `Actor` classes and frames in `GLDEFS`.
|
||||
|
||||
# KEYCONF
|
||||
## KEYCONF
|
||||
|
||||
TODO: this can be used for custom buttons
|
||||
|
||||
# MAPINFO
|
||||
## MAPINFO
|
||||
|
||||
In `MAPINFO`, the `GameInfo` block (referred to as `MAPINFO`/GameInfo in this
|
||||
document) the following properties interact directly with ZScript:
|
||||
|
||||
- `EventHandlers` and `AddEventHandlers` override or add to the list of `StaticEventHandler` or `EventHandler` classes registered by the game (as opposed to event handlers registered per-map.)
|
||||
- `MessageBoxClass` sets the `MessageBoxMenu` class to use for message boxes used by the engine's GUI.
|
||||
- `PlayerClasses` and `AddPlayerClasses` override or add to the list of `PlayerPawn` classes the game provides.
|
||||
- `PrecacheClasses` will pre-cache all sprites used by an `Actor` class. Note that this also works for `StateProvider` degenerates like `Weapon`.
|
||||
- `StatScreen_CoOp` sets the `StatusScreen` class to use for co-op intermission screens.
|
||||
- `StatScreen_DM` sets the `StatusScreen` class to use for Deathmatch intermission screens.
|
||||
- `StatScreen_Single` sets the `StatusScreen` class to use for single-player intermission screens.
|
||||
- `StatusBarClass` sets the status bar class used by the game to the provided `BaseStatusBar` class.
|
||||
- `WeaponSlot` sets the game's default weapon slots to the provided `Weapon` classes.
|
||||
- `EventHandlers` and `AddEventHandlers` override or add to the list of
|
||||
`StaticEventHandler` or `EventHandler` classes registered by the game (as
|
||||
opposed to event handlers registered per-map.)
|
||||
- `MessageBoxClass` sets the `MessageBoxMenu` class to use for message boxes
|
||||
used by the engine's GUI.
|
||||
- `PlayerClasses` and `AddPlayerClasses` override or add to the list of
|
||||
`PlayerPawn` classes the game provides.
|
||||
- `PrecacheClasses` will pre-cache all sprites used by an `Actor` class. Note
|
||||
that this also works for `StateProvider` degenerates like `Weapon`.
|
||||
- `StatScreen_CoOp` sets the `StatusScreen` class to use for co-op intermission
|
||||
screens.
|
||||
- `StatScreen_DM` sets the `StatusScreen` class to use for Deathmatch
|
||||
intermission screens.
|
||||
- `StatScreen_Single` sets the `StatusScreen` class to use for single-player
|
||||
intermission screens.
|
||||
- `StatusBarClass` sets the status bar class used by the game to the provided
|
||||
`BaseStatusBar` class.
|
||||
- `WeaponSlot` sets the game's default weapon slots to the provided `Weapon`
|
||||
classes.
|
||||
|
||||
TODO: there are other things here as well, like map event handlers
|
||||
|
||||
# MENUDEF
|
||||
## MENUDEF
|
||||
|
||||
TODO: this directly uses ZScript classes
|
||||
|
||||
# TERRAIN
|
||||
## TERRAIN
|
||||
|
||||
The `SmallSplash`, `SplashBase` and `SplashChunk` properties of `Splash` blocks
|
||||
use `Actor`s.
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Concepts
|
||||
|
||||
<!-- vim-markdown-toc GFM -->
|
||||
|
||||
* [Action Scoping](#action-scoping)
|
||||
* [Object Scoping](#object-scoping)
|
||||
* [Format String](#format-string)
|
||||
|
@ -7,7 +9,13 @@
|
|||
* [Game Tick](#game-tick)
|
||||
* [Interpolation](#interpolation)
|
||||
|
||||
TODO
|
||||
<!-- vim-markdown-toc -->
|
||||
|
||||
Here is a cursory view of concepts vital to ZScript and ZDoom in general. If
|
||||
you can't find something here, it's likely inherited directly from Doom, so you
|
||||
should check [the Doom Wiki][1] for more relevant information.
|
||||
|
||||
[1]: https://doomwiki.org/wiki/Entryway
|
||||
|
||||
## Action Scoping
|
||||
|
||||
|
@ -61,15 +69,18 @@ Here is a chart of data access possibilities for each scope:
|
|||
|
||||
A format string is a string that specifies the format of a conversion from
|
||||
arbitrary data to a contiguous character string. A format string contains
|
||||
normal characters and *conversion specifiers*. See [this
|
||||
page](https://en.cppreference.com/w/c/io/fprintf) for more information.
|
||||
Differences between C's `printf` and ZScript formats include:
|
||||
normal characters and *conversion specifiers*. See [this page][2] for more
|
||||
information. Differences between C's `printf` and ZScript formats include:
|
||||
|
||||
- Since there's no `char` type, `int` is used for `%c`.
|
||||
- `%s` also works for `name`.
|
||||
- No `%n` specifier.
|
||||
- An additional conversion specifier `%B` exists which converts a number to binary.
|
||||
- An additional conversion specifier `%H` exists which works like `%g` but automatically selects the smallest appropriate precision.
|
||||
- An additional conversion specifier `%B` exists which converts a number to
|
||||
binary.
|
||||
- An additional conversion specifier `%H` exists which works like `%g` but
|
||||
automatically selects the smallest appropriate precision.
|
||||
|
||||
[2]: https://en.cppreference.com/w/c/io/fprintf
|
||||
|
||||
## Sprite
|
||||
|
||||
|
@ -81,7 +92,9 @@ the file and state block representations, not a character, but an integer. The
|
|||
number `0` for instance represents the letter `A`, `1` to `B`, etc.
|
||||
|
||||
For more information on sprites and rotations, please refer to [the relevant
|
||||
Doom Wiki article](https://doomwiki.org/wiki/Sprite).
|
||||
Doom Wiki article][3].
|
||||
|
||||
[3]: https://doomwiki.org/wiki/Sprite
|
||||
|
||||
## Game Tick
|
||||
|
||||
|
@ -108,7 +121,9 @@ simulation in the same way:
|
|||
smoother rendering.
|
||||
|
||||
For more information on ticks, please refer to [the relevant Doom Wiki
|
||||
article](https://doomwiki.org/wiki/Tic).
|
||||
article][4].
|
||||
|
||||
[4]: https://doomwiki.org/wiki/Tic
|
||||
|
||||
## Interpolation
|
||||
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
# Style
|
||||
|
||||
<!-- vim-markdown-toc GFM -->
|
||||
|
||||
* [Capitalization Conventions](#capitalization-conventions)
|
||||
* [Rationale](#rationale)
|
||||
* [Word Choice](#word-choice)
|
||||
* [Rationale](#rationale-1)
|
||||
* [Naming Type Members](#naming-type-members)
|
||||
* [Rationale](#rationale-2)
|
||||
* [Layout Conventions](#layout-conventions)
|
||||
* [Rationale](#rationale-3)
|
||||
* [Commenting Conventions](#commenting-conventions)
|
||||
* [Rationale](#rationale-4)
|
||||
* [Language Guidelines](#language-guidelines)
|
||||
* [Rationale](#rationale-5)
|
||||
|
||||
<!-- vim-markdown-toc -->
|
||||
|
||||
This is a style guide for the ZScript documentation to encourage best-practice
|
||||
coding with it, focused on clarity and consistency of formatting. It is also
|
||||
intended to be a general style guide for writing new code, but this purpose is
|
||||
ancillary and can be ignored. Within the abstract of each component of style
|
||||
will be rationale for choices made.
|
||||
|
||||
## Capitalization Conventions
|
||||
|
||||
ZScript is case insensitive, however this guide aims to give a way to
|
||||
consistently capitalize all identifiers in the language. Due to case
|
||||
insensitivity, it may be difficult to apply these guidelines to real code, but
|
||||
nonetheless a consistent capitalization style should be followed. Do note that
|
||||
you must not rely on case differences in identifiers due to this.
|
||||
|
||||
Capitalize the first letter of each word in an identifier. Acronyms over 2
|
||||
characters in length are considered whole words, so for instance prefer
|
||||
`XmlWidget` over `XMLWidget` but `IOStream` over `IoStream`. Acronyms of one
|
||||
character also count, so prefer `PrintF` over `Printf`.
|
||||
|
||||
For identifiers of parameter names and local scope variables do not capitalize
|
||||
the first word. In these cases, prefer `xmlWidget` over `XmlWidget` or
|
||||
`ioStream` over `IOStream`. The same for acronyms of one character, so `typeF`
|
||||
over `TypeF` or `nChars` over `NChars`. (Note that the former two are malformed
|
||||
names, however. See the "Word Choice" section for more information.)
|
||||
|
||||
Identifiers used for flags (declared with `flagdef`) and constants (declared
|
||||
with `const`, `static const`, or `enum`) must be all uppercase, except the `b`
|
||||
prefix on flags, and can separate words with underscores.
|
||||
|
||||
Argument names in base archive methods may be renamed, but arguments with
|
||||
defaults may not be renamed as they are part of the API.
|
||||
|
||||
### Rationale
|
||||
|
||||
Case insensitivity in programming is generally regarded as bad practice because
|
||||
the lack of strictness is often a failing in language design. It is not
|
||||
imperative here to reason for or against case insensitivity, however. Code
|
||||
within this style is to be written as uniformly as possible, therefore
|
||||
capitalization is also to be uniform. It is the user's choice whether to follow
|
||||
this rule or not, just as any other, but for authors of this documentation the
|
||||
sole imperative is consistency.
|
||||
|
||||
This style of acronym capitalization has been chosen so as to defer to prior
|
||||
art, primarily C#'s standard, which has been in use for over a decade now. The
|
||||
purpose of not capitalizing more than two characters is to make it more natural
|
||||
to read acronyms where normally they are forced to be next to other capitalized
|
||||
words.
|
||||
|
||||
Not capitalizing the first word of parameter and local scope variables is also
|
||||
decided by deferring to prior art. The majority of programming style guides
|
||||
written advocate for this. The purpose in ZScript is primarily moot due to case
|
||||
insensitivity, but we apply these rules to make reading easier and more
|
||||
consistent with most other programming languages that have existed.
|
||||
|
||||
Capitalizing constants, enumerations, and flags is an artifact of the way they
|
||||
are declared in ZDoom, and also in the original Linux Doom source code. This is
|
||||
extended to static arrays for consistency.
|
||||
|
||||
## Word Choice
|
||||
|
||||
In new identifiers, do not add underscores anywhere within the identifier,
|
||||
unless explicitly stated in this style guide or necessary because of
|
||||
unmodifiable code (such as that in GZDoom's base archive.) Do not use Hungarian
|
||||
notation.
|
||||
|
||||
Do not use keywords or types as names except for the identifier "`name`". Do
|
||||
not, for instance, declare `string Class;`, even though the language will allow
|
||||
you to do so, although `string Name;` is fine.
|
||||
|
||||
It is generally favorable to use shortened terminology, for instance `CanMoveZ`
|
||||
instead of `CanMoveVertically`. Try to make names readable in English, however:
|
||||
`CanThrowItem` instead of `ThrowableItem`.
|
||||
|
||||
In the same vein, use abbreviations where conventional, but avoid them where
|
||||
unnecessary. Prefer `GetMobj` to `GetMapObject` but also `GetAngle` to
|
||||
`GetAng`.
|
||||
|
||||
### Rationale
|
||||
|
||||
The forbidding of underscores and Hungarian notation are in accordance with
|
||||
ZDoom's coding style. These choices are also present in other prior art, but
|
||||
the main deciding factor is that of the engine itself.
|
||||
|
||||
The usage of most keywords in variable names is allowed in ZScript because the
|
||||
parser considers most identifiers to be contextual. In many contexts, keywords
|
||||
are allowed in places they shouldn't be by most standards. Besides the
|
||||
precedence of prior art, it appears that the engine itself also avoids
|
||||
(ab)using this relaxation of context.
|
||||
|
||||
The engine and this style do, however, allow use of the identifier "`name`" in
|
||||
variables and members because it is a frequently used word and would be absurd
|
||||
to disallow.
|
||||
|
||||
Shortened terminology such as abbreviations or contractions are favored due to
|
||||
long-standing conventions within ZDoom's source code. This is also historically
|
||||
relevant because of engines such as Unreal Engine which ZDoom takes inspiration
|
||||
from. Common terminology which may be shortened can be found on [the Doom
|
||||
Wiki.][2]
|
||||
|
||||
[2]: https://doomwiki.org/wiki/Category:Doom_engine
|
||||
|
||||
## Naming Type Members
|
||||
|
||||
Always name methods with verbs or verb phrases, such as "`Split`" or
|
||||
"`CompareTo`." Always try to make names forward compatible, i.e. such that they
|
||||
will likely not conflict with new functions when they are added to the engine.
|
||||
In mods, this can even involve prefixing method names with one unique to the
|
||||
mod. Avoid violent words such as `Die`, `Destroy`, `Kill`, except where
|
||||
literally applicable. Prefer for instance `Stop`, `Drop`, `Halt`.
|
||||
|
||||
Always name members with nouns, noun phrases or adjectives. Boolean values
|
||||
should often be prefixed with `Is`, `Has`, and other existential present-tense
|
||||
verbs. All members of class types should be prefixed with `m_`, despite rules
|
||||
against Hungarian notation and underscores. Try to name members productively
|
||||
rather than vaguely, instead of `RefInt` write `RefCount`.
|
||||
|
||||
### Rationale
|
||||
|
||||
Forwards compatibility is necessary primarily in mods. In this documentation it
|
||||
should be taken into account when writing example code, often when writing
|
||||
examples that involve inheriting from a class in the engine. ZScript will hard
|
||||
error on load if there is more than one definition of a function, so it is
|
||||
necessary to never have a conflict in names, including capitalization-wise.
|
||||
|
||||
The purpose of avoiding violent words in method names is to not unnecessarily
|
||||
invoke potentially uncomfortable or triggering imagery. In much of the base
|
||||
class code, it is literally the action being taken, as Doom is indeed a violent
|
||||
game. In these cases it is entirely normal to use such verbs. An example of
|
||||
when this is entirely wasteful is ZDoom's garbage collector (which is exposed
|
||||
with different naming conventions) in which the flag for objects marked for
|
||||
finalization upon the next collection cycle is named `EuthanizeMe`. This kind
|
||||
of wording is certainly jocular and potentially amusing, but a 'funny' name
|
||||
such as this serves no real purpose, and could easily be re-worded to prevent
|
||||
potential discomfort.
|
||||
|
||||
Members are prefixed with `m_` in order to defuse potential clashes with local
|
||||
variables, since case sensitivity cannot defuse them. The alternative to this
|
||||
is to prefix all member variable accesses with `self.`. However, this is
|
||||
potentially excessive and is not entirely productive in writing short and
|
||||
readable examples. This also provides a layer of forward compatibility, as
|
||||
ZDoom does not use `m_` prefixes anywhere within its code. For the opposite
|
||||
reason, as structure types cannot inherit, there is no need to prefix their
|
||||
members, and so this prefix is omitted within them.
|
||||
|
||||
## Layout Conventions
|
||||
|
||||
Use 3 spaces for indentation. Indent at each block, but do not indent `case`
|
||||
labels. Align all code to 80 columns.
|
||||
|
||||
Write only one statement or declaration per line, except in the case of
|
||||
multiple-assignment operations, in which case pairing all of the related
|
||||
declarations and the statement on the same line is allowed as long as it does
|
||||
not exceed 80 columns.
|
||||
|
||||
Always add one blank line between separate method definitions, and between
|
||||
member declarations and member definitions. Add one blank line between local
|
||||
variable declarations and statements, unless specified otherwise. Add one blank
|
||||
line between conditional statements, except the `else` block of an `if`
|
||||
statement.
|
||||
|
||||
Do not place a space before the parentheses of a conditional or loop statement
|
||||
such as `if` or `for`. Always write `if()` and not `if ()`.
|
||||
|
||||
Always place opening braces on their own line. Using braces is not necessary
|
||||
when there is a single sub-statement, for instance with `if(x) y = z;`.
|
||||
|
||||
### Rationale
|
||||
|
||||
The convention of 3 spaces for indentation comes from [Eternity Engine's style
|
||||
guideline.][1] There is no other reason for this decision, other than it is
|
||||
pleasing to the eye while not being excessive. The indentation and blank line
|
||||
rules are generally the same as the majority of C-like language style
|
||||
guidelines.
|
||||
|
||||
Alignment to 80 columns is for the purpose of reading the raw documentation
|
||||
text under standard size Linux terminals. This is useful, for instance, when
|
||||
reading diff files under the `git` console client. This guideline can generally
|
||||
be ignored outside of this documentation.
|
||||
|
||||
Writing multiple-assignment operations all on one line serves the purpose of
|
||||
grouping all of the relevant information together. In most languages with
|
||||
multiple assignment, you are able to do the declaration and assignment in one
|
||||
line, so this crudely mirrors a more well implemented language syntax.
|
||||
|
||||
Placing opening braces on their own line greatly increases code readability,
|
||||
especially for people hard of sight. Other styles make it easy to confuse where
|
||||
a block begins and create a less clear visual line between the start and end.
|
||||
The purpose of this is to increase readability of this documentation, and not
|
||||
to make code look more pleasing.
|
||||
|
||||
[1]: https://github.com/team-eternity/eternity/blob/master/docs/ee_style_guide.md
|
||||
|
||||
## Commenting Conventions
|
||||
|
||||
Do not use block comments, except for the purpose of example or code that will
|
||||
intentionally not work. Comments may be placed anywhere except at the end of
|
||||
the opening line of a conditional or loop statement, the opening brace of a
|
||||
block, or the ending brace of a block. Always use proper case and punctuation
|
||||
when writing comments. Always put one space between the comment delimiter and
|
||||
comment text.
|
||||
|
||||
### Rationale
|
||||
|
||||
Block comments are mostly an adage of old programming languages made to be
|
||||
printed on paper. In modern times they are most useful for commenting out large
|
||||
blocks of code. They are rather clumsy to format well, and so single-line
|
||||
comments are to be used instead of them. One could argue that if a consistent
|
||||
formatting style was added, this would not be a problem. However, it is
|
||||
generally easier and more readable to just use line comments.
|
||||
|
||||
## Language Guidelines
|
||||
|
||||
Use `let` declarations when the type of the object will be obvious from what it
|
||||
is assigned. Do not use them if it is not obvious, or in example when it is
|
||||
necessary to proclaim the type to make reading easier.
|
||||
|
||||
Don't use integer types except for `int` except in example. Similarly, do not
|
||||
use float types except for `double` except in example.
|
||||
|
||||
No restrictions are placed on the usage of parentheses. Always place spaces
|
||||
between the operands of binary expressions (`1 + 1`) but never unary
|
||||
expressions (`-5`.)
|
||||
|
||||
Do not place semicolons at the end of `enum` or `struct` definitions. However, always place commas at the end of the last enumeration variant.
|
||||
|
||||
### Rationale
|
||||
|
||||
Integer and floating-point types other than `int` and `double` are primarily
|
||||
for internal use. They can be used by user types, but often it's not necessary
|
||||
and can be harmful.
|
||||
|
||||
Placing semicolons at the end of top-level items is not meant to be used by end
|
||||
users. Its main purpose is to make ZScript easier to port from C++. On the
|
||||
other hand, placing a comma at the end of the last enumeration in a set is a
|
||||
common practice, as it allows the user to place more variants without touching
|
||||
much.
|
||||
|
||||
<!-- EOF -->
|
|
@ -5,6 +5,7 @@
|
|||
* [Classes](glossary-Classes.md)
|
||||
* [Concepts](glossary-Concepts.md)
|
||||
* [Structures](glossary-Structures.md)
|
||||
* [Style](glossary-Style.md)
|
||||
* [Versions](glossary-Versions.md)
|
||||
|
||||
<!-- end -->
|
||||
|
|
|
@ -22,7 +22,7 @@ creating within the language.
|
|||
|
||||
All classes inherit from other classes. The base class can be set within the
|
||||
class header, but if it is not the class will automatically inherit from
|
||||
Object.
|
||||
`Object`.
|
||||
|
||||
Classes are subject to Scoping. They are also implicitly reference values, and
|
||||
therefore can be null. Use `new` to instantiate a new class object.
|
||||
|
@ -64,23 +64,38 @@ In place of the class header.
|
|||
## Example: Class headers
|
||||
|
||||
```
|
||||
class MyCoolObject // automatically inherits Object
|
||||
// Automatically inherits Object, similar to the "actor" keyword in DECORATE.
|
||||
class MyCoolObject
|
||||
{
|
||||
}
|
||||
|
||||
class MyCoolScopedObject play // has Play scope
|
||||
// Equivalent to the above.
|
||||
class MyCoolObjectExplicit : Object
|
||||
{
|
||||
}
|
||||
|
||||
class MyCoolThinker : Thinker // inherits Thinker
|
||||
// Has "Play" scope.
|
||||
class MyCoolScopedObject play
|
||||
{
|
||||
}
|
||||
|
||||
// Inherits Thinker and can override functions on it.
|
||||
class MyCoolThinker : Thinker
|
||||
{
|
||||
}
|
||||
|
||||
// Some actor.
|
||||
class OtherActor : Actor
|
||||
{
|
||||
}
|
||||
|
||||
// Replaces "OtherActor."
|
||||
class MyCoolActor : Actor replaces OtherActor
|
||||
{
|
||||
}
|
||||
|
||||
class MyCoolInterface abstract // can only be inherited
|
||||
// Can only be inherited.
|
||||
class MyCoolInterface abstract
|
||||
{
|
||||
}
|
||||
```
|
||||
|
@ -92,8 +107,10 @@ Basic class definition with a member variable and member function.
|
|||
```
|
||||
class BasicClass
|
||||
{
|
||||
// "m_Thing" is attached to any "instance" of BasicClass.
|
||||
int m_Thing;
|
||||
|
||||
// Changes "m_Thing" to 500 on an instance of BasicClass.
|
||||
void ChangeThing()
|
||||
{
|
||||
m_Thing = 500;
|
||||
|
@ -104,11 +121,12 @@ class BasicClass
|
|||
Alternate syntax usage.
|
||||
|
||||
```
|
||||
// This class spans from this point to the end of the file.
|
||||
class TheWholeFileIsAClassOhNo;
|
||||
|
||||
int m_MyMember;
|
||||
|
||||
// end of file
|
||||
// End of file, end of class.
|
||||
```
|
||||
|
||||
# Class Flags
|
||||
|
@ -167,15 +185,19 @@ A class with some properties.
|
|||
```
|
||||
class MyCoolActor : Actor
|
||||
{
|
||||
// You can set defined properties in a "default" block like in DECORATE.
|
||||
// This will also be available in DECORATE code that inherits your class!
|
||||
default
|
||||
{
|
||||
MyCoolActor.MyCoolMember 5000;
|
||||
MyCoolActor.MyCoolMemberList 501, 502;
|
||||
}
|
||||
|
||||
// Declare some members.
|
||||
int m_MyCoolMember;
|
||||
int m_CoolMember1, m_CoolMember2;
|
||||
|
||||
// Declare some properties attached to our members.
|
||||
property MyCoolMember: m_MyCoolMember;
|
||||
property MyCoolMemberList: m_CoolMember1, m_CoolMember2;
|
||||
}
|
||||
|
@ -219,18 +241,25 @@ A class with some flags.
|
|||
```
|
||||
class MyCoolActorWithFlags : Actor
|
||||
{
|
||||
// You can set defined flag in a "default" block like in DECORATE.
|
||||
// This will also be available in DECORATE code that inherits your class!
|
||||
// Hey, those sentences sounded familiar...
|
||||
default
|
||||
{
|
||||
+MYCOOLACTORWITHFLAGS.THIS_ONE_IS_ON
|
||||
-MYCOOLACTORWITHFLAGS.THIS_ONE_IS_OFF
|
||||
}
|
||||
|
||||
// Declare a flag field for all of the flags. This can hold up to 32 flags.
|
||||
int m_Flags;
|
||||
|
||||
flagdef This_One_Is_On: m_Flags, 0;
|
||||
flagdef This_One_Is_Off: m_Flags, 1;
|
||||
flagdef This_One_Aliases_On: m_Flags, 0;
|
||||
// Declare the flags, one at a time...
|
||||
flagdef THIS_ONE_IS_ON: m_Flags, 0;
|
||||
flagdef THIS_ONE_IS_OFF: m_Flags, 1;
|
||||
flagdef THIS_ONE_ALIASES_ON: m_Flags, 0;
|
||||
|
||||
// Unnecessary, since you can just access it directly, but this demonstrates
|
||||
// how declared flags can be used in methods.
|
||||
bool CheckIfOnIsOn()
|
||||
{
|
||||
return bTHIS_ONE_IS_ON;
|
||||
|
|
|
@ -19,10 +19,12 @@ type.
|
|||
|
||||
## Example: Constant definitions
|
||||
|
||||
Making an integer constant from a double.
|
||||
|
||||
```
|
||||
const MY_COOL_INT = int(777.7777);
|
||||
// Making a regular integer constant.
|
||||
const MY_COOL_NUMBER = 777;
|
||||
|
||||
// Making an integer constant from a double.
|
||||
const MY_COOL_NUMBER_FROM_BEYOND = int(777.7777);
|
||||
```
|
||||
|
||||
# Static array definitions
|
||||
|
|
|
@ -35,28 +35,24 @@ Identifier $[ = Expression]$
|
|||
|
||||
## Example: Enumeration definitions
|
||||
|
||||
Basic enumeration.
|
||||
|
||||
```
|
||||
// Basic enumeration.
|
||||
enum MyCoolEnum
|
||||
{
|
||||
A, // has value int(0)
|
||||
B, // 1 ...
|
||||
C, // 2 ...
|
||||
D // and 3
|
||||
A_THING, // Has value int(0) ...
|
||||
BEES, // ... 1 ...
|
||||
CALCIUM, // ... 2 ...
|
||||
DEXTROSE, // ... and 3.
|
||||
}
|
||||
```
|
||||
|
||||
Less trivial example.
|
||||
|
||||
```
|
||||
// Less trivial example.
|
||||
enum MyCoolerEnum : int16
|
||||
{
|
||||
A = 500, // has value int16(500)
|
||||
B, // 501
|
||||
A = 500, // Has value int16(500),
|
||||
B, // 501,
|
||||
C = 200,
|
||||
D, // 201
|
||||
E, // 202
|
||||
};
|
||||
D, // 201,
|
||||
E, // and 202.
|
||||
}
|
||||
```
|
||||
<!-- EOF -->
|
||||
|
|
|
@ -56,9 +56,9 @@ character. Character escapes include:
|
|||
| `\xnn` or `\Xnn` | Byte `0xnn`. |
|
||||
| `\nnn` | Byte `0nnn` (octal.) |
|
||||
|
||||
To quote [cppreference](https://en.cppreference.com/w/cpp/language/escape), "of
|
||||
the octal escape sequences, `\0` is the most useful because it represents the
|
||||
terminating null character in null-terminated strings."
|
||||
To quote [cppreference][1], "of the octal escape sequences, `\0` is the most
|
||||
useful because it represents the terminating null character in null-terminated
|
||||
strings."
|
||||
|
||||
String literals, also like C and C++, will be concatenated when put directly
|
||||
next to each other. For example, this:
|
||||
|
@ -69,6 +69,8 @@ next to each other. For example, this:
|
|||
|
||||
Will be parsed as a single string literal with the text `"text 1text 2"`.
|
||||
|
||||
[1]: https://en.cppreference.com/w/cpp/language/escape
|
||||
|
||||
## Class type literals
|
||||
|
||||
Class type literals take the same form as string literals, but do note that
|
||||
|
|
|
@ -22,10 +22,19 @@ $[Member-declaration-flags...]$ Type Variable-name $[ , Variable-name]$... ;
|
|||
Some basic member variables.
|
||||
|
||||
```
|
||||
// An integer. Visible to and modifiable by everything.
|
||||
int m_MyCoolInt;
|
||||
|
||||
// Three separate integers, defined short-hand.
|
||||
int m_CoolInt1, m_CoolInt2, m_CoolInt3;
|
||||
|
||||
// Ten integers in one variable.
|
||||
int[10] m_CoolIntArray;
|
||||
|
||||
// Can only be seen by this type.
|
||||
private int m_CoolPrivateInt;
|
||||
|
||||
// Read-only (part of the class data, can only be seen by descendant types.
|
||||
protected meta int m_CoolMetaInt;
|
||||
```
|
||||
|
||||
|
|
|
@ -57,31 +57,25 @@ Or, the entire list may simply be `void` or empty.
|
|||
|
||||
## Example: Method argument lists
|
||||
|
||||
With the function:
|
||||
|
||||
```
|
||||
void Fn(int one, int two, int a = 0, int b = 0);
|
||||
```
|
||||
// With the function:
|
||||
void DoSomething(int one, int two, int a = 0, int b = 0);
|
||||
|
||||
One could do the following:
|
||||
// One could do the following:
|
||||
DoSomething(4, 5);
|
||||
DoSomething(5, 6, 7);
|
||||
DoSomething(6, 7, 8, 9);
|
||||
|
||||
```
|
||||
Fn(4, 5);
|
||||
Fn(5, 6, 7);
|
||||
Fn(6, 7, 8, 9);
|
||||
```
|
||||
// Or using named default arguments,
|
||||
DoSomething(5, 6, a: 7);
|
||||
|
||||
Or using named default arguments,
|
||||
// Equivalent to:
|
||||
DoSomething(5, 6, 7);
|
||||
|
||||
```
|
||||
Fn(5, 6, a: 7);
|
||||
Fn(6, 7, b: 8);
|
||||
Fn(7, 8, a: 9, b: 10);
|
||||
|
||||
// equivalent to:
|
||||
Fn(5, 6, 7);
|
||||
// (no equivalent, must use above)
|
||||
Fn(7, 8, 9, 10);
|
||||
// And more examples:
|
||||
DoSomething(6, 7, b: 8);
|
||||
DoSomething(7, 8, a: 9, b: 10);
|
||||
DoSomething(7, 8, 9, 10);
|
||||
```
|
||||
|
||||
# Method Definition Flags
|
||||
|
|
|
@ -53,12 +53,13 @@ Expression ;
|
|||
|
||||
## Example: Expression statements
|
||||
|
||||
Some basic expressions.
|
||||
|
||||
```
|
||||
// Some basic expressions.
|
||||
MyCoolFunction(5, 4);
|
||||
m_MyCoolMember = 500;
|
||||
5 * 5; // does nothing of course, but valid
|
||||
|
||||
// Does nothing, of course, but valid.
|
||||
5 * 5;
|
||||
```
|
||||
|
||||
# Conditional Statements
|
||||
|
@ -72,16 +73,14 @@ if ( Expression ) Statement $[ else Statement]$
|
|||
|
||||
## Example: Conditional statements
|
||||
|
||||
Simple conditional.
|
||||
|
||||
```
|
||||
// Simple conditional.
|
||||
|
||||
if(a)
|
||||
B();
|
||||
```
|
||||
|
||||
Simple conditional, with else statement and a block.
|
||||
// Simple conditional, with else statement and a block.
|
||||
|
||||
```
|
||||
if(a)
|
||||
{
|
||||
B();
|
||||
|
@ -102,17 +101,23 @@ switch ( Expression ) Statement
|
|||
|
||||
## Example: Switch statements
|
||||
|
||||
A switch demonstrating fall-through and default cases.
|
||||
|
||||
```
|
||||
// A switch demonstrating fall-through and default cases.
|
||||
|
||||
switch(a)
|
||||
{
|
||||
case 500: Console.PrintF("a is 500"); break;
|
||||
case 501: Console.PrintF("a is 501"); // falls through to next case
|
||||
case 502: Console.PrintF("a is 501 or 502"); break;
|
||||
case 500:
|
||||
Console.PrintF("a is 500");
|
||||
break;
|
||||
case 501:
|
||||
Console.PrintF("a is 501");
|
||||
// Falls through to the next case.
|
||||
case 502:
|
||||
Console.PrintF("a is 501 or 502");
|
||||
break;
|
||||
default:
|
||||
Console.PrintF("not sure what a is!");
|
||||
// break is implied here
|
||||
// "break" is implied here.
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -185,49 +190,51 @@ return $[Expression $[ , Expression]$...]$ ;
|
|||
|
||||
## Example: Control flow statements
|
||||
|
||||
Use of `continue`.
|
||||
|
||||
```
|
||||
// Use of "continue."
|
||||
for(int i = 0; i < 50; i++)
|
||||
{
|
||||
if(i == 25) continue; // don't do anything on 25!
|
||||
// Don't do anything when "i" is 25.
|
||||
if(i == 25)
|
||||
continue;
|
||||
|
||||
DoThing(i);
|
||||
}
|
||||
```
|
||||
|
||||
Use of `break`.
|
||||
|
||||
```
|
||||
// Use of "break."
|
||||
for(int i = 0; i < 50; i++)
|
||||
{
|
||||
if(i == 25) break; // exit the loop at 25!
|
||||
// "break" when "i" is 25.
|
||||
if(i == 25)
|
||||
break;
|
||||
|
||||
DoThing(i);
|
||||
}
|
||||
```
|
||||
|
||||
Use of `return` in various contexts.
|
||||
|
||||
```
|
||||
// Use of `return` in various contexts.
|
||||
void ReturnsNothing()
|
||||
{
|
||||
if(m_Thing != 50) return; // exit early if m_Thing isn't 50.
|
||||
// Exit early if "m_Thing" isn't 50.
|
||||
if(m_Thing != 50)
|
||||
return;
|
||||
|
||||
DoThing(m_Thing);
|
||||
}
|
||||
|
||||
int ReturnsInt()
|
||||
{
|
||||
// "m_Thing" is 50, so return 50.
|
||||
if(m_Thing == 50)
|
||||
return 50; // m_thing is 50, so return 50.
|
||||
return 50;
|
||||
|
||||
return 0; // must have a return eventually
|
||||
// Must have a return, eventually.
|
||||
return 0;
|
||||
}
|
||||
|
||||
int, int ReturnsTwoInts()
|
||||
{
|
||||
return 1, 2; // returns 1 and 2.
|
||||
// Returns 1 and 2.
|
||||
return 1, 2;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -264,12 +271,9 @@ Note that the surrounding brackets are literal and not an optional element.
|
|||
|
||||
## Example: Multi-assignment statements
|
||||
|
||||
Getting the actor out of `A_SpawnItemEx`.
|
||||
|
||||
```
|
||||
Actor mo;
|
||||
bool spawned;
|
||||
[spawned, mo] = A_SpawnItemEx("MyCoolActor");
|
||||
// Getting the actor out of "A_SpawnItemEx."
|
||||
Actor mo; bool spawned; [spawned, mo] = A_SpawnItemEx("MyCoolActor");
|
||||
```
|
||||
|
||||
# Static Array Statements
|
||||
|
|
|
@ -34,9 +34,8 @@ Optionally followed by a semicolon.
|
|||
|
||||
## Example: Structure definitions
|
||||
|
||||
Simple structure.
|
||||
|
||||
```
|
||||
// Simple structure.
|
||||
struct MyCoolStructure
|
||||
{
|
||||
int X;
|
||||
|
|
|
@ -15,7 +15,7 @@ def filter_emit r
|
|||
end
|
||||
|
||||
def find_toc_areas f
|
||||
re = /^(<!-- inter-toc ([^\s]+)\s+-->)(?:.|\n)*?(<!-- end -->)/i
|
||||
re = /^(<!-- inter-toc\s*([^\s]+)\s*-->)(?:.|\n)*?(<!-- end -->)/i
|
||||
f.to_enum(:scan, re).map{$~}
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue