Author Topic: Imitating BCs shield recharge when gen offline?  (Read 1485 times)

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Imitating BCs shield recharge when gen offline?
« on: July 17, 2012, 01:43:22 PM »
Whether it's cannon or makes sense in the Trek Universe I don't know. All I do know is that when you go from Red Alert to green alert or go to brex and power shield generator down to 0% the shields slowly regain health. This is clearly evident after a battle and you go to green alert, wait a minute or so and then turn them on voilla they've mysteriously healed even though they were offline.

The script in question here is the very same that was being developed in this thread:
http://bc-central.net/forums/index.php/topic,8750.0.html

Given that i've got two shield generators, one primary and one secondary, and that when they switch the previously active generators shield strengths are stored in a dictionary *and* that when a generator comes online its values are loaded from that dictionary.

How could I apply what BC does to the shields when they're offline so that it'd appear as though the shields have been slowly repairing?

I know in order for you to help me you need to know how the script works at the moment so i'll just give you a run down of how it works in the simplest way. Hopefully the basics of what it does are all you need.

Code: [Select]
shipShieldVals = {}
#how values are first loaded
shipShieldVals[pShipID][0][Shield]  = pPrimaryGen.GetMaxShields(Shield)
shipShieldVals[pShipID][1][Shield] = pSecondaryGen.GetMaxShields(Shield)
ShieldMax = shipShieldVals[pShipID][0][Shield]
ShieldStrength = shipShieldVals[pShipID][0][Shield]
ShieldReload = pPrimaryGen.GetProperty().GetShieldChargePerSecond(Shield)
# how shield values are first set
pShields.GetProperty().SetMaxShields(Shield, ShieldMax)
pShields.GetProperty().SetShieldChargePerSecond(Shield, ShieldReload)
pShields.SetCurShields(Shield, ShieldStrength)
Obviously the getting and setting of shield values takes place in a loop as there are, of course, 6 shield values to be get/set.

Code: [Select]
# happens in the loop when it's established secondary is taking over for primary
shipShieldVals[pShipID][0][Shield] = pPrimaryGen.GetMaxShields(Shield) / 100 * ShieldPercentage * 100
# happens in the loop when it's established primary is taking over for secondary
shipShieldVals[pShipID][1][Shield] = pSecondaryGen.GetMaxShields(Shield) / 100 * ShieldPercentage * 100
Of course, again, it all goes down in loop.

Ignoring all the code snippets and python excerpts the script essentially is just loading values of the primary or secondary generator and overwriting the properties of the real hidden generator to give the illusion that there are two active working generators ingame.
There are three generators, the real one is hidden indestrictuble and non-targetable, the primary and secondary are just shield generator susbsystems with the primary flag set to 0.

If you've read the above and still feel lacking in info then here ya go. Just ignore all the print statements (debugging) and follow the overkill amount of comments and hopefully you won't get lost in my spaghetti code  :D

EDIT: Where in the hell did the attach to post feature go? Well, if I can't upload you're gonna have to suffer it being posted in the thread. Behold, the entire script!
Code: [Select]
import App
import MissionLib
import Foundation
import string
# libEngineering import & pButton variable are for the toggle button on the tactical menu
import Lib.LibEngineering

MODINFO = {"Author": "\"Defiant\" erik@vontaene.de",
"Version": "0.1",
"License": "BSD",
"Description": "Allows for ships to utilize two shield generators in BC",
"needBridge": 0
    }

# master dictionary, stores all shield values for all ships with primary/secondary generator configuration
shipShieldVals = {}
# ^ ships unique identifier code, primary shield specifier (0 = primary, 1 = secondary), the 6 shield values (front rear, top bottom,  left right)

# stores sub-system ID of CTRL+SHIFT+K targetted gennies so SubsystemOperational() can check and run RedefineShieldGenerators() when they are disabled (without any shields being damaged) then repaired
ctrlShiftKGenVictims = {}

pButton = None
# indicates what generator player has specifically selected to be active
# for when player uses button to select secondary generator (when primary is operational), transports to another ship and then transports back
plyrGenChoice = {}
# ^ ships unique identifier code, 1 = primary 2 = secondary 0 = neither

# function is needed to target the correct ship and get the primary/secondary gen names through Foundation plugin
def GetShipType(pShip):
    if pShip.GetScript():
        return string.split(pShip.GetScript(), '.')[-1]
    return None

# uses Foundation plugin to return list containing names of fake (non-primary) generators
def GetPrimarySecondaryGenNames(pShip):
sShipType = GetShipType(pShip)
pFoundationShip = Foundation.shipList[sShipType]
if "lShields" in dir(pFoundationShip):
return pFoundationShip.lShields
else:
return None

# returns a list of all fake (non-primary) shield generators
def GetAllShieldGenerators(pShip):
retList = []
        print "GetAllShieldGenerators() ---------------------------------"
        pPropSet = pShip.GetPropertySet()
        pShipSubSystemPropInstanceList = pPropSet.GetPropertiesByType(App.CT_SHIELD_PROPERTY)
        iNumItems = pShipSubSystemPropInstanceList.TGGetNumItems()
        pShipSubSystemPropInstanceList.TGBeginIteration()
        for i in range(iNumItems):
                pInstance = pShipSubSystemPropInstanceList.TGGetNext()
                pProperty = App.ShieldProperty_Cast(pInstance.GetProperty())
                if not pProperty.IsPrimary():
                        pSubSystem = pShip.GetSubsystemByProperty(pProperty)
                        pShieldGenerator = App.ShieldClass_Cast(pSubSystem)
                        retList.append(pShieldGenerator)
                        
        pShipSubSystemPropInstanceList.TGDoneIterating()
        return retList

# sets up a ship for use with this script by making the REAL hidden primary shield generator invincible
# after all, this script swapping shield values is no good if the real generator can be damaged
def SetUpShip(pShip):
        # Make our "real" shield generator indestructible
        pShields = pShip.GetShields()
        pShields.SetInvincible(0)
        pShields.GetProperty().SetDisabledPercentage(0.0)
        # and don't waste too much repair points on it
        pShields.GetProperty().SetRepairComplexity(0.0)

# changes the shield strength according to what (if any) fake generators have or are disabled/active
def RedefineShieldGenerators(pShip, ShieldGenerators, firstScriptRun=0,  pDisabledObjectName=None, pOperationalObjectName=None, toggleRequest=0):
print "RedefineShieldGenerators() ---------------------------------"
        
pShields = pShip.GetShields() # variable value: <C ShieldClass instance at _6162c64_p_ShieldClass>
pShipID = pShip.GetObjID()
lShields = GetPrimarySecondaryGenNames(pShip)

# get properties of fake primary and secondary shield generators
pPrimaryGen = MissionLib.GetSubsystemByName(pShip, lShields[0])
pSecondaryGen = MissionLib.GetSubsystemByName(pShip, lShields[1])

activeShieldGen = None
primaryAlreadyOn = 0 # for when the primary is on but the secondary becomes operational/disabled

if toggleRequest!=0:
# toggleRequest = 1 means secondary generator is already currently active and vice versa
if toggleRequest==1:
if not pPrimaryGen.IsDisabled():
activeShieldGen = pPrimaryGen
else:
return
elif toggleRequest==2 and not pSecondaryGen.IsDisabled():
# TOGGLE BUTTON, primary should be active but secondary has been specified
activeShieldGen = pSecondaryGen
else:
return
# determine which generator, if any, is going to become the activeShieldGen
elif firstScriptRun == 0:
if not pPrimaryGen.IsDisabled():
if pOperationalObjectName and pOperationalObjectName==lShields[0]:
print "Primary generator has just become operational. PRIMARY IS ACTIVESHIELDGEN"
# primary has just become operational
activeShieldGen = pPrimaryGen
elif pOperationalObjectName or pDisabledObjectName:
print "Secondary has just repaired OR secondary has just disabled. Either way PRIMARY IS ACTIVESHIELDGEN"
# secondary has just repaired OR secondary has just disabled, either way primary isn't disabled & so is already the active gen
primaryAlreadyOn = 1
else:
print "Primary isn't disabled and primary isn't already active"
# primary isn't disabled and primary isn't already active
activeShieldGen = pPrimaryGen
elif not pSecondaryGen.IsDisabled():
print "Primary IS disabled, Secondary is not. SECONDARY IS ACTIVESHIELDGEN"
# primary is offline & secondary is good to go
activeShieldGen = pSecondaryGen
else:
# both generators are disabled, disable the generator
print "REAL SHIELD GENERATOR NOW *DISABLED*"
pShields.GetProperty().SetDisabledPercentage(100.0)
else:
# first script run, both generators are operational so primary generator is the activeShieldGen
shipShieldVals[pShipID] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
activeShieldGen = pPrimaryGen

if activeShieldGen:
#  a generator will be going online, re-enable the players real generator
activeShieldGen = App.ShieldClass_Cast(activeShieldGen)
if pShields.IsDisabled():
print "REAL SHIELD GENERATOR NOW *ENABLED*"
pShields.GetProperty().SetDisabledPercentage(0.0)
# set power drained to that of new generator
pShields.GetProperty().SetNormalPowerPerSecond(activeShieldGen.GetProperty().GetNormalPowerPerSecond())
else:
pShields.GetProperty().SetNormalPowerPerSecond(0)

print "primaryAlreadyOn =", primaryAlreadyOn
print "firstScriptRun =", firstScriptRun
print "activeShieldGen =", activeShieldGen
print "primaryGen =", pPrimaryGen
print "secondaryGen =", pSecondaryGen

if pDisabledObjectName:
pDisabledObject = MissionLib.GetSubsystemByName(pShip, pDisabledObjectName)
pDisabledObject = App.ShieldClass_Cast(pDisabledObject)

        # assign each shield their values (front,rear,top,bottom,left,right)
        for Shield in range(App.ShieldClass.NUM_SHIELDS):
ShieldStrength = 0
                ShieldReload = 0
ShieldMax = 0

if firstScriptRun == 1:
print "FIRST RUN"
# store the MAX shield values for primary & secondary shield gens
pPrimaryGen = App.ShieldClass_Cast(pPrimaryGen)
shipShieldVals[pShipID][0][Shield]  = pPrimaryGen.GetMaxShields(Shield)
print Shield, "MAX shipShieldVals[", pShipID, "][0] = ", shipShieldVals[pShipID][0]
pSecondaryGen = App.ShieldClass_Cast(pSecondaryGen)
shipShieldVals[pShipID][1][Shield] = pSecondaryGen.GetMaxShields(Shield)
print Shield, "MAX shipShieldVals[", pShipID, "][1] = ", shipShieldVals[pShipID][1]
# set the MAX shield values for primary as the new shield strength/reload
ShieldMax = shipShieldVals[pShipID][0][Shield]
ShieldStrength = shipShieldVals[pShipID][0][Shield]
ShieldReload = pPrimaryGen.GetProperty().GetShieldChargePerSecond(Shield)
# apply the set values to the current shield
pShields.GetProperty().SetMaxShields(Shield, ShieldMax)
pShields.GetProperty().SetShieldChargePerSecond(Shield, ShieldReload)
pShields.SetCurShields(Shield, ShieldStrength)
print Shield, "Current shield max value is = ", ShieldMax
print Shield, "Current shield value is = ", ShieldStrength
print Shield, "Current shield reload value is = ", ShieldReload
else:
# get percent strength of current shield
ShieldPercentage = pShields.GetSingleShieldPercentage(Shield)
print "Percentage of current shield =", ShieldPercentage
if activeShieldGen:
# there will be a new generator taking over
if activeShieldGen.GetName() == lShields[0]:
if primaryAlreadyOn == 0:
if not pSecondaryGen.IsDisabled():
# secondary was the active gen, but primary is taking over
pSecondaryGen = App.ShieldClass_Cast(pSecondaryGen)
# using it's percentage, store the current  shield value of secondary shield generator
shipShieldVals[pShipID][1][Shield] = pSecondaryGen.GetMaxShields(Shield) / 100 * ShieldPercentage * 100
print Shield, "New STORED shipShieldVals[",pShipID,"][1] = ", shipShieldVals[pShipID][1]
# load the stored value of primary shield generator
pPrimaryGen = App.ShieldClass_Cast(pPrimaryGen)
ShieldMax = pPrimaryGen.GetMaxShields(Shield)
ShieldStrength = shipShieldVals[pShipID][0][Shield]
ShieldReload = activeShieldGen.GetProperty().GetShieldChargePerSecond(Shield)
print "Primary shield max = ", ShieldMax
print "Primary shield strength = ", ShieldStrength
print "Primary shield reload = ", ShieldReload
else:
# primary is active, secondary has just been disabled or fixed, nothing is changing so abort
print "Aborted because primaryAlreadyOn = 1"
return
else:
if pDisabledObjectName or toggleRequest==2:
# primary was the active gen, but secondary is taking over
# using it's percentage, store the current shield value of primary shield generator
pPrimaryGen = App.ShieldClass_Cast(pPrimaryGen)
shipShieldVals[pShipID][0][Shield] = pPrimaryGen.GetMaxShields(Shield) / 100 * ShieldPercentage * 100
print Shield, "New STORED shipShieldVals[", pShipID, "][0] = ", shipShieldVals[pShipID][0]
# load the stored value of secondary shield generator
pSecondaryGen = App.ShieldClass_Cast(pSecondaryGen)
ShieldMax = pSecondaryGen.GetProperty().GetMaxShields(Shield)
ShieldStrength = shipShieldVals[pShipID][1][Shield]
ShieldReload = activeShieldGen.GetProperty().GetShieldChargePerSecond(Shield)
print "Primary shield max = ", ShieldMax
print "Primary shield strength = ", ShieldStrength
print "Primary shield reload = ", ShieldReload
if ShieldStrength == 0.0:
ShieldStrength = 0.1
# apply the set values to the current shield
pShields.GetProperty().SetMaxShields(Shield, ShieldMax)
pShields.GetProperty().SetShieldChargePerSecond(Shield, ShieldReload)
pShields.SetCurShields(Shield, ShieldStrength)
print Shield, "Current shield max value is = ", ShieldMax
print Shield, "Current shield value is = ", ShieldStrength
print Shield, "Current shield reload value is = ", ShieldReload
else:
# there's no activeShieldGen, store shield values of the disabled gen (if there is one)
if pDisabledObjectName:
# store the current state of the disabled generators shields
if pDisabledObjectName == lShields[0]:
# using it's percentage, store the current  shield value of PRIMARY shield generator
shipShieldVals[pShipID][0][Shield] = pDisabledObject.GetMaxShields(Shield) / 100 * ShieldPercentage * 100
print Shield, "PRIMARY WAS ON, but is now OFF."
print Shield, "New STORED shipShieldVals[", pShipID, "][0] = ", shipShieldVals[pShipID][0]
else:
# using it's percentage, store the current  shield value of SECONDARY shield generator
shipShieldVals[pShipID][1][Shield] = pDisabledObject.GetMaxShields(Shield) / 100 * ShieldPercentage * 100
print Shield, "SECONDARY WAS ON, but is now OFF."
print Shield, "New STORED shipShieldVals[", pShipID, "][1] = ", shipShieldVals[pShipID][1]
if toggleRequest!=0 and activeShieldGen:
return activeShieldGen.GetObjID()

def ObjectDestroyed(pObject, pEvent):
        pObject = App.ObjectClass_Cast(pEvent.GetDestination())
print "ObjectDestroyed() ---------------------------------"
# abort if destroyed object is not a ship
        pShip = App.ShipClass_Cast(pObject)
        if not pShip or not pObject:
print "Destroyed object is NOT a ship."
                pObject.CallNextHandler(pEvent)
                return
# if the ship had a key in the dictionary, remove it
pShipID = pShip.GetObjID()
if shipShieldVals:
if shipShieldVals.has_key(pShipID):
del shipShieldVals[pShipID]
print "Removed the key", pShipID, "from shipShieldVals"
print "shipShieldVals is now =", shipShieldVals
if ctrlShiftKGenVictims:
if ctrlShiftKGenVictims.has_key(pShipID):
del ctrlShiftKGenVictims[pShipID]
print "Removed the key", pShipID, "from ctrlShiftKGenVictims"
print "ctrlShiftKGenVictims is now =", ctrlShiftKGenVictims
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
pButton = GetGenButton(pMenu)
if pShipID==MissionLib.GetPlayer().GetObjID() and pButton!=0:
# players ship has been destroyed, player is dead, remove button
print "Player is dead, button should have been been removed"
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
pMenu.DeleteChild(pButton)
print "plyrGenChoice = ", plyrGenChoice
if plyrGenChoice:
# bugfix: using 'in' instead of .has_key to avoid "TypeError: unsubscriptable object"
if pShip in plyrGenChoice.keys():
del plyrGenChoice[pShipID]
print "Destroyed ship removed from plyrGenChoice. plyrGenChoice = ", plyrGenChoice
print "pShipID is ", pShipID
print "ctrlShiftKGenVictims is =", ctrlShiftKGenVictims
print '\n\n'
        pObject.CallNextHandler(pEvent)

# check if ShipInstaRepair() has already ran
def InstaRepairAlreadyRan(pShip, opObjID=None):
shipID = pShip.GetObjID()
ShieldGenerators = GetAllShieldGenerators(pShip)
# checking if both generators are operational
if ShieldGenerators[0].IsDisabled() or ShieldGenerators[1].IsDisabled():
return 0
else:
# are all shields at full strength
lShields = GetPrimarySecondaryGenNames(pShip)
pPrimaryGen = MissionLib.GetSubsystemByName(pShip, lShields[0])
pSecondaryGen = MissionLib.GetSubsystemByName(pShip, lShields[1])
pPrimaryGen = App.ShieldClass_Cast(pPrimaryGen)
pSecondaryGen = App.ShieldClass_Cast(pSecondaryGen)
i = 0
while(i < 6):
if not shipShieldVals[shipID][0][i] == pPrimaryGen.GetMaxShields(i):
return 0
if not shipShieldVals[shipID][1][i] == pSecondaryGen.GetMaxShields(i):
return 0
i = i + 1
# bugfix: return 0 so SubsystemOperational() will redefine the generators even if the operational generator was  a CTRL+SHIFT+K victim
if ctrlShiftKGenVictims.has_key(shipID):
if opObjID==None:
print "There is no opObjID"
print "ctrlShiftKGenVictim ship key ", shipID, " removed from ctrlShiftKGenVictims"
del ctrlShiftKGenVictims[shipID]
return 0
else:
if opObjID in ctrlShiftKGenVictims[shipID]:
# function was called by SubsystemOperational()
print ">>>>>>>>>>>>>opObjID is ", opObjID
print "ctrlShiftKGenVictim ship key ", shipID, " removed from ctrlShiftKGenVictims"
del ctrlShiftKGenVictims[shipID]
return 0
else:
print "Ship does NOT have a ctrlShiftKVictim generator"
print "ctrlShiftKGenVictims contents: ", ctrlShiftKGenVictims
return 1

# returns 1 if ship has correct number of generators and properties of primary/secondary generators can be accessed through the foundation plugin
def CheckFakeGenerators(pShip, ShieldGenerators):
        if len(ShieldGenerators) > 1:
if len(ShieldGenerators) != 2:
print "ERROR: Ship type: ", GetShipType(pShip), " must have two non-primary generators for the Primary/Secondary shield script '\scripts\Custom\QBautostart\ShieldGenerators.py' to work."
else:
lShields = GetPrimarySecondaryGenNames(pShip)
print "LSHIELDS = ", lShields
if lShields == None:
print "ERROR: Unable to get any of the Primary/Secondary shield generators names from \scripts\Custom\Ships\\", GetShipType(pShip), ".py ."
elif len(lShields) != 2:
print "ERROR: Ship type: ", GetShipType(pShip), " must have the correct names of its two non-primary generators listed in scripts\Custom\Ships\\", GetShipType(pShip), ".py for the Primary/Secondary shield script '\scripts\Custom\QBautostart\ShieldGenerators.py' to work."
elif MissionLib.GetSubsystemByName(pShip, lShields[0]) == None or MissionLib.GetSubsystemByName(pShip, lShields[1]) == None:
print "ERROR: One or more of the Primary/Secondary shield generators names given in \scripts\Custom\Ships\\",GetShipType(pShip),".py are incorrect."
else:
return 1
return 0

# get the button and return it, if button can't be gotten return 0
def GetGenButton(pMenu, stateToGet=0):
if stateToGet==1:
pButton = Lib.LibEngineering.GetButton("Gen status: " + "Primary", pMenu)
elif stateToGet==2:
pButton = Lib.LibEngineering.GetButton("Gen status: " + "Secondary", pMenu)
elif stateToGet==3:
pButton = Lib.LibEngineering.GetButton("Gen status: " + "Offline", pMenu)
else:
pButton = Lib.LibEngineering.GetButton("Gen status: " + "Primary", pMenu)
if not pButton:
pButton = Lib.LibEngineering.GetButton("Gen status: " + "Secondary", pMenu)
if not pButton:
pButton = Lib.LibEngineering.GetButton("Gen status: " + "Offline", pMenu)
if pButton:
return pButton
else:
return 0

# determines what generator is currently active and sets button to reflect it
def SetButtonAppropriately(pShip, pButton):
lShields = GetPrimarySecondaryGenNames(pShip)
pPrimaryGen = MissionLib.GetSubsystemByName(pShip, lShields[0])
pSecondaryGen = MissionLib.GetSubsystemByName(pShip, lShields[1])
pShipID = pShip.GetObjID()
print "plyrGenChoice is = ", plyrGenChoice
print "my pShipID is = ", pShipID

if not pPrimaryGen.IsDisabled():
if (not plyrGenChoice.has_key(pShipID)) or (plyrGenChoice.has_key(pShipID) and plyrGenChoice[pShipID]!=2):
pButton.SetEnabled(1)
pButton.SetName(App.TGString("Gen status: " + "Primary"))
print "Text set to primary"
return
if not pSecondaryGen.IsDisabled():
print "A2"
pButton.SetEnabled(1)
pButton.SetName(App.TGString("Gen status: " + "Secondary"))
print "Text set to secondary"
if plyrGenChoice.has_key(pShipID) and plyrGenChoice[pShipID]!=0:
plyrGenChoice[pShipID] = 2
return
print "A3"
pButton.SetName(App.TGString("Gen status: " + "Offline"))
pButton.SetDisabled(1)
print "Text set to off"
if plyrGenChoice.has_key(pShipID):
plyrGenChoice[pShipID] = 0
print "plyrGenChoice = ", plyrGenChoice

# event handler for clicking the Primary/Secondary shield swap/toggle button
# button MUST only be present on menu when player is in a ship with primary/secondary shields
def SwapButton(pObject, pEvent):
global pButton
pShip = MissionLib.GetPlayer()
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
returnedVal = None
print ">!>!>!>!>!>!>!>!>!>!>!>! Button clicked!"
returnedVal = GetGenButton(pMenu, 1)
if returnedVal != 0:
pButton = returnedVal
ShieldGenerators = GetAllShieldGenerators(pShip)
returnedVal = RedefineShieldGenerators(pShip, ShieldGenerators, 0,  None, None, 2)
else:
returnedVal = GetGenButton(pMenu, 2)
if returnedVal != 0:
ShieldGenerators = GetAllShieldGenerators(pShip)
returnedVal = RedefineShieldGenerators(pShip, ShieldGenerators, 0,  None, None, 1)
genNames = GetPrimarySecondaryGenNames(pShip)
pPrimaryGenID = MissionLib.GetSubsystemByName(pShip, genNames[0]).GetObjID()
pSecondaryGenID = MissionLib.GetSubsystemByName(pShip, genNames[1]).GetObjID()
if returnedVal != None:
if returnedVal==pPrimaryGenID:
pButton.SetName(App.TGString("Gen status: " + "Primary"))
plyrGenChoice[pShip.GetObjID()] = 1
#FelixReaction(1)
print "TOGGLED FROM SECONDARY TO PRIMARY"
elif returnedVal==pSecondaryGenID:
pButton.SetName(App.TGString("Gen status: " + "Secondary"))
plyrGenChoice[pShip.GetObjID()] = 2
#FelixReaction(2)
print "TOGGLED FROM PRIMARY TO SECONDARY"
print "returnedVal", returnedVal
print "!!!!!!!!!!!!!!!!!!! plyrGenChoice IS = ", plyrGenChoice
pObject.CallNextHandler(pEvent)

def FelixReaction(switchSentence=0):
pBridgeSet = App.g_kSetManager.GetSet("bridge")
pTactical = App.CharacterClass_GetObject(pBridgeSet, "Tactical")
if (not pBridgeSet) or (not pTactical):
return

###Load localization database

pDatabase = App.g_kLocalizationManager.Load("data/TGL/Bridge Crew General.tgl")
pDatabase2 = App.g_kLocalizationManager.Load("data/TGL/PrimarySecondaryShieldGen.tgl")

pSequence = App.TGSequence_Create()

pAction1 = App.CharacterAction_Create(pTactical, App.CharacterAction.AT_SAY_LINE, pTactical.GetCharacterName() + "Yes4", None, 1, pDatabase)
pSequence.AddAction(pAction1)
if switchSentence==1:
pAction2 = App.CharacterAction_Create(pTactical, App.CharacterAction.AT_SAY_LINE, "PrimaryOnline", None, 1, pDatabase2)
else:
pAction2 = App.CharacterAction_Create(pTactical, App.CharacterAction.AT_SAY_LINE, "SecondaryOnline", None, 1, pDatabase2)
pSequence.AddAction(pAction2)
pAction3 = App.CharacterAction_Create(pTactical, App.CharacterAction.AT_PLAY_ANIMATION, "PushingButtons")
pSequence.AddAction(pAction3, pAction2, 0.7)

pSequence.Play()

###Unload database
App.g_kLocalizationManager.Unload(pDatabase)

def GodModeOn(pObject, pEvent):
print "GodModeOn() ---------------------------------"
# get players ship
pGame = App.Game_GetCurrentGame()
pShip = App.ShipClass_Cast(pGame.GetPlayer())
pShipID = pShip.GetObjID()

# is targetted ship in the dictionary?
        if shipShieldVals.has_key(pShipID):
# check if this handler has already been called
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
pButton = GetGenButton(pMenu, 1)
if pButton!=0 and InstaRepairAlreadyRan(pShip)==1:
return
ShieldGenerators = GetAllShieldGenerators(pShip)
RedefineShieldGenerators(pShip, ShieldGenerators, 1)
if plyrGenChoice.has_key(pShipID):
del plyrGenChoice[pShipID]
print "Players generator choice removed from plyrGenChoice. plyrGenChoice = ", plyrGenChoice
if pButton==0:
pButton = GetGenButton(pMenu)
SetButtonAppropriately(pShip, pButton)
print '\n\n'
        pObject.CallNextHandler(pEvent)

# toggle a global warning variable so SubsystemOperational() runs RedefineShieldGenerators()
# when CTRL+SHIFT+K is used to disable a generator without damaging any of the primary/secondary shields
def CtrlShiftKHit(pObject, pEvent):
print "CtrlShiftKHit() ---------------------------------"
# get players ship
pGame = App.Game_GetCurrentGame()
pShip = App.ShipClass_Cast(pGame.GetPlayer()) # pShip = <C ShipClass instance at _67fc330_p_ShipClass>

# add targetted subsystem to dictionary IF:
pTarget = pShip.GetTarget()
if(pTarget is None):
print "CtrlShiftK, no TARGET, aborting!"
return
pTargetSubSys = pShip.GetTargetSubsystem()
# is targetted ship in the dictionary?
        if shipShieldVals.has_key(pTarget.GetObjID()):
print "Targetted ship is in the master dictionary!"
# is targetted subsystem a shield generator?
subSysTargID = pTargetSubSys.GetObjID()
lShields = GetPrimarySecondaryGenNames(App.ShipClass_Cast(pTarget))
pPrimaryGen = MissionLib.GetSubsystemByName(App.ShipClass_Cast(pTarget), lShields[0])
pSecondaryGen = MissionLib.GetSubsystemByName(App.ShipClass_Cast(pTarget), lShields[1])
pPrimaryGenID = pPrimaryGen.GetObjID()
pSecondaryGenID = pSecondaryGen.GetObjID()
print "subSysTargID = ", subSysTargID
print "pPrimaryGenID = ", pPrimaryGenID
print "pSecondaryGenID = ", pSecondaryGenID
if subSysTargID == pPrimaryGenID or subSysTargID == pSecondaryGenID:
print "TARGETTED SUB-SYSTEM IS A FAKE PRIMARY OR SECONDARY SHIELD GENERATOR!"
else:
print "TARGETTED SUB-SYSTEM IS *NOT* A SHIELD GENERATOR!"
return
# add targeted generator to victim dictionary if disabled and doesn't already have a key
pTargShipID = pTarget.GetObjID()
if MissionLib.GetSubsystemByName(App.ShipClass_Cast(pTarget), lShields[0]).GetObjID() == subSysTargID:
target = 0
else:
target = 1
if pTargetSubSys.IsDisabled():
if ctrlShiftKGenVictims.has_key(pTargShipID):
if not subSysTargID in ctrlShiftKGenVictims[pTargShipID]:
ctrlShiftKGenVictims[pTargShipID][target]  = subSysTargID
print "CtrlShiftK victim ", subSysTargID, " added to ctrlShiftKGenVictims"
else:
print "Victim already in ctrlShiftKGenVictims"
else:
ctrlShiftKGenVictims[pTargShipID] = [0, 0]
ctrlShiftKGenVictims[pTargShipID][target]  = subSysTargID
print "CtrlShiftK victim ", subSysTargID, " added to ctrlShiftKGenVictims"
print "ctrlShiftKGenVictims contents: ", ctrlShiftKGenVictims
print '\n\n'
        pObject.CallNextHandler(pEvent)

# run RedefineShieldGenerators() with firstRun=1 (reset everything to MAX values & use primary generator)
def ShipInstaRepair(pObject, pEvent):
print "ShipInstaRepair() ---------------------------------"
# get players target
pGame = App.Game_GetCurrentGame()
pShip = App.ShipClass_Cast(pGame.GetPlayer())
pTarget = pShip.GetTarget()

if(pTarget is None):
print "No TARGET, aborting!"
return

# if the target is in the dictionary, call RedefineShieldGenerators() to reset it's shields to MAX
        if shipShieldVals.has_key(pTarget.GetObjID()):
pTarget = App.ShipClass_Cast(pTarget)
# stop the RedefineShieldGenerators() being called over and over
if InstaRepairAlreadyRan(pTarget) == 1:
print "ShipInstaRepair() HAS ALREADY RAN!"
return
ShieldGenerators = GetAllShieldGenerators(pTarget)
RedefineShieldGenerators(pTarget, ShieldGenerators, 1)
if plyrGenChoice.has_key(pTarget.GetObjID):
del plyrGenChoice[pTarget.GetObjID()]
print "InstaRepair target removed from plyrGenChoice. plyrGenChoice = ", plyrGenChoice
print '\n\n'
        pObject.CallNextHandler(pEvent)

# calls RedefineShieldGenerators() if disabled objects ship has a key in shipShieldVals
# the only way object can have a key in shipShieldVals is if NewShip() or NewPlayerShip() called RedefineShieldGenerators()
def SubsystemDisabled(pObject, pEvent):
        pDisabledObject = pEvent.GetSource()
print "SubsystemDisabled() ---------------------------------"
        if pDisabledObject.IsTypeOf(App.CT_SHIELD_SUBSYSTEM):
                pShip = App.ShipClass_Cast(pEvent.GetDestination())
shipID = pShip.GetObjID()
                ShieldGenerators = GetAllShieldGenerators(pShip)
                # check for multiple shield generators
                if shipShieldVals.has_key(shipID):
# get the name of the disabled object
lShields = GetPrimarySecondaryGenNames(pShip)
pDisabledObject = App.ShieldClass_Cast(pDisabledObject)
pDisabledObjectName = pDisabledObject.GetName()
print "Disabled object is =", pDisabledObjectName
# player gets special attention because of the swap button on his menu
# nothing needs to happen if primary is disabled but player has already manually
# toggled to secondary
if shipID==MissionLib.GetPlayer().GetObjID():
genNames = GetPrimarySecondaryGenNames(pShip)
if not pDisabledObjectName==genNames[1] and plyrGenChoice[shipID]!=2:
RedefineShieldGenerators(pShip, ShieldGenerators, 0,  pDisabledObjectName)
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
pButton = GetGenButton(pMenu)
SetButtonAppropriately(pShip, pButton)
else:
if plyrGenChoice.has_key(shipID):
if (plyrGenChoice[shipID]==2 and pDisabledObjectName==lShields[1]) or (plyrGenChoice[shipID]==1 and pDisabledObjectName==lShields[0]) or plyrGenChoice[shipID]==0:
# players previous choice of generator on the ship is irrelavant now as either: disabled object is the selected generator or there was no selected generator
del plyrGenChoice[shipID]
RedefineShieldGenerators(pShip, ShieldGenerators, 0,  pDisabledObjectName)
print "Player old choice on old ship was removed. plyrGenChoice = ", plyrGenChoice
else:
RedefineShieldGenerators(pShip, ShieldGenerators, 0,  pDisabledObjectName)
        print '\n\n'
        pObject.CallNextHandler(pEvent)

# calls RedefineShieldGenerators() if operational objects ship has a key in shipShieldVals
# the only way object can have a key in shipShieldVals is if NewShip() or NewPlayerShip() called RedefineShieldGenerators()
def SubsystemOperational(pObject, pEvent):
        pOperationalObject = pEvent.GetSource()
print "SubsystemOperational() ---------------------------------"
        if pOperationalObject.IsTypeOf(App.CT_SHIELD_SUBSYSTEM):
                pShip = App.ShipClass_Cast(pEvent.GetDestination())
                ShieldGenerators = GetAllShieldGenerators(pShip)
                # check for multiple shield generators
                if shipShieldVals.has_key(pShip.GetObjID()):
shipID = pShip.GetObjID()
lShields = GetPrimarySecondaryGenNames(pShip)
pOperationalObject = App.ShieldClass_Cast(pOperationalObject)
# bugfix: don't keep trying to redefine generators when CTRL+SHIFT+R has just been used
if InstaRepairAlreadyRan(pShip, pOperationalObject.GetObjID()) == 1:
print "ShipInstaRepair() HAS ALREADY RAN!"
return
pOperationalObjectName = pOperationalObject.GetName()
print "Operational object is =", pOperationalObjectName
# player gets special attention because of the swap button on his menu
# nothing needs to happen if primary is operational but player has already manually
# toggled to secondary
if shipID==MissionLib.GetPlayer().GetObjID():
genNames = GetPrimarySecondaryGenNames(pShip)
if not pOperationalObjectName==genNames[1] and plyrGenChoice[shipID]!=2:
RedefineShieldGenerators(pShip, ShieldGenerators, 0,  None, pOperationalObjectName)
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
pButton = GetGenButton(pMenu)
SetButtonAppropriately(pShip, pButton)
else:
if plyrGenChoice.has_key(shipID):
# players previous choice of generator on the ship is irrelavant, ship generator handling returns to automatic
del plyrGenChoice[shipID]
print "Player old choice on old ship was removed. plyrGenChoice = ", plyrGenChoice
RedefineShieldGenerators(pShip, ShieldGenerators, 0,  None, pOperationalObjectName)
        print '\n\n'
pObject.CallNextHandler(pEvent)

# called when a new ship (object) is created
# also called once for the player when quickbattle starts
def NewShip(pObject, pEvent):
        pShip = App.ShipClass_Cast(pEvent.GetDestination())
print "NewShip() ---------------------------------"
        if not pShip:
print "NEWSHIP IS NOT A SHIP!"
                return
        print "New ships type = ", GetShipType(pShip)
ShieldGenerators = GetAllShieldGenerators(pShip)
        # check if new ship is configured for primary/secondary generators
global pButton
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
if CheckFakeGenerators(pShip, ShieldGenerators) == 1:
print "New ship is elligable for primary/secondary shield generators."
SetUpShip(pShip)
RedefineShieldGenerators(pShip, ShieldGenerators, 1)
pButton = GetGenButton(pMenu)
if pShip.GetObjID() == MissionLib.GetPlayer().GetObjID() and pButton==0:
# add button to players new ship tactical menu
pButton = Lib.LibEngineering.CreateMenuButton("Gen status: " + "Primary", "Tactical", __name__ + ".SwapButton")
#plyrGenChoice[pShip.GetObjID()] = 0
SetButtonAppropriately(pShip, pButton)
print ">!>!>!>!>!>!>!>!>!>!>!>! BUTTON CREATED"
else:
pButton = GetGenButton(pMenu)
if pShip.GetObjID()==MissionLib.GetPlayer().GetObjID() and pButton!=0:
# remove the button from players menu as his newship isn't a prim/sec shield ship
print ">!>!>!>!>!>!>!>!>!>!>!>! BUTTON SHOULD HAVE BEEN REMOVED"
if plyrGenChoice.has_key(pShip.GetObjID()):
del plyrGenChoice[pShip.GetObjID()]
pMenu.DeleteChild(pButton)
print '\n\n'
        pObject.CallNextHandler(pEvent)

# called by QBautostart extension when the player gets a new ship
# sets up players shields if his new ship has correct number of fake (non-primary) generator
def NewPlayerShip():
        pShip = MissionLib.GetPlayer()
print "NewPlayerShip() ---------------------------------"
        if not pShip:
print "NEW PLAYERS SHIP IS NOT A SHIP!"
                return
print "Players new ship type = ", GetShipType(pShip)
global pButton
pMenu = Lib.LibEngineering.GetBridgeMenu("Tactical")
pButton = GetGenButton(pMenu)
if shipShieldVals.has_key(pShip.GetObjID()):
# players new ship has an entry and therefor has been setup already
print "PLAYER HAS TRANSPORTED TO ANOTHER ", GetShipType(pShip)
# TELEPORTED TO A SHIP WITH PRIM/SEC SHIELDS, DO SPECIAL STUFF WITH THE BUTTON
if pButton==0:
# players newship is eligable for the button but it hasn't been created yet
pButton = Lib.LibEngineering.CreateMenuButton("Gen status: " + "Primary", "Tactical", __name__ + ".SwapButton")
print ">!>!>!>!>!>!>!>!>!>!>!>! BUTTON CREATED"
# now button exists, set it to reflect status of newships generators
#if not plyrGenChoice.has_key(pShip.GetObjID()):
# plyrGenChoice[pShip.GetObjID()] = 0
SetButtonAppropriately(pShip, pButton)
print "BUTTON SHOULD REFLECT STATUS OF NEWSHIP"
return
        # check if new ship is configured for primary/secondary generators
        ShieldGenerators = GetAllShieldGenerators(pShip)
if CheckFakeGenerators(pShip, ShieldGenerators) == 1:
print "Players new ship is elligable for primary/secondary shield generators."
SetUpShip(pShip)
RedefineShieldGenerators(pShip, ShieldGenerators, 1)
elif pButton!=0:
# REMOVE THE BUTTON FROM PLAYERS MENU AS HIS NEWSHIP ISN'T A PRIM/SEC SHIELD SHIP
print ">!>!>!>!>!>!>!>!>!>!>!>! BUTTON SHOULD HAVE BEEN REMOVED"
pShip = App.ShipClass_Cast(pShip)
if plyrGenChoice.has_key(pShip.GetObjID()):
del plyrGenChoice[pShip.GetObjID()]
pMenu.DeleteChild(pButton)
print "!!!!!!!!!!!!!!!!!!! plyrGenChoice IS = ", plyrGenChoice
print '\n\n'

def init():
# Multiplayer check
if App.g_kUtopiaModule.IsMultiplayer() and not App.g_kUtopiaModule.IsHost():
return
print "init() ---------------------------------"
pMission = MissionLib.GetMission()
# player mission value = <C Mission instance at _3505240_p_Mission>
# event handlers
App.g_kEventManager.AddBroadcastPythonFuncHandler(App.ET_SUBSYSTEM_DISABLED, pMission ,  __name__ + ".SubsystemDisabled")
App.g_kEventManager.AddBroadcastPythonFuncHandler(App.ET_SUBSYSTEM_OPERATIONAL, pMission ,  __name__ + ".SubsystemOperational")
App.g_kEventManager.AddBroadcastPythonFuncHandler(Foundation.TriggerDef.ET_FND_CREATE_SHIP, pMission, __name__ + ".NewShip")
App.g_kEventManager.AddBroadcastPythonFuncHandler(App.ET_OBJECT_EXPLODING, pMission, __name__ + ".ObjectDestroyed")
# TestMode / debug / CHEAT event handlers
App.g_kEventManager.AddBroadcastPythonFuncHandler(App.ET_INPUT_DEBUG_QUICK_REPAIR, pMission, __name__ + ".ShipInstaRepair")
App.g_kEventManager.AddBroadcastPythonFuncHandler(App.ET_INPUT_DEBUG_KILL_TARGET, pMission, __name__ + ".CtrlShiftKHit")
App.g_kEventManager.AddBroadcastPythonFuncHandler(App.ET_INPUT_DEBUG_GOD_MODE, pMission, __name__ + ".GodModeOn")
        NewPlayerShip()

Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: Imitating BCs shield recharge when gen offline?
« Reply #1 on: July 17, 2012, 01:51:54 PM »
What about a timer? You check the state of the shields then update the dictionary values to simulate the recharge.
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #2 on: July 17, 2012, 01:59:39 PM »
I've been suspecting something like that after looking over how the Shield Percentages mod updates the numbers in the shield display window BUT even if I could imitate the timer how do I accurately reflect what BC does when it updates shield health.

I mean, where's the code that BC runs to heal the shields even when they're offline. I know for sure it uses definitions made in the hardpoint file such as:
Code: [Select]
PrimaryShieldGenerator.SetMaxShields(PrimaryShieldGenerator.FRONT_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetMaxShields(PrimaryShieldGenerator.REAR_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetMaxShields(PrimaryShieldGenerator.TOP_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetMaxShields(PrimaryShieldGenerator.BOTTOM_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetMaxShields(PrimaryShieldGenerator.LEFT_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetMaxShields(PrimaryShieldGenerator.RIGHT_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetShieldChargePerSecond(PrimaryShieldGenerator.FRONT_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetShieldChargePerSecond(PrimaryShieldGenerator.REAR_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetShieldChargePerSecond(PrimaryShieldGenerator.TOP_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetShieldChargePerSecond(PrimaryShieldGenerator.BOTTOM_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetShieldChargePerSecond(PrimaryShieldGenerator.LEFT_SHIELDS, 1.000000)
PrimaryShieldGenerator.SetShieldChargePerSecond(PrimaryShieldGenerator.RIGHT_SHIELDS, 1.000000)
but where's it actually *doing* the update?

I figure if the Totally Games written code that does what it does now were found it could be applied or at least adapted to work on my dictionary of values. It just seems more obvious and less labor intensive to adapt what TG has already done than ignore it and throw together some concoction of my own.

What do you think Sov?
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: Imitating BCs shield recharge when gen offline?
« Reply #3 on: July 17, 2012, 02:16:05 PM »
My best guess is that its handled by the C++ portion and is not exposed to python. So you will have to mimic the behavior with your own equivalent python code. And that will take trial and error.
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #4 on: July 17, 2012, 02:33:19 PM »
My best guess is that its handled by the C++ portion and is not exposed to python. So you will have to mimic the behavior with your own equivalent python code. And that will take trial and error.
Ah, so i'm looking for something that's compiled away into an inaccessable part of the game... go figure (thinks back to modding C&C Generals)  :cry:

Could be worse I guess. Only complication I can imagine would actually be determining what generator is not active and only specifically updating that ones values. You see, strangely, I havn't actually told the script to keep a record of what generator on what ship is active and not to mention the player can use a button to manually swap generators even when none of them are disabled.

Don't worry about it though, i've reshaped this script countless times to add functionality I want and i'm sure I can get this working.
Of course, if you want to throw in some sample code or any helping tips regarding how to implement this timer update thing I wouldn't be upset  :P

If you don't reply back i'll post here to tell you how successful i've been.
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: Imitating BCs shield recharge when gen offline?
« Reply #5 on: July 17, 2012, 02:40:10 PM »
Timer sample code here:
Code: [Select]
MissionLib.CreateTimer(Libs.LibEngineering.GetEngineeringNextEventType(), __name__ + ".MethodToCall", App.g_kUtopiaModule.GetGameTime() + 1, 0, 0)

def MethodToCall(pObj, pEvent):
# do something with dict
        # maybe loop through all ships and check their state + the magical formula which we don't have yet

# call again and again
MissionLib.CreateTimer(Libs.LibEngineering.GetEngineeringNextEventType(), __name__ + ".MethodToCall", App.g_kUtopiaModule.GetGameTime() + 1, 0, 0)
Acta, non verba.
aka USS Sovereign

Offline King Class Scout

  • Posts: 1775
  • Cookies: 893
  • the other half of SFRD
Re: Imitating BCs shield recharge when gen offline?
« Reply #6 on: July 17, 2012, 03:20:19 PM »
the attach bits were disabled by admin for cleanup and bandwidth reduction purposes.  there was a crisis over it, of sorts.

OS novel fan

Coming Soon: King's Mod Tuning Shop

best line I've ever read
Me: mine [my bridges] would probably be simple to get the characters to use.  the only person that sits is the captian.
Baz: space is vast there[sic] legs will be tired by the time they get to the next planet

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #7 on: July 17, 2012, 05:03:00 PM »
Timer sample code here:
Code: [Select]
MissionLib.CreateTimer(Libs.LibEngineering.GetEngineeringNextEventType(), __name__ + ".MethodToCall", App.g_kUtopiaModule.GetGameTime() + 1, 0, 0)

def MethodToCall(pObj, pEvent):
# do something with dict
        # maybe loop through all ships and check their state + the magical formula which we don't have yet

# call again and again
MissionLib.CreateTimer(Libs.LibEngineering.GetEngineeringNextEventType(), __name__ + ".MethodToCall", App.g_kUtopiaModule.GetGameTime() + 1, 0, 0)
Thanks Sov. I wouldn't have expected to have to keep resetting the timer when the handler is called.

the attach bits were disabled by admin for cleanup and bandwidth reduction purposes.  there was a crisis over it, of sorts.


That's surprisingly annoying. Us users only realize what we had when it's gone I guess. Now bc-central is just like countless other forums that force users to link in files from 3rd party sites  :mad:
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: Imitating BCs shield recharge when gen offline?
« Reply #8 on: July 17, 2012, 05:16:10 PM »
Thanks Sov. I wouldn't have expected to have to keep resetting the timer when the handler is called.

The idea is to simulate threading, you could start your own thread however but in your case this will do.

That's surprisingly annoying. Us users only realize what we had when it's gone I guess. Now bc-central is just like countless other forums that force users to link in files from 3rd party sites  :mad:

It was either this or no forum at all. Viper had to make a tough decision.
Acta, non verba.
aka USS Sovereign

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: Imitating BCs shield recharge when gen offline?
« Reply #9 on: July 17, 2012, 05:40:04 PM »
What Mods are you running your BC with? KM any version?

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #10 on: July 17, 2012, 06:11:54 PM »
The idea is to simulate threading, you could start your own thread however but in your case this will do.

It was either this or no forum at all. Viper had to make a tough decision.
Threading, errr yeah... heard it's more trouble than it's worth in many cases. For what i'm doing remaking the timer is far more suitable.

What Mods are you running your BC with? KM any version?
I havn't got KM installed. I've been trying for the past day but the .zip won't open because my brother probably somehow corrupted it before giving it me.

My BC install actually really doesn't have all that much customised yet. Here's the list.

Quote
############################# GENERAL ###############################
> BCUTs Foundation (full version)
> qbautostart0.9.1 (with a very buggy, or atleast poorly tested, version of Transport2Ship)
> tractor_beam_settings   
> addship (quite buggy, doesn't give names to ships when you use "Use names" etc)
> singlepulsetoggle (lets you fire all disruptors at same time, very usefull)
> ShieldPercentages
############################# TEXTURES ###############################
> damageTextures
> deadShipExplosions
> KessokLightRetexture
############################# SHIPS ###################################
> nemesisSovEntBridge
> \MyCustomMods\Hybrid Mods.zip\Repair System\+Cloak
> crcube
> KessokSpaceStation-AND-KessokDrydock
> \MyCustomMods\Custom Scorpion
> \MyCustomMods\Custom Scimitar   (my heavily re-hardpointed version of scimitarJH)
I've been working on this secondary shield generators script for a long time now and thinking of working on it ever since my first post about it. Just can't bring myself to do other things until this script is *done*. More than anything I want this to be bug free. With BC already so inherantly unstable and so many mods being released that are, at best, half-baked I don't want this script to be one of them that messes up.
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: Imitating BCs shield recharge when gen offline?
« Reply #11 on: July 17, 2012, 06:24:59 PM »
Quote
Threading, errr yeah... heard it's more trouble than it's worth in many cases. For what i'm doing remaking the timer is far more suitable.

I agree for this scenario, however you should not fear multithreading in applications. It has legitimate uses and it should be utilized, not feared.
Acta, non verba.
aka USS Sovereign

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: Imitating BCs shield recharge when gen offline?
« Reply #12 on: July 18, 2012, 02:47:04 AM »
> qbautostart0.9.1 (with a very buggy, or atleast poorly tested, version of Transport2Ship)
uhm, what Bugs?

 
> addship (quite buggy, doesn't give names to ships when you use "Use names" etc)
Probably because you are missing a requirement. What do you mean with "etc"?

-

The behaviour on red/green alert you describe might be caused by a mod, but I don't see any evil on your list.

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #13 on: July 18, 2012, 07:54:39 AM »
uhm, what Bugs?
Probably because you are missing a requirement. What do you mean with "etc"?

-

The behaviour on red/green alert you describe might be caused by a mod, but I don't see any evil on your list.
Not a darned clue what was causing my Transport2Ship problems but i've reinstalled it and QBAutostart and it seems to run okay now.
Addship is a little glitchy, selecting a ship to be added as neutral and most of the addship GUI interface dissappears. Checking the "Use Names" flag also does nothing; ships are named same regardless.

As for the shield behaviour, it could possibly be caused by a mod (I guess) but then again my 1.1 isn't exactly a monster overhaul yet and you've got the list of all mods installed posted above. I don't see anything in there that mentions changing shield functionality. Although... I never found out what mysteriously caused my phasers to become innacurate at range and why the main battery in F5 view pulses up and down  :idk:

EDIT: Can I have an example of how to get a specific subsystem with only its shipID and subsystemID at hand? I've managed to get the ship using its ID but can't get the subsystem.

Here's what I got at the moment:
Code: [Select]
# imitates what Bridge Commander does when shields are powered to 0%
# increases stored shield values for generators on ships that aren't currently being used
def UpdateStoredGenHealth(pObject, pEvent):
if nonActiveGens and shipShieldVals:
print "UpdateStoredGenHealth() ---- at", App.g_kUtopiaModule.GetGameTime()
# for each ship in dictionary
for shipID in nonActiveGens.keys():
noChangeMade = 1
currGenerator = App.ShipClass_GetObjectByID(App.SetClass_GetNull(), nonActiveGens[shipID])
print "currGenerator =", currGenerator
currGenerator = App.ShieldClass_Cast(currGenerator)
ship = App.ShipClass_GetObjectByID(App.SetClass_GetNull(), shipID)
ship = App.ShipClass_Cast(ship)
genNames = GetPrimarySecondaryGenNames(ship)
generator = 0
print "ship =", ship
print "currGenerator =", currGenerator
print "genNames =", genNames
if currGenerator.GetName() == genNames[1]:
generator = 1
print "->->->->shipShieldVals[", shipID, "] =,", shipShieldVals[shipID]
# for all stored shield values of that generator
for shield in range(0, 6):
# set shield strength equal to current + perSecond amount, but don't allow it to go over maximum charge
print "shipShieldVals[shipID] =",shipShieldVals[shipID]
print "nonActiveGens[shipID] =",nonActiveGens[shipID]
print "[shield]",[shield]
result = shipShieldVals[shipID][generator][shield] + currGenerator.GetShieldChargePerSecond(shield)
max = currGenerator.GetMaxShields(shield)
if shipShieldVals[shipID][generator][shield] == max:
continue
elif max < result:
shipShieldVals[shipID][generator][shield] = result
noChangeMade = 0
else:
shipShieldVals[shipID][generator][shield] = max
if noChangeMade:
# if no change was made then values are all at full strength, remove it
del nonActiveGens[shipID]
print "->->->-> no change made,", shipID, "removed from dictionary"
print "->->->->shipShieldVals[", shipID, "] =,", shipShieldVals[shipID]
# call again and again
MissionLib.CreateTimer(Lib.LibEngineering.GetEngineeringNextEventType(), __name__ + ".UpdateStoredGenHealth", App.g_kUtopiaModule.GetGameTime() + 1, 0, 0)
Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: Imitating BCs shield recharge when gen offline?
« Reply #14 on: July 18, 2012, 11:01:04 AM »
Not a darned clue what was causing my Transport2Ship problems but i've reinstalled it and QBAutostart and it seems to run okay now.

Addship is a little glitchy, selecting a ship to be added as neutral and most of the addship GUI interface dissappears. Checking the "Use Names" flag also does nothing; ships are named same regardless.
Not really a bug, just more my lack of GUI-skills. You have to scroll up again.

As for the shield behaviour, it could possibly be caused by a mod (I guess) but then again my 1.1 isn't exactly a monster overhaul yet and you've got the list of all mods installed posted above. I don't see anything in there that mentions changing shield functionality.
I had a bug in QBsutostart/power.py that could cause this, but since you do not have this one installed..
Try to reproduce the problem with all mods disabled.

Although... I never found out what mysteriously caused my phasers to become innacurate at range and why the main battery in F5 view pulses up and down  :idk:
Phaser: Foundation Tech or Sneaker inaccurate Phasers.
Battery: Is also on Stock BC. The battery constantly charged/discharged.

EDIT: Can I have an example of how to get a specific subsystem with only its shipID and subsystemID at hand? I've managed to get the ship using its ID but can't get the subsystem.
What exactly do you want to do?
You probably need to iterate over all ship subsystems until you got the one with the id.
Look at Missionlib.py/GetSubsystemByName() on how to do that.
It would be easier if you use the subsystem name instead.

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #15 on: July 18, 2012, 11:24:34 AM »
What exactly do you want to do?
You probably need to iterate over all ship subsystems until you got the one with the id.
UpdateStoredHealthGen is called every 1 second and basically (is supposed to) go through all generators that aren't active and update their health by + whatever that current shields ShieldChargePerSecond is.

I want to run through that shield generators stored values in the master dictionary. Before I can do that though I need to retrieve each shields ShieldRecharge and MaxShield values. I can only do this by getting properties of the generator subsystem.

The useful information I have to do so is:
shipShieldVals, dictionary storing the ship id, generator number and shield values. e.g. {(shipID: [frontVal,rearVal,leftVal,rightVal,topVal,bottomVal], [frontVal,rearVal,leftVal,rightVal,topVal,bottomVal])}
nonActiveGens, dictionary storing the ship id and generator id in key value pairs. e.g. {shipID: genID}

Hence these lines in UpdateStoredHealthGen(pObject, pEvent):
Code: [Select]
currGenerator = App.ShipClass_GetObjectByID(App.SetClass_GetNull(), nonActiveGens[shipID])
currGenerator = App.ShieldClass_Cast(currGenerator)
Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: Imitating BCs shield recharge when gen offline?
« Reply #16 on: July 18, 2012, 12:17:19 PM »
Use pShip.GetShields().
Code: [Select]
pShip = App.ShipClass_GetObjectByID(None, shipID)
pShields = pShip.GetShields()
..
pShip.GetShields().GetProperty().SetShieldChargePerSecond(fValue)

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #17 on: July 18, 2012, 09:44:27 PM »
Use pShip.GetShields().
Code: [Select]
pShip = App.ShipClass_GetObjectByID(None, shipID)
pShields = pShip.GetShields()
..
pShip.GetShields().GetProperty().SetShieldChargePerSecond(fValue)
Thanks but I needed to get properties of the fake (non primary) generator subsystems so I did what you suggested and use GetSubsystemByName().
Code: [Select]
# imitates what Bridge Commander does when shields are powered to 0%
# increases stored shield values for generators on ships that aren't currently being used
def UpdateStoredGenHealth(pObject, pEvent):
if nonActiveGens and shipShieldVals:
print "UpdateStoredGenHealth() ---------"
# for each ship in dictionary
for shipID in nonActiveGens.keys():
# get the ship, use the ship to get fake generator names, use names to get correct fake generator
ship = App.ShipClass_GetObjectByID(App.SetClass_GetNull(), shipID)
ship = App.ShipClass_Cast(ship)
genNames = GetPrimarySecondaryGenNames(ship)
currGenerator = MissionLib.GetSubsystemByName(ship, genNames[0])
generator = 0
if not currGenerator.GetObjID() == nonActiveGens[shipID]:
currGenerator = MissionLib.GetSubsystemByName(ship, genNames[1])
currGenerator = App.ShieldClass_Cast(currGenerator)
generator = 1
# for all stored shield values of that generator
noChangeMade = 1
currGenerator = App.ShieldClass_Cast(currGenerator)
for shield in range(0, 6):
# set shield strength equal to current + perSecond amount, but don't allow it to go over maximum charge
result = shipShieldVals[shipID][generator][shield] + currGenerator.GetShieldChargePerSecond(shield)
max = currGenerator.GetMaxShields(shield)
if shipShieldVals[shipID][generator][shield] == max:
continue
elif max > result:
shipShieldVals[shipID][generator][shield] = result
noChangeMade = 0
else:
shipShieldVals[shipID][generator][shield] = max
noChangeMade = 0
if noChangeMade:
# if no change was made then values are all at full strength, remove it
del nonActiveGens[shipID]
# call again and again
MissionLib.CreateTimer(Lib.LibEngineering.GetEngineeringNextEventType(), __name__ + ".UpdateStoredGenHealth", App.g_kUtopiaModule.GetGameTime() + 1, 0, 0)

I know it's not exactly award winning for code quality but it works exactly like BC works when shields are powered to 0%... .... but... doesn't the heal rate vary according to the % amount of power given to the shield system? It must right, or else what's the point in the percentage slider? What do you guys think? How much further would I need to take the above function to repair shields at different rates depending on the selected power % ?
Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: Imitating BCs shield recharge when gen offline?
« Reply #18 on: July 19, 2012, 03:35:27 AM »
Check if you already get different GetShieldChargePerSecond() values for different power settings.

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: Imitating BCs shield recharge when gen offline?
« Reply #19 on: July 19, 2012, 09:04:28 AM »
Check if you already get different GetShieldChargePerSecond() values for different power settings.
I performed a little test as you suggested. I transported to another ship, damaged my ships shields, transported back to my ship, set shield generator power to 50% and swapped shields to secondary.

The results were that the GetShieldChargePerSecond() value is unnafected by changes in % power given. It simply retrieves the same value from the hardpoint file. If only there was a function to get the % value that's displayed in the F5 menu it'd be possible to do something like:

Code: [Select]
charge = currGenerator.GetShieldChargePerSecond(shield) / 100 * currGenerator.GetSystemPowerGiven()
result = shipShieldVals[shipID][generator][shield] + charge
max = currGenerator.GetMaxShields(shield)
# proceed on to doing what needs to be done :)

 :(
Great men are not peacemakers! Great men are conquerors!