4DFAF Uploaded
-
Updated the Vulcanizers description test to show: "The word Overkill, accurately describes this cannons level of overwhelming firepower. Fielding a quad barreled artillery cannon with selectable rate of fire (vs accuracy) and a secondary turret for close encounters."
Will look to see if i can add something similar for the toggle mouseover as well.
-Resin
-
Version 8 released!
-Rescaled a few units to better match with the existing scale of the games original units.
-Did a fair bit of rebalancing but is by no means prefect.
-Reworked the help text for many units to better describe what they do and how to better use them.
-Pushed all the custom UIs to show at the end of the UI build bar, so not to crowd out the preexisting units.
-Added a few more Cybran and Aeon units.Only 3 or more until left from the 4DC core units to add. These are units that I've asked Domino to work with as they've been tied into DMS code such that It would take me weeks to figure out how they work.
Enjoy!
Resin
-
(Evil scientist laugh) Presenting shield piercing weapons...
Snippet from hook'd shield.lua
do local oldShield = Shield Shield = Class(oldShield) { OnCollisionCheck = function(self,other) if self and not self:BeenDestroyed() then -- Allows Shield Piercing Projectiles to ignore shields, return true to process this collision, false to ignore it. if EntityCategoryContains( categories.PROJECTILE, other ) and EntityCategoryContains( categories.SHIELDPIERCING, other ) then return false else return oldShield.OnCollisionCheck(self,other) end end end, } end
Enjoy!
Resin
-
Got missile redirection working for the URA0206 Vampire stealth fighter, will be included in the next update!
In /hook'd unit.lua
########################################################################################## ## --Unit intel ########################################################################################## GetEnabledIntels = function(self) local Intels = {} if self.IntelDisables and table.getsize(self.IntelDisables) > 0 then for id, value in self.IntelDisables do if not Intels[id] then Intels[id] = false end local intelenabled = self:IsIntelEnabled(id) if intelenabled then Intels[id] = true else Intels[id] = nil end end end return Intels end,
Superclass called by the stealth unit...
---------------------------------------------------------------------------- -- File : /mods/4DFAF/lua/4D_CloakRedirect/4D_CloakRedirect.lua -- -- Author : Resin_Smoker -- -- Summary : 4D_SDR: Allows a structure so enhanced to resist enemy fire. -- -- Special Thanks: Mithy for his redirect script -- Copyright © 2024 4DFAF, All rights reserved. ---------------------------------------------------------------------------- -- -- The following is required in the units script for Struture Damage Resistance (SDR) -- This calls into action the SDR scripts for AStructureUnit -- -- local CAirUnit = import('/lua/cybranunits.lua').CAirUnit -- CAirUnit = import('/mods/4DC_V0.81/lua/CustomAbilities/4D_CloakRedirect/4D_CloakRedirect.lua').CloakRedirect( CAirUnit ) -- ---------------------------------------------------------------------------- ### Start of CloakRedirect(SuperClass) ### function CloakRedirect(SuperClass) return Class(SuperClass) { OnCollisionCheck = function(self, other, firingWeapon) -- Cloaking allows 50% chance to avoid anti-air missiles if self and not ( self:IsDead() or self:BeenDestroyed() ) then local EffectUnit = false local EffectsIntels = { 'CloakStealth', 'Cloak', 'CloakField', 'RadarStealth', 'RadarStealthField' } local EnabledIntels = self:GetEnabledIntels() for IntelType, Param in EnabledIntels do if table.find(EffectsIntels, IntelType) then EffectUnit = true break end end --check if unit is in field. if not EffectUnit then for id, IntelType in EffectsIntels do if self:IsInField(IntelType) then EffectUnit = true break end end end if EffectUnit then if ( other:GetBlueprint().Physics.TrackTarget or EntityCategoryContains(categories.MISSILE, other) ) and Random(1, 2) == 1 then if other:GetLauncher() then -- Projectile returns to launcher other:SetNewTarget(other:GetLauncher()) other:TrackTarget(true) other.DamageData.CollideFriendly = true other.DamageData.DamageFriendly = true other.DamageData.DamageSelf = true other:SetLifetime(10) other.Redirector = self -- *** Mithy's Function *** Hook projectile's DoDamage to set (living) redirector to instigator on impact local prevDoDamage = other.DoDamage other.DoDamage = function(self, instigator, damageData, targetEntity) --This should always allow the projectile to damage its launcher instigator = self.Redirector or self prevDoDamage(self, instigator, damageData, targetEntity) end else -- Projectile passes thru and losses tracking other:TrackTarget(false) end return false else -- Projectile impacts normally return true end end return SuperClass.OnCollisionCheck(self, other, firingWeapon) end end, } end ### End of CloakRedirect(SuperClass) ###
Keep in mind that the above script only applies to the unit calling the SuperClass. Hence all of the stock units won't have this ability unless modified to use the SuperClass.
Enjoy!
Resin
-
Did some work on the Hellhound shadow-step to improve its reliability and add in a few new FX: https://youtu.be/q6NtQ7HN-es
-
Version 9 uploaded.
"4D-FAF, a 4DC-DMS adaptation for FAF"
-
So apart from feedback, what from DMS would folks like to see incorporated?
-
@blackrobe said in 4DFAF Uploaded:
- Regarding Sera T2 shield Drone: it does work on some units, when you first released it, it shielded every unit and building, including ACU; I see the logic in later versions only shields some; thus my confusion. Might be good to add shield health amount, as you can't tell how strong shield is.
I took a look at how or rather where the information of where the shields health info is coming from. Far as I can tell, this isn't being provided by the shield, but by the units blueprint. Being that our shield drone adds a P-shield to a unit there isn't a blueprint to be drawn from. Maybe there is some way to "hook" in a change for that. Unfortunately , UI modding is not my area of knowledge.
Unless someone can pitch in or offer up some advice on how this can be done?
In the mean time, here is how the shield health is being calculated by the drone currently:
if table.find(bp.Categories ,'EXPERIMENTAL') then sldHealth = 10000 rChgTime = 120 rChgRate = 100 eCost = 300 elseif table.find(bp.Categories ,'TECH3') then sldHealth = sldHealth * 0.3 rChgTime = 90 rChgRate = 10 eCost = 25 elseif table.find(bp.Categories ,'TECH2') then sldHealth = sldHealth * 0.5 rChgTime = 60 rChgRate = 5 eCost = 10 else sldHealth = sldHealth * 0.75 rChgTime = 30 rChgRate = 2 eCost = 5 end
in many ways, the above figures are not properly balanced. Though the idea was for the shield drone to be a significant material investment and thus I gave it more wiggle room. If you have ideas on how to improve this, I'm open to suggestions.
Resin
-
Digging into all this further it appears that shields are not really holding the base health figures in self.MyShield and thus the UI has to constantly refer to the units blueprint. While for units that have their shields predefined in the blueprint or enhancement this is all good, but for units that are given shields via non standard means this creates a problem. How can the shields Max and current health figures be discovered if its not held in self.MyShields? Without which It's not possible to update Unitview.lua to show the shield max for that unit during a mouse over.
Edit: Ok figured it out...
Apparently the shields are being treated as entities (I forgot about this). Thus its possible to call on a units shield health via...
if self.MyShield then WARN(' self.Shield: ', self.MyShield:GetMaxHealth() ) end
This its possible to alter the Unitview.lua to work with most custom shields that are not based off a units Blueprint such as the 4DFAF shield drones.
Modified snippet from Unitview.lua, that I will try out...
if not shield.ShieldMaxHealth then if unitBp.Enhancements then shield = unitBp.Enhancements[getEnh.GetEnhancements(info.entityId).Back] elseif self.MyShield then shield = self.MyShield:GetMaxHealth() end end
Side note: It could just as easily be unitviewdetail.lua as I'm not ever messed with either of these before and have yet to discover what each one does despite similar names and inferred purpose.
-
So far my attempts to do anything with the UI are showing nothing. None of the expected outputs, or errors of any kind.
-
Made a little more progress... It appears that unitviewDetail.lua specifically the "show" function is responsible for this portion of the UI. That being said, not much information is being passed to it to be able to pull the units ShieldMaxHealth from anything other than its blue print. This appears to be by design if i recall, to prevent players with UI mods from being able to directly alter SIM side assets.
Unfortunately this means that it will NOT be possible to have the units ShieldMaxHealth shown on the UI, if the unit received its shields from anything other than a blueprint.
Only possibility is to figure out how to alter the UI from the SIM such when the drone shield is created this gets added somehow. Not sure how this would be possible, as the UI triggers on mouse over, not on the shields creation.
-
@resin_smoker said in 4DFAF Uploaded:
I took a look at how or rather where the information of where the shields health info is coming from. Far as I can tell, this isn't being provided by the shield, but by the units blueprint. Being that our shield drone adds a P-shield to a unit there isn't a blueprint to be drawn from. Maybe there is some way to "hook" in a change for that. Unfortunately , UI modding is not my area of knowledge.
Well if there's one thing I've observed about you Resin, whether on your own, or with the aid of someone else, you always seem to figure things out
PS: Loving the custom Cybran cloak. I always thought that every faction should have its custom cloak. Now you can differentiate UEF and Cybran cloak. While not essential, to the aesthetic lovers amongst us, a treat. Might as well bring in what you can from DMS. Something different is always good.
-
@resin_smoker said in 4DFAF Uploaded:
So apart from feedback, what from DMS would folks like to see incorporated?
Maybe a list of what features are inside DMS would help feedback on what to incorporate ?
-
@krapougnak there is litteraly too much to write about, as Domino rescripted the entire game prior to FAF.
I'd recommend playing a vanilla SC-FA with DMS and 4DC. If you think what I've done was good, prepare to be shocked.
-
@blackrobe sad thing is that doing so, would break the UI ban on using SIM data. It's why UI mods are allowed in ranked matches, and why most sim-side mods are not. Being able to bridge that gap would enable rampant cheating and a huge amount of desyncs.
-
A UI mod can not interfere with sim code, except through tailored engine calls and sim callbacks. The user layer is in a separate Lua context. You can import even sim files and make edits - the simulation wouldn't notice because it runs in a separate Lua context.
@resin_smoker said in 4DFAF Uploaded:
Unfortunately this means that it will NOT be possible to have the units ShieldMaxHealth shown on the UI, if the unit received its shields from anything other than a blueprint.
Only possibility is to figure out how to alter the UI from the SIM such when the drone shield is created this gets added somehow. Not sure how this would be possible, as the UI triggers on mouse over, not on the shields creation.We'd probably need to use a unit statistic that is synced from the sim to the UI. And then update the UI code in FAForever to read from that statistic and use the blueprint as a fallback. I'm not entirely sure about the solution because I've not investigated what the exact problem is.
But there's solutions if you really want them, just ask for help of the game team and maybe there's something we can do for you .
-
@resin_smoker said in 4DFAF Uploaded:
If you think what I've done was good, prepare to be shocked.I am prepared, shoot !
-
@jip I'm down with that... I only need the shields:GetMaxHealth() to be passed to be able to update the UI. Otherwise, the drone custom p-shield, would never be able to display without hijacking the SIM in some game breaking way.
Edit: Just rubbed two neurons together and made coherent thought.
Some smart guy, could during the game startup, use blueprint.lua to go through the units that would be drone shield capable. Then assign, what the max shield value would be as a hard value. This is effect would allow me to pass the MaxShieldHealth into the blueprint to be later used by the UI !
-
Half way there! Here is the Blueprint.lua script to merge the data that i needed...
########################################################################################## ## --Add drone shield max health into unit bp so UI can use it ########################################################################################## function Custom_Drone_MaxHealth_Blueprint(bp) if not bp then return end local id = bp.BlueprintId local bpDefense = original_blueprints.defense[id] -- Check to see if the gUnit has a Cloak, BuildRate or Economy, if so return false if bp.Intel.Cloak or bp.Defense.Shield.ShieldMaxHealth > 0 or bp.Enhancements.Shield or bp.Economy.MaintenanceConsumptionPerSecondEnergy then return false end -- Unit Categories to exclude local excludedCats = { -- Primary unit retrictions, basicly anything that build, upgrades or makes ammo 'COMMAND','SUBCOMMANDER','ENGINEER','OMNI','FACTORY','ECONOMIC','SILO', -- Custom unit restrictions 'DRONE','MINE','PHASING','TRANSFORMABLE', -- Misc unit restrictions 'POD','SATELLITE','UNTARGETABLE','SHIELD','WALL','PROJECTILE','OPERATION','CIVILIAN','INSIGNIFICANTUNIT','UNSELECTABLE','BENIGN','PROP', } local cats = bp.Categories for k, v in excludedCats do if table.find(cats, v) then return false end end -- Calc the drone shield max health based on the unit cat local droneShieldHealth = bp.Defense.MaxHealth if table.find(bp.Categories ,'EXPERIMENTAL') then droneShieldHealth = 10000 elseif table.find(bp.Categories ,'TECH3') then droneShieldHealth = droneShieldHealth * 0.3 elseif table.find(bp.Categories ,'TECH2') then droneShieldHealth = droneShieldHealth * 0.5 else droneShieldHealth = droneShieldHealth * 0.75 end WARN('Custom_Drone_MaxHealth_Blueprint for unit ID: ', bp.General.UnitName or 'no unit name found') local unitBp = table.deepcopy(bp.Defense) if unitBp then unitBp.Merge = true unitBp.DroneShieldMaxHealth = droneShieldHealth bp.Defense = unitBp end end
Repr of a units "self"... Look for the "Defense" and then "DroneShieldMaxHealth"...
WARNING: - Defense: table: 11FB39D8 WARNING: - AirThreatLevel: 0 WARNING: - ArmorType: Normal WARNING: - DroneShieldMaxHealth: 235.5 WARNING: - EconomyThreatLevel: 0 WARNING: - Health: 314 WARNING: - MaxHealth: 314 WARNING: - Merge: true WARNING: - PersonalShieldThreat: 0 WARNING: - RegenRate: 0 WARNING: - Shield: table: 11FB36B8 WARNING: - RegenAssistMult: 1 WARNING: - ShieldSize: 0 WARNING: - SubThreatLevel: 0 WARNING: - SurfaceThreatLevel: 13 WARNING: - UnknownWeaponThreat: 0 WARNING: - Description: Heavy Tank WARNING: - DesiredShooterCap: 3
-
Got the shield info to display, but dam it displays for everything, when it should only display when the drone-shield is active. the problem is becoming a circular one.... I need info from the sim to activate or deactivate an ability but i can't. Not without using a sim.sync.
Notice that the unit is showing a shield stat, without it having a shield on it...
Sure I can pass the data to the units blueprint, but there isn't any way that i can figure to tell the UI that the shield is active or not.
Question: Isn't the shield data already in Sync somewhere ?