Exemple #1
0
class DefenseCannonGUI(CannonGUI):
    notify = DirectNotifyGlobal.directNotify.newCategory('DefenseCannonGUI')

    def __init__(self, cannon):
        CannonGUI.__init__(self, cannon)
        self.exitEvent = None
        self.__dialog = None
        self.helpButton = None
        self.helpUI = None
        self.flashHelp = None
        self.ammoFade = None
        self.__ammoCountersHidden = False
        self.setupExtraButtons()
        self.exitCannon['command'] = self.showExitDialog
        self.volleyLabel.setPos(-0.28, 0, 0.09)
        self.reloadBar.setPos(-0.13, 0, 0.08)
        self.ammoImage.setPos(-0.38, 0, 0.06)
        self.repMeter = ReputationMeter(InventoryType.DefenseCannonRep,
                                        width=0.7)
        self.repMeter.reparentTo(base.a2dBottomCenter)
        self.repMeter.setPos(0.0, 0.0, 0.025)
        self.hud = CannonDefenseHUD()
        self.hud.create()
        self._exp = 0
        self.lastLevel = 1
        self.accept('incDefenseCannonExp', self.increaseExp)
        if __dev__:
            base.dcg = self
        return

    def destroy(self):
        if self.ammoFade:
            self.ammoFade.finish()
            self.ammoFade = None
        if self.flashHelp:
            self.flashHelp.finish()
            self.flashHelp = None
        if self.helpButton:
            self.helpButton.destroy()
            self.helpButton = None
        if self.helpUI:
            self.helpUI.destroy()
            self.helpUI = None
        if self.hud:
            self.hud.destroy()
            self.hud = None
        base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_MINIGAME_CANNON)
        self.repMeter.destroy()
        self.ignore('incDefenseCannonExp')
        CannonGUI.destroy(self)
        return

    def setupExtraButtons(self):
        weaponIcons = loader.loadModel('models/gui/gui_icons_weapon')
        self.helpButton = DirectButton(
            parent=base.a2dBottomRight,
            relief=None,
            pos=(-0.6, 0, 0.09),
            scale=0.5,
            text='?',
            text_pos=(0, -0.055),
            text_scale=0.21,
            text_fg=PiratesGuiGlobals.TextFG2,
            text_shadow=PiratesGuiGlobals.TextShadow,
            text_font=PiratesGlobals.getPirateBoldOutlineFont(),
            sortOrder=2,
            command=self.toggleHelpUI)
        DirectLabel(parent=self.helpButton,
                    text=PLocalizer.CannonDefense['Help'],
                    text_pos=(0, -0.15),
                    text_scale=0.08,
                    text_fg=PiratesGuiGlobals.TextFG2,
                    text_shadow=PiratesGuiGlobals.TextShadow,
                    text_font=PiratesGlobals.getPirateBoldOutlineFont(),
                    frameColor=(1, 1, 1, 0))
        return

    def increaseExp(self, amt, total):
        self._exp += amt
        if self._exp > total:
            return
        level, leftoverValue = ReputationGlobals.getLevelFromTotalReputation(
            InventoryType.DefenseCannonRep, self._exp)
        self.repMeter.update(self._exp)
        if level > self.lastLevel:
            base.localAvatar.levelUpMsg(InventoryType.DefenseCannonRep, level,
                                        0)
            self.lastLevel = level

    def toggleHelpUI(self):
        if self.helpUI == None:
            self.__createHelpUI()
            self.fadeOutAmmoCounters()
            if self.cannon.ammoPanel.state == pirates.minigame.AmmoPanel.CLOSED:
                self.cannon.ammoPanel.onTabClick()
        else:
            self.__destroyHelpUI()
            self.fadeInAmmoCounters()
            if self.cannon.ammoPanel.state == pirates.minigame.AmmoPanel.OPENED:
                self.cannon.ammoPanel.onTabClick()
        return

    def __createHelpUI(self):
        self.helpUI = CannonDefenseHelpManager(0.5)
        self.helpUI.exit.reparentTo(self.exitCannon)
        self.helpUI.exit.setScale(2.0)
        self.helpUI.help.reparentTo(self.helpButton)
        self.helpUI.help.setScale(2.0)
        self.helpUI.ammoPanel.reparentTo(self.cannon.ammoPanel.panel)
        self.helpUI.ammoPanel.setScale(1.0 / 3.0)
        self.helpUI.ammo.reparentTo(base.a2dBottomCenter)
        self.helpUI.mine.reparentTo(self.hud.goldRemainingUI.mineCounter)
        self.helpUI.mine.setScale(2.0 / 3.0)
        self.helpUI.wave.reparentTo(self.hud.timeRemainingUI.timeRemaining)
        self.helpUI.wave.setScale(1.0 / 0.75)
        self.helpUI.fadeIn.start()

    def __destroyHelpUI(self):
        cleanup = Sequence(Func(self.helpUI.fadeIn.pause),
                           self.helpUI.fadeOut,
                           Func(self.helpUI.destroy),
                           name=self.cannon.uniqueName('HelpUI_FadeIn'))
        cleanup.start()
        self.helpUI = None
        return

    def isHelpUIVisible(self):
        return self.helpUI != None

    def flashHelpButton(self, delay=0.2, length=5):
        if self.flashHelp:
            self.flashHelp.finish()
            self.flashHelp = None
        self.flashHelp = Sequence(
            name=self.cannon.uniqueName('HelpButton_Flash'))

        def setColor(key, value):
            self.helpButton[key] = value

        for i in range(0, length):
            self.flashHelp.append(Wait(delay))
            self.flashHelp.append(
                Func(setColor, 'text_fg', PiratesGuiGlobals.TextFG19))
            self.flashHelp.append(Wait(delay))
            self.flashHelp.append(
                Func(setColor, 'text_fg', PiratesGuiGlobals.TextFG2))

        self.flashHelp.start()
        return

    def fadeOutAmmoCounters(self, length=0.5):
        if self.__ammoCountersHidden:
            return
        transparent = Vec4(1, 1, 1, 0)
        if self.ammoFade:
            self.ammoFade.finish()
        self.ammoFade = Parallel(
            self.volleyLabel.colorScaleInterval(length, transparent),
            self.reloadBar.colorScaleInterval(length, transparent),
            self.ammoImage.colorScaleInterval(length, transparent))
        self.ammoFade.start()
        self.__ammoCountersHidden = True

    def fadeInAmmoCounters(self, length=0.5):
        if self.__ammoCountersHidden == False:
            return
        opaque = Vec4(1, 1, 1, 1)
        transparent = Vec4(1, 1, 1, 0)
        if self.ammoFade:
            self.ammoFade.finish()
        self.ammoFade = Parallel(
            self.volleyLabel.colorScaleInterval(length, opaque, transparent),
            self.reloadBar.colorScaleInterval(length, opaque, transparent),
            self.ammoImage.colorScaleInterval(length, opaque, transparent))
        self.ammoFade.start()
        self.__ammoCountersHidden = False

    def showExitDialog(self):
        if self.__dialog == None:
            self.__dialog = PDialog(
                text=PLocalizer.CannonDefense['ExitCannon'],
                style=OTPDialog.YesNo,
                giveMouse=False,
                command=self.__onDialogItemSelected)
        else:
            self.__dialog.cleanup()
            self.__dialog = None
        return

    def __onDialogItemSelected(self, value):
        if value == 1:
            if self.exitEvent:
                self.exitEvent()
        self.__dialog.cleanup()
        self.__dialog = None
        return
class SkillTray:
    SkillIcons = None
    MeterFrame = None
    
    def __init__(self):
        if not self.SkillIcons:
            self.SkillIcons = loader.loadModel('models/textureCards/skillIcons')
            icons = loader.loadModel('models/gui/gui_icons_weapon')
            icons.reparentTo(self.SkillIcons)
            self.MeterFrame = loader.loadModel('models/gui/ship_battle')
        
        self.tray = { }
        self.origMap = { }
        self.traySkillMap = None
        self.skillTrayState = False
        self.rep = None
        self.weaponMode = None
        self.callback = None
        self.numberOfItems = 0
        self.repMeter = None
        self.skillRechargedSound = loadSfx(SoundGlobals.SFX_GUI_SKILL_RECHARGED)
        self.skillTray = DirectFrame(parent = base.a2dBottomCenter, pos = (0, 0, -0.14000000000000001), scale = 0.85999999999999999, sortOrder = 2)
        self.hide()
        self.defaultMoveUp = 0.27000000000000002
        self.currentMoveUp = 0
        self.skillTrayz = self.skillTray.getZ()
        self.showSkillTrayIval = None
        self.hideSkillTrayIval = None
        self.resetMoveUpVale()
        gui = loader.loadModel('models/gui/toplevel_gui')
        self.lockArt = gui.find('**/pir_t_gui_gen_key_subscriber')
        self.isPowerRecharged = False

    
    def show(self):
        self.skillTray.show()

    
    def hide(self):
        self.skillTray.hide()

    
    def setMoveUpValue(self, moveUp):
        if self.currentMoveUp != moveUp:
            self.currentMoveUp = moveUp
            if self.showSkillTrayIval:
                self.showSkillTrayIval.pause()
            
            self.showSkillTrayIval = Sequence(Func(self.show), LerpFunc(self.skillTray.setZ, 0.25, self.skillTrayz, moveUp + self.skillTrayz))
            if self.hideSkillTrayIval:
                self.hideSkillTrayIval.pause()
            
            self.hideSkillTrayIval = Sequence(LerpFunc(self.skillTray.setZ, 0.25, moveUp + self.skillTrayz, self.skillTrayz), Func(self.hide))
        

    
    def resetMoveUpVale(self):
        self.setMoveUpValue(self.defaultMoveUp)

    
    def showSkillTray(self, task = None):
        if localAvatar.isWeaponDrawn == False:
            if localAvatar.gameFSM.state != 'ShipPilot' and not (localAvatar.cannon):
                return None
            
        
        if self.skillTrayState:
            return None
        else:
            self.skillTrayState = True
        if self.showSkillTrayIval.isPlaying():
            self.showSkillTrayIval.pause()
        
        if self.hideSkillTrayIval.isPlaying():
            self.hideSkillTrayIval.pause()
        
        self.showSkillTrayIval.start()

    
    def hideSkillTray(self):
        if not self.skillTrayState:
            return None
        else:
            self.skillTrayState = False
        if self.showSkillTrayIval.isPlaying():
            self.showSkillTrayIval.pause()
        
        if self.hideSkillTrayIval.isPlaying():
            self.hideSkillTrayIval.pause()
        
        self.hideSkillTrayIval.start()

    
    def updateSkillTrayMeter(self):
        if not self.traySkillMap:
            return None
        
        inv = base.localAvatar.getInventory()
        reputation = inv.getReputation(self.rep)
        if self.repMeter:
            self.repMeter.setCategory(self.rep)
            self.repMeter.update(reputation, playFX = True)
        

    
    def rebuildSkillTray(self, rep = None, weaponMode = None, callback = None):
        if not rep:
            rep = self.rep
        
        if not weaponMode:
            weaponMode = self.weaponMode
        
        if not callback:
            callback = self.callback
        
        if rep is None:
            return None
        
        self.updateSkillTray(rep, weaponMode, callback, hideFirst = False)

    
    def updateSkillTray(self, rep, weaponMode, callback = None, hideFirst = True):
        if rep == InventoryType.MeleeRep:
            return None
        
        if not callback:
            callback = localAvatar.guiMgr.combatTray.triggerSkillTraySkill
        
        if taskMgr.hasTaskNamed('updateSkillTray'):
            taskMgr.remove('updateSkillTray')
        
        if self.skillTrayState and hideFirst:
            self.hideSkillTray()
            taskMgr.doMethodLater(0.75, self.updateSkillTray, 'updateSkillTray', extraArgs = [
                rep,
                weaponMode,
                callback])
            return None
        
        text = PLocalizer.InventoryTypeNames.get(rep, 'Unknown')
        for i in range(self.numberOfItems):
            self.tray[i + 1].destroy()
        
        self.tray = { }
        if self.repMeter:
            self.repMeter.destroy()
        
        self.rep = rep
        self.weaponMode = weaponMode
        self.callback = callback
        linkedSkillIds = { }
        linkedSkills = ItemGlobals.getLinkedSkills(localAvatar.currentWeaponId)
        for skillId in linkedSkills:
            realSkillId = WeaponGlobals.getLinkedSkillId(skillId)
            linkedSkillIds[realSkillId] = skillId
        
        skillMap = []
        self.origMap = getAllSkills(self.rep, 2, wantWeaponSkill = 1)
        for i in range(len(self.origMap)):
            skillMap.append(self.origMap[i][0])
        
        self.traySkillMap = skillMap
        self.numberOfItems = len(self.traySkillMap)
        self.skillTray.setX(0)
        if self.rep != InventoryType.DefenseCannonRep:
            self.repMeter = ReputationMeter(self.rep, width = 0.69999999999999996)
            self.repMeter.setScale(1.1499999999999999, 1.1499999999999999, 1.1499999999999999)
            self.repMeter.reparentTo(self.skillTray)
            self.repMeter.setCategory(self.rep)
        
        inv = base.localAvatar.getInventory()
        if inv is None:
            return None
        
        if self.repMeter:
            self.repMeter.update(inv.getReputation(self.rep))
        
        x = 0.0
        offset = 0.0
        for i in range(self.numberOfItems):
            if self.origMap[i][1] == False:
                locked = False
                if locked:
                    image = (self.SkillIcons.find('**/base'), self.SkillIcons.find('**/base_down'), self.SkillIcons.find('**/base_over'))
                else:
                    image = self.SkillIcons.find('**/base')
                button = DirectButton(parent = self.skillTray, relief = None, state = DGG.DISABLED, image = image, image_pos = (0.0, 0.0, 0.059999999999999998), image_scale = 0.12, image_color = (0.20000000000000001, 0.20000000000000001, 0.20000000000000001, 0.55000000000000004), sortOrder = 100, pos = (x, 0, -0.0))
                button.setTransparency(1)
                button.showQuantity = False
                button.greyOut = -1
                button.showRing = False
                button.skillStatus = False
                if locked:
                    lock = DirectFrame(parent = button, relief = None, image = self.lockArt, image_scale = 0.14000000000000001, image_pos = (0.050000000000000003, 0, 0.035000000000000003))
                    button['state'] = DGG.NORMAL
                    button['command'] = base.localAvatar.guiMgr.showNonPayer
                    button['extraArgs'] = [
                        'Restricted_Radial_Menu',
                        5]
                
                self.tray[i + 1] = button
                x = x + 0.14999999999999999
                if i < self.numberOfItems - 1:
                    offset = offset + 0.01
                    self.skillTray.setX(self.skillTray.getX() - 0.074999999999999997)
                
            i < self.numberOfItems - 1
            if self.origMap[i][1] == True:
                skillId = self.traySkillMap[i]
                if linkedSkillIds.has_key(skillId):
                    skillId = linkedSkillIds[skillId]
                
                name = PLocalizer.InventoryTypeNames[skillId]
                hotkey = str(i + 1)
                totalRechargeTime = base.cr.battleMgr.getModifiedRechargeTime(localAvatar, skillId)
                timeSpentRecharging = localAvatar.skillDiary.getTimeSpentRecharging(skillId)
                if not timeSpentRecharging:
                    timeSpentRecharging = 0
                
                if weaponMode not in (WeaponGlobals.CANNON, WeaponGlobals.FIREARM, WeaponGlobals.GRENADE, WeaponGlobals.STAFF, WeaponGlobals.DEFENSE_CANNON) and skillId in WeaponGlobals.SpecialSkills or WeaponGlobals.getSkillReputationCategoryId(skillId) not in (InventoryType.PistolRep, InventoryType.WandRep, InventoryType.CannonRep, InventoryType.GrenadeRep, InventoryType.DefenseCannonRep):
                    showRing = True
                else:
                    showRing = False
                locked = self.origMap[i][2]
                if weaponMode == WeaponGlobals.DEFENSE_CANNON:
                    button = AmmoSkillButton(skillId, i, self.callback, 99, 0, showQuantity = True, showHelp = False, showRing = showRing, hotkey = hotkey, name = name, showLock = locked)
                else:
                    button = SkillButton(skillId, self.callback, 0, 0, showQuantity = False, showHelp = False, showRing = showRing, hotkey = hotkey, name = name, showLock = locked)
                button.skillStatus = True
                if locked:
                    button.skillButton['command'] = base.localAvatar.guiMgr.showNonPayer
                    button.skillButton['extraArgs'] = [
                        'Restricted_Radial_Menu',
                        5]
                
                if showRing:
                    button.skillRing.meterFaceHalf1.setScale(0.95999999999999996)
                    button.skillRing.meterFaceHalf2.setScale(0.95999999999999996)
                
                button.reparentTo(self.skillTray)
                button.setPos(x, 0, 0.070000000000000007)
                self.tray[i + 1] = button
                if weaponMode in (WeaponGlobals.CANNON, WeaponGlobals.FIREARM, WeaponGlobals.GRENADE, WeaponGlobals.STAFF):
                    lastAmmo = localAvatar.guiMgr.combatTray.lastAmmoSkillId.get(localAvatar.currentWeaponId)
                    if lastAmmo is not None:
                        if lastAmmo == skillId:
                            button.toggleButton(True)
                        
                    elif self.tray[1].skillStatus is True:
                        self.tray[1].toggleButton(True)
                    
                
                if self.weaponMode in (WeaponGlobals.FIREARM, WeaponGlobals.THROWING, WeaponGlobals.CANNON, WeaponGlobals.GRENADE):
                    inv = localAvatar.getInventory()
                    maxQuant = WeaponGlobals.getSkillMaxQuantity(skillId)
                    if maxQuant == WeaponGlobals.INF_QUANT and WeaponGlobals.canUseInfiniteAmmo(localAvatar.currentWeaponId, skillId) or WeaponGlobals.canUseInfiniteAmmo(localAvatar.getCurrentCharm(), skillId):
                        ammoAmt = WeaponGlobals.INF_QUANT
                    else:
                        ammoInvId = WeaponGlobals.getSkillAmmoInventoryId(skillId)
                        ammoAmt = inv.getStackQuantity(ammoInvId)
                        ammoMax = inv.getStackLimit(ammoInvId)
                        button.showQuantity = True
                        button.updateQuantity(ammoAmt)
                
                x = x + 0.17000000000000001
                if i < self.numberOfItems - 1:
                    if weaponMode == WeaponGlobals.DEFENSE_CANNON:
                        self.skillTray.setX(self.skillTray.getX() - 0.072499999999999995)
                    else:
                        self.skillTray.setX(self.skillTray.getX() - 0.085000000000000006)
                
            i < self.numberOfItems - 1
        
        currentX = self.skillTray.getX()
        self.skillTray.setX(currentX + float(offset))
        if self.repMeter:
            self.repMeter.setPos(-currentX, 0.0, -0.11)
        
        self.updateSkillTrayStates()
        if weaponMode == WeaponGlobals.DEFENSE_CANNON:
            self.setMoveUpValue(0.34499999999999997)
        else:
            self.resetMoveUpVale()
        self.showSkillTray()

    
    def updateSkillTrayStates(self):
        if not self.traySkillMap:
            return None
        
        if not hasattr(base, 'localAvatar'):
            return None
        
        inv = localAvatar.getInventory()
        if not inv:
            return None
        
        self.numberOfItems = len(self.traySkillMap)
        for i in range(self.numberOfItems):
            skillId = self.traySkillMap[i]
            greyOut = 0
            if self.tray[i + 1].greyOut == -1:
                continue
            
            if self.tray[i + 1].showQuantity:
                maxQuant = WeaponGlobals.getSkillMaxQuantity(skillId)
                if maxQuant == WeaponGlobals.INF_QUANT and WeaponGlobals.canUseInfiniteAmmo(localAvatar.currentWeaponId, skillId) or WeaponGlobals.canUseInfiniteAmmo(localAvatar.getCurrentCharm(), skillId):
                    quantity = WeaponGlobals.INF_QUANT
                else:
                    ammoInvId = WeaponGlobals.getSkillAmmoInventoryId(skillId)
                    quantity = inv.getStackQuantity(ammoInvId)
                if quantity == 0:
                    greyOut = 1
                
            
            if localAvatar.mojo < -1 * WeaponGlobals.getMojoCost(skillId):
                greyOut = 1
            
            if localAvatar.ship:
                if (skillId == InventoryType.SailBroadsideLeft or skillId == InventoryType.SailBroadsideRight) and not (localAvatar.ship.broadside):
                    greyOut = 1
                elif localAvatar.guiMgr.combatTray.skillDisabled(skillId):
                    greyOut = 1
                
            
            rep = WeaponGlobals.getSkillReputationCategoryId(skillId)
            if rep == InventoryType.DollRep:
                haveFriendly = localAvatar.getFriendlyStickyTargets()
                haveHostile = localAvatar.getHostileStickyTargets()
                if haveFriendly and not haveHostile:
                    if not WeaponGlobals.isFriendlyFire(skillId):
                        greyOut = 1
                    
                elif not haveFriendly and haveHostile:
                    if WeaponGlobals.isFriendlyFire(skillId):
                        greyOut = 1
                    
                
            
            if self.tray[i + 1].greyOut != greyOut:
                if hasattr(self.tray[i + 1], 'skillButton'):
                    self.tray[i + 1].greyOut = greyOut
                    if greyOut == 1:
                        self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                        if self.tray[i + 1].showRing:
                            self.tray[i + 1].skillRing.meterFaceHalf1.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                            self.tray[i + 1].skillRing.meterFaceHalf2.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                        
                    elif greyOut == 2:
                        self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                    elif greyOut == 3:
                        self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                    else:
                        self.tray[i + 1].setGeomColor(1, 1, 1, 1)
                        if self.tray[i + 1].showRing:
                            self.tray[i + 1].skillRing.meterFaceHalf1.clearColorScale()
                            self.tray[i + 1].skillRing.meterFaceHalf2.clearColorScale()
                        
                
            
            if self.isPowerRecharged:
                self.continuePowerRechargeEffect()
                continue
        

    
    def callback(self, skillId):
        if WeaponGlobals.getSkillEffectFlag(skillId):
            localAvatar.guiMgr.combatTray.trySkill(InventoryType.UsePotion, skillId, 0)
        else:
            localAvatar.guiMgr.combatTray.trySkill(InventoryType.UseItem, skillId, 0)

    
    def decrementSkillTrayAmount(self, skillId, amt = 1):
        if not self.traySkillMap:
            return None
        
        if self.weaponMode not in (WeaponGlobals.FIREARM, WeaponGlobals.THROWING, WeaponGlobals.CANNON, WeaponGlobals.GRENADE):
            return None
        
        if not hasattr(base, 'localAvatar'):
            return None
        
        self.numberOfItems = len(self.traySkillMap)
        for i in range(self.numberOfItems):
            if self.tray[i + 1].greyOut == -1:
                continue
            
            if self.tray[i + 1].showQuantity:
                if skillId == self.traySkillMap[i]:
                    currentAmt = self.tray[i + 1].quantity
                    newAmt = currentAmt - amt
                    if newAmt >= 0:
                        self.tray[i + 1].updateQuantity(newAmt)
                        if newAmt == 0:
                            self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                            if self.tray[i + 1].showRing:
                                self.tray[i + 1].skillRing.meterFaceHalf1.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                                self.tray[i + 1].skillRing.meterFaceHalf2.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                            
                        
                        return None
                    
                
            skillId == self.traySkillMap[i]
        

    
    def updateSkillTrayAmounts(self):
        if not self.traySkillMap:
            return None
        
        if self.weaponMode not in (WeaponGlobals.FIREARM, WeaponGlobals.THROWING, WeaponGlobals.CANNON, WeaponGlobals.GRENADE):
            return None
        
        if not hasattr(base, 'localAvatar'):
            return None
        
        inv = localAvatar.getInventory()
        if not inv:
            return None
        
        self.numberOfItems = len(self.traySkillMap)
        for i in range(self.numberOfItems):
            if self.tray[i + 1].greyOut == -1:
                continue
            
            skillId = self.traySkillMap[i]
            maxQuant = WeaponGlobals.getSkillMaxQuantity(skillId)
            if maxQuant == WeaponGlobals.INF_QUANT and WeaponGlobals.canUseInfiniteAmmo(localAvatar.currentWeaponId, skillId) or WeaponGlobals.canUseInfiniteAmmo(localAvatar.getCurrentCharm(), skillId):
                ammoAmt = WeaponGlobals.INF_QUANT
            else:
                ammoInvId = WeaponGlobals.getSkillAmmoInventoryId(skillId)
                ammoAmt = inv.getStackQuantity(ammoInvId)
                ammoMax = inv.getStackLimit(ammoInvId)
            self.tray[i + 1].updateQuantity(ammoAmt)
        

    
    def updateSkillIval(self, skillId):
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty() and self.tray[button].skillId == skillId:
                if not self.tray[button].skillRingIval.isPlaying():
                    self.tray[button].skillRingIval.start()
                
            self.tray[button].skillRingIval.isPlaying()
        

    
    def addPowerRechargeEffect(self):
        self.isPowerRecharged = True
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].quickGlowImpulse()
                    self.tray[button].startPowerImpulse()
                    self.tray[button].updateSkillRingIval()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def continuePowerRechargeEffect(self):
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].startPowerImpulse()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def removePowerRechargeEffect(self):
        self.isPowerRecharged = False
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].stopPowerImpulse()
                    self.tray[button].updateSkillRingIval()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def updateCharmSkills(self):
        self.rebuildSkillTray()
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].updateSkillRingIval()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def destroy(self):
        self.hideSkillTray()
        self.skillTray.destroy()
        if self.repMeter:
            self.repMeter.destroy()
        
        for i in range(self.numberOfItems):
            self.tray[i + 1].destroy()
        
        del self.tray
        del self.callback
        if self.showSkillTrayIval:
            self.showSkillTrayIval.pause()
            self.showSkillTrayIval = None
        
        if self.hideSkillTrayIval:
            self.hideSkillTrayIval.pause()
            self.hideSkillTrayIval = None
class WeaponPage(InventoryPage.InventoryPage):
    
    def __init__(self):
        InventoryPage.InventoryPage.__init__(self)
        self.initialiseoptions(WeaponPage)
        self.weaponPanels = { }
        self.tonicButtons = { }
        self.fishingIcon = None
        self.potionIcon = None
        self.fishingRepMeter = None
        self.potionRepMeter = None
        self.fishingPoleName = None
        self.fishingChangeMsg = None
        self.needRefresh = 1
        self.showing = 0

    
    def show(self):
        self.showing = 1
        InventoryPage.InventoryPage.show(self)
        if self.needRefresh:
            self.refreshList()
            self.needRefresh = 0
        

    
    def hide(self):
        self.showing = 0
        self.equipStatus = 0
        InventoryPage.InventoryPage.hide(self)

    
    def tonicCallback(self, skillId):
        localAvatar.guiMgr.combatTray.trySkill(InventoryType.UseItem, skillId, 0)

    
    def rePanel(self, inventory):
        if not self.showing:
            self.needRefresh = 1
            return None
        
        skillTokens = {
            InventoryType.CutlassToken: (ItemGlobals.RUSTY_CUTLASS,),
            InventoryType.PistolToken: (ItemGlobals.FLINTLOCK_PISTOL,),
            InventoryType.DollToken: (ItemGlobals.VOODOO_DOLL,),
            InventoryType.DaggerToken: (ItemGlobals.BASIC_DAGGER,),
            InventoryType.GrenadeToken: (ItemGlobals.GRENADE_POUCH,),
            InventoryType.WandToken: (ItemGlobals.CURSED_STAFF,) }
        zIndex = 1
        for skillTokenKey in TOKEN_LIST:
            quantity = 0
            if localAvatar.getInventory().stacks.get(skillTokenKey):
                quantity = 1
            
            skillData = skillTokens[skillTokenKey]
            weaponId = skillData[0]
            key = None
            panel = WeaponPanel.WeaponPanel((weaponId, quantity), key)
            panel.reparentTo(self)
            panel.setZ(PiratesGuiGlobals.InventoryPanelHeight - 0.17999999999999999 - zIndex * panel.height)
            zIndex += 1
            repCat = WeaponGlobals.getRepId(weaponId)
            self.weaponPanels[repCat] = panel
            self.ignore('inventoryQuantity-%s' % inventory.getDoId())
            self.acceptOnce('inventoryQuantity-%s-%s' % (inventory.getDoId(), skillTokenKey), self.refreshList)
        
        repIcon_gui = loader.loadModel('models/textureCards/skillIcons')
        repIcon = repIcon_gui.find('**/box_base')
        if config.GetBool('want-fishing-game', 0):
            self.fishingIcon = GuiButton(pos = (0.16600000000000001, 0, 0.044999999999999998 + (PiratesGuiGlobals.InventoryPanelHeight - 0.17999999999999999) - zIndex * panel.height), helpText = PLocalizer.FishingRepDescription, helpOpaque = True, image = (repIcon, repIcon, repIcon, repIcon), image_scale = (0.14399999999999999, 0.14399999999999999, 0.14399999999999999))
            fishIconCard = loader.loadModel('models/textureCards/fishing_icons')
            inv = localAvatar.getInventory()
            fishingChangeMsg = InventoryGlobals.getCategoryQuantChangeMsg(inv.doId, InventoryType.FishingRod)
            if self.fishingChangeMsg:
                self.ignore(fishingChangeMsg)
            
            self.fishingChangeMsg = fishingChangeMsg
            self.acceptOnce(fishingChangeMsg, self.refreshList)
            rodIcons = [
                'pir_t_gui_fsh_smRodIcon',
                'pir_t_gui_fsh_mdRodIcon',
                'pir_t_gui_fsh_lgRodIcon']
            rodLvl = inv.getStackQuantity(InventoryType.FishingRod)
            rodIcon = rodIcons[rodLvl - 1]
            rodText = PLocalizer.FishingRodNames[rodLvl]
            if rodLvl >= 1:
                self.fishingIcon['geom'] = fishIconCard.find('**/' + rodIcon)
            
            self.fishingIcon['geom_scale'] = 0.10000000000000001
            self.fishingIcon['geom_pos'] = (0, 0, 0)
            self.fishingIcon.reparentTo(self)
            fishingRepValue = localAvatar.getInventory().getReputation(InventoryType.FishingRep)
            self.fishingRepMeter = ReputationMeter(InventoryType.FishingRep, width = 0.66000000000000003)
            self.fishingRepMeter.setPos(0.62, 0, 0.041000000000000002 + (PiratesGuiGlobals.InventoryPanelHeight - 0.17999999999999999) - zIndex * panel.height)
            self.fishingRepMeter.update(fishingRepValue)
            self.fishingRepMeter.reparentTo(self)
            self.fishingRepMeter.flattenLight()
            self.fishingPoleName = DirectLabel(parent = self, relief = None, state = DGG.DISABLED, text = rodText, text_scale = PiratesGuiGlobals.TextScaleSmall, text_align = TextNode.ALeft, text_fg = PiratesGuiGlobals.TextFG2, text_shadow = PiratesGuiGlobals.TextShadow, pos = (0.28999999999999998, 0, -0.0050000000000000001 + (PiratesGuiGlobals.InventoryPanelHeight - 0.17999999999999999) - 7 * panel.height), text_font = PiratesGlobals.getInterfaceFont())
            self.fishingPoleName.reparentTo(self)
            zIndex += 1
        
        iconCard = loader.loadModel('models/textureCards/skillIcons')
        if config.GetBool('want-potion-game', 0):
            self.potionIcon = GuiButton(pos = (0.16600000000000001, 0, 0.044999999999999998 + (PiratesGuiGlobals.InventoryPanelHeight - 0.17999999999999999) - zIndex * panel.height), helpText = PLocalizer.PotionRepDescription, helpOpaque = True, image = (repIcon, repIcon, repIcon, repIcon), image_scale = (0.14399999999999999, 0.14399999999999999, 0.14399999999999999))
            self.potionIcon['geom'] = iconCard.find('**/pir_t_gui_pot_base')
            self.potionIcon['geom_scale'] = 0.10000000000000001
            self.potionIcon['geom_pos'] = (0, 0, 0)
            self.potionIcon.reparentTo(self)
            potionRepValue = localAvatar.getInventory().getReputation(InventoryType.PotionsRep)
            self.potionRepMeter = ReputationMeter(InventoryType.PotionsRep, width = 0.66000000000000003)
            self.potionRepMeter.setPos(0.62, 0, 0.041000000000000002 + (PiratesGuiGlobals.InventoryPanelHeight - 0.17999999999999999) - zIndex * panel.height)
            self.potionRepMeter.update(potionRepValue)
            self.potionRepMeter.reparentTo(self)
            self.potionRepMeter.flattenLight()
            zIndex += 1
        
        items = dict(map(lambda x: (x.getType(), x.getCount()), inventory.getConsumables().values()))
        possibleItems = ItemGlobals.getAllHealthIds()
        havePorky = items.get(ItemGlobals.ROAST_PORK)
        if not havePorky and ItemGlobals.ROAST_PORK in possibleItems:
            possibleItems.remove(ItemGlobals.ROAST_PORK)
        
        offset = 0
        if base.config.GetBool('want-potion-game', 0):
            items = inventory.getConsumables()
            listLength = len(InventoryType.PotionMinigamePotions)
            count = 0
            for i in range(listLength):
                tonicId = InventoryType.PotionMinigamePotions[i]
                if items.get(tonicId):
                    button = SkillButton(tonicId, self.tonicCallback, items.get(tonicId), showQuantity = True, showHelp = True, showRing = True)
                    button.skillButton['geom_scale'] = 0.080000000000000002
                    x = 0.16 * (count % 6) + -1.2
                    z = 1.0 - int(count / 6) * 0.16
                    button.setPos(x, 0, z)
                    button.reparentTo(self)
                    self.tonicButtons[tonicId] = button
                    count += 1
                    continue
            
        

    
    def refreshList(self, newWeaponId = None):
        for panel in self.weaponPanels.values():
            panel.destroy()
        
        for panel in self.tonicButtons.values():
            panel.destroy()
        
        if self.fishingIcon is not None:
            self.fishingIcon.destroy()
        
        if self.potionIcon is not None:
            self.potionIcon.destroy()
        
        if self.fishingRepMeter is not None:
            self.fishingRepMeter.destroy()
        
        if self.potionRepMeter is not None:
            self.potionRepMeter.destroy()
        
        if self.fishingPoleName is not None:
            self.fishingPoleName.destroy()
        
        inventory = localAvatar.getInventory()
        if inventory:
            if inventory.isReady():
                self.rePanel(inventory)
            else:
                self.ignore('inventoryReady-%s' % inventory.getDoId())
                self.acceptOnce('inventoryReady-%s' % inventory.getDoId(), self.rePanel)
        

    
    def destroy(self):
        if self.fishingChangeMsg:
            self.ignore(self.fishingChangeMsg)
        
        InventoryPage.InventoryPage.destroy(self)

    
    def updateTonics(self):
        if not hasattr(base, 'localAvatar'):
            return None
        
        inv = localAvatar.getInventory()
        if not inv:
            return None
        
        possibleTonics = ItemGlobals.getAllHealthIds()
        for tonicId in possibleTonics:
            tonicAmt = inv.getItemQuantity(InventoryType.ItemTypeConsumable, tonicId)
            if self.tonicButtons.has_key(tonicId):
                self.tonicButtons[tonicId].updateQuantity(tonicAmt)
                self.tonicButtons[tonicId].checkAmount()
                continue
class DefenseCannonGUI(CannonGUI):
    notify = DirectNotifyGlobal.directNotify.newCategory('DefenseCannonGUI')
    
    def __init__(self, cannon):
        CannonGUI.__init__(self, cannon)
        self.exitEvent = None
        self._DefenseCannonGUI__dialog = None
        self.helpButton = None
        self.helpUI = None
        self.flashHelp = None
        self.ammoFade = None
        self._DefenseCannonGUI__ammoCountersHidden = False
        self.setupExtraButtons()
        self.exitCannon['command'] = self.showExitDialog
        self.volleyLabel.setPos(-0.28000000000000003, 0, 0.089999999999999997)
        self.reloadBar.setPos(-0.13, 0, 0.080000000000000002)
        self.ammoImage.setPos(-0.38, 0, 0.059999999999999998)
        self.repMeter = ReputationMeter(InventoryType.DefenseCannonRep, width = 0.69999999999999996)
        self.repMeter.reparentTo(base.a2dBottomCenter)
        self.repMeter.setPos(0.0, 0.0, 0.025000000000000001)
        self.hud = CannonDefenseHUD()
        self.hud.create()
        self._exp = 0
        self.lastLevel = 1
        self.accept('incDefenseCannonExp', self.increaseExp)
        if __dev__:
            base.dcg = self
        

    
    def destroy(self):
        if self.ammoFade:
            self.ammoFade.finish()
            self.ammoFade = None
        
        if self.flashHelp:
            self.flashHelp.finish()
            self.flashHelp = None
        
        if self.helpButton:
            self.helpButton.destroy()
            self.helpButton = None
        
        if self.helpUI:
            self.helpUI.destroy()
            self.helpUI = None
        
        if self.hud:
            self.hud.destroy()
            self.hud = None
        
        base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_MINIGAME_CANNON)
        self.repMeter.destroy()
        self.ignore('incDefenseCannonExp')
        CannonGUI.destroy(self)

    
    def setupExtraButtons(self):
        weaponIcons = loader.loadModel('models/gui/gui_icons_weapon')
        self.helpButton = DirectButton(parent = base.a2dBottomRight, relief = None, pos = (-0.59999999999999998, 0, 0.089999999999999997), scale = 0.5, text = '?', text_pos = (0, -0.055), text_scale = 0.20999999999999999, text_fg = PiratesGuiGlobals.TextFG2, text_shadow = PiratesGuiGlobals.TextShadow, text_font = PiratesGlobals.getPirateBoldOutlineFont(), sortOrder = 2, command = self.toggleHelpUI)
        DirectLabel(parent = self.helpButton, text = PLocalizer.CannonDefense['Help'], text_pos = (0, -0.14999999999999999), text_scale = 0.080000000000000002, text_fg = PiratesGuiGlobals.TextFG2, text_shadow = PiratesGuiGlobals.TextShadow, text_font = PiratesGlobals.getPirateBoldOutlineFont(), frameColor = (1, 1, 1, 0))

    
    def increaseExp(self, amt, total):
        self._exp += amt
        if self._exp > total:
            return None
        
        (level, leftoverValue) = ReputationGlobals.getLevelFromTotalReputation(InventoryType.DefenseCannonRep, self._exp)
        self.repMeter.update(self._exp)
        if level > self.lastLevel:
            base.localAvatar.levelUpMsg(InventoryType.DefenseCannonRep, level, 0)
            self.lastLevel = level
        

    
    def toggleHelpUI(self):
        if self.helpUI == None:
            self._DefenseCannonGUI__createHelpUI()
            self.fadeOutAmmoCounters()
            if self.cannon.ammoPanel.state == pirates.minigame.AmmoPanel.CLOSED:
                self.cannon.ammoPanel.onTabClick()
            
        else:
            self._DefenseCannonGUI__destroyHelpUI()
            self.fadeInAmmoCounters()
            if self.cannon.ammoPanel.state == pirates.minigame.AmmoPanel.OPENED:
                self.cannon.ammoPanel.onTabClick()
            

    
    def _DefenseCannonGUI__createHelpUI(self):
        self.helpUI = CannonDefenseHelpManager(0.5)
        self.helpUI.exit.reparentTo(self.exitCannon)
        self.helpUI.exit.setScale(2.0)
        self.helpUI.help.reparentTo(self.helpButton)
        self.helpUI.help.setScale(2.0)
        self.helpUI.ammoPanel.reparentTo(self.cannon.ammoPanel.panel)
        self.helpUI.ammoPanel.setScale(1.0 / 3.0)
        self.helpUI.ammo.reparentTo(base.a2dBottomCenter)
        self.helpUI.mine.reparentTo(self.hud.goldRemainingUI.mineCounter)
        self.helpUI.mine.setScale(2.0 / 3.0)
        self.helpUI.wave.reparentTo(self.hud.timeRemainingUI.timeRemaining)
        self.helpUI.wave.setScale(1.0 / 0.75)
        self.helpUI.fadeIn.start()

    
    def _DefenseCannonGUI__destroyHelpUI(self):
        cleanup = Sequence(Func(self.helpUI.fadeIn.pause), self.helpUI.fadeOut, Func(self.helpUI.destroy), name = self.cannon.uniqueName('HelpUI_FadeIn'))
        cleanup.start()
        self.helpUI = None

    
    def isHelpUIVisible(self):
        return self.helpUI != None

    
    def flashHelpButton(self, delay = 0.20000000000000001, length = 5):
        if self.flashHelp:
            self.flashHelp.finish()
            self.flashHelp = None
        
        self.flashHelp = Sequence(name = self.cannon.uniqueName('HelpButton_Flash'))
        
        def setColor(key, value):
            self.helpButton[key] = value

        for i in range(0, length):
            self.flashHelp.append(Wait(delay))
            self.flashHelp.append(Func(setColor, 'text_fg', PiratesGuiGlobals.TextFG19))
            self.flashHelp.append(Wait(delay))
            self.flashHelp.append(Func(setColor, 'text_fg', PiratesGuiGlobals.TextFG2))
        
        self.flashHelp.start()

    
    def fadeOutAmmoCounters(self, length = 0.5):
        if self._DefenseCannonGUI__ammoCountersHidden:
            return None
        
        transparent = Vec4(1, 1, 1, 0)
        if self.ammoFade:
            self.ammoFade.finish()
        
        self.ammoFade = Parallel(self.volleyLabel.colorScaleInterval(length, transparent), self.reloadBar.colorScaleInterval(length, transparent), self.ammoImage.colorScaleInterval(length, transparent))
        self.ammoFade.start()
        self._DefenseCannonGUI__ammoCountersHidden = True

    
    def fadeInAmmoCounters(self, length = 0.5):
        if self._DefenseCannonGUI__ammoCountersHidden == False:
            return None
        
        opaque = Vec4(1, 1, 1, 1)
        transparent = Vec4(1, 1, 1, 0)
        if self.ammoFade:
            self.ammoFade.finish()
        
        self.ammoFade = Parallel(self.volleyLabel.colorScaleInterval(length, opaque, transparent), self.reloadBar.colorScaleInterval(length, opaque, transparent), self.ammoImage.colorScaleInterval(length, opaque, transparent))
        self.ammoFade.start()
        self._DefenseCannonGUI__ammoCountersHidden = False

    
    def showExitDialog(self):
        if self._DefenseCannonGUI__dialog == None:
            self._DefenseCannonGUI__dialog = PDialog(text = PLocalizer.CannonDefense['ExitCannon'], style = OTPDialog.YesNo, giveMouse = False, command = self._DefenseCannonGUI__onDialogItemSelected)
        else:
            self._DefenseCannonGUI__dialog.cleanup()
            self._DefenseCannonGUI__dialog = None

    
    def _DefenseCannonGUI__onDialogItemSelected(self, value):
        if value == 1:
            if self.exitEvent:
                self.exitEvent()
            
        
        self._DefenseCannonGUI__dialog.cleanup()
        self._DefenseCannonGUI__dialog = None
class SkillTray:
    SkillIcons = None
    MeterFrame = None
    
    def __init__(self):
        if not self.SkillIcons:
            self.SkillIcons = loader.loadModel('models/textureCards/skillIcons')
            icons = loader.loadModel('models/gui/gui_icons_weapon')
            icons.reparentTo(self.SkillIcons)
            self.MeterFrame = loader.loadModel('models/gui/ship_battle')
        
        self.tray = { }
        self.origMap = { }
        self.traySkillMap = None
        self.skillTrayState = False
        self.rep = None
        self.weaponMode = None
        self.callback = None
        self.numberOfItems = 0
        self.repMeter = None
        self.skillRechargedSound = loadSfx(SoundGlobals.SFX_GUI_SKILL_RECHARGED)
        self.skillTray = DirectFrame(parent = base.a2dBottomCenter, pos = (0, 0, -0.14000000000000001), scale = 0.85999999999999999, sortOrder = 2)
        self.hide()
        self.defaultMoveUp = 0.27000000000000002
        self.currentMoveUp = 0
        self.skillTrayz = self.skillTray.getZ()
        self.showSkillTrayIval = None
        self.hideSkillTrayIval = None
        self.resetMoveUpVale()
        gui = loader.loadModel('models/gui/toplevel_gui')
        self.lockArt = gui.find('**/pir_t_gui_gen_key_subscriber')
        self.isPowerRecharged = False

    
    def show(self):
        self.skillTray.show()

    
    def hide(self):
        self.skillTray.hide()

    
    def setMoveUpValue(self, moveUp):
        if self.currentMoveUp != moveUp:
            self.currentMoveUp = moveUp
            if self.showSkillTrayIval:
                self.showSkillTrayIval.pause()
            
            self.showSkillTrayIval = Sequence(Func(self.show), LerpFunc(self.skillTray.setZ, 0.25, self.skillTrayz, moveUp + self.skillTrayz))
            if self.hideSkillTrayIval:
                self.hideSkillTrayIval.pause()
            
            self.hideSkillTrayIval = Sequence(LerpFunc(self.skillTray.setZ, 0.25, moveUp + self.skillTrayz, self.skillTrayz), Func(self.hide))
        

    
    def resetMoveUpVale(self):
        self.setMoveUpValue(self.defaultMoveUp)

    
    def showSkillTray(self, task = None):
        if localAvatar.isWeaponDrawn == False:
            if localAvatar.gameFSM.state != 'ShipPilot' and not (localAvatar.cannon):
                return None
            
        
        if self.skillTrayState:
            return None
        else:
            self.skillTrayState = True
        if self.showSkillTrayIval.isPlaying():
            self.showSkillTrayIval.pause()
        
        if self.hideSkillTrayIval.isPlaying():
            self.hideSkillTrayIval.pause()
        
        self.showSkillTrayIval.start()

    
    def hideSkillTray(self):
        if not self.skillTrayState:
            return None
        else:
            self.skillTrayState = False
        if self.showSkillTrayIval.isPlaying():
            self.showSkillTrayIval.pause()
        
        if self.hideSkillTrayIval.isPlaying():
            self.hideSkillTrayIval.pause()
        
        self.hideSkillTrayIval.start()

    
    def updateSkillTrayMeter(self):
        if not self.traySkillMap:
            return None
        
        inv = base.localAvatar.getInventory()
        reputation = inv.getReputation(self.rep)
        if self.repMeter:
            self.repMeter.setCategory(self.rep)
            self.repMeter.update(reputation, playFX = True)
        

    
    def rebuildSkillTray(self, rep = None, weaponMode = None, callback = None):
        if not rep:
            rep = self.rep
        
        if not weaponMode:
            weaponMode = self.weaponMode
        
        if not callback:
            callback = self.callback
        
        if rep is None:
            return None
        
        self.updateSkillTray(rep, weaponMode, callback, hideFirst = False)

    
    def updateSkillTray(self, rep, weaponMode, callback = None, hideFirst = True):
        if rep == InventoryType.MeleeRep:
            return None
        
        if not callback:
            callback = localAvatar.guiMgr.combatTray.triggerSkillTraySkill
        
        if taskMgr.hasTaskNamed('updateSkillTray'):
            taskMgr.remove('updateSkillTray')
        
        if self.skillTrayState and hideFirst:
            self.hideSkillTray()
            taskMgr.doMethodLater(0.75, self.updateSkillTray, 'updateSkillTray', extraArgs = [
                rep,
                weaponMode,
                callback])
            return None
        
        text = PLocalizer.InventoryTypeNames.get(rep, 'Unknown')
        for i in range(self.numberOfItems):
            self.tray[i + 1].destroy()
        
        self.tray = { }
        if self.repMeter:
            self.repMeter.destroy()
        
        self.rep = rep
        self.weaponMode = weaponMode
        self.callback = callback
        linkedSkillIds = { }
        linkedSkills = ItemGlobals.getLinkedSkills(localAvatar.currentWeaponId)
        for skillId in linkedSkills:
            realSkillId = WeaponGlobals.getLinkedSkillId(skillId)
            linkedSkillIds[realSkillId] = skillId
        
        skillMap = []
        self.origMap = getAllSkills(self.rep, 2, wantWeaponSkill = 1)
        for i in range(len(self.origMap)):
            skillMap.append(self.origMap[i][0])
        
        self.traySkillMap = skillMap
        self.numberOfItems = len(self.traySkillMap)
        self.skillTray.setX(0)
        if self.rep != InventoryType.DefenseCannonRep:
            self.repMeter = ReputationMeter(self.rep, width = 0.69999999999999996)
            self.repMeter.setScale(1.1499999999999999, 1.1499999999999999, 1.1499999999999999)
            self.repMeter.reparentTo(self.skillTray)
            self.repMeter.setCategory(self.rep)
        
        inv = base.localAvatar.getInventory()
        if inv is None:
            return None
        
        if self.repMeter:
            self.repMeter.update(inv.getReputation(self.rep))
        
        x = 0.0
        offset = 0.0
        for i in range(self.numberOfItems):
            if self.origMap[i][1] == False:
                locked = False
                if locked:
                    image = (self.SkillIcons.find('**/base'), self.SkillIcons.find('**/base_down'), self.SkillIcons.find('**/base_over'))
                else:
                    image = self.SkillIcons.find('**/base')
                button = DirectButton(parent = self.skillTray, relief = None, state = DGG.DISABLED, image = image, image_pos = (0.0, 0.0, 0.059999999999999998), image_scale = 0.12, image_color = (0.20000000000000001, 0.20000000000000001, 0.20000000000000001, 0.55000000000000004), sortOrder = 100, pos = (x, 0, -0.0))
                button.setTransparency(1)
                button.showQuantity = False
                button.greyOut = -1
                button.showRing = False
                button.skillStatus = False
                if locked:
                    lock = DirectFrame(parent = button, relief = None, image = self.lockArt, image_scale = 0.14000000000000001, image_pos = (0.050000000000000003, 0, 0.035000000000000003))
                    button['state'] = DGG.NORMAL
                    button['command'] = base.localAvatar.guiMgr.showNonPayer
                    button['extraArgs'] = [
                        'Restricted_Radial_Menu',
                        5]
                
                self.tray[i + 1] = button
                x = x + 0.14999999999999999
                if i < self.numberOfItems - 1:
                    offset = offset + 0.01
                    self.skillTray.setX(self.skillTray.getX() - 0.074999999999999997)
                
            i < self.numberOfItems - 1
            if self.origMap[i][1] == True:
                skillId = self.traySkillMap[i]
                if linkedSkillIds.has_key(skillId):
                    skillId = linkedSkillIds[skillId]
                
                name = PLocalizer.InventoryTypeNames[skillId]
                hotkey = str(i + 1)
                totalRechargeTime = base.cr.battleMgr.getModifiedRechargeTime(localAvatar, skillId)
                timeSpentRecharging = localAvatar.skillDiary.getTimeSpentRecharging(skillId)
                if not timeSpentRecharging:
                    timeSpentRecharging = 0
                
                if weaponMode not in (WeaponGlobals.CANNON, WeaponGlobals.FIREARM, WeaponGlobals.GRENADE, WeaponGlobals.STAFF, WeaponGlobals.DEFENSE_CANNON) and skillId in WeaponGlobals.SpecialSkills or WeaponGlobals.getSkillReputationCategoryId(skillId) not in (InventoryType.PistolRep, InventoryType.WandRep, InventoryType.CannonRep, InventoryType.GrenadeRep, InventoryType.DefenseCannonRep):
                    showRing = True
                else:
                    showRing = False
                locked = self.origMap[i][2]
                if weaponMode == WeaponGlobals.DEFENSE_CANNON:
                    button = AmmoSkillButton(skillId, i, self.callback, 99, 0, showQuantity = True, showHelp = False, showRing = showRing, hotkey = hotkey, name = name, showLock = locked)
                else:
                    button = SkillButton(skillId, self.callback, 0, 0, showQuantity = False, showHelp = False, showRing = showRing, hotkey = hotkey, name = name, showLock = locked)
                button.skillStatus = True
                if locked:
                    button.skillButton['command'] = base.localAvatar.guiMgr.showNonPayer
                    button.skillButton['extraArgs'] = [
                        'Restricted_Radial_Menu',
                        5]
                
                if showRing:
                    button.skillRing.meterFaceHalf1.setScale(0.95999999999999996)
                    button.skillRing.meterFaceHalf2.setScale(0.95999999999999996)
                
                button.reparentTo(self.skillTray)
                button.setPos(x, 0, 0.070000000000000007)
                self.tray[i + 1] = button
                if weaponMode in (WeaponGlobals.CANNON, WeaponGlobals.FIREARM, WeaponGlobals.GRENADE, WeaponGlobals.STAFF):
                    lastAmmo = localAvatar.guiMgr.combatTray.lastAmmoSkillId.get(localAvatar.currentWeaponId)
                    if lastAmmo is not None:
                        if lastAmmo == skillId:
                            button.toggleButton(True)
                        
                    elif self.tray[1].skillStatus is True:
                        self.tray[1].toggleButton(True)
                    
                
                if self.weaponMode in (WeaponGlobals.FIREARM, WeaponGlobals.THROWING, WeaponGlobals.CANNON, WeaponGlobals.GRENADE):
                    inv = localAvatar.getInventory()
                    maxQuant = WeaponGlobals.getSkillMaxQuantity(skillId)
                    if maxQuant == WeaponGlobals.INF_QUANT and WeaponGlobals.canUseInfiniteAmmo(localAvatar.currentWeaponId, skillId) or WeaponGlobals.canUseInfiniteAmmo(localAvatar.getCurrentCharm(), skillId):
                        ammoAmt = WeaponGlobals.INF_QUANT
                    else:
                        ammoInvId = WeaponGlobals.getSkillAmmoInventoryId(skillId)
                        ammoAmt = inv.getStackQuantity(ammoInvId)
                        ammoMax = inv.getStackLimit(ammoInvId)
                        button.showQuantity = True
                        button.updateQuantity(ammoAmt)
                
                x = x + 0.17000000000000001
                if i < self.numberOfItems - 1:
                    if weaponMode == WeaponGlobals.DEFENSE_CANNON:
                        self.skillTray.setX(self.skillTray.getX() - 0.072499999999999995)
                    else:
                        self.skillTray.setX(self.skillTray.getX() - 0.085000000000000006)
                
            i < self.numberOfItems - 1
        
        currentX = self.skillTray.getX()
        self.skillTray.setX(currentX + float(offset))
        if self.repMeter:
            self.repMeter.setPos(-currentX, 0.0, -0.11)
        
        self.updateSkillTrayStates()
        if weaponMode == WeaponGlobals.DEFENSE_CANNON:
            self.setMoveUpValue(0.34499999999999997)
        else:
            self.resetMoveUpVale()
        self.showSkillTray()

    
    def updateSkillTrayStates(self):
        if not self.traySkillMap:
            return None
        
        if not hasattr(base, 'localAvatar'):
            return None
        
        inv = localAvatar.getInventory()
        if not inv:
            return None
        
        self.numberOfItems = len(self.traySkillMap)
        for i in range(self.numberOfItems):
            skillId = self.traySkillMap[i]
            greyOut = 0
            if self.tray[i + 1].greyOut == -1:
                continue
            
            if self.tray[i + 1].showQuantity:
                maxQuant = WeaponGlobals.getSkillMaxQuantity(skillId)
                if maxQuant == WeaponGlobals.INF_QUANT and WeaponGlobals.canUseInfiniteAmmo(localAvatar.currentWeaponId, skillId) or WeaponGlobals.canUseInfiniteAmmo(localAvatar.getCurrentCharm(), skillId):
                    quantity = WeaponGlobals.INF_QUANT
                else:
                    ammoInvId = WeaponGlobals.getSkillAmmoInventoryId(skillId)
                    quantity = inv.getStackQuantity(ammoInvId)
                if quantity == 0:
                    greyOut = 1
                
            
            if localAvatar.mojo < -1 * WeaponGlobals.getMojoCost(skillId):
                greyOut = 1
            
            if localAvatar.ship:
                if (skillId == InventoryType.SailBroadsideLeft or skillId == InventoryType.SailBroadsideRight) and not (localAvatar.ship.broadside):
                    greyOut = 1
                elif localAvatar.guiMgr.combatTray.skillDisabled(skillId):
                    greyOut = 1
                
            
            rep = WeaponGlobals.getSkillReputationCategoryId(skillId)
            if rep == InventoryType.DollRep:
                haveFriendly = localAvatar.getFriendlyStickyTargets()
                haveHostile = localAvatar.getHostileStickyTargets()
                if haveFriendly and not haveHostile:
                    if not WeaponGlobals.isFriendlyFire(skillId):
                        greyOut = 1
                    
                elif not haveFriendly and haveHostile:
                    if WeaponGlobals.isFriendlyFire(skillId):
                        greyOut = 1
                    
                
            
            if self.tray[i + 1].greyOut != greyOut:
                if hasattr(self.tray[i + 1], 'skillButton'):
                    self.tray[i + 1].greyOut = greyOut
                    if greyOut == 1:
                        self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                        if self.tray[i + 1].showRing:
                            self.tray[i + 1].skillRing.meterFaceHalf1.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                            self.tray[i + 1].skillRing.meterFaceHalf2.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                        
                    elif greyOut == 2:
                        self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                    elif greyOut == 3:
                        self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                    else:
                        self.tray[i + 1].setGeomColor(1, 1, 1, 1)
                        if self.tray[i + 1].showRing:
                            self.tray[i + 1].skillRing.meterFaceHalf1.clearColorScale()
                            self.tray[i + 1].skillRing.meterFaceHalf2.clearColorScale()
                        
                
            
            if self.isPowerRecharged:
                self.continuePowerRechargeEffect()
                continue
        

    
    def callback(self, skillId):
        if WeaponGlobals.getSkillEffectFlag(skillId):
            localAvatar.guiMgr.combatTray.trySkill(InventoryType.UsePotion, skillId, 0)
        else:
            localAvatar.guiMgr.combatTray.trySkill(InventoryType.UseItem, skillId, 0)

    
    def decrementSkillTrayAmount(self, skillId, amt = 1):
        if not self.traySkillMap:
            return None
        
        if self.weaponMode not in (WeaponGlobals.FIREARM, WeaponGlobals.THROWING, WeaponGlobals.CANNON, WeaponGlobals.GRENADE):
            return None
        
        if not hasattr(base, 'localAvatar'):
            return None
        
        self.numberOfItems = len(self.traySkillMap)
        for i in range(self.numberOfItems):
            if self.tray[i + 1].greyOut == -1:
                continue
            
            if self.tray[i + 1].showQuantity:
                if skillId == self.traySkillMap[i]:
                    currentAmt = self.tray[i + 1].quantity
                    newAmt = currentAmt - amt
                    if newAmt >= 0:
                        self.tray[i + 1].updateQuantity(newAmt)
                        if newAmt == 0:
                            self.tray[i + 1].setGeomColor(0.5, 0.5, 0.5, 1.0)
                            if self.tray[i + 1].showRing:
                                self.tray[i + 1].skillRing.meterFaceHalf1.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                                self.tray[i + 1].skillRing.meterFaceHalf2.setColorScale(0.40000000000000002, 0.40000000000000002, 0.40000000000000002, 1.0)
                            
                        
                        return None
                    
                
            skillId == self.traySkillMap[i]
        

    
    def updateSkillTrayAmounts(self):
        if not self.traySkillMap:
            return None
        
        if self.weaponMode not in (WeaponGlobals.FIREARM, WeaponGlobals.THROWING, WeaponGlobals.CANNON, WeaponGlobals.GRENADE):
            return None
        
        if not hasattr(base, 'localAvatar'):
            return None
        
        inv = localAvatar.getInventory()
        if not inv:
            return None
        
        self.numberOfItems = len(self.traySkillMap)
        for i in range(self.numberOfItems):
            if self.tray[i + 1].greyOut == -1:
                continue
            
            skillId = self.traySkillMap[i]
            maxQuant = WeaponGlobals.getSkillMaxQuantity(skillId)
            if maxQuant == WeaponGlobals.INF_QUANT and WeaponGlobals.canUseInfiniteAmmo(localAvatar.currentWeaponId, skillId) or WeaponGlobals.canUseInfiniteAmmo(localAvatar.getCurrentCharm(), skillId):
                ammoAmt = WeaponGlobals.INF_QUANT
            else:
                ammoInvId = WeaponGlobals.getSkillAmmoInventoryId(skillId)
                ammoAmt = inv.getStackQuantity(ammoInvId)
                ammoMax = inv.getStackLimit(ammoInvId)
            self.tray[i + 1].updateQuantity(ammoAmt)
        

    
    def updateSkillIval(self, skillId):
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty() and self.tray[button].skillId == skillId:
                if not self.tray[button].skillRingIval.isPlaying():
                    self.tray[button].skillRingIval.start()
                
            self.tray[button].skillRingIval.isPlaying()
        

    
    def addPowerRechargeEffect(self):
        self.isPowerRecharged = True
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].quickGlowImpulse()
                    self.tray[button].startPowerImpulse()
                    self.tray[button].updateSkillRingIval()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def continuePowerRechargeEffect(self):
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].startPowerImpulse()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def removePowerRechargeEffect(self):
        self.isPowerRecharged = False
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].stopPowerImpulse()
                    self.tray[button].updateSkillRingIval()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def updateCharmSkills(self):
        self.rebuildSkillTray()
        for button in self.tray:
            if isinstance(self.tray[button], SkillButton) and not self.tray[button].isEmpty():
                if (WeaponGlobals.getIsShipSkill(self.tray[button].skillId) or WeaponGlobals.getIsCannonSkill(self.tray[button].skillId)) and self.tray[button].skillId != InventoryType.SailPowerRecharge:
                    self.tray[button].updateSkillRingIval()
                
            self.tray[button].skillId != InventoryType.SailPowerRecharge
        

    
    def destroy(self):
        self.hideSkillTray()
        self.skillTray.destroy()
        if self.repMeter:
            self.repMeter.destroy()
        
        for i in range(self.numberOfItems):
            self.tray[i + 1].destroy()
        
        del self.tray
        del self.callback
        if self.showSkillTrayIval:
            self.showSkillTrayIval.pause()
            self.showSkillTrayIval = None
        
        if self.hideSkillTrayIval:
            self.hideSkillTrayIval.pause()
            self.hideSkillTrayIval = None