COAL Manual

From 3DGE Wiki
Jump to: navigation, search

Contents

OVERVIEW

COAL is a new scripting language which has been developed especially for 3DGE. At the moment, 3DGE uses this to define custom HUD modules. This manual is designed to get you up-to-speed on all of the functions that COAL provides.
The standard Coal scripts for drawing the DOOM HUD is loaded from this file: doom_ddf/coal_hud.ec
The API that COAL itself is contained in is loaded from doom_ddf/coal_api.ec, which is a good reference to look at while developing your HUD. Take note that the API is hard-coded to 3DGE.
Additionally, each archive may contain a lump called "COALHUDS" which is automatically loaded (which can reside in the PAK/PK3 namespace ./scripts). Later scripts are able to replace any definitions (functions etc) in earlier scripts.

FILES CONTENTS

The contents of each file or lump is simply the text of the COAL code.

The engine provides two modules: the "hud" module provides drawing functions and general queries, whereas the "player" module provides query functions about the current player. All of their functions and variables are described in separate sections below.

In order to customize the default HUDs, your COAL code needs to redefine one of the existing functions, as follows:
doom_status_bar() : replace this function if you only want to customize the full status bar (including the one shown in the automap screen). The size has to be the same (width 320, height 32).
overlay_status_bar() : write your own version of this function if you only want to change the overlay status bar.
doom_automap() : this function draws the automap screen (including the status bar at the bottom). Replacing it means you can show other information here instead of (or in addition to) the automap.
draw_all() : this is the function which EDGE calls to draw everything. The normal version (in EDGE.WAD) will call the above functions depending on the user's current HUD and whether the automap is active or not. Replacing this function gives you total control: you could provide more hud configurations (or less) than the usual three, ignore the automap mode completely if you wanted, or even draw the view from multiple players.

HUD MODULE

General Queries

hud.check_automap() : float

This function returns true while the user is viewing the automap (by pressing TAB) and false for the normal view.

hud.which_hud() : float

This variable returns the current HUD number which the user cycles through when pressing '+' and '-' keys. It ranges from 0 to 119, allowing 120 different HUD screens, but in reality you must use the modulo operator '%' to convert this number to a smaller range.
For example, the standard code uses hud.which_hud() % 3 to select between three different huds (none, normal and overlay).
The following are good modulo numbers: 2,3,4,5,6,8 and 10 (because they divide into 120).
For a HUD which never changes, simply ignore this value.

hud.get_time() : float

This function returns the current time, in terms of "tics" where there are 35 tics per second. In other words, after each 1/35th of a second the value of hud.now_time increases by one. It keeps going even during menus or while the game is paused.

hud.passed_time

This variable is updated by the hud.grab_times() call, and contains the number of "tics" that have passed since the last time the draw_all() function was called. Note that a result of zero is possible.

hud.game_mode() : string

This function returns a string for the current game mode: "sp" (Single Player), "coop" (Cooperative), or "dm" (Deathmatch).

hud.game_name() : string

This function returns the DDF name of the current game being played (the one defined in GAMES.DDF).

hud.map_name() : string

This function returns the DDF name of the current map being played (the one defined in LEVELS.DDF).

hud.map_title() : string

This function returns the title of the map being played, mainly to be displayed on the automap.

* Drawing Stuff

hud.coord_sys(w, h)

In the original DOOM, the screen size was always 320x200, and by default all of the drawing functions here use screen coordinates as if that were the case (even when EDGE is running in different modes likes 640x480 or 1024x768). This function allows you to set a different "virtual" resolution, for example 640x400, and then all coordinates will be for this new system, plus the size of images and text characters will be affected as well.

hud.text_font(name)

Sets the current text font, where the 'name' parameter refers to an entry in FONTS.DDF. The default font is "DOOM" and is reset after each frame.

hud.text_color(name)

Sets the current text color, which must refer to an entry in COLMAPS.DDF, or can be the empty string "" which causes the text to be drawn normally (without being colormapped). The default is "" and is reset after each frame.

hud.set_scale(value)

Sets the scaling for drawing text and for hud.draw_image(). Larger values make the text/image bigger. The default scale is 1.0 and is reset after each frame.

hud.set_alpha(value)

Set the alpha value (translucency) for drawing text, lines, boxes and images. The 'value' parameter ranges from 0.0 (completely invisible) to 1.0 (completely solid). The default alpha is 1.0 and is reset after each frame.

hud.solid_box(x, y, w, h, color)

Draws a solid rectangle consisting of a single color. The 'x' and 'y' parameters are the coordinates of the top left corner, whereas 'w' and 'h' are the width and height. The current alpha value is also applied.
The 'color' parameter can take two different forms. Firstly it may be a string with the same notation as DDF and HTML, which begins with a "#" character and is followed by 6 hexadecimal digits. For example "#FF0000" for red and "#0000FF" for blue. Secondly it can be a Lua table with fields called 'r', 'g' and 'b' (for red, green and blue). Each of these fields is a number from 0 to 255. For example: { r=255, g=170, b=0 } for orange.

hud.solid_line(x1, y1, x2, y2, color)

Draws a solid line between the start coordinate (x1,y1) to the end coordinate (x2, y2). The 'color' parameter is the same as for hud.solid_box(), and the current alpha value is also applied.

hud.thin_box(x, y, w, h, color)

Similar to hud.solid_box(), but only draws the outline of a rectangle. The inside area is not affected. The sides are always two pixels thick, and never go outside the specified area. The 'color' parameter is the same as for hud.solid_box(), and the current alpha value is also applied.

hud.gradient_box(x, y, w, h, TL, BL, TR, BR)

Similar to hud.solid_box(), but the colors for each corner are specified individually: 'TL' for top left, 'BL' for bottom left, 'TR' for top right and 'BR' for bottom right. The current alpha value will also be applied.

hud.draw_image(x, y, name)

Draws an image at the given coordinates, which specify the top/left corner of the image. The current alpha and scaling factors are applied as well.

hud.stretch_image(x, y, w, h, name)

Similar to hud.draw_image(), but the image will be stretched or squashed so that it fits exactly into the given rectangle on the screen. The current alpha value is also applied.

hud.tile_image(x, y, w, h, name, [x_offset, y_offset])

Draws an image (usually a texture or flat) on the screen, where the image is tiled (repeated) to fill up the given rectangle. The current alpha and scaling factors are also applied. The 'x_offset' and 'y_offset' parameters are optional, and can be used to offset the texture by a certain number of pixels.

hud.draw_text(x, y, str)

Draws some text on the screen using the current text font, color, alpha and scaling values. Newlines ("\n") in the string can be used to draw multi-line text.

hud.draw_num2(x, y, len, num)

Draws a number (an integer) on the screen using the current text font, color, alpha and scaling. The number is right-aligned, in other words the 'x' parameter specified the right-most pixel, and the 'len' parameter gives the maximum number of characters (including the minus sign if the number is negative).

hud.render_world(x, y, w, h)

Renders the view for the player on the screen, in a rectangle with the given coordinates. The player's weapon is also drawn. The views of different players can be rendered by using the hud.set_render_who() function below.

hud.render_automap(x, y, w, h, [options])

Renders the automap for the player on the screen, in a rectangle with the given coordinates. Note that no background is drawn, hence you can use this function to create an overlay automap (drawn over the top of the player's view). If you need a solid color behind it, use the hud.solid_box() function first.
The 'options' parameter is optional, when present it is a table containing a set of variables which modify the way the automap is drawn. Variables which are not present in the table are not affected (stay the same as the user's normal automap). The following list shows all the possible variables:
Variable Description
    • zoom Set a fixed zoom factor, where 1.0 shows the whole map, and larger values make the map bigger
    • grid force the grid lines on/off
    • rotate force map rotation on/off
    • follow force follow-player mode on/off
    • things draw all things
    • walls draw all walls (like IDDT cheat)
    • allmap draw walls like All-Map powerup

hud.set_render_who(index)

Sets the current player for rendering the world or the automap. The 'index' parameter is a small number: 1 for the "main player" on this computer (the person at the keyboard), 2 for the next player in the list, etc... upto the number of players in the game.

hud.automap_colors(table)

This function can be used to change some or all of the colors used when drawing the automap. The 'table' parameter is a Lua table where the names are automap parts and the values are the colors. For example: { grid = "#006666", wall = "#FFFFFF" }. Parts that are not present in the table are not affected (stay the same as before). Here is a list of all the automap parts that can be changed:
Automap Part Description
    • grid Grid lines
    • wall One sided walls
    • step Floor height change, climable
    • ledge Floor drop-off, too high to climb
    • ceil Ceiling height difference
    • secret Secret doors
    • allmap Unseen walls when you have the All-Map
    • player Player object
    • monster Monsters
    • corpse Dead monsters
    • item Pickup items
    • missile Missiles, fireballs, etc
    • scenery Scenery items

* Audio Functions

hud.play_sound(name)

Plays the given sound, which must be an entry in SOUNDS.DDF.

PLAYER MODULE

General Queries

player.is_bot()

Returns true if the current player is a bot.

player.get_name()

Returns the name of the current player.

player.get_angle()

Returns the angle of the current player.

player.get_pos()

Returns the position of the current player.

player.get_mlook()

Returns the mlook (mouse-look) angle of the current player.

player.health()

Returns the health of the current player. The result will normally be in the range 0 to 100, regardless of the SPAWNHEALTH setting for the player in DDF (in other words, the result is a percentage value of the spawn health). Values higher than 100 are possible when the player has bonus health (e.g. from the Soul Sphere pickup).

player.armor(type)

For the given armor type, returns the amount the player is currently wearing. The 'type' parameter is a number in the range 1-5, but the following names can be used for more readable code:
    • ARMORS.green
    • ARMORS.blue
    • ARMORS.purple
    • ARMORS.yellow
    • ARMORS.red

player.total_armor(type)

Returns the total amount of armor the player has.

player.frags()

Number of frags the player has (for Deathmatch games).

player.move_speed()

Returns a number for how fast the player is currently moving, roughly the number of map units per tic (there are 35 tics per second).

player.air_in_lungs()

Returns amount of air in the player lungs, as a percentage value from 0 to 100. Only guaranteed to be valid while the player is underwater.

player.has_key(key)

Returns true if the player currently has the specified key, which is a number from 1 to 16. For more readable code, the following names can be used:
    • KEYS.blue_card KEYS.gold_key
    • KEYS.red_card KEYS.brass_key
    • KEYS.yellow_card KEYS.steel_key
    • KEYS.green_card KEYS.fire_key
    • KEYS.blue_skull KEYS.silver_key
    • KEYS.red_skull KEYS.copper_key
    • KEYS.yellow_skull KEYS.wooden_key
    • KEYS.green_skull KEYS.water_key

player.has_power(power)

Returns true if the player currently has the specified powerup. The 'power' parameter is a number from 1 to 16. For more readable code, the following names can be used:
    • POWERS.invuln
    • POWERS.berserk
    • POWERS.invis
    • POWERS.acid_suit
    • POWERS.automap
    • POWERS.goggles
    • POWERS.jet_pack
    • POWERS.night_vis
    • POWERS.scuba

player.power_left(power)

Returns the number of seconds remaining for the specified powerup, or zero when the player does not have it. The berserk powerup only counts down the red-screen effect, and returns -1 when that is finished. The automap powerup returns a large value when active and it never counts down. The result for invulnerability is not affected by the God-mode cheat.

* Weapon Stuff

player.has_weapon(name)

Returns true if the player currently owns the weapon, where 'name' is the DDF name of the weapon.

player.has_weapon_slot(slot)

Returns true if the player currently owns any weapon which uses the given 'slot', which is a number for 0 to 9 (same as the BINDKEY command in the DDF).

player.cur_weapon()

Returns the DDF name of the weapon the player is currently holding, or the special value "none" when the player is holding no weapon at all, or "change" while the weapon is switching to a new one.

player.cur_weapon_slot()

Returns the slot number (i.e. BINDKEY) of the weapon the player is currently holding, or -1 when the player is holding no weapon at all.

player.ammo(type)

Returns the amount of ammo the player is carrying (not including any ammo inside the clips of weapons). The 'type' parameter is a number in the range 1-16. For more readable code, one of the following names can be used instead:
    • AMMOS.bullets AMMOS.pellets
    • AMMOS.shells AMMOS.nails
    • AMMOS.rockets AMMOS.grenades
    • AMMOS.cells AMMOS.gas

player.ammomax(type)

Returns the maximum amount of ammo the player can carry (not including weapon clips). The 'type' parameter is the same as the player.ammo() function.

player.main_ammo()

Returns the main ammo quantity for the player's current weapon. This is zero for weapons that don't use any ammo (like the FIST). If the weapon has a clip and the SHOWCLIP command (in DDF) is true, then the amount of ammo inside the clip is returned instead. Note that only the primary attack is checked, the secondary attack (if present) will be ignored.

player.ammo_type(ATK)

Returns the ammo type of the player's current weapon for the given attack (primary or secondary). The result is in the range 1-16, or can be 0 for the special case of NOAMMO. The 'ATK' parameter is 1 for the primary attack, 2 for the secondary attack, and is compulsory.

player.ammo_pershot(ATK)

Returns the ammo used up per shot by the current weapon for the given attack (primary or secondary). Same as the AMMOPERSHOT commands in WEAPONS.DDF. The 'ATK' parameter is 1 for the primary attack, 2 for the secondary attack, and is compulsory.

player.clip_ammo(ATK)

Returns the current amount of ammo the clip in the player's current weapon is holding, or zero if the weapon has no clip. The 'ATK' parameter is 1 for the primary attack, 2 for the secondary attack, and is compulsory.

player.clip_size(ATK)

Returns the maximum amount of ammo the clip in the player's current weapon can hold, or zero if the weapon has no clip. The 'ATK' parameter is 1 for the primary attack, 2 for the secondary attack, and is compulsory.

player.clip_is_shared()

Returns true if the player's current weapon is sharing a single clip between primary and secondary attackes (the SHARED_CLIP command).

* Conditions

player.on_ground()

Returns true if player is standing on solid ground.

player.under_water()

Returns true if player is in AIRLESS water and doesn't have the Scuba powerup.

player.is_swimming()

Returns true if player is in swimmable water (i.e. the SWIM sector special).

player.is_jumping()

Returns true if player is jumping.

player.is_crouching()

Returns true if player is crouching.

player.get_side_move()

Returns true if player is strafing from side-to-side.

player.is_attacking()

Returns true if player is firing his weapon (either first or second attack).

player.is_rampaging()

Returns true if player has been firing his weapon for two seconds or more.

player.is_using()

Returns true if player is holding the USE button down.

player.is_grinning()

Returns true if player is grinning (after picking up a weapon).

* Miscellaneous

player.num_players()

Returns the total number of players in the game, including bots.

player.set_who(index)

Sets who the current player is. The 'index' parameter is a small number: 1 for the "main player" on this computer (the person at the keyboard), 2 for the next player in the list, for instance the split-screen player) etc... up to the number of players in the game. All the player query functions described here return their results for the current player.

player.hurt_by()

If the player has been hurt in the last few seconds, this returns a string describing what did the damage. Otherwise this function returns nil. The result is usually "enemy", but could be "friend" for friendly fire. If the player hurt himself with his own damn stupidity then the result is "self", whereas damaging floors and crushers will return "other".

player.hurt_mon()

If the player has been hurt in the last few seconds, this returns the name of the monster or other player. Otherwise this function returns nil.

player.hurt_pain()

If the player was just hurt, this returns the damage amount, otherwise this function returns 0.

player.hurt_dir()

If the player was just hurt, this returns a direction relative to the player where the attacker was: -1 for the left side, +1 for the right side, and 0 for all other cases.

player.hurt_angle()

Like player.hurt_dir(), except this returns the map angle from the player to his attacker. The result is in degrees (ranging from 0 to 359), where East is 0 and North is 90.

player.add_tactile(id, freq, amp)

This function can be called to add a screen-shaking effect to the player's view. The three integers above are explained below. This can be used in conjunction with others like player.hurt_dir(), or RTS commands that call COAL directly.
  • The following integers for player.add_tactile are as described:
    • id: the player whom is receiving the shake (integer)
    • freq: the frequency at which the screen shakes at (integer)
    • amp: the intensity at which the screen shakes (integer)

* CAMERA MODULE

cam.set_vert_bob(f)

Sets the Player bobbing. The parameter flags above are as follows:
  • Parameter is a Float for controlling the vertical bobbing. This was previously encapsulated in DDF where it is now controlled via COAL.
  • The default value is 1.2 - setting it to 0.0 will completely disable bobbing.

cam.set_roll_bob(f)

Parameter is a Float for customizing camera rolling. Note that this can be combined with set_vert_bob, OR can be called from other functions (such as being combined with player.get_side_move() or combined with player.hurt_pain()).
By Default the camera set_roll_bob amount is 0.0.

CAMERA-MAN MODULE

The new Camera-Man system is in reality a COAL module, and can be completely configured through COAL. However, due to its complexity and the fact that the format is not in the QC extension (which is actually done with Console Commands), it has its own article and how-to's. You can visit that guide by clicking on this sentence.