Skip to content

Commit

Permalink
Rewrites & fixes of the variety of things
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonardoTheMutant committed Oct 4, 2024
1 parent bc29734 commit 7647cbd
Show file tree
Hide file tree
Showing 25 changed files with 105 additions and 494 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Murder Mystery gametype add-on for [Sonic Robo Blast 2](https://www.srb2.org)

A port of the popular multiplayer game in SRB2

***Not to be confused with the [Saxashitter's Murder Mystery](https://github.com/Saxashitter/murder-mystery) add-on, which tries to acomplish the same goal but is an entirely different project***

<a href="https://github.com/LeonardoTheMutant/SRB2-Murder-Mystery/graphs/contributors" alt="Contributors">
<img src="https://img.shields.io/github/contributors/LeonardoTheMutant/SRB2-Murder-Mystery"></a>
<a href="https://github.com/LeonardoTheMutant/SRB2-Murder-Mystery/pulse" alt="Activity">
Expand All @@ -15,7 +17,7 @@ A port of the popular multiplayer game in SRB2

## How to build your **MurderMystery.PK3** from this repository

***Please note that MAKE scripts generate the Debug (Test) versions of the Add-On and it is highly recomended to HOST THESE BUILDS ONLY ON PRIVATE SERVERS.***
**Please note that MAKE scripts generate the Debug (Test) versions of the Add-On and it is highly recomended to HOST THESE BUILDS ONLY ON PRIVATE SERVERS.**
Release versions of the Add-On, which are tested and approved to be showcased publicly, are available in **Releases**

### If you have `git` installed
Expand Down Expand Up @@ -61,4 +63,4 @@ All contributions would be greatly appreciated especially maps, music, graphics,
1. Modifying the source code you are having right now
2. Making a **Custom Language File** from the [template](TEMPLATES/customlang.lua) and then adding it as a regular ADD-ON together with MM (Main Add-On has to be loaded first)

## Please read the [READ_BEFORE_HOSTING.TXT](SRC/READ_BEFORE_HOSTING.TXT) file before starting the server with Murder Mystery add-on for the correct host setup and details
### Also check out the [Saxashitter's Murder Mystery](https://github.com/Saxashitter/murder-mystery) project
32 changes: 16 additions & 16 deletions SRC/DEV_DOCS/List_of_Func_and_Const.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

---

This document contains the description of some important functions and constants which are used in Murder Mystery's LUA source code.
This document contains the description of some important and globaly defined functions as well as constants which are used in Murder Mystery's LUA source code.

## Table of Contents

Expand All @@ -23,15 +23,15 @@ This document contains the description of some important functions and constants
- Win reasons (`WIN_*`)
- Time Zones (`TIMEZONE_*`)
- Time Warp (`TWS_*`)
- The core `MM` table
- [The core `MM` table](#the-core-mm-table)

# Functions

## `INIT.LUA`

### Customisation API

There are two customization functions in initialization script that allow you create your own mods for the Murder Mystery gametype. Both functions are defined in <code>MM</code> table inside the code.
There is a customization function defined in <code>MM</code> table inside the code which allows you to create your own "sub-mods" for the Murder Mystery gametype.

| Name | Description |
| --- | --- |
Expand All @@ -43,23 +43,23 @@ There is a dedicated LUA script that contains the code of some MM functions. Som

### `GAME.LUA`

These are the functions that are used in [`GAME.LUA`](../LUA/MAIN//GAME.LUA):
These are the functions that are used in [`GAME.LUA`](../LUA/MAIN//GAME.LUA) (the main game logic script):

| Name | Return value | Description |
| --- | --- | --- |
| <code>**MM_AssignRoles**()</code> | nil | The main role assigner function. Called durring `MapLoad` hook and when another player joins the game with a single player online.<br>Iterates through all players and makes them **Murderers**, **Sheriffs**, **Innocent** randomly. Then it tells the assigned role to each player personally.<br>If the splitscreen game is loaded it switches the game to MATCH and prints a warning message. |
| <code>**MM_GetRoleMultiplier**()</code> | nil | Get the number of role duplicates. It is primarily used in <code>**MM_AssignRoles()**</code> to understand how many players should share **Murderer** or **Sheriff** role. It is also used to adjust the map timelimit when a level starts. |
| <code>**MM_ChatprintGlobal**(*string* message_id, * var)</code> | nil | Works similarly to <code>**chatprint**()</code> but prints the message in player's language. Unlike <code>**chatprint**()</code> this function can print only the messages available in the multilingual <code>MM.text</code> table. Possible values for the arguments of this function are shown below in the Constants section (`WIN_*` constants). |
| <code>**MM_TeammatesCount**(*player_t* player)</code> | *int* | Returns the number of teammates the player has.<br>*Note:* Do not use this function for Innocents as they are technically not in a team |
| <code>**MM_AreTeammates**(*player_t* player1, *player_t* player2)</code> | *boolean* | Compares if <code>player1</code> and <codeplayer2</code> are in the same team (Murderer team, Sheriff/Hero team). Note that for Innocents this functions returns `false` (such team does not exist in the game). |
| <code>**MM_KillPlayerByPlayer**(*mobj_t* player, [*mobj_t* attacker])</code> | nil | Make <code>player</code> *DEAD*. <code>attacker</code> is a player who killed the <code>player</code>, it is used to print the killer's name for the <code>player</code>. If the <code>attacker</code> is not specified the killer's name is `"your stupidity"` instead.<br>*Note:* Both <code>player</code> and <code>attacker</code> arguments have to be `mobj_t`! |
| <code>**MM_KillPlayerByHazard**(*mobj_t* player, [*bool* spawnBody])</code> | nil | Similar to <code>MM_KillPlayer()</code> but used to kill by a hazard. Set <code>spawnBody</code> to `true` to also spawn the dead body (does not spawn one by default).<br>*Note:* <code>player</code> argument has to be `mobj_t`! |
| <code>**MM_AssignRoles**()</code> | nil | The main role assigner function. Called durring `MapLoad` hook and when another player joins the game with a single player online.<br>Iterates through all players and gives them the role of **Murderer**, **Sheriff** or **Innocent** randomly. Then it tells the assigned role to each player personally. |
| <code>**MM_GetRoleMultiplier**()</code> | nil | Get the number of the required role duplicates. It is primarily used in <code>**MM_AssignRoles()**</code> to understand how many players should share **Murderer** or **Sheriff** roles. It is also used to adjust the map timelimit when a level starts. |
| <code>**MM_ChatprintGlobal**(*string* message_id, * var)</code> | nil | Works similarly to <code>**chatprint**()</code> but prints the message in player's language. Unlike <code>**chatprint**()</code> this function can print only the messages available in the multilingual <code>MM.text</code> table. Possible values for the arguments of this function are shown below in the [Constants](#constants) section (`WIN_*` constants). |
| <code>**MM_TeammatesCount**(*player_t* player)</code> | *int* | Returns the number of teammates the player has.<br>*Note:* Do not use this function for Innocents as they are technically not in a team. |
| <code>**MM_AreTeammates**(*player_t* player1, *player_t* player2)</code> | *boolean* | Compares if <code>player1</code> and <code>player2</code> are in the same team (Murderer team, Sheriff/Hero team).<br>*Note*: For Innocents this functions returns `false` because such team does not exist in the game. |
| <code>**MM_KillPlayerByPlayer**(*mobj_t* player, [*mobj_t* attacker])</code> | nil | Kill <code>player</code> by making him *DEAD*. <code>attacker</code> is a player who killed the <code>player</code>, it is used to print the killer's name for the <code>player</code>. If the <code>attacker</code> is not specified the killer's name is `"your stupidity"` instead.<br>*Note:* Both <code>player</code> and <code>attacker</code> arguments have to be `mobj_t`! |
| <code>**MM_KillPlayerByHazard**(*mobj_t* player, [*bool* spawnBody])</code> | nil | Similar to <code>MM_KillPlayer()</code> but is used to kill by the level hazard (crusher, death pit, drown). Set <code>spawnBody</code> to `true` to also spawn the dead body (does not spawn one by default).<br>*Note:* <code>player</code> argument has to be `mobj_t`! |
| <code>**MM_HitTeammate**(*player_t* victim, *player_t* attacker)</code> | nil | Make <code>victim</code> being hit by a teammate <code>attacker</code>. This function prints personal messages to both <code>victim</code> and <code>attacker</code> to let them know that they are in one team and they should not hit each other next time. |
| <code>**MM_EndRound**(*int* win, * var, [*int* winreason])</code> | nil | Finish the round. <code>w</code> specifies the winner, possible values are: 0 - Tie, 1 - Murderers, 2 - Civilians (Sheriffs, Heros & Innocents). <code>winreason</code> is optional but can be one of the `WIN_*` constants. |
| <code>**MM_CheckShowdown**()</code> | nil | A function to check if the Showdown Duel music can be started or not. |
| <code>**MM_StartShowdownMusic**()</code> | *boolean* | Starts one of the Showdown Duel tunes and returns `true` value if there are no Innocents in the game.|
| <code>**MM_SetRandomInnoAs**(*int* role, *int* message)</code> | nil | Similar to <code>**MM_AssignRoles()**</code> but works for only for Innocents. In some gameplay situations, there has to be a replacement of the player with some important <code>role</code> and this function selects random Innocent to give the <code>role</code> to it. Any of the `ROLE_*` constants (except `ROLE_INNOCENT`) can act as a possible value for the <code>role</code> argument.<br>Possible values for <code>Message</code>:<table><tr><th>Value</th><th>Message</th></tr><tr><td>1</td><td>*"You became a Murderer"*</td></tr><tr><td>2</td><td>*"You became a Sheriff"*</td></tr><tr><td>3</td><td>*"You became a Hero"*</td></tr><tr><td>4</td><td>*"You were rewarded the role of Hero"*</td></tr></table> |
| <code>**MM_GetMMSHREMLinterval**(*int* distance)</code> | *int* | Get the interval time in tics between each radar beep depending on the <code>dist</code> distance. Used for Innocents' Sheriff Emerald radar. |
| <code>**MM_IsTimelineCorrect**(*int* timezone1, *int* timezone2)</code> | *boolean* | Check if the events from <code>timezone1</code> can happen in <code>timezone2</code>. For example, if the event has happened in the *Past* the consequence of this event can be seen in the *Present*, *Bad Future*, and *Good Future*. But the event from the *Present*, *Bad Future*, or the *Good Future* cannot be seen in the *Past* (because it happened in the future). For easier understanding imagine a one-way road (timeline): `Past > Present > Bad/Good Future`<br>*Note:* Both of the arguments are **TIMEZONE_*** constants. |
| <code>**MM_IsTimelineCorrect**(*int* timezone1, *int* timezone2)</code> | *boolean* | Check if the events from <code>timezone1</code> can happen in <code>timezone2</code>. For example, if the event has happened in the *Past* the consequence of this event can be seen in the *Present*, *Bad Future*, and *Good Future*. But the event from the *Present*, *Bad Future*, or the *Good Future* cannot be seen in the *Past* (because it happened in the future). For easier understanding imagine a one-way road (timeline): `Past > Present > Bad/Good Future`<br>*Note:* Both of the arguments are `TIMEZONE_*` constants. |
| <code>**MM_GetText**(*string* language, *string* line, [*string*/*int* parameter])</code> | *string* | A safe way to extract the strings from the global MM Text Table (<code>MM.text</code>) without crashing/erroring LUA. When all 3 arguments are given this function returns the value at <code>MM.text[language][line][parameter]</code>. If only <code>language</code> and <code>line</code> arguments are given the function returns the value from <code>MM.text[language][line]</code>. If the text is not found or the arguments are invalid a blank string is returned instead.<br>*Note:* Even if the expected return value is table, this function will return an empty string!<br>*In Debug Builds:* If the text can not be reached or invalid arguments are given an error is triggered with the details. |
| <code>**MM_PunishPlayer**(*player_t* player, *string* message, [*boolean* ban?])</code> | *nil* | Kick player from the game or ban if <code>ban?</code> is set. <code>message</code> is the kick/ban message.<br>*Note:* If the player who is going to be punished is the host, SRB2 automatically closes for this player, causing the server to shut down. |
| <code>**MM_WeaponConfigFlags**(*int* role, *int* flags)</code> | *int* | Returns the result of the Logical AND operation between Weapon Configuration CVAR (`mm_wepconfig`) and <code>flags</code> argument for the given <code>role</code>. |
Expand Down Expand Up @@ -125,7 +125,7 @@ Here is the full list of MM constants:
| `ROLE_INNOCENT` | 3 | Innocent |
| `ROLE_HERO` | 4 | Hero |

### Game messages
### Game messages (for <code>MM_ChatprintGlobal()</code>)

| `message_id` | Possible value(s) for `var` | Description |
| --- | --- | --- |
Expand Down Expand Up @@ -181,14 +181,14 @@ The constants for the configurations flag checks. Useful only with the `mm_wepco
| `WEPCFG_REDONLY` | 1 | Only the Weapon Slot 1 is usable (Red/Infinite rings. Knife)
| `WEPCFG_DISABLERED` | 2 | Weapon Slot 1 is occupied by the Knife only |

### The core table
# The core `MM` table

The description of each value in the `MM` table. The `MM` constant itself is defined in [INIT.LUA](../INIT.LUA)

| Name | Type | Description | Example value |
| --- | --- | --- | --- |
| <code>version</code> | *string* | Version number of the add-on | <code>"1.0-ALPHA"</code> |
| <code>devbuild</code> | *boolean* | Mark add-on build as a *Developer Build*, when set to <code>true</code> it enables the *Debug Mode* in the add-on | <code>true</code> |
| <code>debug</code> | *boolean* | Enable/Disable the add-on's *Debug Mode* functionality<br>*Note:* **The add-on must boot with this variable set to <code>true</code> to use the Debug in any form.** | <code>true</code> |
| <code>releasedate</code> | *string* | The release date of the add-on version. | <code>"August 19th 2024"</code> |
| <code>text</code> | *table* | Collection of all text used in **Murder Mystery** with all translations. This variable is **netsynced** | *See [the template file](https://github.com/LeonardoTheMutant/SRB2-Murder-Mystery/blob/main/TEMPLATES/customlang.lua)* |
| <code>RoleColor</code> | *string[5]* | The text colors for roles | *See [<code>INIT.LUA</code>](../INIT.LUA)* |
Expand Down
8 changes: 5 additions & 3 deletions SRC/FOR_DEVELOPERS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ But for now let me introduce you to our file structure first:

MM_MurderMystery_v1.0-ALPHA.pk3
|
+-INIT.LUA - Init, freeslot, add-on PK3 properties (such as devbuild or not), and some objects
+-INIT.LUA - Init, freeslot, add-on PK3 properties, and some objects
|
+-DEV_DOCS-\
| +-List_of_Func_and_Const.md - Documentation of functions and constants
Expand All @@ -19,7 +19,9 @@ MM_MurderMystery_v1.0-ALPHA.pk3
| +-LEVELS-\
| | +-MAPK0.LUA - Code for Eggman's Bedroom door (Abandoned Shelter)
| | +-MAPK7.LUA - "The truth ray" and lab doors (Sky Mesa)
| | \-MAPK8.LUA - Definition of the MT_8BALL object (8-Ball Hotel)
| | +-MAPK8.LUA - Definition of the MT_8BALL object (8-Ball Hotel)
| | +-MAPKB.LUA - Door and tower lift logic (Myst Island)
| | \-MAPKC.LUA - Granfather clock strikes (Stauf's Mansion)
| |
| +-MINIGAMES-\
| | +-HUD_MINIGAMES.LUA - Dedicated HUD renderer for the minigames
Expand Down Expand Up @@ -57,4 +59,4 @@ Have a nice modding!
LeonardoTheMutant


...oh you need the GitHub link? It's listed in Readme.txt, just look here as well :]
...oh you need the GitHub link? It's listed in Readme.txt, just look here as well :]
6 changes: 3 additions & 3 deletions SRC/INIT.LUA
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ if (MM)
end
rawset(_G, "MM", {
version = "1.0-ALPHA", --string, VERSION NUMBER
devbuild = true, --boolean, if set to true, enable the debug functionality in MM
debug = true, --boolean, if set to true, enable the debug functionality in MM
releasedate = "not released yet", --string, meant to contain the day of release
RoleColor = {
"\x85", --Murderer
Expand Down Expand Up @@ -197,7 +197,7 @@ mobjinfo[MT_MMKNIFE]={
states[S_MMSTEP]={
sprite = SPR_STEPA0,
frame = FF_SEMIBRIGHT|FF_FLOORSPRITE|A,
tics = 700,
tics = 700, --20 seconds
nextstate = S_NULL
}

Expand All @@ -220,7 +220,7 @@ sfxinfo[sfx_mmdth7].caption = "Moonwalker"
--Script files init
dofile("TEXT.LUA")
dofile("FUNCTIONS.LUA")
if (MM.devbuild) dofile("DEBUG.LUA") end
if (MM.debug) dofile("DEBUG.LUA") end
dofile("GAME.LUA")
dofile("WEAPONS.LUA")
if (not isdedicatedserver) dofile("HUD.LUA") end
Expand Down
2 changes: 1 addition & 1 deletion SRC/LUA/ABILITIES.LUA
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ addHook("PlayerThink", function(p)
CONS_Printf(p, "The Administrator has disabled the use of Custom Skins in the current MM game")
R_SetPlayerSkin(p, "sonic")
end
end)
end)
4 changes: 2 additions & 2 deletions SRC/LUA/CCMD.LUA
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ local function helpCMD(p, page)
CONS_Printf(p, "\x87MM_WEPCONFIG\x80 - Set how weapons work for each role (except "..MM.RoleColor[ROLE_INNOCENT].."Innocent\x80) during the normal gameplay and the Showdown Duel")
CONS_Printf(p, "\x87MM_WEPINNO\x80 - Enable/Disable weapons for "..MM.RoleColor[ROLE_INNOCENT].."Innocents\x80. Setting this CVAR to\x81 1\x80 will let them use Red Ring + Knife,\x82 2\x80 forces to Knife-only. In both situations "..MM.RoleColor[ROLE_INNOCENT].."Innocents\x80 need to have 100 rings to make one shot")
end
if (MM.devbuild)
if (MM.debug)
CONS_Printf(p, "\n\x82".."DEVELOPER DEBUG COMMANDS")
CONS_Printf(p, "\x87MMPLAYER\x80 - Change player state/role")
CONS_Printf(p, "\x87MMEXITLEVEL\x80 - Force round end with the winner")
Expand Down Expand Up @@ -271,4 +271,4 @@ hud.add(function(v, p)

V_DrawStrASCII(v, 0, 192, charset, MM_GetText(consoleplayer.mmlang, "MMHELP_CMD", 1), V_SNAPTOBOTTOM|V_SNAPTOLEFT, true)
V_DrawStrASCII(v, 0, 196, charset, MM_GetText(consoleplayer.mmlang, "MMHELP_CMD", 2), V_SNAPTOBOTTOM|V_SNAPTOLEFT, true)
end, "game")
end, "game")
7 changes: 4 additions & 3 deletions SRC/LUA/DEBUG.LUA
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
--Code by LeonardoTheMutant
--
--Murder Mystery Debug commands
--This script is executes on startup if MM.devbuild is set to true
--This script is executes on startup if MM.debug is set to true
--I keep this minimalistic so don't wonder why code is unreadable there

local shwdwn_music={"S2MSBS","S2GGBS","EWJ2TN","DRMBM2","STORMR","UNDYNE","SSBLSD"}
Expand Down Expand Up @@ -63,7 +63,8 @@ COM_AddCommand("mmcharset",function(p, set) --Draw all characters from the Exten
p.debugdrawer=set
p.debugcolor=0
end)
addHook("PlayerThink",function(p) --MMCHARSET logic
addHook("PlayerThink",function(p) --MMCHARSET and DebugToggle logic
if (p.cmd.buttons & BT_CUSTOM1) MM.debug = not $ end
if not p.debugdrawer return end
if (p.cmd.buttons&BT_SPIN)
p.debugdrawer=nil
Expand Down Expand Up @@ -91,4 +92,4 @@ hud.add(function(v, p) --MMCHARSET render
end
v.drawString(0,184,"Color: "..p.debugcolor)
v.drawString(0,192,"JUMP - next color, SPIN - exit")
end,"game")
end,"game")
2 changes: 1 addition & 1 deletion SRC/LUA/FOOTSTEPS.LUA
Original file line number Diff line number Diff line change
Expand Up @@ -2421,4 +2421,4 @@ end)

--addHook("MobjThinker", function(mo)
-- if (not P_IsObjectOnGround(mo)) then P_KillMobj(mo) end
--end, MT_MMSTEP)
--end, MT_MMSTEP)
Loading

0 comments on commit 7647cbd

Please sign in to comment.