Files
gtav-src/script/dev_ng/singleplayer/include/public/fuelTrail.sch
T
2025-09-29 00:52:08 +02:00

253 lines
10 KiB
XML
Executable File

//-- Dave Watson
//-- Header file containing functions for creating & igniting a trail of fuel from a petrol-can without relying on code.
//-- N.B. Only works with the fuel can, doesn't have functionality ofr vehicle leaks.
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_graphics.sch"
USING "commands_entity.sch"
USING "commands_weapon.sch"
USING "commands_pad.sch"
USING "commands_misc.sch"
USING "commands_streaming.sch"
USING "commands_object.sch"
USING "script_maths.sch"
//--Currently limited to 400 individual "fuel drops". This is enough to create a long trail, but will stop working if this limit is exceeded (will assert)
CONST_INT MAX_SCRIPT_FUEL_DROPS 400
STRUCT structFuelTrail
VECTOR vScriptFuelLoc[MAX_SCRIPT_FUEL_DROPS]
PTFX_ID fxScriptFuelFire[MAX_SCRIPT_FUEL_DROPS]
INT iScriptFuelIgniteTime[MAX_SCRIPT_FUEL_DROPS]
INT iNumberScriptFuelDrops
ENDSTRUCT
//PURPOSE: Returns True if the specified time has passed
FUNC BOOL hasFuelTrailTimePassed(INT iStartTimer, INT iTimeToCheck)
// INPUT PARAMS: iStartTimer This is considered time = 0
// iTimeToCheck The time since iStartTimer being tested for
// RETURN VALUE BOOL TRUE if time iTimeToCheck has passed since time iStartTimer
// NOTE: Requires iStartTimer to have been set before the fn is called
INT iTempTime
IF iStartTimer > 0
iTempTime = GET_GAME_TIMER()
IF iTempTime - iStartTimer > iTimeToCheck
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
//PURPOSE: Evolves the particle effect "fxName" over time "iTimeToTake" using the evolution "evoName"
PROC evolveFuelPtfxOverTime(PTFX_ID& fxName, STRING evoName, INT iStartTime, INT iTimeToTake = 1000)
INT iTimePassed
IF DOES_PARTICLE_FX_LOOPED_EXIST(fxName)
iTimePassed = (GET_GAME_TIMER() - iStartTime)
IF iTimePassed <= iTimeToTake
SET_PARTICLE_FX_LOOPED_EVOLUTION(fxName, evoName, (TO_FLOAT(iTimePassed) / (TO_FLOAT(iTimeToTake))))
ELSE
SET_PARTICLE_FX_LOOPED_EVOLUTION(fxName, evoName, 1.0)
ENDIF
ENDIF
ENDPROC
//PURPOSE: Checks for any unlit fuel drops in the angled area specified
FUNC BOOL ARE_ANY_SCRIPT_FUEL_DROPS_IN_ANGLED_AREA(structFuelTrail &fuelTrailList, VECTOR vCoord1, VECTOR vCoord2, FLOAT fWidth)
INT i
REPEAT COUNT_OF(fuelTrailList.vScriptFuelLoc) i
IF NOT ARE_VECTORS_EQUAL(fuelTrailList.vScriptFuelLoc[i] , <<0.0, 0.0, 0.0>>)
IF IS_POINT_IN_ANGLED_AREA(fuelTrailList.vScriptFuelLoc[i], vCoord1, vCoord2, fWidth)
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
//PURPOSE: Checks for any ignited fuel drops within the angled are specified. Set iMinTimeSinceIgnite to something like 500 if you want to check for a full-blown fire
FUNC BOOL ARE_ANY_IGNITED_SCRIPT_FUEL_DROPS_IN_ANGLED_AREA(structFuelTrail &fuelTrailList, VECTOR vCoord1, VECTOR vCoord2, FLOAT fWidth, INT iMinTimeSinceIgnite = 0)
INT i
REPEAT COUNT_OF(fuelTrailList.vScriptFuelLoc) i
IF NOT ARE_VECTORS_EQUAL(fuelTrailList.vScriptFuelLoc[i] , <<0.0, 0.0, 0.0>>)
IF fuelTrailList.iScriptFuelIgniteTime[i] > 0
IF hasFuelTrailTimePassed(fuelTrailList.iScriptFuelIgniteTime[i],iMinTimeSinceIgnite)
IF IS_POINT_IN_ANGLED_AREA(fuelTrailList.vScriptFuelLoc[i], vCoord1, vCoord2, fWidth)
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
//PURPOSE: Needs to be called before a fuel trail can be created
PROC INIT_SCRIPT_FUEL_TRAIL(structFuelTrail &fuelTrailList)
INT i
REPEAT COUNT_OF(fuelTrailList.vScriptFuelLoc) i
fuelTrailList.vScriptFuelLoc[i] = <<0.0, 0.0, 0.0>>
fuelTrailList.fxScriptFuelFire[i] = NULL
fuelTrailList.iScriptFuelIgniteTime[i] = 0
ENDREPEAT
fuelTrailList.iNumberScriptFuelDrops = 0
//-- Stops the code trying to ignite the fuel decals
//SET_DISABLE_PETROL_DECALS_IGNITING(TRUE)
REQUEST_PTFX_ASSET()
ENDPROC
//PURPOSE: Needs to be called when the script is finished with the fuel trail. Will remove the "script" fx asset if bRemovePtfxAsset is set
PROC CLEANUP_SCRIPT_FUEL_TRAIL(structFuelTrail &fuelTrailList, BOOL bRemovePtfxAsset = TRUE)
INT i
REPEAT COUNT_OF(fuelTrailList.fxScriptFuelFire) i
IF DOES_PARTICLE_FX_LOOPED_EXIST(fuelTrailList.fxScriptFuelFire[i])
STOP_PARTICLE_FX_LOOPED(fuelTrailList.fxScriptFuelFire[i])
fuelTrailList.fxScriptFuelFire[i] = NULL
ENDIF
ENDREPEAT
SET_DISABLE_PETROL_DECALS_IGNITING(FALSE)
IF bRemovePtfxAsset
REMOVE_PTFX_ASSET()
ENDIF
ENDPROC
//PURPOSE: Deals with tracking the position of the trail of fuel. More info...
PROC MANAGE_CREATE_SCRIPT_FUEL_TRAIL(structFuelTrail &fuelTrailList, FLOAT fMinDropFuelDistance = 0.25)
// INPUT PARAMS: fMinDropFuelDistance The current position needs to be at least this far away from the previous bit of dropped fuel before it will be stored.
// NOTES: Currently assumes that having the RT button pressed and having the fuel can eqipped is enough to check for fuel being dropped, but
// it's not currently sufficent. Waiting for bug 147473 to get fixed.
// Currently only checks for the current position Vs. the most recently stored fuel position to determine if we need to store
// a new position. Should probably compare current position with all previously dropped fuel.
VECTOR vCreateFuelPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PLAYER_PED_ID(), <<0.214, 0.484, -0.984>>)
WEAPON_TYPE wPed
IF GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), wPed)
IF wPed = WEAPONTYPE_PETROLCAN
IF IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_RT)
IF fuelTrailList.iNumberScriptFuelDrops < (MAX_SCRIPT_FUEL_DROPS -1)
IF fuelTrailList.iNumberScriptFuelDrops = 0
fuelTrailList.vScriptFuelLoc[fuelTrailList.iNumberScriptFuelDrops] = vCreateFuelPos
fuelTrailList.iNumberScriptFuelDrops++
ELSE
IF VMAG2(vCreateFuelPos - fuelTrailList.vScriptFuelLoc[fuelTrailList.iNumberScriptFuelDrops - 1]) > fMinDropFuelDistance
vCreateFuelPos.z += 1.0
IF GET_GROUND_Z_FOR_3D_COORD(vCreateFuelPos, vCreateFuelPos.z)
fuelTrailList.vScriptFuelLoc[fuelTrailList.iNumberScriptFuelDrops] = vCreateFuelPos
fuelTrailList.iNumberScriptFuelDrops++
ENDIF
ENDIF
ENDIF
ELSE
SCRIPT_ASSERT("Script fuel trail: Too many fuel drops!")
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
//PURPOSE: Checks for the fuel trail being ignited. More info...
PROC MANAGE_IGNITE_SCRIPT_FUEL_TRAIL(structFuelTrail &fuelTrailList, FLOAT fIgniteFuelDist = 2.0, INT iTimeBetweenFuelIgniting = 100, INT iFuelBurnTime = 3000, INT iFuelEvolveTime = 500)
// INPUT PARAMS: fIgniteFuelDist If an unlit fuel drop is at most this distance from a lit fuel drop, then the unlit fuel drop will ignite
// iTimeBetweenFuelIgniting The time bewteen adjacent fuel drops igniting
// iFuelBurnTime The length of time (in ms) each drop of fuel will burn for
// iFuelEvolveTime The length of time (in ms) that it takes for the fuel burning effect to get to full strength
INT i, j
FLOAT fIgniteDist2 = fIgniteFuelDist * fIgniteFuelDist
FLOAT fDist2 = 0.0
#IF IS_DEBUG_BUILD
IF iFuelEvolveTime > iFuelBurnTime
//-- Doesn't make sense to have the fuel effect evolve time longer than the fuel burn time
SCRIPT_ASSERT("Script fuel trail: Evolve time should be less than burn time")
ENDIF
#ENDIF
IF fuelTrailList.iNumberScriptFuelDrops > 0
IF HAS_PTFX_ASSET_LOADED()
SET_DISABLE_PETROL_DECALS_IGNITING_THIS_FRAME()
FOR i = 0 TO fuelTrailList.iNumberScriptFuelDrops
SET_DISABLE_PETROL_DECALS_IGNITING_THIS_FRAME()
IF fuelTrailList.iScriptFuelIgniteTime[i] = 0
IF NOT ARE_VECTORS_EQUAL(fuelTrailList.vScriptFuelLoc[i], <<0.0, 0.0, 0.0>>)
IF IS_BULLET_IN_AREA(fuelTrailList.vScriptFuelLoc[i], 0.25, TRUE)
//-- CHeck for player shooting petrol drops
fuelTrailList.fxScriptFuelFire[i] = START_PARTICLE_FX_LOOPED_AT_COORD("scr_petrol_trail_fire",fuelTrailList.vScriptFuelLoc[i], <<0.0, 0.0, 0.0>>)
fuelTrailList.iScriptFuelIgniteTime[i] = GET_GAME_TIMER()
ENDIF
ENDIF
ELSE
IF hasFuelTrailTimePassed(fuelTrailList.iScriptFuelIgniteTime[i], iTimeBetweenFuelIgniting)
FOR j = 0 TO fuelTrailList.iNumberScriptFuelDrops
IF NOT ARE_VECTORS_EQUAL(fuelTrailList.vScriptFuelLoc[j], <<0.0, 0.0, 0.0>>)
IF fuelTrailList.iScriptFuelIgniteTime[j] = 0
//-- Ignite any unlit fuel drops close to the current lit fuel drop
fDist2 = VDIST2(fuelTrailList.vScriptFuelLoc[i],fuelTrailList.vScriptFuelLoc[j])
IF fDist2 < fIgniteDist2
fuelTrailList.fxScriptFuelFire[j] = START_PARTICLE_FX_LOOPED_AT_COORD("scr_petrol_trail_fire", fuelTrailList.vScriptFuelLoc[j],<<0.0, 0.0, 0.0>>)
fuelTrailList.iScriptFuelIgniteTime[j] = GET_GAME_TIMER()
ENDIF
ENDIF
ENDIF
ENDFOR
ENDIF
IF hasFuelTrailTimePassed(fuelTrailList.iScriptFuelIgniteTime[i], iFuelBurnTime)
//--Stop the current fuel drop burning
STOP_PARTICLE_FX_LOOPED(fuelTrailList.fxScriptFuelFire[i])
fuelTrailList.vScriptFuelLoc[i] = << 0.0, 0.0, 0.0>>
fuelTrailList.iScriptFuelIgniteTime[i] = 0
ELSE
//-- Evolve the fuel trail particle effects
IF hasFuelTrailTimePassed(fuelTrailList.iScriptFuelIgniteTime[i], iFuelEvolveTime)
REMOVE_DECALS_IN_RANGE(fuelTrailList.vScriptFuelLoc[i] , 0.5)
ENDIF
evolveFuelPtfxOverTime(fuelTrailList.fxScriptFuelFire[i],"strengTh", fuelTrailList.iScriptFuelIgniteTime[i], iFuelEvolveTime)
evolveFuelPtfxOverTime(fuelTrailList.fxScriptFuelFire[i],"FUEL", fuelTrailList.iScriptFuelIgniteTime[i], iFuelEvolveTime)
ENDIF
ENDIF
ENDFOR
ELSE
REQUEST_PTFX_ASSET()
ENDIF
ENDIF
ENDPROC
//PURPOSE: Needs to be called every frame to track for a fuel trail being created, and checking for it igniting.
PROC UPDATE_SCRIPT_FUEL_TRAIL(structFuelTrail &fuelTrailList, FLOAT fMinDistanceBetweenDrops = 0.25, FLOAT fIgniteNearbyFuelDist = 1.0,
INT iTimeBetweenFuelIgniting = 100, INT iScriptFuelBurnTime = 3000, INT iScriptFuelEvolveTime = 500)
MANAGE_CREATE_SCRIPT_FUEL_TRAIL(fuelTrailList, fMinDistanceBetweenDrops)
MANAGE_IGNITE_SCRIPT_FUEL_TRAIL(fuelTrailList, fIgniteNearbyFuelDist, iTimeBetweenFuelIgniting, iScriptFuelBurnTime,iScriptFuelEvolveTime)
ENDPROC