Add createWaterCannon for script-controlled water jets - #5313
Open
TheCrazy17 wants to merge 4 commits into
Open
Conversation
createWaterCannon/setWaterCannonDirection/setWaterCannonForce/ setWaterCannonEnabled/setWaterCannonModel (plus getters and the OOP WaterCannon class) let a script aim and spray a water jet anywhere, independent of any vehicle. A custom cannon runs on its own native CWaterCannon instance, kept entirely apart from the Firetruck/SWAT tank's own fixed-size array (CWaterCannons::aCannons); CMultiplayerSA_WaterCannons.cpp drives a separate list of these from the same two call sites that already run the vehicle-owned array every frame (CWaterCannons::Update/Render), without ever touching that array. A script spawning many custom cannons can this way never starve a real vehicle's own cannon of a slot, capped at 256 only as a memory/perf sanity limit of its own, not a native constraint. Vehicle water cannons are untouched by this. setWaterCannonModel optionally attaches a plain CClientObject kept aimed with the same heading/pitch-from-direction formula CAutomobile::FireTruckControl/TankControl already use for their own nozzle, since the native jet itself needs no visible part to work.
onClientPedHitByWaterCannon's handler unconditionally cancelled the native push and event whenever it could not resolve a cannon vehicle, which was always the case for a script-owned standalone cannon; it now only asks the water cannon manager whether that particular cannon has knockdown enabled, and createWaterCannon plus setWaterCannonKnockdownEnabled/ isWaterCannonKnockdownEnabled let a script opt back out per cannon.
PushPeds hit-tests from a ped's feet with a tight ~2.24 unit radius, which only a vehicle cannon's sagging arc reliably reaches; a custom cannon aimed at someone's chest can miss every droplet despite visibly spraying them. Widen the radius only for vehicle-less cannons, and fire onClientPedHitByWaterCannon/onClientPlayerHitByWaterCannon from the cannon element itself, matching what a vehicle cannon already gives scripts.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
createWaterCannon, a Lua function that spawns a standalone native water jet (the sameCWaterCannonsystem a Firetruck or SWAT tank uses) at any position, not tied to a vehicle. The jet uses the real native physics, particle spray, and sound, also knocks peds down the same way a real vehicle cannon does.createWaterCannon(x, y, z [, color, knockdownEnabled])
Creates the cannon at the given position.
coloris a packed color fromtocolor(defaults to the native light blue if omitted).knockdownEnableddefaults to true. Returns the newwater-cannonelement, or false if the (separate, capped) pool of custom cannons is full.setWaterCannonDirection(cannon, x, y, z) / getWaterCannonDirection(cannon)
The jet's aim.
setWaterCannonForce(cannon, force) / getWaterCannonForce(cannon)
Scales the jet's velocity, and with it, its range. 1.0 is the default/native strength.
setWaterCannonEnabled(cannon, enabled) / isWaterCannonEnabled(cannon)
Turns the spray on or off without destroying the cannon. Starts enabled.
setWaterCannonKnockdownEnabled(cannon, enabled) / isWaterCannonKnockdownEnabled(cannon)
Whether getting sprayed knocks a ped down. Starts enabled, matching vanilla vehicle-cannon behavior; turn it off for a purely decorative jet.
setWaterCannonColor(cannon, r, g, b [, a]) / getWaterCannonColor(cannon) / resetWaterCannonColor(cannon)
Overrides the jet's RGBA color as separate components (not a packed
tocolorvalue, unlike the color argument on creation).resetWaterCannonColorgoes back to the native light blue.Also available as the
WaterCannonOOP class (WaterCannon.create(...),cannon.direction,cannon:setColor(...), etc), and two new events:onClientPedHitByWaterCannon(ped) / onClientPlayerHitByWaterCannon(player)
Fired on the cannon element (vehicle-mounted or standalone) when it hits a ped or player. Cancel it to block that specific hit's push and knockdown.
Motivation
The water cannon was only ever exposed through a vehicle. This lets scripts place one anywhere (a fountain, a trap, a custom prop or vehicle) while keeping the native jet behavior.
Test plan
Test script: a hose 😄
https://streamable.com/7k78mq
hosetest.zip
Checklist