[DISCUSSION] A new thought on faking shields

So it looks like it’s working. This is presumably a better way of doing it than the subsystem anyway?

1 Like

Yes! As the number goes down at all :stuck_out_tongue:

keep in mind with this system, your shield HP is 1:1 with your ship HP

@radar3301 yes that’s true.

I can retrieve strings from a ship’s *.ship file by loading it when I’m building our SOB table for it with the “create” part of the custom command, storing the value (and a shield value) to be used in calculations but I’m not sure how much it’s worth doing.

In Star Trek the shields were used more as a tension mechanic by the writers than an actual means of protection, so there’s not much indication on if they doubled the life expectancy of a ship under fire or what. So I am thinking that I’ll have the shields as you described, 1:1 with the ship HP

Ok, ready for scruitiny! I am just needing to finish adapting the old “drop shields when cloaking” script that assumes the shields drop at 25% health and figure out a way to show the shield values in the UI

Script
dofilepath("data:scripts/continuum/lib/stc_dummyShipFunctions.lua")
dofilepath("data:scripts/continuum/lib/stc_cloak.lua")

function shieldUpdate(CustomGroup, playerIndex, shipID)

	local shipclass = SOB_tShips[shipID].sShipClass
	
	-- Retrieve the ship file content so we can refer to the armour family
	if (SOB_tShips[shipID].sArmourFamily == nil) then
		dofilepath("data:ship/"..shipclass.."/"..shipclass..".ship")
		SOB_tShips[shipID].sArmourFamily = NewShipType.ArmourFamily
	end
	
	-- If there's a shield set the global table value to a number
	if (SOB_tShips[shipID].sArmourFamily ~= "NoShieldArmour") and (SOB_tShips[shipID].fShieldHealth == nil) then
		SOB_tShips[shipID].fShieldHealth = 1
	end
	
	-- Do all the stuff for cloaking
	SHIELD_Cloak_Rule(CustomGroup, playerIndex, shipID)
	
	-- establish the ship and shield HP that we're working with
	local shipHP = SobGroup_HealthPercentage(CustomGroup)
	local storedShipHP = SOB_tShips[shipID].fShipHealth
	local shieldHP = SOB_tShips[shipID].fShieldHealth
	local underAttack = SobGroup_UnderAttack(CustomGroup)
	
	if (shieldHP ~= nil) then
		if (shieldHP > 0) then

			-- print(">> SHIELDS 01 >> | "..shipclass.." belonging to player "..playerIndex.." has shipHP of "..shipHP.." and shieldHP of "..shieldHP)
			
			if (underAttack == 1) and (shipHP < 1) then
			
				local shipMissingHP = SOB_tShips[shipID].fShipHealth - shipHP
				-- print(">> SHIELDS 02 - Ship Lost HP >> | "..shipMissingHP.." ("..SOB_tShips[shipID].fShipHealth.." - "..shipHP..")")
				
				-- -- print(">> SHIELDS 02 >> | "..shipclass.." belonging to player "..playerIndex.." has lost "..shipMissingHP.." health")
				
				if (shipMissingHP > 0) then
				
					local shieldNewHP = shieldHP - shipMissingHP
					local shipNewHP = shipHP + shipMissingHP
					-- print(">> SHIELDS 03 - New Shield HP >> | "..shieldNewHP.." ("..shieldHP.." - "..shipMissingHP..")")
					-- print(">> SHIELDS 04 - New Ship HP >> | "..shipNewHP.." ("..shipHP.." + "..shipMissingHP..")")
					
					-- Update the shipHP and the shieldHP
					if (shieldNewHP < 0) then
						SOB_tShips[shipID].fShieldHealth = 0
						-- This is the point that the shields fail, play the failure animation
						SobGroup_SetMadState(CustomGroup, "HyperspaceGateDeActivate")
						-- print(">> SHIELDS 05 >> | "..shipclass.." belonging to player "..playerIndex.." has lost shields")
					else
						SOB_tShips[shipID].fShieldHealth = shieldNewHP
					end
					
					SobGroup_SetHealth(CustomGroup, shipNewHP)
					SOB_tShips[shipID].fShipHealth = shipNewHP
									
					-- print(">> SHIELDS 06 >> | "..shipclass.." belonging to player "..playerIndex.." now has shipHP of "..shipNewHP.." and shieldHP of "..shieldNewHP)
					
				end
			end
				
			-- shields will only recharge when out of battle
			if (underAttack ~= 1) and (shieldHP < 1) then
			
				-- this is the recharge rate of the shields
				local shieldNewHP = shieldHP + 0.0001
		
				-- Update the shipHP and the shieldHP
				if (shieldNewHP > 1) then
					SOB_tShips[shipID].fShieldHealth = 1
				else
					SOB_tShips[shipID].fShieldHealth = shieldNewHP
				end
				
				-- Keep this value up to scratch too as there could be a repair ship on the job
				SOB_tShips[shipID].fShipHealth = shipHP
				
				-- print(">> SHIELDS 07 >> | "..shipclass.." belonging to player "..playerIndex.." now has shipHP of "..shipHP.." and shieldHP of "..shieldNewHP)
			
			end
		
		elseif (shieldHP == 0) then
			
			local shieldTimer = SOB_tShips[shipID].iShieldTimer
			local timerCount = 1000 -- ? seconds
			
			-- shields will restore on their own after ? seconds disabled
			if (shieldTimer < timerCount) then
			
				SOB_tShips[shipID].iShieldTimer = shieldTimer + 1
				-- print(">> SHIELDS 08 >> | "..shipclass.." belonging to player "..playerIndex.." has a shieldTimer value of "..shieldTimer)
			
			elseif (shieldTimer == timerCount) then
			
				-- shields up! They will randomly restore at 10% to 60% of capactiy 
				SOB_tShips[shipID].iShieldTimer = 0
				SOB_tShips[shipID].fShieldHealth = random(10,60)/100
				SOB_tShips[shipID].fShipHealth = shipHP -- make a note of the current ship health so we don't jump it back to 100%
				SobGroup_SetMadState(CustomGroup, "HyperspaceGateActivate")
				
				-- print(">> SHIELDS 09 >> | "..shipclass.." belonging to player "..playerIndex.." has restored shield to "..SOB_tShips[shipID].fShieldHealth)
				
			end
			
		end	
	end
end

That looks good to me. The proof I is in the pudding though - does it work as intended?

EDIT: if you are running this script on lots of ships, you can make it more efficient by using @radar3301 global custom code script…

1 Like

I saw @radar3301’s custom code library, it seems to be a variation of the same SOB grouping that Stargazer set up for us in the old HW2 modding days but as we’ve already got something like that I’d not looked into it too closely.

The shields do now work as intended, surprisingly! Today I am going to work on:

  • Shields drop when ships are disabled
  • Shields drop when ships are cloaked
  • Showing shield value in the UI, hopefully with another (blue) health bar

//EDIT
Except for the UI part, the script is now complete :smiley:

Script
dofilepath("data:scripts/continuum/lib/stc_dummyShipFunctions.lua")
dofilepath("data:scripts/continuum/lib/stc_cloak.lua")

function shieldUpdate(CustomGroup, playerIndex, shipID)

	local shipclass = SOB_tShips[shipID].sShipClass
	
	-- Retrieve the ship file content so we can refer to the armour family
	if (SOB_tShips[shipID].sArmourFamily == nil) then
		dofilepath("data:ship/"..shipclass.."/"..shipclass..".ship")
		SOB_tShips[shipID].sArmourFamily = NewShipType.ArmourFamily
	end
	
	-- If there's a shield set the global table value to a number
	if (SOB_tShips[shipID].sArmourFamily ~= "NoShieldArmour") and (SOB_tShips[shipID].fShieldHealth == nil) then
		SOB_tShips[shipID].fShieldHealth = 1
	end
		
	-- establish the ship and shield HP that we're working with
	local shipHP = SobGroup_HealthPercentage(CustomGroup)
	local storedShipHP = SOB_tShips[shipID].fShipHealth
	local shieldHP = SOB_tShips[shipID].fShieldHealth
	local underAttack = SobGroup_UnderAttack(CustomGroup)
	local cloakStatus = SOB_tShips[shipID].iCloakStatus
	if (SobGroup_CanDoAbility(CustomGroup, AB_Steering) == 0) and (SobGroup_CanDoAbility(CustomGroup, AB_Targeting) == 0) then
		local disabledStatus = 1
	else
		local disabledStatus = 0
	end
	
	-- If the ship has shields and is not cloaked
	if (shieldHP ~= nil and cloakStatus == 0) then
		if (disabledStatus == 1) then
			-- print(>> SHIELDS 01 >> | "..shipclass.." belonging to player "..playerIndex.." is disabled! Wiping out shield HP")
			SOB_tShips[shipID].fShieldHealth = 0
		else
			if (shieldHP > 0) then

				-- print(">> SHIELDS 01 >> | "..shipclass.." belonging to player "..playerIndex.." has shipHP of "..shipHP.." and shieldHP of "..shieldHP.." and Cloak Status of "..cloakStatus)
				
				if (underAttack == 1) and (shipHP < 1) then
				
					local shipMissingHP = storedShipHP - shipHP
					-- print(">> SHIELDS 02 - Ship Lost HP >> | "..shipMissingHP.." ("..storedShipHP.." - "..shipHP..")")
					
					-- -- print(">> SHIELDS 02 >> | "..shipclass.." belonging to player "..playerIndex.." has lost "..shipMissingHP.." health")
					
					if (shipMissingHP > 0) then
					
						local shieldNewHP = shieldHP - shipMissingHP
						local shipNewHP = shipHP + shipMissingHP
						-- print(">> SHIELDS 03 - New Shield HP >> | "..shieldNewHP.." ("..shieldHP.." - "..shipMissingHP..")")
						-- print(">> SHIELDS 04 - New Ship HP >> | "..shipNewHP.." ("..shipHP.." + "..shipMissingHP..")")
						
						-- Update the shipHP and the shieldHP
						if (shieldNewHP < 0) then
							SOB_tShips[shipID].fShieldHealth = 0
							-- This is the point that the shields fail, play the failure animation
							SobGroup_SetMadState(CustomGroup, "HyperspaceGateDeActivate")
							-- print(">> SHIELDS 05 >> | "..shipclass.." belonging to player "..playerIndex.." has lost shields")
						else
							SOB_tShips[shipID].fShieldHealth = shieldNewHP
						end
						
						SobGroup_SetHealth(CustomGroup, shipNewHP)
						SOB_tShips[shipID].fShipHealth = shipNewHP
										
						-- print(">> SHIELDS 06 >> | "..shipclass.." belonging to player "..playerIndex.." now has shipHP of "..shipNewHP.." and shieldHP of "..shieldNewHP.." and Cloak Status of "..cloakStatus)
						
					end
				end
					
				-- shields will only recharge when out of battle
				if (underAttack ~= 1) and (shieldHP < 1) then
				
					-- this is the recharge rate of the shields
					local shieldNewHP = shieldHP + 0.0001
			
					-- Update the shipHP and the shieldHP
					if (shieldNewHP > 1) then
						SOB_tShips[shipID].fShieldHealth = 1
					else
						SOB_tShips[shipID].fShieldHealth = shieldNewHP
					end
					
					-- Keep this value up to scratch too as there could be a repair ship on the job
					SOB_tShips[shipID].fShipHealth = SobGroup_HealthPercentage(CustomGroup)
					
					-- print(">> SHIELDS 07 >> | "..shipclass.." belonging to player "..playerIndex.." now has shipHP of "..shipHP.." and shieldHP of "..shieldNewHP.." and Cloak Status of "..cloakStatus)
				
				end
			
			elseif (shieldHP == 0) then
				
				local shieldTimer = SOB_tShips[shipID].iShieldTimer
				local timerCount = 1000 -- ? seconds
				
				-- shields will restore on their own after ? seconds disabled
				if (shieldTimer < timerCount) then
				
					SOB_tShips[shipID].iShieldTimer = shieldTimer + 1
					-- print(">> SHIELDS 08 >> | "..shipclass.." belonging to player "..playerIndex.." has a shieldTimer value of "..shieldTimer)
				
				elseif (shieldTimer == timerCount) then
				
					-- shields up! They will randomly restore at 10% to 60% of capactiy 
					SOB_tShips[shipID].iShieldTimer = 0
					SOB_tShips[shipID].fShieldHealth = random(10,60)/100
					SOB_tShips[shipID].fShipHealth = SobGroup_HealthPercentage(CustomGroup) -- make a note of the current ship health so we don't jump it back to 100%
					SobGroup_SetMadState(CustomGroup, "HyperspaceGateActivate")
					
					-- print(">> SHIELDS 09 >> | "..shipclass.." belonging to player "..playerIndex.." has restored shield to "..SOB_tShips[shipID].fShieldHealth)
					
				end
				
			end	
		end
	end
	
	-- Check for the cloak stuff
	SHIELD_Cloak_Rule(CustomGroup, playerIndex, shipID)
	
end

X system provides a similar shield function. And it can display how many percent the shield left.

You guys are ahead of me there then! :smiley:

Can you share here how you display the remaining shields? That’s my next task… UI!

//Edit
Oh… you’re using pings… I see… :thinking:
I was hoping to use an ATI overlay, as it will stay static in relation to the health bar

I did some testing of this. SobGroup_SetHealth(<sobgroup>,<health>) only affects the ship(s) in the group (both for increasing and reducing the health) regardless of the subsystem health.

The thing you need to know about SobGroup_SetHardPointHealth(<sobgroup>,<subsystem>,<health>) is that <subsystem> is not the name of the subsystem but the name of the slot in the ship file. For example, from m02_hiigara.lua, line 1662: SobGroup_SetHardPointHealth( "EnemyCarrier", "Production 1", CurrentFighterFacilityHealth).

1 Like

I may have gotten it wrong… but for the following subsystem (extract from fed_TNG_flagship.ship)

StartShipHardPointConfig(NewShipType,"Shield","Hardpoint_Shield","System","Innate","Damageable","Shield_large","","","","","","","","")

I was using this set health line (taken from my first post)

SobGroup_SetHardPointHealth(CustomGroup, "Shield", shieldNewHP)

Perhaps I had something else causing the issue with the non-reducing health when I was trying this with a subsystem? :thinking:

//Edit
Maybe if it wasn’t innate?

ATI and Pings are very much similar, we don’t have lua functions to add/edit ATI, so we used pings. We added a new Ping template so that it displays right next the health bar.

What’s the name of that ping? :thinking:
I could only get a nice display of ping data when I added it to a mouseover

Ping Template
templates.shipmark_1_over = 
	{
		minGrowSize = 0,
		maxGrowSize = 0.1,
		minWorldSize = 0,
		growTime = 1,
		pauseTime = 0,
		lifespan = INFINITE,
		metaSelPriority = LowPriority,
		--metaSelPrioritySM = LowPriority,
		metaSelPrioritySM = NoPriority,
		--pingSfxPatch = "data:sound/sfx/ui/sensorsmanager/FIntelObjectivePing",
		circle = 
		{
			scaleParam = PPI_PingSize,
			mesh = 
			{
				colour = 
				{
					1,
					1,
					1,
					0,
				},
				lineWeight = 0.5,
				renderFlags = 
				{
					"scaleX",
					"scaleY",
				},
				LODs = 
				{
					1,
					"UI\\Pings\\Meshes\\Circle00.hod",
				},
			},
			placement2D = 
			{
				factorX = 0,
				factorY = 0,
				plusX = 0,
				plusY = 0,
				factorWidth = 0.1,
				factorHeight = 0.1,
				minWidth = WIDTH(8),
				minHeight = HEIGHT(8),
				maxWidth = WIDTH(55),
				maxHeight = HEIGHT(55),
				minATIArea = 0,
				maxATIArea = HUGE,
				visibility = 
				{
					"PVF_Pinging",
					"PVF_PingSize",
					"PVF_MouseOver",
				},
				invisibility = 
				{
					"PVF_SensorsManager",
				},
			},
		},
		description0 = 
		{
			stringParam = PPI_Description0,
			text = 
			{
				colour = 
				{
					0.5,
					0.7,
					1,
					1,
				},
				renderFlags = 
				{
					"justifyRight",
				},
				dropshadow = 1,
				LODs = 
				{
					LOD0,
					"ButtonFont",
					LOD1,
					"ButtonFont",
					LOD2,
					"ButtonFont",
				},
			},
			placement2D = 
			{
				factorX = 1,
				factorY = 1,
				--plusX = WIDTH(1),
				--plusY = HEIGHT(-94),
				plusX = WIDTH(90),
				plusY = HEIGHT(14),
				factorWidth = 1,
				factorHeight = 1,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				visibility = 
				{
					"PVF_PingSize",
					--"PVF_MouseOver",
					"PVF_Description0",
					--"PVF_SensorsManager",
				},
				invisibility = 
				{
					"PVF_SensorsManager",
				},
				--placementFlags = 
				--{
				--	"attachToMouse",
				--},
			},
		},
		description1 = 
		{
			stringParam = PPI_Description1,
			text = 
			{
				colour = 
				{
					0.7,
					0.7,
					0.7,
					1,
				},
				renderFlags = 
				{
					"justifyRight",
				},
				dropshadow = 1,
				LODs = 
				{
					LOD0,
					"ButtonFont",
					LOD1,
					"ButtonFont",
					LOD2,
					"ButtonFont",
				},
			},
			placement2D = 
			{
				factorX = 1,
				factorY = 1,
				--plusX = WIDTH(1),
				--plusY = HEIGHT(-106),
				plusX = WIDTH(130),
				plusY = HEIGHT(14),
				factorWidth = 1,
				factorHeight = 1,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				visibility = 
				{
					"PVF_PingSize",
					--"PVF_MouseOver",
					"PVF_Description1",
					--"PVF_SensorsManager",
				},
				invisibility = 
				{
					"PVF_SensorsManager",
				},
				--placementFlags = 
				--{
				--	"attachToMouse",
				--},
			},
		},
		description2 = 
		{
			stringParam = PPI_Description2,
			text = 
			{
				colour = 
				{
					0.2,
					1,
					0.2,
					1,
				},
				renderFlags = 
				{
					"justifyRight",
				},
				dropshadow = 1,
				LODs = 
				{
					LOD0,
					"ButtonFont",
					LOD1,
					"ButtonFont",
					LOD2,
					"ButtonFont",
				},
			},
			placement2D = 
			{
				factorX = 1,
				factorY = 1,
				--plusX = WIDTH(175),
				--plusY = HEIGHT(29),
				plusX = WIDTH(50),
				plusY = HEIGHT(14),
				factorWidth = 1,
				factorHeight = 1,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				visibility = 
				{
					"PVF_PingSize",
					--"PVF_MouseOver",
					"PVF_Description2",
					--"AVF_Visible",
					--"AVF_Selecting",
					--"AVF_TO_SelectionIcons",
					--"AVF_Selected",
					--"AVF_HealthBarStyle0",
					--"AVF_SquadLeader",
					--"PVF_SensorsManager",
				},
				invisibility = 
				{
					"PVF_SensorsManager",
				},
			},
		},
		description3 = 
		{
			stringParam = PPI_Description3,
			text = 
			{
				colour = 
				{
					0.9,
					0.7,
					0.1,
					1,
				},
				renderFlags = 
				{
					"justifyLeft",
					--"justifyRight",
				},
				dropshadow = 1,
				LODs = 
				{
					LOD0,
					"ButtonFont",
					LOD1,
					"ButtonFont",
					LOD2,
					"ButtonFont",
				},
			},
			placement2D = 
			{
				factorX = 1,
				factorY = 1,
				plusX = WIDTH(170),
				plusY = HEIGHT(14),
				--plusX = WIDTH(172),
				--plusY = HEIGHT(37),
				factorWidth = 1,
				factorHeight = 1,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				visibility = 
				{
					"PVF_PingSize",
					--"PVF_MouseOver",
					"PVF_Description3",
					--"PVF_SensorsManager",
				},
				invisibility = 
				{
					"PVF_SensorsManager",
				},
			},
		},
	}
1 Like

Nice! Thanks for sharing that. How would you link that to the custom code?

It’s a ping. Use Ping_AddSobGroup and Ping_AddDescription.

Thank you for sharing that @HW_Lover, but it’s not going to be suitable for my purposes :frowning:

I would need it to be essentially taking the place of the squadron numbering, but that’s ok. My mouseover works quite well even if it’s not immediately visible.

For reference, here’s the ping I’m going with and the final version of the script

STC Mouseover ping
mouseOver =
	{
		minGrowSize	 = 0,	 
		maxGrowSize	 = 0,	
		minWorldSize	= 0,
		growTime		= 2.0, 
		pauseTime		 = 0.0,
		lifespan		= INFINITE,				
		metaSelPriority = LowPriority,
		metaSelPrioritySM = LowPriority,
		label =
		{
			stringParam = PPI_Label,
			text =
			{
				colour = shield_default,
				renderFlags = {"justifyLeft"},
				dropshadow = 1,
				LODs =
				{
					LOD0, "ATISmallFont",
					LOD1, "ATISmallFont",
					LOD2, "ATISmallFont"
				},
			},
			placement2D =
			{
				factorX = 0,
				factorY = 0,
				plusX = 0.02,
				plusY = 0.004,
				factorWidth = 0,
				factorHeight = 0,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				-- visibility = {"PVF_Label", "PVF_SensorsManager"},
				-- visibility = {"PVF_Label", },
			},
		},
		description0 = -- Shield header
		{
			stringParam = PPI_Description0,
			text =
			{
				colour = shield_default,
				renderFlags = {"justifyLeft"},
				dropshadow = 1,
				LODs =
				{
					LOD0, "ATISmallFont",
					LOD1, "ATISmallFont",
					LOD2, "ATISmallFont"
				},
			},
			placement2D =
			{
				factorX = 0,
				factorY = -1,
				plusX = WIDTH(12),
				plusY = HEIGHT(-30),
				factorWidth = 0,
				factorHeight = 0,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				placementFlags = { "attachToMouse", },
				visibility = {"PVF_Description1", "PVF_MouseOver"},
				invisibility = {"PVF_SensorsManager"},
			},
		},
		description1 = -- Blue shield value
		{
			stringParam = PPI_Description1,
			text =
			{
				colour = shield_blue,
				renderFlags = {"justifyLeft"},
				dropshadow = 1,
				LODs =
				{
					LOD0, "ATISmallFont",
					LOD1, "ATISmallFont",
					LOD2, "ATISmallFont"
				},
			},
			placement2D =
			{
				factorX = 0,
				factorY = -1,
				plusX = WIDTH(31),
				plusY = HEIGHT(-46.5),
				factorWidth = 0,
				factorHeight = 0,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				placementFlags = { "attachToMouse", },
				visibility = {"PVF_Description1", "PVF_MouseOver"},
				invisibility = {"PVF_SensorsManager"},
			},
		},
		description2 = -- Yellow shield value
		{
			stringParam = PPI_Description2,
			text =
			{
				colour = shield_yellow,
				renderFlags = {"justifyLeft"},
				dropshadow = 1,
				LODs =
				{
					LOD0, "ATISmallFont",
					LOD1, "ATISmallFont",
					LOD2, "ATISmallFont"
				},
			},
			placement2D =
			{
				factorX = 0,
				factorY = -1,
				plusX = WIDTH(31),
				plusY = HEIGHT(-46.5),
				factorWidth = 0,
				factorHeight = 0,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				placementFlags = { "attachToMouse", },
				visibility = {"PVF_Description1", "PVF_MouseOver"},
				invisibility = {"PVF_SensorsManager"},
			},
		},
		description3 = -- Red shield value
		{
			stringParam = PPI_Description3,
			text =
			{
				colour = shield_red,
				renderFlags = {"justifyLeft"},
				dropshadow = 1,
				LODs =
				{
					LOD0, "ATISmallFont",
					LOD1, "ATISmallFont",
					LOD2, "ATISmallFont"
				},
			},
			placement2D =
			{
				factorX = 0,
				factorY = -1,
				plusX = WIDTH(31),
				plusY = HEIGHT(-46.5),
				factorWidth = 0,
				factorHeight = 0,
				minWidth = WIDTH(32),
				minHeight = HEIGHT(12),
				maxWidth = WIDTH(32),
				maxHeight = HEIGHT(12),
				placementFlags = { "attachToMouse", },
				visibility = {"PVF_Description1", "PVF_MouseOver"},
				invisibility = {"PVF_SensorsManager"},
			},
		},
	},	
STC Shield script
dofilepath("data:scripts/continuum/lib/stc_dummyShipFunctions.lua")
dofilepath("data:scripts/continuum/lib/stc_cloak.lua")

function shieldUpdate(CustomGroup, playerIndex, shipID)

	local shipclass = SOB_tShips[shipID].sShipClass
	
	-- Retrieve the ship file content so we can refer to the armour family
	if (SOB_tShips[shipID].sArmourFamily == nil) then
		dofilepath("data:ship/"..shipclass.."/"..shipclass..".ship")
		SOB_tShips[shipID].sArmourFamily = NewShipType.ArmourFamily
	end
	
	-- If there's a shield set the global table value to a number
	if (SOB_tShips[shipID].sArmourFamily ~= "NoShieldArmour") and (SOB_tShips[shipID].fShieldHealth == nil) then
		SOB_tShips[shipID].fShieldHealth = 1
	end
		
	-- establish the ship and shield HP that we're working with
	local shipHP = SobGroup_HealthPercentage(CustomGroup)
	local storedShipHP = SOB_tShips[shipID].fShipHealth
	local shieldHP = SOB_tShips[shipID].fShieldHealth
	local underAttack = SobGroup_UnderAttack(CustomGroup)
	local cloakStatus = SOB_tShips[shipID].iCloakStatus
	if (SobGroup_CanDoAbility(CustomGroup, AB_Steering) == 0) and (SobGroup_CanDoAbility(CustomGroup, AB_Targeting) == 0) then
		local disabledStatus = 1
	else
		local disabledStatus = 0
	end
	
	-- If the ship has shields and is not cloaked
	if (shieldHP ~= nil and cloakStatus == 0) then
		if (disabledStatus == 1) then
			-- print(>> SHIELDS 01 >> | "..shipclass.." belonging to player "..playerIndex.." is disabled! Wiping out shield HP")
			SOB_tShips[shipID].fShieldHealth = 0
		else
			if (shieldHP > 0) then

				-- print(">> SHIELDS 01 >> | "..shipclass.." belonging to player "..playerIndex.." has shipHP of "..shipHP.." and shieldHP of "..shieldHP.." and Cloak Status of "..cloakStatus)
				
				if (underAttack == 1) and (shipHP < 1) then
				
					local shipMissingHP = storedShipHP - shipHP
					-- print(">> SHIELDS 02 - Ship Lost HP >> | "..shipMissingHP.." ("..storedShipHP.." - "..shipHP..")")
					
					-- -- print(">> SHIELDS 02 >> | "..shipclass.." belonging to player "..playerIndex.." has lost "..shipMissingHP.." health")
					
					if (shipMissingHP > 0) then
					
						local shieldNewHP = shieldHP - shipMissingHP
						local shipNewHP = shipHP + shipMissingHP
						-- print(">> SHIELDS 03 - New Shield HP >> | "..shieldNewHP.." ("..shieldHP.." - "..shipMissingHP..")")
						-- print(">> SHIELDS 04 - New Ship HP >> | "..shipNewHP.." ("..shipHP.." + "..shipMissingHP..")")
						
						-- Update the shipHP and the shieldHP
						if (shieldNewHP < 0) then
							SOB_tShips[shipID].fShieldHealth = 0
							-- This is the point that the shields fail, play the failure animation
							SobGroup_SetMadState(CustomGroup, "HyperspaceGateDeActivate")
							-- print(">> SHIELDS 05 >> | "..shipclass.." belonging to player "..playerIndex.." has lost shields")
						else
							SOB_tShips[shipID].fShieldHealth = shieldNewHP
						end
						
						SobGroup_SetHealth(CustomGroup, shipNewHP)
						SOB_tShips[shipID].fShipHealth = shipNewHP
										
						-- print(">> SHIELDS 06 >> | "..shipclass.." belonging to player "..playerIndex.." now has shipHP of "..shipNewHP.." and shieldHP of "..shieldNewHP.." and Cloak Status of "..cloakStatus)
						
					end
				end
					
				-- shields will only recharge when out of battle
				if (underAttack ~= 1) and (shieldHP < 1) then
				
					-- this is the recharge rate of the shields
					local shieldNewHP = shieldHP + 0.0001
			
					-- Update the shipHP and the shieldHP
					if (shieldNewHP > 1) then
						SOB_tShips[shipID].fShieldHealth = 1
					else
						SOB_tShips[shipID].fShieldHealth = shieldNewHP
					end
					
					-- Keep this value up to scratch too as there could be a repair ship on the job
					SOB_tShips[shipID].fShipHealth = SobGroup_HealthPercentage(CustomGroup)
					
					-- print(">> SHIELDS 07 >> | "..shipclass.." belonging to player "..playerIndex.." now has shipHP of "..shipHP.." and shieldHP of "..shieldNewHP.." and Cloak Status of "..cloakStatus)
				
				end
			
			elseif (shieldHP == 0) then
				
				local shieldTimer = SOB_tShips[shipID].iShieldTimer
				local timerCount = 1000 -- ? seconds
				
				-- shields will restore on their own after ? seconds disabled
				if (shieldTimer < timerCount) then
				
					SOB_tShips[shipID].iShieldTimer = shieldTimer + 1
					-- print(">> SHIELDS 08 >> | "..shipclass.." belonging to player "..playerIndex.." has a shieldTimer value of "..shieldTimer)
				
				elseif (shieldTimer == timerCount) then
				
					-- shields up! They will randomly restore at 10% to 60% of capactiy 
					SOB_tShips[shipID].iShieldTimer = 0
					SOB_tShips[shipID].fShieldHealth = random(10,60)/100
					SOB_tShips[shipID].fShipHealth = SobGroup_HealthPercentage(CustomGroup) -- make a note of the current ship health so we don't jump it back to 100%
					SobGroup_SetMadState(CustomGroup, "HyperspaceGateActivate")
					
					-- print(">> SHIELDS 09 >> | "..shipclass.." belonging to player "..playerIndex.." has restored shield to "..SOB_tShips[shipID].fShieldHealth)
					
				end
				
			end	
		end
	end
	
	-- Check for the cloak stuff
	SHIELD_Cloak_Rule(CustomGroup, playerIndex, shipID)

	-- Show the shield bar	
	if (shieldHP ~= nil) then
		
		local displayString = floor(SOB_tShips[shipID].fShieldHealth * 100)
		Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 0, SOB_tShips[shipID].sName.."\n \nShields:")
		
		if (cloakStatus ~= 0 or disabledStatus == 1) then 
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 1, " ")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 2, " ")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 3, "Offline")
		elseif (displayString < 25) then
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 1, " ")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 2, " ")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 3, displayString.."%")
		elseif (displayString < 50) then
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 1, " ")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 2, displayString.."%")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 3, " ")
		else 
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 1, displayString.."%")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 2, " ")
			Ping_AddDescription(SOB_tShips[shipID].iShieldPingId, 3, " ")
		end
	end
	
end

We’re also setting the ping ID in our ship table as below:

tShip.iShieldPingId			= Ping_AddSobGroup("shieldPing_"..shipID, "mouseOver", CustomGroup)

You can always change a ping from MouseOver visible to Selected visible or whatever you like.

EDIT: I was wrong. It seems ping cannot set to selected visible, but you can set description text to “” when the ship is not selected.

1 Like

Setting the string to " " is what I’ve done to have the shield value change colour as it depletes :slight_smile:

Wait, you can set text colour via this format:
<c=00FF00>This is a green string.</c>

1 Like