Contents

Introduction

Usage

Setup

This section is for those who are unfamiliar with using Lua scripts in solo or network games. Skip ahead to Playing if you already know how to do this.

  1. Place the Lua script (a file called Headshots v1.0.lua) somewhere you can easily access from the Aleph One interface. Do not place it in the Scripts or MML folders in your Aleph One directory.
  2. Start Aleph One.
  3. Single-Player
    1. Select Preferences from the main menu.
    2. Select the Environment section of the preferences menu.
    3. Under the Solo Script section, check the Use Solo Script box.
    4. Click on the field next to Script File and navigate to the script, then click on it.
    5. Once back at the Environment Settings screen, click the Accept button.
    6. Start a new game or continue a saved one as usual.
  4. Multi-Player (Co-Operative)
    1. Select Gather Network Game from the main menu.
    2. Under the Net Script section, check the Use Netscript box.
    3. Choose the script by navigating to it and clicking on it.

Playing

It's pretty simple. Shoot something in the head. Maybe you will deal extra damage. The way I've configured the script by default, only players and security BoBs can actually accomplish headshots. A headshot occurs when a pistol bullet collides with a monster at roughly head height. Note that the SMG technically shoots pistol bullets according to the default Infinity physics model. Therefore, headshots are treated the same way whether the bullet came from a pistol or from an SMG. I can't do anything about that. As an added element of fun, I have also made the charged fusion shot capable of causing head shot behavior.

You will know when you accomplish a headshot because the screen will fade a nasty yellow color and you'll hear an accompanying sound effect. Something similar happens if you are the victim of a headshot.

A few types of monster are not susceptible to head shots. Some monsters (and the player counts as a monster) receive different amounts of damage from the default amount, which causes an instant kill.

You should be able to use this script in both cooperative and uncooperative network games. Hopefully, the extra damage, which technically comes from no particular source, does not interfere with scores. Let me know if it does.

If you want to know the exact parameters I've vaguely outlined above, or if you want to change how the script works, see the next section (Customizing).

I have tried to make the headshot behavior as reasonable as possible. There are a few limitations that the current version of Aleph One can't overcome. Among these is specifying the width of a monster's head along with its height. This would be useful for figuring out if the shot was dead-center or if it was glancing, which would in turn allow awkward monsters like the juggernaut to have a more "realistic" head location. I've done my best.

Customizing

As noted above, the settings in this script are based on my own quick assessment of what might work best for Marathon: Infinity. If you are playing a different scenario, or if you simply wish to change these settings, you can edit the script. Even if you are unfamiliar with scripting in Lua, you should be able to follow along based on the comments I've included in the script. These, along with the values I've chosen, appear below for easy reading and navigation.

HEADSHOT_BONUS_DAMAGE

The amount of extra damage that a headshot causes. At present, the amount of damage each projectile deals is not visible to lua scripts, so this can't be a percentage (unless you add your own lookup). For reference, a player at "red" or "1x" shields has 150 points.

Set to zero or below to cause instant death regardless of the monster's starting health.

Set to a value between zero and one to make this a percentage of the monster's base health. For example, 0.75 would cause all monsters to receive damage equal to 75% of their base health. If you want to deal 100% (i.e. probably instantly kill), see above about setting this value to zero or below.

It is possible to override this per monster type in the HEADS_BY_MONSTER_TYPE table.

HEADSHOT_BONUS_DAMAGE = 0
EXCLUDED_VICTIM_MONSTERS_BY_TYPE

The list of monster types that do not receive extra damage from a headshot. The monster type names are in the MonsterTypes section of the lua documentation.

EXCLUDED_VICTIM_MONSTERS_BY_TYPE = {
    -- ticks are all (or no) head.  one-shot kill anyway
    "minor tick",
    "major tick",
    -- drones don't really have heads
    "minor drone",
    "major drone",
    "big minor drone",
    "big major drone",
    "possessed drone",
    -- juggernaut head is just a hood ornament afaik.  also,
    -- juggernaut head is at a horizontal offset from its center.
    -- without being able to account for hit angle, this would allow
    -- hits on its "side" to register as headshots.
    "minor juggernaut",
    "major juggernaut",
}
INCLUDED_PROJECTILES_BY_TYPE

The list of projectile types that do give extra damage via headshot, assuming the victim monster is not of a type in the table EXCLUDED_VICTIM_MONSTERS_BY_TYPE and the aggressor monster is in the table INCLUDED_AGGRESSOR_MONSTERS_BY_TYPE. The projectile type names are in the ProjectileTypes section of the lua documentation.

INCLUDED_PROJECTILES_BY_TYPE = {
    "pistol bullet", -- note: used in both pistol and SMG
    "fusion bolt major",
}
INCLUDED_AGGRESSOR_MONSTERS_BY_TYPE

The list of monster types whose projectiles do give extra damage via headshot, assuming the victim monster is not of a type in the table EXCLUDED_VICTIM_MONSTERS_BY_TYPE and the projectile that hit the monster is in INCLUDED_PROJECTILES_BY_TYPE. The monster type names are in the MonsterTypes section of the lua documentation.

INCLUDED_AGGRESSOR_MONSTERS_BY_TYPE = {
    "player",
    "security bob",
}
DEFAULT_HEAD_HEIGHT_PERCENT

The percentage of a monster between its lowest point and where its head starts. Everything above this counts as the head. Might be weird on juggernauts and similar monsters. See below for a solution.

DEFAULT_HEAD_HEIGHT_PERCENT = 0.89
PLAYER_SHOOTER_SOUND

The sound to play for a player who just made a headshot. Set to nil or empty string if you want no sound. Sounds are in the Sounds section of the documentation.

PLAYER_SHOOTER_SOUND = "puzzle switch"
PLAYER_SHOOTER_FADE

The fader to play for a player who just made a headshot. Set to nil or empty string if you want no fader. Faders are in the FaderTypes section of the documentation.

PLAYER_SHOOTER_FADE = "dodge yellow"
PLAYER_VICTIM_SOUND

The sound to play for a player whose head was just shot. Set to nil or empty string if you want no sound. Sounds are in the Sounds section of the documentation.

PLAYER_VICTIM_SOUND = "empty gun"
PLAYER_VICTIM_FADE

The fader to play for a player whose head was just shot. Set to nil or empty string if you want no fader. Faders are in the FaderTypes section of the documentation.

PLAYER_VICTIM_FADE = "dodge purple"
HEADS_BY_MONSTER_TYPE

A table listing the lowest/highest point of a monster's head vs. the monster's lowest point by monster type. You can store this in absolute world units (min_absolute/max_absolute) or you can store it in percentages (min_percent/max_percent).

If you do not populate a max value, the script assumes that everything higher than the head start includes the head. If you want the head to start at the monster's lowest point, set the min to 0; the max determines where the top of the head is.

You can override the value of HEADSHOT_BONUS_DAMAGE per monster type by populating damage in following similar guidelines.

I have included some sample entries below. The monster type names are in the MonsterTypes section of the lua documentation.

HEADS_BY_MONSTER_TYPE = {
    -- player is harder to hit
    ["player"] = { min_absolute = 0.85, damage = 100 },
    -- troopers have helmets
    ["minor trooper"] = { damage = 0.50 },
    ["major trooper"] = { damage = 0.50 },
    -- compilers have metal heads
    ["minor compiler"] = { damage = 0.40 },
    ["major compiler"] = { damage = 0.40 },
    ["minor invisible compiler"] = { damage = 0.40 },
    ["major invisible compiler"] = { damage = 0.40 },
    -- fuck these guys
    ["minor enforcer"] = { min_percent = 0.80, damage = 1000 },
    ["major enforcer"] = { min_percent = 0.80, damage = 1000 },
    -- hunters have thick skulls(?)
    ["minor hunter" ] = { damage = 0.45 },
    ["major hunter" ] = { damage = 0.45 },
}

Credits and Derivative Works

I would like to thank every person who tried Marathon for five seconds and thought "this game would be perfect if only it was like every other game and had headshots"—and then bugged other players to create a script for them. You got your wish after 20 years. Now you can be happy.

If you wish to incorporate this script into your own work, be it a standalone script, a plugin, a scenario, etc., feel free to do so. I ask that you please give me credit with inline notes in the script, in whatever credits section your work's readme/manual has, or both.

Changelog

2024-04-19: v1.0

First version. Customizable through specific variables. Hopefully the last version.