//-- 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