File information
Created by
DrarenThiralas and S6S based on work by YvileapsisUploaded by
xax34hahVirus scan
About this mod
An addon for Just Assorted Mods that adds some new features for Just Bullet Time, fixes bugs, and implements a system for improved compatibility and interaction with the JBT state by other mods.
- Requirements
- Permissions and credits
- Changelogs
- Donations
This addon requires JAM, and will only work with the merged version - not the standalone JBT.
A version for standalone JBT will not be made.
There will be no attempt made to try to fix the vanilla killcam function when turned on with bullet time, as it is oblique and engine related.
- Highlighting has been made active, rather than dynamic - it will now highlight the limb you are currently aiming at, instead of the limb you last hit.
While this feature may be a little jank, it's more responsive and active than the alternative, and not worse than vanilla VATS targeting by any means. See video for demonstration. - Fixed a bug where JBT's highlighting would occasionally label body parts wrong.
For example, a Cazador's right wing would occasionally be displayed as "right arm". - A system allowing for proactive perk modifiers has been implemented. Previously the perks Sniper, Center of Mass, and Hobbler would only modify your accuracy and damage for the next shot after you land a hit on a limb that qualified for that perk. Perks can now pre-emptively modify various factors during Bullet Time, such as spread, damage, reload speed, attack speed, and movement speed, based on the targeted limb, weapon used, target type, and more.
- JBT's initial compatibility with VATS related perks used the standard values for the base game perks, and it was not dynamic to potential changes to those perks without an explicit patch to JBT's internal perk. This has been reworked with scriptlets which can be dynamically removed and replaced by other mods which intend to alter the VATS related values associated with those perks.
- Other mods can now create their own scriptlets to inject into formlists present in this mod which allow them to affect the calculated factors specified above, without needing to make this mod a requirement for their own file. Information for mod authors on how to implement this can be found below.
- A modifier for JBT's time multiplier based on Perception has been added, which can be adjusted through the MCM. The configurable value coordinates to how much each additional point of Perception will multiply the current time multiplier. Set this value to 1.0 to remove Perception's effect on the time multiplier.
- Added proper support for the perks Mysterious Stranger and Miss Fortune. These characters will now actually have a chance to appear and lend you a hand during Bullet Time. These appearances will properly increment the relevant Pip-Boy stats and challenges, and perks like the challenge Friendly Help will alter their chance of appearing, just like they do for VATS. Their odds are now affected by the appropriate gamesettings, and if the player has both perks, each helper's odds to show up are handled proportionately, rather than being a 50/50 roll.
- Dialog will be blocked during bullet time.
The information provided here is for mod authors, not users. Implementing compatibility via the scripted compatibility system requires familiarity with scripting, and knowledge of best practices associated with mitigating performance concerns.
The original implementation of VATS perk compatibility has been completely removed. Previously this was implemented by having entry points to modify things like weapon damage and spread explicitly on the JBT perk entry, which were explicit value amounts, and would require direct patching to alter.
All of those perk entry point entries have been changed to a non-functional entry point (Adjust Range Penalty, which isn't a functional entry point in the game, it doesn't do anything at all) and the spread, reload/attack/movement speed, and damage modifiers are assessed and altered by script at two points: Upon entering VATS or changing a weapon, and when the raycaster script assesses a targeted reference and the targeted limb.
Generalized modifiers for VATS (Wired Reflexes spread reduction) and weapon-specific modifiers are assessed upon entering VATS, and upon changing weapons. The system iterates through a formlist of scripts to determine the final value to assign to the associated JBT perk entry point entry.
The characteristics that can be modified at this phase are damage, spread, reload, movement, and attack speed. When this is performed, the calculated values for each of these stats is established as a baseline for the VATS session/equipped weapon. Upon equipping a new weapon, these baselines are reassessed and established.
NOTE: Scripting is set up for equip speed, but it can't be expected to perform particularly well. Equip speed will only update upon changing weapons, and since the system only assesses baselines once a weapon is already equipped, the equip speed won't change until the next time a weapon is equipped. All this can really functionally do is establish a standardized equip speed boost for any circumstance in VATS, and it can't functionally be modified mid-VATS session.
The second time that values are updated are when the Raycaster dummy weapon assesses a new target or targeted limb. When this occurs, damage and spread can be modified based on the targeted limb, characteristics about the target, or the equipped weapon.
A critical factor in interacting with this system is being as performance minded as possible at all times. While the initial/weapon change scripts are only checked upon entering VATS and changing weapons, the raycaster script is called very frequently at all times while in VATS, and the AP cost script formlist is interated through every single time the player attacks, and as such any scripts that are involved with those events need to be as prudent about performance as possible.
Scripts which intend to alter the baseline or weapon specific damage/spread/attack/reload/movement speed are to be placed in these appropriate formlists:
FLSTJBTGeneralDamageModifierScripts
FLSTJBTGeneralSpreadModifierScripts
FLSTJBTGeneralReloadSpeedModifierScripts
FLSTJBTGeneralMoveSpeedModifierScripts
FLSTJBTGeneralAttackSpeedModifierScripts
Scripts which intend to alter damage/spread or track the targeted ref are to be placed in these appropriate formlists:
FLSTJBTDamageModifierScripts
FLSTJBTSpreadModifierScripts
Scripts which simply want to track the targeted ref and don't care about altering damage or spread can be placed in either formlist.
Scripts can also be used to alter Mysterious Stranger and Miss Fortune odds.
Scripts which intend to alter the chance for VATS helpers are to be placed in this script:
FLSTJBTVatsHelperModifierScripts
There are individual scripts present in the appropriate formlists to provide standard value modifiers for Center Of Mass, Sniper, Hobbler, Concentrated Fire, Commando, Gunslinger, Wired Reflexes, Math Wrath, Plasma Spaz, Sneering Imperialist, Friendly Help, and Lonesome Road. Each of these can be individually removed by another mod, to be able to remove their standard value changes completely, or replace them with a different script with different values.
Here are two example scripts that details various performance factors and good practices:
scn JBTDamageMultInterventionExampleScript
;this is a raytracer damage alteration script that should apply specifically based on the target or body part targeted
;these go in FLSTJBTDamageModifierScripts
ref rTargetWorldRef
int iBodyPart
ref rTargetBaseForm
float fDamage
float fDamageLocal
ref rWeapon
begin function {rTargetWorldRef, iBodyPart, fDamage}
SetFunctionValue fDamage
;set the function value right away so we don't have to have extra lines to do it before a "return"
;if player.hasperk CenterOfMass == 0
;return
;endif
if iBodyPart != 0
return
endif
;this hypothetical script is working on Center Of Mass, which provides a damage bonus vs the torso, so call it off if they're targeting anything else
;since there's a bunch of non torso body parts on every actor, use this first, as it's the next broadest disqualifier after the absence of the perk
if isformvalid rTargetWorldRef == 0
return
endif
;always do your validity checks before you perform script actions on them
if rTargetWorldRef.GetType != 42
;return
endif
;this command can be done on the world reference
;if we're going to say, check if the target is Benny like I show below, cut off all non-NPC form types, since that's a broader check than specific NPC
;a great many of the checks you might perform on a targeted actor can be done on the world reference, but you *might* need to check something about their base form in a small number of cases
rTargetBaseForm = rTargetWorldRef.GBO
if isformvalid rTargetBaseForm == 0
return
endif
;if rTargetBaseForm == Benny
;return
;endif
;baseform exclusion example
rWeapon = player.geteqobj 5
;we can just check the equipped object during this script instead of passing it from the Raytracing script, since this script will actively fire while raytracing is calculating, so it will be timely
;if isformvalid rWeapon == 0
;return
;endif
fDamageLocal = fDamage
;move it to a local var to maintain the original value in case you need the old one
;we already called the script off earlier if the player doesn't have center of mass, and if the targeted body part isn't the torso, so if the script has arrived here, all the qualifications are met, so you don't need any ifs here
fDamageLocal *= 1.15
SetFunctionValue fDamageLocal
;set the function value to the new one, and it'll either be used directly if it's the last script in the chain, or used by the next script
end
scn JBTGlobalSpreadMultExampleScript
;this is a global spread alteration script that applies when VATS is entered or the player's weapon changes
;these go in FLSTJBTGeneralSpreadModifierScripts
float fSpread
float fSpreadLocal
ref rWeapon
begin function {fSpread}
SetFunctionValue fSpread
;set the function value right away so we don't have to have extra lines to do it before a "return"
;if PlayerRef.HasPerk MS08RewardPerk == 0
;using eval means that if the first condition isn't met, it'll skip checking the other conditions, which is better for performance
;return
;endif
;wired reflexes applies to all vats costs, so we don't do a player.geteqobj 5 check to see about the equipped weapon cause it doesn't matter
fSpreadLocal = fSpread
;move it to a local var to maintain the original value in case you need the old one
;we already called the script off earlier if the player doesn't have wired reflexes, so if the script has arrived here, all the qualifications are met, so you don't need any ifs here
fSpread *= 1.15
SetFunctionValue fSpread
;set the function value to the new one, and it'll either be used directly if it's the last script in the chain, or used by the next script
end
Here are some of the default perk modifier scripts:
Global VATS spread modifier:
scn JBTStandardWiredReflexesSpreadPerkValues
float fSpread
float fSpreadLocal
ref rWeapon
begin function {fSpread}
SetFunctionValue fSpread
if player.hasperk MS08RewardPerk == 0
return
endif
fSpreadLocal = fSpread * 0.9
SetFunctionValue fSpreadLocal
end
Global VATS damage modifier scripts work basically the same way, but they are passed an fDamage value instead of fSpread.
Contextual VATS spread modifier:
scn JBTStandardHobblerSpreadPerkValues
ref rTargetWorldRef
int iBodyPart
ref rTargetBaseForm
float fSpread
float fSpreadLocal
begin function {rTargetWorldRef, iBodyPart, fSpread}
SetFunctionValue fSpread
if eval PlayerRef.HasPerk NVDLC01Hobbler == 0 || (iBodyPart < 7 || iBodyPart > 12)
return
endif
fSpreadLocal = fSpread * 0.75
SetFunctionValue fSpreadLocal
end
AP Cost Change Script:
scn JBTStandardMathWrathAPValues
ref rWeapon
float fAP
float fAPLocal
begin function {rWeapon, fAP}
SetFunctionValue fAP
if player.hasperk MathWrath == 0
return
endif
fAPLocal = fAP * 0.9
SetFunctionValue fAPLocal
end
VATS Helper Chance Script:
scn JBTStandardVATSHelperPerkValues
float fChance
begin function {fChance}
SetFunctionValue fChance
if player.hasperk VATSHelperChallengePerk == 0
return
endif
fChance *= 2
SetFunctionValue fChance
end
Script to track targeted ref to use for other conditions:
scn JBTTargetTrackerExampleScript
ref rTargetWorldRef
int iBodyPart
ref rTargetBaseForm
float fPassedFloat
begin function {rTargetWorldRef, iBodyPart, fPassedFloat}
;fPassedFloat is named such because this is an example of simply tracking the current target ref for another mod to potentially set a local variable there based on the nature of the targeted entity, so the float that gets passed isn't important
;this script can be added to either the damage or spread formlist of scripts - as long as this script doesn't touch the aux vars or SetFunctionValue used by the other script formats, it can be anywhere in the chain of scripts and do its own thing freely without affecting the other scripts in the chain
SetFunctionValue fPassedFloat
;just pass the value received through further, else it'll pass 0 to the next script
if isformvalid rTargetWorldRef == 0
return
endif
;always do your validity checks
rTargetBaseForm = rTargetWorldRef.GBO
if isformvalid rTargetBaseForm == 0
return
endif
player.AuxVarSetRef "_rPublicJBTTrackedTargetWorldRef" rTargetWorldRef
player.AuxVarSetRef "_rPublicJBTTrackedTargetBaseForm" rTargetBaseForm
;if doing this, the aux ref with this name can be checked by any script in any mod
if rTargetWorldRef.GetType == 42
player.AuxVarSetFLT "bLocalVariable" 1
else
player.AuxVarSetFLT "bLocalVariable" 0
endif
;set up as a private var for the mod whose script is being called by the script chain in case of using an aux var for a AuxVarGetFLTCond
;if rTargetWorldRef.GetType == 42
;MyModGlobal = 1
;else
;MyModGlobal = 0
;endif
;using a global in your own mod is a much easier condition than AuxVarGetFLTCond
;put GetGlobalValue MyModGlobal == 1 or whatever on a condition for say, a perk entry point, and you can have effects which are target-type relevant even without being able to define conditions on the target for entry points that don't have access to it
end
Script formlist injection example:
scn JBTMultListInjectionExampleScript
ref rFLSTJBTDamageModifierScripts
begin gamemode
if getgamerestarted
if ismodloaded "JBTImproved.esp" == 1 && isModLoaded "JustAssortedMods.esp" == 1
ref rFLSTJBTDamageModifierScripts = EditorIDToFormID "FLSTJBTDamageModifierScripts"
if isformvalid rFLSTJBTDamageModifierScripts
;ListAddForm rFLSTJBTDamageModifierScripts MyDamageModifierScript
;ref rJBTStandardConcentratedFireDamagePerkValues = EditorIDToFormID "JBTStandardConcentratedFireDamagePerkValues"
;if isformvalid rJBTStandardHobblerSpreadPerkValues
;ListRemoveForm rFLSTJBTDamageModifierScripts rJBTStandardConcentratedFireDamagePerkValues
;endif
;if you are altering vanilla hobbler perk values, remove the default script for that perk and insert your own with your own values
endif
endif
endif
end
These scripts are present in the JBT Improved esp for easy reference.