-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 850b37f
Showing
9 changed files
with
530 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.sentry-native | ||
*.log | ||
*.exe | ||
*.toml | ||
|
||
# Can't delete it right now so just ignore it.. | ||
/Server/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# BeamMP-FloodMod | ||
|
||
This is a resource for BeamMP that adds a flood to all sorts of maps (as long as they have an ocean). | ||
|
||
## Installation | ||
1. Download the latest release from the [releases page](https://github.com/vulcan-dev/BeamMP-FloodMod/releases) | ||
2. Copy `floodBeamMP.zip` into your `BeamMP-Server/Resources/Client` folder | ||
3. Copy `Flood` into your `BeamMP-Server/Resources/Server` folder | ||
|
||
## Commands | ||
- `/flood_start` - Starts the flood | ||
- `/flood_stop` - Stops the flood | ||
- `/flood_reset` - Resets the height and disables the flood | ||
- `/flood_setLevel <level>` - Sets the flood level/height | ||
- `/flood_setSpeed <speed>` - Sets the flood speed (0.001 is default) | ||
- `/flood_setDecrease <decrease>` - Makes the water level decrease instead of increase | ||
- `/flood_setLimit <limit>` - Sets the flood height limit | ||
- `/flood_setLimitEnabled <enabled>` - Enables or disables the flood height limit | ||
- `/flood_printSettings` - Prints the current flood settings |
Binary file not shown.
125 changes: 125 additions & 0 deletions
125
Resources/Client/floodBeamMP/lua/ge/extensions/floodBeamMP.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
local M = {} | ||
|
||
local allWater = {} | ||
local ocean = nil | ||
local calledOnInit = false -- For calling "E_OnInitialize" only once when BeamMP's experimental "Disable lua reloading when bla bla bla" is enabled | ||
|
||
local function findObject(objectName, className) | ||
local obj = scenetree.findObject(objectName) | ||
if obj then return obj end | ||
if not className then return nil end | ||
|
||
local objects = scenetree.findClassObjects(className) | ||
for _, name in pairs(objects) do | ||
local object = scenetree.findObject(name) | ||
if string.find(name, objectName) then return object end | ||
end | ||
|
||
return | ||
end | ||
|
||
local function tableToMatrix(tbl) | ||
local mat = MatrixF(true) | ||
mat:setColumn(0, tbl.c0) | ||
mat:setColumn(1, tbl.c1) | ||
mat:setColumn(2, tbl.c2) | ||
mat:setColumn(3, tbl.c3) | ||
return mat | ||
end | ||
|
||
local function getOcean() | ||
local waterPlane = findObject("Ocean", "WaterPlane") | ||
if waterPlane then | ||
initialWaterPosition = waterPlane.position | ||
end | ||
|
||
return waterPlane | ||
end | ||
|
||
local hiddenWater = {} | ||
|
||
local function getWaterLevel() | ||
if not ocean then return nil end | ||
return ocean.position:getColumn(3).z | ||
end | ||
|
||
local function getAllWater() | ||
local water = {} | ||
local toSearch = { | ||
"River", | ||
"WaterBlock" | ||
} | ||
|
||
for _, name in pairs(toSearch) do | ||
local objects = scenetree.findClassObjects(name) | ||
for _, id in pairs(objects) do | ||
if not tonumber(id) then | ||
local source = scenetree.findObject(id) | ||
if source then | ||
table.insert(water, source) | ||
end | ||
else | ||
local source = scenetree.findObjectById(tonumber(id)) | ||
if source then | ||
table.insert(water, source) | ||
end | ||
end | ||
end | ||
end | ||
|
||
return water | ||
end | ||
|
||
local function handleWaterSources() | ||
local height = getWaterLevel() | ||
|
||
for id, water in pairs(allWater) do | ||
local waterHeight = water.position:getColumn(3).z | ||
if M.hideCoveredWater and not hiddenWater[id] and waterHeight < height then | ||
water.isRenderEnabled = false | ||
hiddenWater[id] = true | ||
elseif waterHeight > height and hiddenWater[id] then | ||
water.isRenderEnabled = true | ||
hiddenWater[id] = false | ||
elseif not M.hideCoveredWater and hiddenWater[id] then | ||
water.isRenderEnabled = true | ||
hiddenWater[id] = false | ||
end | ||
end | ||
end | ||
|
||
AddEventHandler("E_OnPlayerLoaded", function() | ||
allWater = getAllWater() | ||
ocean = getOcean() | ||
|
||
if calledOnInit then return end | ||
TriggerServerEvent("E_OnInitiliaze", tostring(getWaterLevel())) | ||
calledOnInit = true | ||
end) | ||
|
||
AddEventHandler("E_SetWaterLevel", function(level) | ||
level = tonumber(level) or nil | ||
if not level then log("W", "setWaterLevel", "level is nil") return end | ||
if not ocean then log("W", "setWaterLevel", "ocean is nil") return end | ||
local c3 = ocean.position:getColumn(3) | ||
ocean.position = tableToMatrix({ | ||
c0 = ocean.position:getColumn(0), | ||
c1 = ocean.position:getColumn(1), | ||
c2 = ocean.position:getColumn(2), | ||
c3 = vec3(c3.x, c3.y, level) | ||
}) | ||
|
||
handleWaterSources() -- Hides/Shows water sources depending on the ocean level | ||
end) | ||
|
||
AddEventHandler("E_SendLua", function(luaStr) | ||
local f, err = loadstring(luaStr) | ||
if not f then | ||
log("E", "E_SendLua", "Error loading lua string: " .. err) | ||
return | ||
end | ||
end) | ||
|
||
M.hideCoveredWater = hideCoveredWater | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
load("floodBeamMP") | ||
registerCoreModule("floodBeamMP") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
require("multiplayer") | ||
|
||
local M = {} | ||
|
||
M.options = { | ||
oceanLevel = 0.0, | ||
floodSpeed = 0.001, | ||
limit = 0.0, | ||
limitEnabled = false, | ||
enabled = false, | ||
decrease = false | ||
} | ||
|
||
M.isOceanValid = false | ||
M.initialLevel = 0.0 | ||
M.commands = {} | ||
|
||
local invalidCount = 0 | ||
|
||
function onPlayerJoin(pid) | ||
local success = MP.TriggerClientEvent(pid, "E_OnPlayerLoaded", "") | ||
if not success then | ||
print("Failed to send \"E_OnPlayerLoaded\" to " .. pid) | ||
end | ||
end | ||
|
||
function onInit() | ||
MP.CancelEventTimer("ET_Update") | ||
|
||
for pid, player in pairs(MP.GetPlayers()) do | ||
onPlayerJoin(pid) | ||
end | ||
end | ||
|
||
local function setWaterLevel(level) | ||
if not M.isOceanValid then | ||
print("setWaterLevel: ocean is nil") | ||
return | ||
end | ||
|
||
MP.TriggerClientEvent(-1, "E_SetWaterLevel", tostring(level)) | ||
end | ||
|
||
function T_Update() | ||
if not M.isOceanValid or not M.options.enabled then return end | ||
|
||
local level = M.options.oceanLevel | ||
local speed = M.options.floodSpeed | ||
local limit = M.options.limit | ||
local limitEnabled = M.options.limitEnabled | ||
local decrease = M.options.decrease | ||
|
||
-- Check if we can change the level | ||
local canChange = true | ||
if limitEnabled then | ||
if decrease then | ||
if level - speed < limit then | ||
canChange = false | ||
end | ||
else | ||
if level + speed > limit then | ||
canChange = false | ||
end | ||
end | ||
end | ||
|
||
if canChange then | ||
if decrease then | ||
level = level - speed | ||
else | ||
level = level + speed | ||
end | ||
end | ||
|
||
M.options.oceanLevel = level | ||
setWaterLevel(level) | ||
end | ||
|
||
function E_OnInitialize(pid, waterLevel) | ||
waterLevel = tonumber(waterLevel) or nil | ||
|
||
-- Make sure the level has an ocean, we use "invalidCount" to make sure it's not just 1 player that doesn't have an ocean | ||
if not waterLevel and invalidCount < 2 then | ||
print("E_OnInitialize: waterLevel for player " .. GetPlayerName(pid) .. " is nil") | ||
invalidCount = invalidCount + 1 | ||
return | ||
elseif not waterLevel and invalidCount >= 2 then | ||
print("This map doesn't have an ocean, disabling flood") | ||
M.isOceanValid = false | ||
return | ||
end | ||
|
||
M.isOceanValid = true | ||
if M.initialLevel == 0.0 then | ||
print("Setting initial water level to " .. waterLevel) | ||
M.initialLevel = waterLevel -- We sadly have to rely on the client 😅🔫 | ||
end | ||
end | ||
|
||
M.commands["start"] = function(pid) | ||
if not M.isOceanValid then | ||
MP.hSendChatMessage(pid, "This map doesn't have an ocean, unable to flood") | ||
return | ||
end | ||
|
||
if M.options.enabled then | ||
MP.hSendChatMessage(pid, "Flood has already started") | ||
return | ||
end | ||
|
||
M.options.enabled = true | ||
if M.options.oceanLevel == 0.0 then | ||
M.options.oceanLevel = M.initialLevel | ||
end | ||
|
||
MP.CreateEventTimer("ET_Update", 25, MP.CallStrategy.Precise) | ||
|
||
MP.hSendChatMessage(-1, "A flood has started!") | ||
end | ||
|
||
M.commands["stop"] = function(pid) | ||
if not M.options.enabled then | ||
MP.hSendChatMessage(pid, "Flood is already stopped") | ||
return | ||
end | ||
|
||
MP.CancelEventTimer("ET_Update") | ||
M.options.enabled = false | ||
MP.hSendChatMessage(-1, "The flood has stopped!") | ||
end | ||
|
||
M.commands["reset"] = function(pid) | ||
if not M.isOceanValid then | ||
MP.hSendChatMessage(pid, "This map doesn't have an ocean, unable to flood") | ||
return | ||
end | ||
|
||
MP.CancelEventTimer("ET_Update") | ||
M.options.enabled = false | ||
M.options.oceanLevel = M.initialLevel | ||
setWaterLevel(M.initialLevel) | ||
end | ||
|
||
M.commands["setLevel"] = function(pid, level) | ||
level = tonumber(level) or nil | ||
if not level then | ||
MP.hSendChatMessage(pid, "Invalid level") | ||
return | ||
end | ||
|
||
if not M.isOceanValid then | ||
MP.hSendChatMessage(pid, "This map doesn't have an ocean, unable to flood") | ||
return | ||
end | ||
|
||
M.options.oceanLevel = level | ||
setWaterLevel(level) | ||
MP.hSendChatMessage(pid, "Set water level to " .. level) | ||
end | ||
|
||
M.commands["setSpeed"] = function(pid, speed) | ||
speed = tonumber(speed) or nil | ||
if not speed then | ||
MP.hSendChatMessage(pid, "Invalid speed") | ||
return | ||
end | ||
|
||
M.options.floodSpeed = speed | ||
MP.hSendChatMessage(pid, "Set flood speed to " .. speed) | ||
end | ||
|
||
M.commands["setLimit"] = function(pid, limit) | ||
limit = tonumber(limit) or nil | ||
if not limit then | ||
MP.hSendChatMessage(pid, "Invalid limit") | ||
return | ||
end | ||
|
||
M.options.limit = limit | ||
MP.hSendChatMessage(pid, "Set flood limit to " .. limit) | ||
end | ||
|
||
M.commands["setLimitEnabled"] = function(pid, enabled) | ||
print("flood_setLimitEnabled: " .. enabled) | ||
if string.lower(enabled) == "true" or enabled == "1" then | ||
enabled = true | ||
elseif string.lower(enabled) == "false" or enabled == "0" then | ||
enabled = false | ||
else | ||
MP.hSendChatMessage(pid, "Please use true/false or 1/0") | ||
return | ||
end | ||
|
||
M.options.limitEnabled = enabled | ||
MP.hSendChatMessage(pid, tostring(enabled and "Enabled" or "Disabled") .. " flood limit") | ||
end | ||
|
||
M.commands["printSettings"] = function(pid) | ||
local message = "Flood settings:\n" | ||
message = message .. "Level: " .. M.options.oceanLevel .. "\n" | ||
message = message .. "Speed: " .. M.options.floodSpeed .. "\n" | ||
message = message .. "Limit: " .. M.options.limit .. "\n" | ||
message = message .. "Limit enabled: " .. tostring(M.options.limitEnabled) .. "\n" | ||
message = message .. "Decrease: " .. tostring(M.options.decrease) .. "\n" | ||
message = message .. "Enabled: " .. tostring(M.options.enabled) .. "\n" | ||
MP.hSendChatMessage(pid, message) | ||
end | ||
|
||
M.commands["setDecrease"] = function(pid, enabled) | ||
if string.lower(enabled) == "true" or enabled == "1" then | ||
enabled = true | ||
elseif string.lower(enabled) == "false" or enabled == "0" then | ||
enabled = false | ||
else | ||
MP.hSendChatMessage(pid, "Please use true/false or 1/0") | ||
return | ||
end | ||
|
||
M.options.decrease = enabled | ||
MP.hSendChatMessage(pid, "Set flood decrease to " .. tostring(enabled)) | ||
end | ||
|
||
MP.RegisterEvent("onInit", "onInit") | ||
MP.RegisterEvent("onPlayerJoin", "onPlayerJoin") | ||
MP.RegisterEvent("E_OnInitiliaze", "E_OnInitialize") | ||
MP.RegisterEvent("ET_Update", "T_Update") | ||
MP.CreateEventTimer("ET_Update", 25, MP.CallStrategy.Precise) | ||
|
||
return M |
Oops, something went wrong.