def startEffects(self):
        if not self.fireflies:
            self.fireflies = Fireflies()
        if self.fireflies:
            if hasattr(base, 'cr'):
                self.fireflies.reparentTo(base.localAvatar)
                self.fireflies.startLoop()
            base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_JUNGLE, duration=10, finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority=1)
            self.swamp_water = None
            reflection = Reflection.getGlobalReflection()
            if 'jungle_a' in self.modelPrefix:
                water_color = base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20 and Vec4(13, 15, 21, 255.0)
                self.water = Swamp(self.modelPrefix + 'water', self.parent, reflection, None, None, water_color)
                self.water.reflection_factor = 0.3
                self.water.set_reflection_parameters_np()
            else:
                water = loader.loadModel(self.modelPrefix + 'water')
                water.reparentTo(self.parent)
                color = Vec4(0)
                water.setColorScale(color)
                mask = 4294967295L
                stencil = StencilAttrib.make(1, StencilAttrib.SCFAlways, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOReplace, 1, mask, mask)
                water.setAttrib(stencil)
                water.setBin('water', 0)
                self.reflection = reflection
                taskMgr.add(self.camTask, 'jungleEffectsCamTask-' + str(id(self)), priority=49)
                water.setFogOff()
        for file in self.randomAnimalSoundFiles:
            sfx = loadSfx(file)
            self.randomSfx.append(sfx)

        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD, self.checkForRandomSound, name='checkForRandomSound-' + str(id(self)))
        return
    def startEffects(self):
        self.swamp_water = None
        if base.config.GetBool(
                'want-shaders',
                1) and base.win and base.win.getGsg() and base.win.getGsg(
                ).getShaderModel() >= GraphicsStateGuardian.SM20:
            reflection = Reflection.getGlobalReflection()
            self.swamp_water = Swamp(self.modelPath + '_water', self.parent,
                                     reflection)
        else:
            self.water = loader.loadModel(self.modelPath + '_water')
            self.water.reparentTo(self.parent)
            self.water.setTransparency(TransparencyAttrib.MNone, 100)
            alpha_test_attrib = AlphaTestAttrib.make(RenderAttrib.MAlways, 0)
            self.water.setAttrib(alpha_test_attrib, 100)
        if not self.fireflies:
            self.fireflies = Fireflies()

        if self.fireflies and hasattr(base, 'cr'):
            self.fireflies.reparentTo(base.localAvatar)
            self.fireflies.startLoop()

        if not self.groundFog:
            self.groundFog = GroundFog()

        if self.groundFog and hasattr(base, 'options'):
            if base.options.getSpecialEffectsSetting(
            ) >= base.options.SpecialEffectsMedium:
                self.groundFog.reparentTo(base.localAvatar)
                self.groundFog.startLoop(
                    base.options.getSpecialEffectsSetting())

        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            taskMgr.add(self.adjustGroundFogZ,
                        self.parent.uniqueName('groundFogZTask'))

        base.ambientMgr.requestFadeIn(
            SoundGlobals.AMBIENT_SWAMP,
            duration=10,
            finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME,
            priority=1)
        for file in self.randomAnimalSoundFiles:
            sfx = loadSfx(file)
            self.randomSfx.append(sfx)

        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD,
                              self.checkForRandomSound,
                              name='checkForRandomSound-' + str(id(self)))
Beispiel #3
0
 def startEffects(self):
     if not self.fireflies:
         self.fireflies = Fireflies()
     
     if self.fireflies and hasattr(base, 'cr'):
         self.fireflies.reparentTo(base.localAvatar)
         self.fireflies.startLoop()
     
     base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_JUNGLE, duration = 10, finalVolume = PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority = 1)
     self.swamp_water = None
     reflection = Reflection.getGlobalReflection()
     if 'jungle_a' in self.modelPrefix:
         if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
             water_color = Vec4(13, 15, 21, 255.0)
             self.water = Swamp(self.modelPrefix + 'water', self.parent, reflection, None, None, water_color)
             self.water.reflection_factor = 0.29999999999999999
             self.water.set_reflection_parameters_np()
         else:
             water = loader.loadModel(self.modelPrefix + 'water')
             water.reparentTo(self.parent)
             color = Vec4(0)
             water.setColorScale(color)
             mask = 0xFFFFFFFFL
             stencil = StencilAttrib.make(1, StencilAttrib.SCFAlways, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOReplace, 1, mask, mask)
             water.setAttrib(stencil)
             water.setBin('water', 0)
             self.reflection = reflection
             taskMgr.add(self.camTask, 'jungleEffectsCamTask-' + str(id(self)), priority = 49)
             water.setFogOff()
     
     for file in self.randomAnimalSoundFiles:
         sfx = loadSfx(file)
         self.randomSfx.append(sfx)
     
     taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD, self.checkForRandomSound, name = 'checkForRandomSound-' + str(id(self)))
 def startEffects(self):
     reflection = Reflection.getGlobalReflection()
     non_shader_water_color = Vec4(0.0, 1.0 / 255.0, 4.0 / 255.0, 1.0)
     shader_water_color = Vec4(0.0, 1.0, 4.0, 255.0)
     if self.parent.uniqueId in self.WaterCaves:
         if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
             self.water = Swamp('models/caves/cave_a_water', self.parent, reflection, None, None, shader_water_color)
             self.water.reflection_factor = 0.29999999999999999
             self.water.set_reflection_parameters_np()
         else:
             water = loader.loadModel('models/caves/cave_a_water')
             water.reparentTo(self.parent)
             color = non_shader_water_color
             water.setColorScale(color)
             water.setTextureOff(1)
             mask = 0xFFFFFFFFL
             stencil = StencilAttrib.make(1, StencilAttrib.SCFAlways, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOReplace, 1, mask, mask)
             water.setAttrib(stencil)
             water.setBin('water', 0)
             self.reflection = reflection
             taskMgr.add(self.camTask, 'caveEffectsCamTask-' + str(id(self)), priority = 49)
             water.setFogOff()
     elif self.parent.uniqueId in self.LavaCaves:
         if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
             self.water = Swamp(self.modelPrefix + 'lava', self.parent, reflection, None, None, shader_water_color)
             l1 = LerpScaleInterval(self.water.seamodel, 2, Vec3(1.006, 1.006, 1.0), Vec3(1.0, 1.0, 1.0), blendType = 'easeInOut')
             l2 = LerpScaleInterval(self.water.seamodel, 2, Vec3(1.0, 1.0, 1.0), Vec3(1.006, 1.006, 1.0), blendType = 'easeInOut')
             seq = Sequence(l1, l2)
             seq.loop()
             self.water.reflection_factor = 0.29999999999999999
             self.water.set_reflection_parameters_np()
         else:
             water = loader.loadModel(self.modelPrefix + 'lava')
             water.reparentTo(self.parent)
             water.setFogOff()
     
     base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_CAVE, duration = 10, finalVolume = PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority = 1)
     if self.water:
         self.water.supports_sky_only = self.supports_sky_only
     
     if reflection:
         if base.options.reflection >= 1:
             reflection.reflectShowThroughOnly(False)
             reflection.enable(True)
 def startEffects(self):
     reflection = Reflection.getGlobalReflection()
     non_shader_water_color = Vec4(0.0, 1.0 / 255.0, 4.0 / 255.0, 1.0)
     shader_water_color = Vec4(0.0, 1.0, 4.0, 255.0)
     if self.parent.uniqueId in self.WaterCaves:
         if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
             self.water = Swamp('models/caves/cave_a_water', self.parent, reflection, None, None, shader_water_color)
             self.water.reflection_factor = 0.3
             self.water.set_reflection_parameters_np()
         else:
             water = loader.loadModel('models/caves/cave_a_water')
             water.reparentTo(self.parent)
             color = non_shader_water_color
             water.setColorScale(color)
             water.setTextureOff(1)
             mask = 4294967295L
             stencil = StencilAttrib.make(1, StencilAttrib.SCFAlways, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOReplace, 1, mask, mask)
             water.setAttrib(stencil)
             water.setBin('water', 0)
             self.reflection = reflection
             taskMgr.add(self.camTask, 'caveEffectsCamTask-' + str(id(self)), priority=49)
             water.setFogOff()
     elif self.parent.uniqueId in self.LavaCaves:
         if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
             self.water = Swamp(self.modelPrefix + 'lava', self.parent, reflection, None, None, shader_water_color)
             l1 = LerpScaleInterval(self.water.seamodel, 2, Vec3(1.006, 1.006, 1.0), Vec3(1.0, 1.0, 1.0), blendType='easeInOut')
             l2 = LerpScaleInterval(self.water.seamodel, 2, Vec3(1.0, 1.0, 1.0), Vec3(1.006, 1.006, 1.0), blendType='easeInOut')
             seq = Sequence(l1, l2)
             seq.loop()
             self.water.reflection_factor = 0.3
             self.water.set_reflection_parameters_np()
         else:
             water = loader.loadModel(self.modelPrefix + 'lava')
             water.reparentTo(self.parent)
             water.setFogOff()
     base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_CAVE, duration=10, finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority=1)
     if self.water:
         self.water.supports_sky_only = self.supports_sky_only
     if reflection:
         if base.options.reflection >= 1:
             reflection.reflectShowThroughOnly(False)
             reflection.enable(True)
     return
Beispiel #6
0
 def startEffects(self):
     self.swamp_water = None
     if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
         reflection = Reflection.getGlobalReflection()
         self.swamp_water = Swamp(self.modelPath + '_water', self.parent, reflection)
     else:
         self.water = loader.loadModel(self.modelPath + '_water')
         self.water.reparentTo(self.parent)
         self.water.setTransparency(TransparencyAttrib.MNone, 100)
         alpha_test_attrib = AlphaTestAttrib.make(RenderAttrib.MAlways, 0)
         self.water.setAttrib(alpha_test_attrib, 100)
     if not self.fireflies:
         self.fireflies = Fireflies()
     
     if self.fireflies and hasattr(base, 'cr'):
         self.fireflies.reparentTo(base.localAvatar)
         self.fireflies.startLoop()
     
     if not self.groundFog:
         self.groundFog = GroundFog()
     
     if self.groundFog and hasattr(base, 'options'):
         if base.options.getSpecialEffectsSetting() >= base.options.SpecialEffectsMedium:
             self.groundFog.reparentTo(base.localAvatar)
             self.groundFog.startLoop(base.options.getSpecialEffectsSetting())
         
     
     if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
         taskMgr.add(self.adjustGroundFogZ, self.parent.uniqueName('groundFogZTask'))
     
     base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_SWAMP, duration = 10, finalVolume = PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority = 1)
     for file in self.randomAnimalSoundFiles:
         sfx = loadSfx(file)
         self.randomSfx.append(sfx)
     
     taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD, self.checkForRandomSound, name = 'checkForRandomSound-' + str(id(self)))
class CaveEffects(EnvironmentEffects.EnvironmentEffects):
    WaterCaves = [LocationIds.ANVIL_CAVE_BARBOSA]
    LavaCaves = []

    def __init__(self, parent, modelPath):
        EnvironmentEffects.EnvironmentEffects.__init__(self, parent, modelPath)
        self.modelPath = modelPath
        self.modelPrefix = ''
        self.animActor = None
        self.water = None
        self.reflection = None
        self.supports_sky_only = False
        self.startEffects()

    def delete(self):
        del self.animActor
        self.stopEffects()
        EnvironmentEffects.EnvironmentEffects.delete(self)

    def startEffects(self):
        reflection = Reflection.getGlobalReflection()
        non_shader_water_color = Vec4(0.0, 1.0 / 255.0, 4.0 / 255.0, 1.0)
        shader_water_color = Vec4(0.0, 1.0, 4.0, 255.0)
        if self.parent.uniqueId in self.WaterCaves:
            if base.config.GetBool(
                    'want-shaders',
                    1) and base.win and base.win.getGsg() and base.win.getGsg(
                    ).getShaderModel() >= GraphicsStateGuardian.SM20:
                self.water = Swamp('models/caves/cave_a_water', self.parent,
                                   reflection, None, None, shader_water_color)
                self.water.reflection_factor = 0.29999999999999999
                self.water.set_reflection_parameters_np()
            else:
                water = loader.loadModel('models/caves/cave_a_water')
                water.reparentTo(self.parent)
                color = non_shader_water_color
                water.setColorScale(color)
                water.setTextureOff(1)
                mask = 0xFFFFFFFFL
                stencil = StencilAttrib.make(1, StencilAttrib.SCFAlways,
                                             StencilAttrib.SOKeep,
                                             StencilAttrib.SOKeep,
                                             StencilAttrib.SOReplace, 1, mask,
                                             mask)
                water.setAttrib(stencil)
                water.setBin('water', 0)
                self.reflection = reflection
                taskMgr.add(self.camTask,
                            'caveEffectsCamTask-' + str(id(self)),
                            priority=49)
                water.setFogOff()
        elif self.parent.uniqueId in self.LavaCaves:
            if base.config.GetBool(
                    'want-shaders',
                    1) and base.win and base.win.getGsg() and base.win.getGsg(
                    ).getShaderModel() >= GraphicsStateGuardian.SM20:
                self.water = Swamp(self.modelPrefix + 'lava', self.parent,
                                   reflection, None, None, shader_water_color)
                l1 = LerpScaleInterval(self.water.seamodel,
                                       2,
                                       Vec3(1.006, 1.006, 1.0),
                                       Vec3(1.0, 1.0, 1.0),
                                       blendType='easeInOut')
                l2 = LerpScaleInterval(self.water.seamodel,
                                       2,
                                       Vec3(1.0, 1.0, 1.0),
                                       Vec3(1.006, 1.006, 1.0),
                                       blendType='easeInOut')
                seq = Sequence(l1, l2)
                seq.loop()
                self.water.reflection_factor = 0.29999999999999999
                self.water.set_reflection_parameters_np()
            else:
                water = loader.loadModel(self.modelPrefix + 'lava')
                water.reparentTo(self.parent)
                water.setFogOff()

        base.ambientMgr.requestFadeIn(
            SoundGlobals.AMBIENT_CAVE,
            duration=10,
            finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME,
            priority=1)
        if self.water:
            self.water.supports_sky_only = self.supports_sky_only

        if reflection:
            if base.options.reflection >= 1:
                reflection.reflectShowThroughOnly(False)
                reflection.enable(True)

    def camTask(self, task):
        if self.reflection:
            self.reflection.update_reflection(base.camLens, base.cam)

        return Task.cont

    def stopEffects(self):
        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            if base.options.reflection == 0:
                Water.all_reflections_off()
            elif base.options.reflection == 1:
                Water.all_reflections_show_through_only()
            elif base.options.reflection == 2:
                Water.all_reflections_on()

        if self.water:
            self.water.delete()
            self.water = None

        taskMgr.remove('caveEffectsCamTask-' + str(id(self)))
        base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_CAVE,
                                       duration=5,
                                       priority=1)
Beispiel #8
0
class ForestEffects(EnvironmentEffects.EnvironmentEffects):
    FIREFLIES_Z = 6.0
    RANDOM_SOUND_PERIOD = 6
    RANDOM_SOUND_CHANCE = 12
    
    def __init__(self, parent, modelPath):
        EnvironmentEffects.EnvironmentEffects.__init__(self, parent, modelPath)
        self.fireflies = None
        self.modelPrefix = modelPath[:-4]
        self.animActor = self.setupAnimActor()
        self.water = None
        self.randomAnimalSoundFiles = [
            SoundGlobals.SFX_FX_JUNGLE_BIRDS_01,
            SoundGlobals.SFX_FX_JUNGLE_BIRDS_02]
        self.randomSfx = []
        self.startEffects()

    
    def delete(self):
        del self.animActor
        self.stopEffects()
        EnvironmentEffects.EnvironmentEffects.delete(self)

    
    def startEffects(self):
        if not self.fireflies:
            self.fireflies = Fireflies()
        
        if self.fireflies and hasattr(base, 'cr'):
            self.fireflies.reparentTo(base.localAvatar)
            self.fireflies.startLoop()
        
        base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_JUNGLE, duration = 10, finalVolume = PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority = 1)
        self.swamp_water = None
        reflection = Reflection.getGlobalReflection()
        if 'jungle_a' in self.modelPrefix:
            if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
                water_color = Vec4(13, 15, 21, 255.0)
                self.water = Swamp(self.modelPrefix + 'water', self.parent, reflection, None, None, water_color)
                self.water.reflection_factor = 0.29999999999999999
                self.water.set_reflection_parameters_np()
            else:
                water = loader.loadModel(self.modelPrefix + 'water')
                water.reparentTo(self.parent)
                color = Vec4(0)
                water.setColorScale(color)
                mask = 0xFFFFFFFFL
                stencil = StencilAttrib.make(1, StencilAttrib.SCFAlways, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOReplace, 1, mask, mask)
                water.setAttrib(stencil)
                water.setBin('water', 0)
                self.reflection = reflection
                taskMgr.add(self.camTask, 'jungleEffectsCamTask-' + str(id(self)), priority = 49)
                water.setFogOff()
        
        for file in self.randomAnimalSoundFiles:
            sfx = loadSfx(file)
            self.randomSfx.append(sfx)
        
        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD, self.checkForRandomSound, name = 'checkForRandomSound-' + str(id(self)))

    
    def stopEffects(self):
        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            taskMgr.remove(self.parent.uniqueName('groundFogZTask'))
        
        if self.water:
            self.water.delete()
            self.water = None
        
        if self.fireflies:
            self.fireflies.destroy()
            self.fireflies = None
        
        taskMgr.remove('jungleEffectsCamTask-' + str(id(self)))
        taskMgr.remove('checkForRandomSound-' + str(id(self)))
        for sfx in self.randomSfx:
            sfx.stop()
        
        base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_JUNGLE, duration = 5, priority = 1)

    
    def checkForRandomSound(self, task):
        randomSoundPlaying = False
        for sfx in self.randomSfx:
            if sfx.status() == 2:
                randomSoundPlaying = True
                break
                continue
        
        if not randomSoundPlaying:
            roll = random.randint(0, 100)
            if roll < self.RANDOM_SOUND_CHANCE:
                sfxToPlay = random.choice(self.randomSfx)
                sfxToPlay.play()
            
        
        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD, self.checkForRandomSound, name = 'checkForRandomSound-' + str(id(self)))
        return Task.done

    
    def camTask(self, task):
        if self.reflection:
            self.reflection.update_reflection(base.camLens, base.cam)
        
        return Task.cont

    
    def adjustGroundFogZ(self, task):
        if self.fireflies:
            self.fireflies.setZ(render, self.FIREFLIES_Z)
        
        if self.fireflies:
            return Task.cont
        
        return Task.done
Beispiel #9
0
class ForestEffects(EnvironmentEffects.EnvironmentEffects):
    FIREFLIES_Z = 6.0
    RANDOM_SOUND_PERIOD = 6
    RANDOM_SOUND_CHANCE = 12

    def __init__(self, parent, modelPath):
        EnvironmentEffects.EnvironmentEffects.__init__(self, parent, modelPath)
        self.fireflies = None
        self.modelPrefix = modelPath[:-4]
        self.animActor = self.setupAnimActor()
        self.water = None
        self.randomAnimalSoundFiles = [
            SoundGlobals.SFX_FX_JUNGLE_BIRDS_01,
            SoundGlobals.SFX_FX_JUNGLE_BIRDS_02
        ]
        self.randomSfx = []
        self.startEffects()
        return

    def delete(self):
        del self.animActor
        self.stopEffects()
        EnvironmentEffects.EnvironmentEffects.delete(self)

    def startEffects(self):
        if not self.fireflies:
            self.fireflies = Fireflies()
        if self.fireflies and hasattr(base, 'cr'):
            self.fireflies.reparentTo(base.localAvatar)
            self.fireflies.startLoop()
        base.ambientMgr.requestFadeIn(
            SoundGlobals.AMBIENT_JUNGLE,
            duration=10,
            finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME,
            priority=1)
        self.swamp_water = None
        reflection = Reflection.getGlobalReflection()
        if 'jungle_a' in self.modelPrefix:
            if base.config.GetBool(
                    'want-shaders',
                    1) and base.win and base.win.getGsg() and base.win.getGsg(
                    ).getShaderModel() >= GraphicsStateGuardian.SM20:
                water_color = Vec4(13, 15, 21, 255.0)
                self.water = Swamp(self.modelPrefix + 'water', self.parent,
                                   reflection, None, None, water_color)
                self.water.reflection_factor = 0.3
                self.water.set_reflection_parameters_np()
            else:
                water = loader.loadModel(self.modelPrefix + 'water')
                water.reparentTo(self.parent)
                color = Vec4(0)
                water.setColorScale(color)
                mask = 4294967295L
                stencil = StencilAttrib.make(1, StencilAttrib.SCFAlways,
                                             StencilAttrib.SOKeep,
                                             StencilAttrib.SOKeep,
                                             StencilAttrib.SOReplace, 1, mask,
                                             mask)
                water.setAttrib(stencil)
                water.setBin('water', 0)
                self.reflection = reflection
                taskMgr.add(self.camTask,
                            'jungleEffectsCamTask-' + str(id(self)),
                            priority=49)
                water.setFogOff()
        for file in self.randomAnimalSoundFiles:
            sfx = loadSfx(file)
            self.randomSfx.append(sfx)

        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD,
                              self.checkForRandomSound,
                              name='checkForRandomSound-' + str(id(self)))
        return

    def stopEffects(self):
        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            taskMgr.remove(self.parent.uniqueName('groundFogZTask'))
        if self.water:
            self.water.delete()
            self.water = None
        if self.fireflies:
            self.fireflies.destroy()
            self.fireflies = None
        taskMgr.remove('jungleEffectsCamTask-' + str(id(self)))
        taskMgr.remove('checkForRandomSound-' + str(id(self)))
        for sfx in self.randomSfx:
            sfx.stop()

        base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_JUNGLE,
                                       duration=5,
                                       priority=1)
        return

    def checkForRandomSound(self, task):
        randomSoundPlaying = False
        for sfx in self.randomSfx:
            if sfx.status() == 2:
                randomSoundPlaying = True
                break

        if not randomSoundPlaying:
            roll = random.randint(0, 100)
            if roll < self.RANDOM_SOUND_CHANCE:
                sfxToPlay = random.choice(self.randomSfx)
                sfxToPlay.play()
        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD,
                              self.checkForRandomSound,
                              name='checkForRandomSound-' + str(id(self)))
        return Task.done

    def camTask(self, task):
        if self.reflection:
            self.reflection.update_reflection(base.camLens, base.cam)
        return Task.cont

    def adjustGroundFogZ(self, task):
        if self.fireflies:
            self.fireflies.setZ(render, self.FIREFLIES_Z)
        if self.fireflies:
            return Task.cont
        return Task.done
class SwampEffects(EnvironmentEffects.EnvironmentEffects):
    GROUND_FOG_Z = 2.0
    FIREFLIES_Z = 6.0
    RANDOM_SOUND_PERIOD = 6
    RANDOM_SOUND_CHANCE = 12

    def __init__(self, parent, modelPath):
        EnvironmentEffects.EnvironmentEffects.__init__(self, parent, modelPath)
        self.fireflies = None
        self.groundFog = None
        self.swamp_water = None
        self.water = None
        self.randomAnimalSoundFiles = [
            SoundGlobals.SFX_FX_SWAMP_FROG_01,
            SoundGlobals.SFX_FX_SWAMP_OWL_01, SoundGlobals.SFX_FX_SWAMP_OWL_02
        ]
        self.randomSfx = []
        self.startEffects()

    def delete(self):
        self.stopEffects()
        EnvironmentEffects.EnvironmentEffects.delete(self)

    def startEffects(self):
        self.swamp_water = None
        if base.config.GetBool(
                'want-shaders',
                1) and base.win and base.win.getGsg() and base.win.getGsg(
                ).getShaderModel() >= GraphicsStateGuardian.SM20:
            reflection = Reflection.getGlobalReflection()
            self.swamp_water = Swamp(self.modelPath + '_water', self.parent,
                                     reflection)
        else:
            self.water = loader.loadModel(self.modelPath + '_water')
            self.water.reparentTo(self.parent)
            self.water.setTransparency(TransparencyAttrib.MNone, 100)
            alpha_test_attrib = AlphaTestAttrib.make(RenderAttrib.MAlways, 0)
            self.water.setAttrib(alpha_test_attrib, 100)
        if not self.fireflies:
            self.fireflies = Fireflies()

        if self.fireflies and hasattr(base, 'cr'):
            self.fireflies.reparentTo(base.localAvatar)
            self.fireflies.startLoop()

        if not self.groundFog:
            self.groundFog = GroundFog()

        if self.groundFog and hasattr(base, 'options'):
            if base.options.getSpecialEffectsSetting(
            ) >= base.options.SpecialEffectsMedium:
                self.groundFog.reparentTo(base.localAvatar)
                self.groundFog.startLoop(
                    base.options.getSpecialEffectsSetting())

        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            taskMgr.add(self.adjustGroundFogZ,
                        self.parent.uniqueName('groundFogZTask'))

        base.ambientMgr.requestFadeIn(
            SoundGlobals.AMBIENT_SWAMP,
            duration=10,
            finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME,
            priority=1)
        for file in self.randomAnimalSoundFiles:
            sfx = loadSfx(file)
            self.randomSfx.append(sfx)

        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD,
                              self.checkForRandomSound,
                              name='checkForRandomSound-' + str(id(self)))

    def stopEffects(self):
        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            taskMgr.remove(self.parent.uniqueName('groundFogZTask'))

        taskMgr.remove('checkForRandomSound-' + str(id(self)))
        if self.swamp_water:
            self.swamp_water.delete()
            self.water = None

        if self.fireflies:
            self.fireflies.destroy()
            self.fireflies = None

        if self.groundFog:
            self.groundFog.destroy()
            self.groundFog = None

        base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_SWAMP,
                                       duration=5,
                                       priority=1)
        for sfx in self.randomSfx:
            sfx.stop()

    def adjustGroundFogZ(self, task):
        if self.fireflies:
            self.fireflies.setZ(render, self.FIREFLIES_Z)

        if self.groundFog:
            self.groundFog.setZ(render, self.GROUND_FOG_Z)

        if self.fireflies or self.groundFog:
            return Task.cont

        return Task.done

    def checkForRandomSound(self, task):
        randomSoundPlaying = False
        for sfx in self.randomSfx:
            if sfx.status() == 2:
                randomSoundPlaying = True
                break
                continue

        if not randomSoundPlaying:
            roll = random.randint(0, 100)
            if roll < self.RANDOM_SOUND_CHANCE:
                sfxToPlay = random.choice(self.randomSfx)
                sfxToPlay.play()

        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD,
                              self.checkForRandomSound,
                              name='checkForRandomSound-' + str(id(self)))
        return Task.done
 def initializeIslandWaterParameters(self, reference):
     debug = False
     island_water_parameters = IslandWaterParameters()
     world_position = self.getPos(render)
     world_x_offset = world_position[0]
     world_y_offset = world_position[1]
     world_z_offset = world_position[2]
     if debug:
         print self, '=', self.getName()
         print 'GAME AREA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
     self.swampAreaNode = reference.find('**/ocean')
     model = reference.find('**/water_color')
     if model:
         if debug:
             print 'WATER COLOR X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
         model.hide()
         min_point = Point3(0)
         max_point = Point3(0)
         model.calcTightBounds(min_point, max_point)
         size = max_point - min_point
         if self.getH() == 180 or self.getH() == -180:
             x = -min_point[0] + world_x_offset
             y = -min_point[1] + world_y_offset
             x_size = -size[0]
             y_size = -size[1]
         else:
             x = min_point[0] + world_x_offset
             y = min_point[1] + world_y_offset
             x_size = size[0]
             y_size = size[1]
         island_water_parameters.map_x_origin = x
         island_water_parameters.map_y_origin = y
         island_water_parameters.map_x_scale = x_size
         island_water_parameters.map_y_scale = y_size
         if debug:
             print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[
                 1], x_size, y_size
         texture = model.findTexture('*')
         if texture:
             island_water_parameters.water_color_texture = texture
             if debug:
                 print 'WATER COLOR TEXTURE', texture
     elif debug:
         print '*** water_color NODE NOT FOUND'
     model = reference.find('**/water_alpha')
     if model:
         if debug:
             print 'WATER ALPHA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
         model.hide()
         min_point = Point3(0)
         max_point = Point3(0)
         model.calcTightBounds(min_point, max_point)
         size = max_point - min_point
         if self.getH() == 180 or self.getH() == -180:
             x = -min_point[0] + world_x_offset
             y = -min_point[1] + world_y_offset
             x_size = -size[0]
             y_size = -size[1]
         else:
             x = min_point[0] + world_x_offset
             y = min_point[1] + world_y_offset
             x_size = size[0]
             y_size = size[1]
         island_water_parameters.alpha_map_x_origin = x
         island_water_parameters.alpha_map_y_origin = y
         island_water_parameters.alpha_map_x_scale = x_size
         island_water_parameters.alpha_map_y_scale = y_size
         if debug:
             print 'ALPHA X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[
                 1], x_size, y_size
         texture = model.findTexture('*')
         if texture:
             island_water_parameters.water_alpha_texture = texture
             if debug:
                 print 'WATER ALPHA TEXTURE', texture
     elif debug:
         print '*** water_alpha NODE NOT FOUND'
     use_shader = False
     if base.config.GetBool(
             'want-shaders',
             1) and base.win and base.win.getGsg() and base.win.getGsg(
             ).getShaderModel() >= GraphicsStateGuardian.SM20:
         use_shader = True
     model_ns = reference.find('**/water_swamp_ns')
     if model_ns:
         if use_shader:
             model_ns.hide()
         else:
             model_ns.show()
             model = model_ns
             model.setBin('water', 1)
             parent = model.getParent()
             model.detachNode()
             stencil_one_node_path = NodePath('stencil_one')
             stencil_one_node_path.reparentTo(parent)
             model.instanceTo(stencil_one_node_path)
             mask = 4294967295L
             stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual,
                                              StencilAttrib.SOKeep,
                                              StencilAttrib.SOKeep,
                                              StencilAttrib.SOKeep, 1, mask,
                                              mask)
             stencil_one_node_path.setAttrib(stencil_one, 100)
             stencil_one_node_path.setDepthTest(0)
             if not base.useStencils:
                 stencil_one_node_path.hide()
     model_alpha_texture = None
     model_alpha = reference.find('**/water_alpha_swamp')
     if model_alpha:
         model_alpha_texture = model_alpha.findTexture('*')
         model_alpha.hide()
         if debug:
             print 'model_alpha_texture', model_alpha_texture
         if False:
             texture = model_alpha_texture
             card_x_size = 0.5
             card_y_size = 0.5
             card = CardMaker('test_texture_card')
             card.setFrame(-card_x_size, card_x_size, -card_y_size,
                           card_y_size)
             card_node_path = NodePath(card.generate())
             card_node_path.setTexture(texture, 1)
             card_node_path.node().setBounds(OmniBoundingVolume())
             card_node_path.node().setFinal(1)
             card_node_path.reparentTo(render2d)
     else:
         model_alpha = None
     model = reference.find('**/water_color_swamp')
     if model:
         if use_shader:
             model.show()
             model_texture = model.findTexture('*')
             if debug:
                 print 'WATER COLOR SWAMP X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
             parent = model.getParent()
             model.detachNode()
             stencil_one_node_path = NodePath('stencil_one')
             stencil_one_node_path.reparentTo(parent)
             model.instanceTo(stencil_one_node_path)
             mask = 4294967295L
             stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual,
                                              StencilAttrib.SOKeep,
                                              StencilAttrib.SOKeep,
                                              StencilAttrib.SOKeep, 1, mask,
                                              mask)
             stencil_one_node_path.setAttrib(stencil_one, 100)
             stencil_one_node_path.setDepthTest(0)
             if not base.useStencils:
                 stencil_one_node_path.hide()
             min_point = Point3(0)
             max_point = Point3(0)
             model.calcTightBounds(min_point, max_point)
             size = max_point - min_point
             if self.getH() == 180 or self.getH() == -180:
                 x = -min_point[0] + world_x_offset
                 y = -min_point[1] + world_y_offset
                 x_size = -size[0]
                 y_size = -size[1]
             else:
                 x = min_point[0] + world_x_offset
                 y = min_point[1] + world_y_offset
                 x_size = size[0]
                 y_size = size[1]
             if debug:
                 print 'min_point', min_point
                 print 'max_point', max_point
                 print 'size', size
                 print 'x y', x, y
             island_water_parameters.swamp_map_x_origin = x
             island_water_parameters.swamp_map_y_origin = y
             island_water_parameters.swamp_map_x_scale = x_size
             island_water_parameters.swamp_map_y_scale = y_size
             if debug:
                 print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[
                     1], x_size, y_size
             texture = model.findTexture('*')
             if texture:
                 island_water_parameters.swamp_water_color_texture = texture
                 if debug:
                     print 'SWAMP WATER COLOR TEXTURE', texture
             water_color_file_path = island_water_parameters.default_water_color_file_path
             alpha_texture_file_path = island_water_parameters.default_water_alpha_file_path
             opacity_texture_file_path = None
             shader_file_path = 'models/swamps/cuba_swamp001_2X.cg'
             reflection = Reflection.getGlobalReflection()
             self.swamp_water = Swamp(None, None, reflection, model,
                                      shader_file_path)
             island_water_parameters.swamp_water = self.swamp_water
             unload_previous_texture = True
             self.swamp_water.set_water_color_texture(
                 water_color_file_path, unload_previous_texture,
                 model_texture)
             self.swamp_water.set_water_alpha_texture(
                 alpha_texture_file_path, unload_previous_texture,
                 model_alpha_texture)
             self.swamp_water.set_wrap_or_clamp(True)
             r = 37.0
             g = 62.0
             b = 40.0
             self.swamp_water.water_r = r
             self.swamp_water.water_g = g
             self.swamp_water.water_b = b
             island_water_parameters.swamp_color_r = r
             island_water_parameters.swamp_color_g = g
             island_water_parameters.swamp_color_b = b
             x = 0.0
             y = 1.0
             speed = 3.2
             island_water_parameters.swamp_direction_x = x
             island_water_parameters.swamp_direction_y = y
             island_water_parameters.swamp_speed = speed
             self.swamp_water.update_water_direction_and_speed(x, y, speed)
         else:
             model.hide()
     elif debug:
         print '*** water_color_swamp NODE NOT FOUND'
     self.islandWaterParameters = island_water_parameters
     return
class DistributedGameArea(DistributedNode, MappableArea, StagedObject):
    notify = directNotify.newCategory('DistributedGameArea')

    def __init__(self, cr):
        DistributedNode.__init__(self, cr)
        NodePath.__init__(self, 'GameArea')
        MappableArea.__init__(self)
        StagedObject.__init__(self, StagedObject.OFF)
        self.uniqueId = ''
        self.geom = None
        self.funnelDisplayName = None
        self.previousDisplayName = None
        self.gameFSM = None
        self.links = []
        self.pendingSetupConnector = {}
        self.connectors = {}
        self.connectorInterests = set()
        self.envEffects = None
        self.spawnTriggers = []
        self.blockerColls = []
        self.islandWaterParameters = None
        self.swamp_water = None
        self.entryTime = [None, 0]
        self.timeCheck = 0
        self.minimap = None
        self.footprintNode = None
        self.popupDialog = None
        self.minimapArea = 0
        self.laMinimapObj = None
        self.footstepSound = None
        self.environment = None
        self.connectorsHereCallback = None
        return

    def __repr__(self):
        return '%s (%s)' % (DistributedNode.__repr__(self), self.getName()
                            or self.uniqueId)

    def __str__(self):
        return '%s (%s)' % (DistributedNode.__repr__(self), self.getName()
                            or self.uniqueId)

    def disable(self):
        taskMgr.remove('showEnterMessage')
        DistributedNode.disable(self)
        if self.geom:
            self.geom.removeNode()
        self.unloadConnectors()
        for request in self.pendingSetupConnector.itervalues():
            self.cr.relatedObjectMgr.abortRequest(request)

        self.pendingSetupConnector = {}
        self.builder.delete()
        self.builder = None
        return

    def delete(self):
        if base.zoneLODTarget == self:
            base.disableZoneLODs()
        for trigger in self.spawnTriggers:
            trigger.removeNode()

        del self.spawnTriggers
        del self.connectors
        del self.links
        if self.envEffects:
            self.envEffects.delete()
            self.envEffects = None
        DistributedNode.delete(self)
        if self.islandWaterParameters:
            del self.islandWaterParameters
        if self.swamp_water:
            self.swamp_water.delete()
            del self.swamp_water
        if self.popupDialog:
            self.popupDialog.destroy()
        del self.popupDialog
        self.connectorsHereCallback = None
        return

    def setLocation(self, parentId, zoneId):
        DistributedNode.setLocation(self, parentId, zoneId)
        if parentId:
            parent = self.getParentObj()
            self.reparentTo(parent)

    def setName(self, name):
        self.name = name

    def setModelPath(self, modelPath):
        self.modelPath = modelPath

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def handleChildArrive(self, childObj, zoneId):
        DistributedNode.handleChildArrive(self, childObj, zoneId)
        if childObj.isLocal():
            base.loadingScreen.endStep('enterArea')
            base.enableZoneLODs(self)
            childObj.refreshActiveQuestStep()
            localAvatar.guiMgr.setMinimap(self.minimap)
            localAvatar.setAreaFootstep(self.footstepSound)
            localAvatar.guiMgr.radarGui.showLocation(self.uniqueId)
            envName = base.worldCreator.environmentTable.get(self.uniqueId)
            if envName:
                environmentID = TODGlobals.ENVIRONMENT_NAMES_TO_ID.get(
                    envName, TODGlobals.ENV_DEFAULT)
                envData = {}
                envSettings = base.worldCreator.uidEnvSettings.get(
                    self.uniqueId)
                if envSettings != None:
                    envData = envSettings
                base.cr.timeOfDayManager.setEnvironment(environmentID, envData)
            else:
                envData = None
                envSettings = base.worldCreator.uidEnvSettings.get(
                    self.uniqueId)
                if envSettings != None:
                    envData = envSettings
                base.cr.timeOfDayManager.setEnvironment(
                    TODGlobals.ENV_INTERIOR, envData)
            self.builder.arrived()
        self.accept('transferMinimapObjects', self.transferMinimapObject)
        if self.minimap and hasattr(childObj, 'getMinimapObject'):
            if childObj.getMinimapObject():
                self.laMinimapObj = childObj.getMinimapObject()
                self.minimap.addObject(childObj.getMinimapObject())
        return

    def transferMinimapObject(self, guiMgr):
        if self.laMinimapObj:
            guiMgr.transferMinimapObject(self.laMinimapObj)

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def handleChildLeave(self, childObj, zoneId):
        if childObj.isLocal():
            base.disableZoneLODs()
            localAvatar.guiMgr.clearMinimap(self.minimap)
            self.builder.localAvLeaving()
            self.builder.left()
        self.ignore('transferMinimapObjects')
        self.laMinimapObj = None
        if self.minimap and hasattr(childObj, 'getMinimapObject'):
            if childObj.getMinimapObject():
                self.minimap.removeObject(childObj.getMinimapObject())
        DistributedNode.handleChildLeave(self, childObj, zoneId)
        return

    def setUniqueId(self, uid):
        if self.uniqueId != '':
            self.cr.uidMgr.removeUid(self.uniqueId)
        self.uniqueId = uid
        self.cr.uidMgr.addUid(self.uniqueId, self.getDoId())

    def getUniqueId(self):
        return self.uniqueId

    def loadModel(self):
        pass

    @report(types=['args', 'deltaStamp'], dConfigParam=['jail'])
    def setLinks(self, links):
        for link in links:
            areaNode, connId, areaUid, connParent, connZone, connNode, connWorld, connWorldZone = link
            newLink = [connId, connParent, connZone, connWorld, connWorldZone]
            if newLink in self.links:
                continue
            self.links.append(newLink)

            def setupConnector(connector):
                self.connectors[connector.doId] = connector
                request = self.pendingSetupConnector.pop(connector.doId, None)
                if not request:
                    pass
                return

            connector = self.cr.doId2do.get(connId)
            if connector:
                self.pendingSetupConnector[connId] = None
                setupConnector(connector)
            elif connId:
                if connId in self.pendingSetupConnector:
                    request = self.pendingSetupConnector.pop(connId)
                    self.cr.relatedObjectMgr.abortRequest(request)
                request = self.cr.relatedObjectMgr.requestObjects(
                    [connId], eachCallback=setupConnector)
                self.pendingSetupConnector[connId] = request

        return

    @report(types=['args', 'deltaStamp'], dConfigParam=['jail', 'teleport'])
    def loadConnectors(self):
        for link in self.links:
            if link:
                connectorId = link[0]
                if connectorId not in self.connectorInterests or not self.cr.doId2do.has_key(
                        connectorId):
                    if connectorId not in self.connectorInterests:
                        self.connectorInterests.add(connectorId)
                    parentId = link[1]
                    zoneId = link[2]
                    linkParentId = link[3]
                    linkParentZoneId = link[4]

                    def connectorParentHere(connectorId, parentId, zoneId):
                        connectorEvent = 'connector-%s' % connectorId
                        self.acceptOnce(connectorEvent,
                                        self.reparentConnector,
                                        extraArgs=[connectorId])
                        self.cr.addTaggedInterest(
                            parentId,
                            zoneId,
                            self.cr.ITAG_GAME,
                            'Connectors-%s' % self.doId,
                            event=connectorEvent,
                            otherTags=['Connectors-%s' % self.doId])

                    connectorEvent = 'connector-%s' % connectorId
                    self.acceptOnce(connectorEvent,
                                    connectorParentHere,
                                    extraArgs=[connectorId, parentId, zoneId])
                    self.cr.addTaggedInterest(
                        linkParentId,
                        linkParentZoneId,
                        self.cr.ITAG_GAME,
                        'ConnectorsParent-%s' % self.doId,
                        event=connectorEvent,
                        otherTags=['ConnectorsParent-%s' % self.doId])
                else:
                    self.reparentConnector(connectorId)

    @report(types=['args', 'deltaStamp'], dConfigParam=['jail', 'teleport'])
    def unloadConnectors(self):
        for connectorId, connector in self.connectors.iteritems():
            if connector:
                connector.setLoadedArea(None)
                connector.goOffStage()

        self.connectors = {}
        self.cr.removeInterestTag('Connectors-%s' % self.doId)
        self.cr.removeInterestTag('ConnectorsParent-%s' % self.doId)
        self.connectorInterests = set()
        return

    @report(types=['args', 'deltaStamp'], dConfigParam=['jail', 'teleport'])
    def reparentConnector(self, connectorId):
        connector = self.cr.doId2do.get(connectorId)
        if connector:
            self.connectors[connectorId] = connector
            connector.reparentConnectorToArea(self)
            if self.isOnStage():
                connector.goOnStage()
            else:
                connector.goOffStage()
            if self.connectorsHereCallback and len(self.connectors) == len(
                    self.links):
                self.connectorsHereCallback()
                self.connectorsHereCallback = None
        return

    def setConnectorsHereCallback(self, callback):
        self.connectorsHereCallback = callback

    @report(types=['args', 'deltaStamp'], dConfigParam=['jail', 'teleport'])
    def handleEnterGameArea(self, collEntry=None):
        inventory = localAvatar.getInventory()
        if localAvatar.style.getTutorial(
        ) == PiratesGlobals.TUT_GOT_SEACHEST and self.uniqueId == LocationIds.RAMBLESHACK_ISLAND and len(
                inventory.getWeapons()) < 1 and base.localAvatar.showQuest:
            base.localAvatar.resetQuestShow()
            popupDialogText = ['showBlacksmith', 'closeShowBlacksmith']
            self.popupDialog = NewTutorialPanel(popupDialogText)

            def closeTutorialWindow():
                messenger.send(self.popupDialog.closeMessage)

            self.popupDialog.setYesCommand(closeTutorialWindow)
            self.acceptOnce('closeTutorialWindow', closeTutorialWindow)
            self.popupDialog.activate()
        taskMgr.doMethodLater(1, self.showEnterMessage, 'showEnterMessage')
        UserFunnel.logSubmit(0, 'ENTERING_' + str(self.funnelDisplayName))
        UserFunnel.logSubmit(1, 'ENTERING_' + str(self.funnelDisplayName))
        self.storeLocationTime(self.funnelDisplayName, time.time())
        displayName = PLocalizer.LocationNames.get(self.uniqueId)
        base.setLocationCode(displayName)
        self.builder.initEffects()

    def storeLocationTime(self, loc, time):
        if loc == self.entryTime[0]:
            if self.entryTime[1] == 0:
                self.entryTime[1] = time
            return
        else:
            self.entryTime = [loc, time]

    def readLocationTime(self):
        return self.entryTime[1]

    def showEnterMessage(self, task):
        displayName = PLocalizer.LocationNames.get(self.uniqueId)
        self.displayGameAreaName(displayName)

    @report(types=['args', 'deltaStamp'], dConfigParam=['jail', 'teleport'])
    def handleExitGameArea(self, collEntry=None):
        UserFunnel.logSubmit(0, 'EXITING_' + str(self.funnelDisplayName))
        UserFunnel.logSubmit(1, 'EXITING_' + str(self.funnelDisplayName))
        self.stopCustomEffects()
        self.previousDisplayName = None
        displayName = str(self.funnelDisplayName)
        timeSpent = int(time.time()) - int(self.readLocationTime())
        if int(self.timeCheck) + 1 == int(timeSpent) or int(
                self.timeCheck) - 1 == int(timeSpent) or int(
                    self.timeCheck) == int(timeSpent):
            pass
        else:
            base.cr.centralLogger.writeClientEvent('EXITING_AREA|%s|%d' %
                                                   (displayName, timeSpent))
            self.timeCheck = timeSpent
        return

    def displayGameAreaName(self, displayName):
        self.funnelDisplayName = displayName
        if self.previousDisplayName != displayName:
            self.previousDisplayName = displayName
            base.localAvatar.guiMgr.createTitle(displayName,
                                                PiratesGuiGlobals.TextFG2)

    def setPlayerBarrier(self, isOn):
        pass

    def setupCannonballLandColl(self, collNode, mask, index):
        if collNode and not collNode.isEmpty():
            collNode.node().setCollideMask(mask)
            collNode.setTag('objType', str(PiratesGlobals.COLL_LAND))
            collNode.setTag('groundCode', str(index))
            collNode.setTag('groundId', str(self.doId))

    def projectileWeaponHit(self,
                            skillId,
                            ammoSkillId,
                            skillResult,
                            targetEffects,
                            pos,
                            normal,
                            codes,
                            attacker,
                            itemEffects=[]):
        pass

    def startCustomEffects(self, interior=True, loadIslandMusic=False):
        if self.envEffects:
            self.envEffects.delete()
            self.envEffects = None
        if self.environment == 'Swamp':
            self.envEffects = SwampEffects.SwampEffects(self, self.modelPath)
            base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist=False)
            base.musicMgr.request(SoundGlobals.MUSIC_SWAMP,
                                  priority=1,
                                  volume=0.6)
        elif self.environment == 'Jungle':
            self.envEffects = ForestEffects.ForestEffects(self, self.modelPath)
            base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist=False)
            base.musicMgr.request(SoundGlobals.MUSIC_JUNGLE,
                                  priority=1,
                                  volume=0.6)
        elif self.environment == 'Cave':
            self.envEffects = CaveEffects.CaveEffects(self, self.modelPath)
            base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist=False)
            if self.uniqueId == LocationIds.RAVENS_COVE_MINE:
                base.musicMgr.request(SoundGlobals.getMainMusic(self.uniqueId),
                                      priority=1,
                                      volume=0.6)
            else:
                base.musicMgr.request(SoundGlobals.MUSIC_CAVE,
                                      priority=1,
                                      volume=0.6)
        elif self.uniqueId in ('1189479168.0sdnaik0', '1150922126.8akelts'):
            r = Reflection.getGlobalReflection()
            water = SeaPatch(self, reflection=r)
            water.loadSeaPatchFile('out.spf')
            self.water = water
            self.initializeIslandWaterParameters(self.geom)
        else:
            self.envEffects = EnvironmentEffects(self, self.modelPath)
            if interior:
                pass
        if loadIslandMusic:
            if not base.localAvatar.isInInvasion():
                base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_TORMENTA)
                base.musicMgr.requestFadeOut(
                    SoundGlobals.MUSIC_TORMENTA_COMBAT)

            def getCurrentIslandMusic():
                priZeros = []
                for music in base.musicMgr.playlist:
                    if music.priority == 0:
                        priZeros.append(music)

                return priZeros

            def changeMusic(music, pri):
                for priZero in getCurrentIslandMusic():
                    base.musicMgr.requestFadeOut(priZero.name,
                                                 removeFromPlaylist=True)

                base.musicMgr.request(music, priority=0, volume=0.6)

            mainMusic = SoundGlobals.getMainMusic(self.uniqueId)
            altMusic = SoundGlobals.getAltMusic(self.uniqueId)
            if mainMusic and altMusic:
                base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist=True)
                todMgr = base.cr.timeOfDayManager
                todMgr.addTimeOfDayToggle('Day-Night Area Music', 6.0, 20.0,
                                          changeMusic, [mainMusic, 0],
                                          changeMusic, [altMusic, 0])
            elif mainMusic:
                base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist=True)
                base.musicMgr.request(mainMusic, volume=0.6)
            elif altMusic:
                base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist=True)
                base.musicMgr.request(altMusic, volume=0.6)
        self.builder.initEffects()
        return

    def stopCustomEffects(self):
        if self.envEffects:
            self.envEffects.delete()
            self.envEffects = None
        if 'swamp' in self.modelPath:
            base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_SWAMP,
                                         removeFromPlaylist=True)
        elif 'jungle' in self.modelPath:
            base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_JUNGLE,
                                         removeFromPlaylist=True)
        elif self.uniqueId in getLocationList(LocationIds.ANY_CAVE):
            base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_CAVE,
                                         removeFromPlaylist=True)
            base.musicMgr.requestFadeOut(SoundGlobals.getMainMusic(
                self.uniqueId),
                                         removeFromPlaylist=True)
        elif self.uniqueId == '1189479168.0sdnaik0':
            self.water.delete()
            self.water = None
        if base.cr.timeOfDayManager:
            base.cr.timeOfDayManager.removeTimeOfDayToggle(
                'Day-Night Area Music')
        return

    def updateAvReturnLocation(self, av, uniqueId):
        pass

    @report(types=['frameCount', 'args'], dConfigParam=['jail', 'teleport'])
    def quickLoadOtherSide(self):
        connector = self.connectors.get(localAvatar.lastConnectorId)
        if connector:
            connector.quickLoadOtherSide()

    def addSpawnTriggers(self, triggerSpheres):
        for x, y, z, triggerRadius, spawnPtId in triggerSpheres:
            objectSphere = CollisionSphere(x, y, z, triggerRadius)
            objectName = uniqueName('spawnTriggerSphere')
            objectSphere.setTangible(0)
            objectSphereNode = CollisionNode(objectName)
            objectSphereNode.addSolid(objectSphere)
            objectSphereNode.setIntoCollideMask(PiratesGlobals.WallBitmask)
            objectSphereNodePath = self.builder.collisions.attachNewNode(
                objectSphereNode)
            self.accept('enter' + objectName,
                        self.handleEnterSphere,
                        extraArgs=[spawnPtId])
            self.spawnTriggers.append(objectSphereNodePath)

    def handleEnterSphere(self, spawnPtId, entry):
        if base.localAvatar:
            if hasattr(base.localAvatar, 'getDoId'):
                doId = base.localAvatar.getDoId()
                self.sendUpdate('spawnNPC', [spawnPtId, doId])

    def initBlockers(self, geom):
        self.disableBlockers = False
        if base.config.GetBool('disable-blockers', 0):
            self.disableBlockers = True
        blockerColls = geom.findAllMatches('**/blocker_*;+s')
        interior = False
        if not blockerColls.isEmpty():
            if blockerColls[0].getName().find('_i') != -1:
                interior = True
            for i in range(0, blockerColls.getNumPaths()):
                self.blockerColls.append(blockerColls[i])
                if self.disableBlockers:
                    blockerColls[i].stash()

        if interior:
            self.accept('enterblocker_1_i',
                        self.handleInteriorBlockerCollision)
        else:
            self.accept('enterblocker_1', self.handleBlockerCollision)
            self.accept('enterblocker_0', self.handleBlockerCollision)

    def stashSpecificBlocker(self, name):
        self.ignore('enter' + name)
        for blocker in self.blockerColls:
            if blocker.getName() == name:
                blocker.stash()

    def stashAllBlockers(self):
        self.ignore('enterblocker_1_i')
        self.ignore('enterblocker_1')
        self.ignore('enterblocker_0')
        for blocker in self.blockerColls:
            blocker.stash()

    def handleInteriorBlockerCollision(self, entry):
        questId = localAvatar.activeQuestId
        if base.localAvatar.style.getTutorial(
        ) < PiratesGlobals.TUT_GOT_CUTLASS:
            questId = 'c2_visit_will_turner'
            localAvatar.guiMgr.messageStack.addTextMessage(
                PLocalizer.QuestStrings[questId]['blockerMessage'])
        else:
            self.stashAllBlockers()

    def handleBlockerCollision(self, entry):
        if base.localAvatar.style.getTutorial(
        ) < PiratesGlobals.TUT_KILLED_1_SKELETON:
            questId = 'c2.2defeatSkeletons'
            localAvatar.guiMgr.messageStack.addTextMessage(
                PLocalizer.QuestStrings[questId]['blockerMessage'])
        elif base.localAvatar.style.getTutorial(
        ) < PiratesGlobals.TUT_GOT_COMPASS:
            questId = 'c2_visit_tia_dalma'
            self.stashSpecificBlocker('blocker_1')
            if entry.getIntoNodePath().getName() != 'blocker_1':
                localAvatar.guiMgr.messageStack.addTextMessage(
                    PLocalizer.QuestStrings[questId]['blockerMessage'])
        else:
            self.stashAllBlockers()

    @report(types=['frameCount'], dConfigParam='connector')
    def handleOnStage(self):
        StagedObject.handleOnStage(self)
        for id, connector in self.connectors.iteritems():
            if connector:
                connector.goOnStage()

        self.builder.addCutsceneOriginNode()

    @report(types=['frameCount'], dConfigParam='connector')
    def handleOffStage(self):
        for id, connector in self.connectors.iteritems():
            if connector:
                connector.goOffStage()

        StagedObject.handleOffStage(self)

    def getTeleportDestPosH(self, index=0):
        pt = self._getTunnelSpawnPos(index)
        if not pt:
            self.notify.warning('could not find tunnel location %s' % self)
            return (0, 0, 0, 0)
        return (pt[0], pt[1], pt[2], 0)

    @report(types=['args'], dConfigParam='teleport')
    def _getTunnelSpawnPos(self, index=0):
        connectorNodes = self.findAllMatches(
            '**/portal_exterior*') + self.findAllMatches('**/portal_interior*')
        if not connectorNodes:
            return None
        return self.getRelativePoint(
            connectorNodes[index % len(connectorNodes)], Point3(40, 0, 0))

    def initializeIslandWaterParameters(self, reference):
        debug = False
        island_water_parameters = IslandWaterParameters()
        world_position = self.getPos(render)
        world_x_offset = world_position[0]
        world_y_offset = world_position[1]
        world_z_offset = world_position[2]
        if debug:
            print self, '=', self.getName()
            print 'GAME AREA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
        self.swampAreaNode = reference.find('**/ocean')
        model = reference.find('**/water_color')
        if model:
            if debug:
                print 'WATER COLOR X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
            model.hide()
            min_point = Point3(0)
            max_point = Point3(0)
            model.calcTightBounds(min_point, max_point)
            size = max_point - min_point
            if self.getH() == 180 or self.getH() == -180:
                x = -min_point[0] + world_x_offset
                y = -min_point[1] + world_y_offset
                x_size = -size[0]
                y_size = -size[1]
            else:
                x = min_point[0] + world_x_offset
                y = min_point[1] + world_y_offset
                x_size = size[0]
                y_size = size[1]
            island_water_parameters.map_x_origin = x
            island_water_parameters.map_y_origin = y
            island_water_parameters.map_x_scale = x_size
            island_water_parameters.map_y_scale = y_size
            if debug:
                print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[
                    1], x_size, y_size
            texture = model.findTexture('*')
            if texture:
                island_water_parameters.water_color_texture = texture
                if debug:
                    print 'WATER COLOR TEXTURE', texture
        elif debug:
            print '*** water_color NODE NOT FOUND'
        model = reference.find('**/water_alpha')
        if model:
            if debug:
                print 'WATER ALPHA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
            model.hide()
            min_point = Point3(0)
            max_point = Point3(0)
            model.calcTightBounds(min_point, max_point)
            size = max_point - min_point
            if self.getH() == 180 or self.getH() == -180:
                x = -min_point[0] + world_x_offset
                y = -min_point[1] + world_y_offset
                x_size = -size[0]
                y_size = -size[1]
            else:
                x = min_point[0] + world_x_offset
                y = min_point[1] + world_y_offset
                x_size = size[0]
                y_size = size[1]
            island_water_parameters.alpha_map_x_origin = x
            island_water_parameters.alpha_map_y_origin = y
            island_water_parameters.alpha_map_x_scale = x_size
            island_water_parameters.alpha_map_y_scale = y_size
            if debug:
                print 'ALPHA X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[
                    1], x_size, y_size
            texture = model.findTexture('*')
            if texture:
                island_water_parameters.water_alpha_texture = texture
                if debug:
                    print 'WATER ALPHA TEXTURE', texture
        elif debug:
            print '*** water_alpha NODE NOT FOUND'
        use_shader = False
        if base.config.GetBool(
                'want-shaders',
                1) and base.win and base.win.getGsg() and base.win.getGsg(
                ).getShaderModel() >= GraphicsStateGuardian.SM20:
            use_shader = True
        model_ns = reference.find('**/water_swamp_ns')
        if model_ns:
            if use_shader:
                model_ns.hide()
            else:
                model_ns.show()
                model = model_ns
                model.setBin('water', 1)
                parent = model.getParent()
                model.detachNode()
                stencil_one_node_path = NodePath('stencil_one')
                stencil_one_node_path.reparentTo(parent)
                model.instanceTo(stencil_one_node_path)
                mask = 4294967295L
                stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual,
                                                 StencilAttrib.SOKeep,
                                                 StencilAttrib.SOKeep,
                                                 StencilAttrib.SOKeep, 1, mask,
                                                 mask)
                stencil_one_node_path.setAttrib(stencil_one, 100)
                stencil_one_node_path.setDepthTest(0)
                if not base.useStencils:
                    stencil_one_node_path.hide()
        model_alpha_texture = None
        model_alpha = reference.find('**/water_alpha_swamp')
        if model_alpha:
            model_alpha_texture = model_alpha.findTexture('*')
            model_alpha.hide()
            if debug:
                print 'model_alpha_texture', model_alpha_texture
            if False:
                texture = model_alpha_texture
                card_x_size = 0.5
                card_y_size = 0.5
                card = CardMaker('test_texture_card')
                card.setFrame(-card_x_size, card_x_size, -card_y_size,
                              card_y_size)
                card_node_path = NodePath(card.generate())
                card_node_path.setTexture(texture, 1)
                card_node_path.node().setBounds(OmniBoundingVolume())
                card_node_path.node().setFinal(1)
                card_node_path.reparentTo(render2d)
        else:
            model_alpha = None
        model = reference.find('**/water_color_swamp')
        if model:
            if use_shader:
                model.show()
                model_texture = model.findTexture('*')
                if debug:
                    print 'WATER COLOR SWAMP X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
                parent = model.getParent()
                model.detachNode()
                stencil_one_node_path = NodePath('stencil_one')
                stencil_one_node_path.reparentTo(parent)
                model.instanceTo(stencil_one_node_path)
                mask = 4294967295L
                stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual,
                                                 StencilAttrib.SOKeep,
                                                 StencilAttrib.SOKeep,
                                                 StencilAttrib.SOKeep, 1, mask,
                                                 mask)
                stencil_one_node_path.setAttrib(stencil_one, 100)
                stencil_one_node_path.setDepthTest(0)
                if not base.useStencils:
                    stencil_one_node_path.hide()
                min_point = Point3(0)
                max_point = Point3(0)
                model.calcTightBounds(min_point, max_point)
                size = max_point - min_point
                if self.getH() == 180 or self.getH() == -180:
                    x = -min_point[0] + world_x_offset
                    y = -min_point[1] + world_y_offset
                    x_size = -size[0]
                    y_size = -size[1]
                else:
                    x = min_point[0] + world_x_offset
                    y = min_point[1] + world_y_offset
                    x_size = size[0]
                    y_size = size[1]
                if debug:
                    print 'min_point', min_point
                    print 'max_point', max_point
                    print 'size', size
                    print 'x y', x, y
                island_water_parameters.swamp_map_x_origin = x
                island_water_parameters.swamp_map_y_origin = y
                island_water_parameters.swamp_map_x_scale = x_size
                island_water_parameters.swamp_map_y_scale = y_size
                if debug:
                    print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[
                        1], x_size, y_size
                texture = model.findTexture('*')
                if texture:
                    island_water_parameters.swamp_water_color_texture = texture
                    if debug:
                        print 'SWAMP WATER COLOR TEXTURE', texture
                water_color_file_path = island_water_parameters.default_water_color_file_path
                alpha_texture_file_path = island_water_parameters.default_water_alpha_file_path
                opacity_texture_file_path = None
                shader_file_path = 'models/swamps/cuba_swamp001_2X.cg'
                reflection = Reflection.getGlobalReflection()
                self.swamp_water = Swamp(None, None, reflection, model,
                                         shader_file_path)
                island_water_parameters.swamp_water = self.swamp_water
                unload_previous_texture = True
                self.swamp_water.set_water_color_texture(
                    water_color_file_path, unload_previous_texture,
                    model_texture)
                self.swamp_water.set_water_alpha_texture(
                    alpha_texture_file_path, unload_previous_texture,
                    model_alpha_texture)
                self.swamp_water.set_wrap_or_clamp(True)
                r = 37.0
                g = 62.0
                b = 40.0
                self.swamp_water.water_r = r
                self.swamp_water.water_g = g
                self.swamp_water.water_b = b
                island_water_parameters.swamp_color_r = r
                island_water_parameters.swamp_color_g = g
                island_water_parameters.swamp_color_b = b
                x = 0.0
                y = 1.0
                speed = 3.2
                island_water_parameters.swamp_direction_x = x
                island_water_parameters.swamp_direction_y = y
                island_water_parameters.swamp_speed = speed
                self.swamp_water.update_water_direction_and_speed(x, y, speed)
            else:
                model.hide()
        elif debug:
            print '*** water_color_swamp NODE NOT FOUND'
        self.islandWaterParameters = island_water_parameters
        return

    def getLevel(self):
        return 1

    def announceGenerate(self):
        base.loadingScreen.tick()
        DistributedNode.announceGenerate(self)
        base.worldCreator.registerSpecialNodes(self, self.uniqueId)
        self.areaType = base.worldCreator.getFieldFromUid(
            self.uniqueId, 'Visibility')
        self.envSettings = base.worldCreator.getEnvSettingsByUid(self.uniqueId)
        self.builder = base.worldCreator.getBuilder(self, self.areaType)

    def retrieveFootprintNode(self):
        footprintCache = self.getFootprintCache()
        if footprintCache.hasData() and base.config.GetBool(
                'want-disk-cache', 0):
            data = footprintCache.getData()
            newData = data.copySubgraph()
            footprintNode = NodePath(newData)
        else:
            footprintNode = self.buildFootprintNode()
        return footprintNode

    def getFootprintCache(self):
        return base.bamCache.lookup(
            Filename('/%s_footprint_%s.bam' %
                     (self.uniqueId, base.gridDetail)), 'bam')

    def buildFootprintNode(self):
        footprintCache = self.getFootprintCache()
        footprintNode = self.builder.buildFootprintNode()
        footprintCache.setData(footprintNode.node(), 0)
        base.bamCache.store(footprintCache)
        return footprintNode

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def hideMapNodes(self):
        mapNodes = self.geom.findAllMatches('**/minimap_*')
        mapNodes.hide()

    def setFootstepSound(self, footstepSound):
        self.footstepSound = footstepSound
        if self.footstepSound and base.localAvatar:
            base.localAvatar.setAreaFootstep(self.footstepSound)
            base.localAvatar.setSurfaceIndexFromLevelDefault()

    def setEnvironment(self, environment):
        self.environment = environment

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def setMinimapPrefix(self, prefix):
        minimaps = self.geom.findAllMatches('**/minimap_*;+s')
        for map in minimaps:
            if prefix not in map.getName():
                map.detachNode()

        minimaps = sorted(self.geom.findAllMatches('**/minimap_*;+s'))
        for x, map in enumerate(minimaps):
            map.setName('minimap_%d' % x)

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def getMapNode(self):
        mapNode = self.geom.find('**/minimap_%s' % (self.minimapArea, ))
        if not mapNode:
            minSide = 1500.0
            a, b = self.geom.getTightBounds()
            diff = b - a
            sideScale = 1
            if diff[0] > diff[1]:
                if diff[0] < minSide:
                    sideScale = minSide / diff[0]
            elif diff[1] < minSide:
                sideScale = minSide / diff[1]
            cm = CardMaker('minimap-card')
            cm.setFrame(VBase4(a[0], b[0], a[1], b[1]) * sideScale)
            modelNode = ModelNode('minimap_0')
            modelNode.setPreserveTransform(1)
            mapNode = self.geom.attachNewNode(modelNode)
            mapGeom = mapNode.attachNewNode(cm.generate())
            mapGeom.setP(-90)
            mapGeom.hide()
        return mapNode

    def getMapName(self):
        return 'map-' + self.getUniqueId()

    def getFootprintNode(self):
        if not self.footprintNode:
            self.footprintNode = self.retrieveFootprintNode()
        return self.footprintNode.find('footprint_%s' %
                                       (self.minimapArea, )) or NodePath(
                                           'footprint_%s' %
                                           (self.minimapArea, ))

    def getShopNodes(self):
        shopNodes = self.builder.getMinimapShopNodes()
        mapNodes = NodePathCollection()
        for node in shopNodes:
            minimapArea = int(node.getTag('MinimapArea') or '0')
            if minimapArea == self.minimapArea:
                mapNodes.addPath(node)

        return mapNodes

    def getCapturePointNodes(self, holidayName):
        capturePoints = self.builder.getMinimapCapturePointNodes(holidayName)
        mapNodes = NodePathCollection()
        for node in capturePoints:
            minimapArea = int(node.getTag('MinimapArea') or '0')
            if minimapArea == self.minimapArea:
                mapNodes.addPath(node)

        return mapNodes

    def getZoomLevels(self):
        return ((150, 200, 300), 1)

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def addMinimapObject(self, obj):
        if self.minimap:
            self.minimap.addObject(obj)

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def removeMinimapObject(self, obj):
        if self.minimap:
            self.minimap.removeObject(obj)

    def ensureLoaded(self):
        pass

    @report(types=['args'], dConfigParam='minimap')
    def setMinimapArea(self, areaId):
        if areaId != self.minimapArea:
            self.minimapArea = areaId
            self.destroyMinimap()
            self.setupMinimap()
            self.minimap.addObject(localAvatar.getMinimapObject())
            self.loadConnectors()
            localAvatar.guiMgr.setMinimap(self.minimap)

    @report(types=['frameCount', 'args'], dConfigParam='minimap')
    def showTunnelOnMinimap(self, tunnelUid):
        return self.builder.getTunnelMinimap(tunnelUid) == self.minimapArea

    def getConnectorNodeNamed(self, name):
        return self.find('**/' + name + '*')

    @report(types=['args'], dConfigParam='minimap')
    def handleHolidayStarted(self, holiday):
        if self.minimap:
            self.minimap.handleHolidayStarted(self, holiday)

    @report(types=['args'], dConfigParam='minimap')
    def handleHolidayEnded(self, holiday):
        if self.minimap:
            self.minimap.handleHolidayEnded(self, holiday)
Beispiel #13
0
class SwampEffects(EnvironmentEffects.EnvironmentEffects):
    GROUND_FOG_Z = 2.0
    FIREFLIES_Z = 6.0
    RANDOM_SOUND_PERIOD = 6
    RANDOM_SOUND_CHANCE = 12
    
    def __init__(self, parent, modelPath):
        EnvironmentEffects.EnvironmentEffects.__init__(self, parent, modelPath)
        self.fireflies = None
        self.groundFog = None
        self.swamp_water = None
        self.water = None
        self.randomAnimalSoundFiles = [
            SoundGlobals.SFX_FX_SWAMP_FROG_01,
            SoundGlobals.SFX_FX_SWAMP_OWL_01,
            SoundGlobals.SFX_FX_SWAMP_OWL_02]
        self.randomSfx = []
        self.startEffects()

    
    def delete(self):
        self.stopEffects()
        EnvironmentEffects.EnvironmentEffects.delete(self)

    
    def startEffects(self):
        self.swamp_water = None
        if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
            reflection = Reflection.getGlobalReflection()
            self.swamp_water = Swamp(self.modelPath + '_water', self.parent, reflection)
        else:
            self.water = loader.loadModel(self.modelPath + '_water')
            self.water.reparentTo(self.parent)
            self.water.setTransparency(TransparencyAttrib.MNone, 100)
            alpha_test_attrib = AlphaTestAttrib.make(RenderAttrib.MAlways, 0)
            self.water.setAttrib(alpha_test_attrib, 100)
        if not self.fireflies:
            self.fireflies = Fireflies()
        
        if self.fireflies and hasattr(base, 'cr'):
            self.fireflies.reparentTo(base.localAvatar)
            self.fireflies.startLoop()
        
        if not self.groundFog:
            self.groundFog = GroundFog()
        
        if self.groundFog and hasattr(base, 'options'):
            if base.options.getSpecialEffectsSetting() >= base.options.SpecialEffectsMedium:
                self.groundFog.reparentTo(base.localAvatar)
                self.groundFog.startLoop(base.options.getSpecialEffectsSetting())
            
        
        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            taskMgr.add(self.adjustGroundFogZ, self.parent.uniqueName('groundFogZTask'))
        
        base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_SWAMP, duration = 10, finalVolume = PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority = 1)
        for file in self.randomAnimalSoundFiles:
            sfx = loadSfx(file)
            self.randomSfx.append(sfx)
        
        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD, self.checkForRandomSound, name = 'checkForRandomSound-' + str(id(self)))

    
    def stopEffects(self):
        if hasattr(base, 'cr') and not hasattr(base.cr, 'isFake'):
            taskMgr.remove(self.parent.uniqueName('groundFogZTask'))
        
        taskMgr.remove('checkForRandomSound-' + str(id(self)))
        if self.swamp_water:
            self.swamp_water.delete()
            self.water = None
        
        if self.fireflies:
            self.fireflies.destroy()
            self.fireflies = None
        
        if self.groundFog:
            self.groundFog.destroy()
            self.groundFog = None
        
        base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_SWAMP, duration = 5, priority = 1)
        for sfx in self.randomSfx:
            sfx.stop()
        

    
    def adjustGroundFogZ(self, task):
        if self.fireflies:
            self.fireflies.setZ(render, self.FIREFLIES_Z)
        
        if self.groundFog:
            self.groundFog.setZ(render, self.GROUND_FOG_Z)
        
        if self.fireflies or self.groundFog:
            return Task.cont
        
        return Task.done

    
    def checkForRandomSound(self, task):
        randomSoundPlaying = False
        for sfx in self.randomSfx:
            if sfx.status() == 2:
                randomSoundPlaying = True
                break
                continue
        
        if not randomSoundPlaying:
            roll = random.randint(0, 100)
            if roll < self.RANDOM_SOUND_CHANCE:
                sfxToPlay = random.choice(self.randomSfx)
                sfxToPlay.play()
            
        
        taskMgr.doMethodLater(self.RANDOM_SOUND_PERIOD, self.checkForRandomSound, name = 'checkForRandomSound-' + str(id(self)))
        return Task.done
Beispiel #14
0
class CaveEffects(EnvironmentEffects.EnvironmentEffects):
    WaterCaves = [LocationIds.ANVIL_CAVE_BARBOSA]
    LavaCaves = []

    def __init__(self, parent, modelPath):
        EnvironmentEffects.EnvironmentEffects.__init__(self, parent, modelPath)
        self.modelPath = modelPath
        self.modelPrefix = ""
        self.animActor = None
        self.water = None
        self.reflection = None
        self.supports_sky_only = False
        self.startEffects()

    def delete(self):
        del self.animActor
        self.stopEffects()
        EnvironmentEffects.EnvironmentEffects.delete(self)

    def startEffects(self):
        reflection = Reflection.getGlobalReflection()
        non_shader_water_color = Vec4(0.0, 1.0 / 255.0, 4.0 / 255.0, 1.0)
        shader_water_color = Vec4(0.0, 1.0, 4.0, 255.0)
        if self.parent.uniqueId in self.WaterCaves:
            if (
                base.config.GetBool("want-shaders", 1)
                and base.win
                and base.win.getGsg()
                and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20
            ):
                self.water = Swamp("models/caves/cave_a_water", self.parent, reflection, None, None, shader_water_color)
                self.water.reflection_factor = 0.29999999999999999
                self.water.set_reflection_parameters_np()
            else:
                water = loader.loadModel("models/caves/cave_a_water")
                water.reparentTo(self.parent)
                color = non_shader_water_color
                water.setColorScale(color)
                water.setTextureOff(1)
                mask = 0xFFFFFFFFL
                stencil = StencilAttrib.make(
                    1,
                    StencilAttrib.SCFAlways,
                    StencilAttrib.SOKeep,
                    StencilAttrib.SOKeep,
                    StencilAttrib.SOReplace,
                    1,
                    mask,
                    mask,
                )
                water.setAttrib(stencil)
                water.setBin("water", 0)
                self.reflection = reflection
                taskMgr.add(self.camTask, "caveEffectsCamTask-" + str(id(self)), priority=49)
                water.setFogOff()
        elif self.parent.uniqueId in self.LavaCaves:
            if (
                base.config.GetBool("want-shaders", 1)
                and base.win
                and base.win.getGsg()
                and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20
            ):
                self.water = Swamp(self.modelPrefix + "lava", self.parent, reflection, None, None, shader_water_color)
                l1 = LerpScaleInterval(
                    self.water.seamodel, 2, Vec3(1.006, 1.006, 1.0), Vec3(1.0, 1.0, 1.0), blendType="easeInOut"
                )
                l2 = LerpScaleInterval(
                    self.water.seamodel, 2, Vec3(1.0, 1.0, 1.0), Vec3(1.006, 1.006, 1.0), blendType="easeInOut"
                )
                seq = Sequence(l1, l2)
                seq.loop()
                self.water.reflection_factor = 0.29999999999999999
                self.water.set_reflection_parameters_np()
            else:
                water = loader.loadModel(self.modelPrefix + "lava")
                water.reparentTo(self.parent)
                water.setFogOff()

        base.ambientMgr.requestFadeIn(
            SoundGlobals.AMBIENT_CAVE, duration=10, finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME, priority=1
        )
        if self.water:
            self.water.supports_sky_only = self.supports_sky_only

        if reflection:
            if base.options.reflection >= 1:
                reflection.reflectShowThroughOnly(False)
                reflection.enable(True)

    def camTask(self, task):
        if self.reflection:
            self.reflection.update_reflection(base.camLens, base.cam)

        return Task.cont

    def stopEffects(self):
        if hasattr(base, "cr") and not hasattr(base.cr, "isFake"):
            if base.options.reflection == 0:
                Water.all_reflections_off()
            elif base.options.reflection == 1:
                Water.all_reflections_show_through_only()
            elif base.options.reflection == 2:
                Water.all_reflections_on()

        if self.water:
            self.water.delete()
            self.water = None

        taskMgr.remove("caveEffectsCamTask-" + str(id(self)))
        base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_CAVE, duration=5, priority=1)
 def initializeIslandWaterParameters(self, reference):
     debug = False
     island_water_parameters = IslandWaterParameters()
     world_position = self.getPos(render)
     world_x_offset = world_position[0]
     world_y_offset = world_position[1]
     world_z_offset = world_position[2]
     if debug:
         print self, '=', self.getName()
         print 'GAME AREA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
     
     self.swampAreaNode = reference.find('**/ocean')
     model = reference.find('**/water_color')
     if model:
         if debug:
             print 'WATER COLOR X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
         
         model.hide()
         min_point = Point3(0)
         max_point = Point3(0)
         model.calcTightBounds(min_point, max_point)
         size = max_point - min_point
         if self.getH() == 180 or self.getH() == -180:
             x = -min_point[0] + world_x_offset
             y = -min_point[1] + world_y_offset
             x_size = -size[0]
             y_size = -size[1]
         else:
             x = min_point[0] + world_x_offset
             y = min_point[1] + world_y_offset
             x_size = size[0]
             y_size = size[1]
         island_water_parameters.map_x_origin = x
         island_water_parameters.map_y_origin = y
         island_water_parameters.map_x_scale = x_size
         island_water_parameters.map_y_scale = y_size
         if debug:
             print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[1], x_size, y_size
         
         texture = model.findTexture('*')
         if texture:
             island_water_parameters.water_color_texture = texture
             if debug:
                 print 'WATER COLOR TEXTURE', texture
             
         
     elif debug:
         print '*** water_color NODE NOT FOUND'
     
     model = reference.find('**/water_alpha')
     if model:
         if debug:
             print 'WATER ALPHA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
         
         model.hide()
         min_point = Point3(0)
         max_point = Point3(0)
         model.calcTightBounds(min_point, max_point)
         size = max_point - min_point
         if self.getH() == 180 or self.getH() == -180:
             x = -min_point[0] + world_x_offset
             y = -min_point[1] + world_y_offset
             x_size = -size[0]
             y_size = -size[1]
         else:
             x = min_point[0] + world_x_offset
             y = min_point[1] + world_y_offset
             x_size = size[0]
             y_size = size[1]
         island_water_parameters.alpha_map_x_origin = x
         island_water_parameters.alpha_map_y_origin = y
         island_water_parameters.alpha_map_x_scale = x_size
         island_water_parameters.alpha_map_y_scale = y_size
         if debug:
             print 'ALPHA X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[1], x_size, y_size
         
         texture = model.findTexture('*')
         if texture:
             island_water_parameters.water_alpha_texture = texture
             if debug:
                 print 'WATER ALPHA TEXTURE', texture
             
         
     elif debug:
         print '*** water_alpha NODE NOT FOUND'
     
     use_shader = False
     if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
         use_shader = True
     
     model_ns = reference.find('**/water_swamp_ns')
     if model_ns:
         if use_shader:
             model_ns.hide()
         else:
             model_ns.show()
             model = model_ns
             model.setBin('water', 1)
             parent = model.getParent()
             model.detachNode()
             stencil_one_node_path = NodePath('stencil_one')
             stencil_one_node_path.reparentTo(parent)
             model.instanceTo(stencil_one_node_path)
             mask = 0xFFFFFFFFL
             stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOKeep, 1, mask, mask)
             stencil_one_node_path.setAttrib(stencil_one, 100)
             stencil_one_node_path.setDepthTest(0)
             if not base.useStencils:
                 stencil_one_node_path.hide()
             
     
     model_alpha_texture = None
     model_alpha = reference.find('**/water_alpha_swamp')
     if model_alpha:
         model_alpha_texture = model_alpha.findTexture('*')
         model_alpha.hide()
         if debug:
             print 'model_alpha_texture', model_alpha_texture
         
         if False:
             texture = model_alpha_texture
             card_x_size = 0.5
             card_y_size = 0.5
             card = CardMaker('test_texture_card')
             card.setFrame(-card_x_size, card_x_size, -card_y_size, card_y_size)
             card_node_path = NodePath(card.generate())
             card_node_path.setTexture(texture, 1)
             card_node_path.node().setBounds(OmniBoundingVolume())
             card_node_path.node().setFinal(1)
             card_node_path.reparentTo(render2d)
         
     else:
         model_alpha = None
     model = reference.find('**/water_color_swamp')
     if model:
         if use_shader:
             model.show()
             model_texture = model.findTexture('*')
             if debug:
                 print 'WATER COLOR SWAMP X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
             
             parent = model.getParent()
             model.detachNode()
             stencil_one_node_path = NodePath('stencil_one')
             stencil_one_node_path.reparentTo(parent)
             model.instanceTo(stencil_one_node_path)
             mask = 0xFFFFFFFFL
             stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOKeep, 1, mask, mask)
             stencil_one_node_path.setAttrib(stencil_one, 100)
             stencil_one_node_path.setDepthTest(0)
             if not base.useStencils:
                 stencil_one_node_path.hide()
             
             min_point = Point3(0)
             max_point = Point3(0)
             model.calcTightBounds(min_point, max_point)
             size = max_point - min_point
             if self.getH() == 180 or self.getH() == -180:
                 x = -min_point[0] + world_x_offset
                 y = -min_point[1] + world_y_offset
                 x_size = -size[0]
                 y_size = -size[1]
             else:
                 x = min_point[0] + world_x_offset
                 y = min_point[1] + world_y_offset
                 x_size = size[0]
                 y_size = size[1]
             if debug:
                 print 'min_point', min_point
                 print 'max_point', max_point
                 print 'size', size
                 print 'x y', x, y
             
             island_water_parameters.swamp_map_x_origin = x
             island_water_parameters.swamp_map_y_origin = y
             island_water_parameters.swamp_map_x_scale = x_size
             island_water_parameters.swamp_map_y_scale = y_size
             if debug:
                 print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[1], x_size, y_size
             
             texture = model.findTexture('*')
             if texture:
                 island_water_parameters.swamp_water_color_texture = texture
                 if debug:
                     print 'SWAMP WATER COLOR TEXTURE', texture
                 
             
             water_color_file_path = island_water_parameters.default_water_color_file_path
             alpha_texture_file_path = island_water_parameters.default_water_alpha_file_path
             opacity_texture_file_path = None
             shader_file_path = 'models/swamps/cuba_swamp001_2X.cg'
             reflection = Reflection.getGlobalReflection()
             self.swamp_water = Swamp(None, None, reflection, model, shader_file_path)
             island_water_parameters.swamp_water = self.swamp_water
             unload_previous_texture = True
             self.swamp_water.set_water_color_texture(water_color_file_path, unload_previous_texture, model_texture)
             self.swamp_water.set_water_alpha_texture(alpha_texture_file_path, unload_previous_texture, model_alpha_texture)
             self.swamp_water.set_wrap_or_clamp(True)
             r = 37.0
             g = 62.0
             b = 40.0
             self.swamp_water.water_r = r
             self.swamp_water.water_g = g
             self.swamp_water.water_b = b
             island_water_parameters.swamp_color_r = r
             island_water_parameters.swamp_color_g = g
             island_water_parameters.swamp_color_b = b
             x = 0.0
             y = 1.0
             speed = 3.2000000000000002
             island_water_parameters.swamp_direction_x = x
             island_water_parameters.swamp_direction_y = y
             island_water_parameters.swamp_speed = speed
             self.swamp_water.update_water_direction_and_speed(x, y, speed)
         else:
             model.hide()
     elif debug:
         print '*** water_color_swamp NODE NOT FOUND'
     
     self.islandWaterParameters = island_water_parameters
class DistributedGameArea(DistributedNode, MappableArea, StagedObject):
    notify = directNotify.newCategory('DistributedGameArea')
    
    def __init__(self, cr):
        DistributedNode.__init__(self, cr)
        NodePath.__init__(self, 'GameArea')
        MappableArea.__init__(self)
        StagedObject.__init__(self, StagedObject.OFF)
        self.uniqueId = ''
        self.geom = None
        self.funnelDisplayName = None
        self.previousDisplayName = None
        self.gameFSM = None
        self.links = []
        self.pendingSetupConnector = { }
        self.connectors = { }
        self.connectorInterests = set()
        self.envEffects = None
        self.spawnTriggers = []
        self.blockerColls = []
        self.islandWaterParameters = None
        self.swamp_water = None
        self.entryTime = [
            None,
            0]
        self.timeCheck = 0
        self.minimap = None
        self.footprintNode = None
        self.popupDialog = None
        self.minimapArea = 0
        self.laMinimapObj = None
        self.footstepSound = None
        self.environment = None
        self.connectorsHereCallback = None

    
    def __repr__(self):
        if not self.getName():
            pass
        return '%s (%s)' % (DistributedNode.__repr__(self), self.uniqueId)

    
    def __str__(self):
        if not self.getName():
            pass
        return '%s (%s)' % (DistributedNode.__repr__(self), self.uniqueId)

    
    def disable(self):
        taskMgr.remove('showEnterMessage')
        DistributedNode.disable(self)
        if self.geom:
            self.geom.removeNode()
        
        self.unloadConnectors()
        for request in self.pendingSetupConnector.itervalues():
            self.cr.relatedObjectMgr.abortRequest(request)
        
        self.pendingSetupConnector = { }
        self.builder.delete()
        self.builder = None

    
    def delete(self):
        if base.zoneLODTarget == self:
            base.disableZoneLODs()
        
        for trigger in self.spawnTriggers:
            trigger.removeNode()
        
        del self.spawnTriggers
        del self.connectors
        del self.links
        if self.envEffects:
            self.envEffects.delete()
            self.envEffects = None
        
        DistributedNode.delete(self)
        if self.islandWaterParameters:
            del self.islandWaterParameters
        
        if self.swamp_water:
            self.swamp_water.delete()
            del self.swamp_water
        
        if self.popupDialog:
            self.popupDialog.destroy()
        
        del self.popupDialog
        self.connectorsHereCallback = None

    
    def setLocation(self, parentId, zoneId):
        DistributedNode.setLocation(self, parentId, zoneId)
        if parentId:
            parent = self.getParentObj()
            self.reparentTo(parent)
        

    
    def setName(self, name):
        self.name = name

    
    def setModelPath(self, modelPath):
        self.modelPath = modelPath

    
    def handleChildArrive(self, childObj, zoneId):
        DistributedNode.handleChildArrive(self, childObj, zoneId)
        if childObj.isLocal():
            base.loadingScreen.endStep('enterArea')
            base.enableZoneLODs(self)
            childObj.refreshActiveQuestStep()
            localAvatar.guiMgr.setMinimap(self.minimap)
            localAvatar.setAreaFootstep(self.footstepSound)
            localAvatar.guiMgr.radarGui.showLocation(self.uniqueId)
            envName = base.worldCreator.environmentTable.get(self.uniqueId)
            if envName:
                environmentID = TODGlobals.ENVIRONMENT_NAMES_TO_ID.get(envName, TODGlobals.ENV_DEFAULT)
                envData = { }
                envSettings = base.worldCreator.uidEnvSettings.get(self.uniqueId)
                if envSettings != None:
                    envData = envSettings
                
                base.cr.timeOfDayManager.setEnvironment(environmentID, envData)
            else:
                envData = None
                envSettings = base.worldCreator.uidEnvSettings.get(self.uniqueId)
                if envSettings != None:
                    envData = envSettings
                
                base.cr.timeOfDayManager.setEnvironment(TODGlobals.ENV_INTERIOR, envData)
            self.builder.arrived()
        
        self.accept('transferMinimapObjects', self.transferMinimapObject)
        if self.minimap and hasattr(childObj, 'getMinimapObject'):
            if childObj.getMinimapObject():
                self.laMinimapObj = childObj.getMinimapObject()
                self.minimap.addObject(childObj.getMinimapObject())
            
        

    handleChildArrive = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(handleChildArrive)
    
    def transferMinimapObject(self, guiMgr):
        if self.laMinimapObj:
            guiMgr.transferMinimapObject(self.laMinimapObj)
        

    
    def handleChildLeave(self, childObj, zoneId):
        if childObj.isLocal():
            base.disableZoneLODs()
            localAvatar.guiMgr.clearMinimap(self.minimap)
            self.builder.localAvLeaving()
            self.builder.left()
        
        self.ignore('transferMinimapObjects')
        self.laMinimapObj = None
        if self.minimap and hasattr(childObj, 'getMinimapObject'):
            if childObj.getMinimapObject():
                self.minimap.removeObject(childObj.getMinimapObject())
            
        
        DistributedNode.handleChildLeave(self, childObj, zoneId)

    handleChildLeave = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(handleChildLeave)
    
    def setUniqueId(self, uid):
        if self.uniqueId != '':
            self.cr.uidMgr.removeUid(self.uniqueId)
        
        self.uniqueId = uid
        self.cr.uidMgr.addUid(self.uniqueId, self.getDoId())

    
    def getUniqueId(self):
        return self.uniqueId

    
    def loadModel(self):
        pass

    
    def setLinks(self, links):
        for link in links:
            (areaNode, connId, areaUid, connParent, connZone, connNode, connWorld, connWorldZone) = link
            newLink = [
                connId,
                connParent,
                connZone,
                connWorld,
                connWorldZone]
            if newLink in self.links:
                continue
            
            self.links.append(newLink)
            
            def setupConnector(connector):
                self.connectors[connector.doId] = connector
                request = self.pendingSetupConnector.pop(connector.doId, None)
                if not request:
                    pass

            connector = self.cr.doId2do.get(connId)
            if connector:
                self.pendingSetupConnector[connId] = None
                setupConnector(connector)
                continue
            if connId:
                if connId in self.pendingSetupConnector:
                    request = self.pendingSetupConnector.pop(connId)
                    self.cr.relatedObjectMgr.abortRequest(request)
                
                request = self.cr.relatedObjectMgr.requestObjects([
                    connId], eachCallback = setupConnector)
                self.pendingSetupConnector[connId] = request
                continue
        

    setLinks = report(types = [
        'args',
        'deltaStamp'], dConfigParam = [
        'jail'])(setLinks)
    
    def loadConnectors(self):
        for link in self.links:
            if link:
                connectorId = link[0]
                if connectorId not in self.connectorInterests or not self.cr.doId2do.has_key(connectorId):
                    if connectorId not in self.connectorInterests:
                        self.connectorInterests.add(connectorId)
                    
                    parentId = link[1]
                    zoneId = link[2]
                    linkParentId = link[3]
                    linkParentZoneId = link[4]
                    
                    def connectorParentHere(connectorId, parentId, zoneId):
                        connectorEvent = 'connector-%s' % connectorId
                        self.acceptOnce(connectorEvent, self.reparentConnector, extraArgs = [
                            connectorId])
                        self.cr.addTaggedInterest(parentId, zoneId, self.cr.ITAG_GAME, 'Connectors-%s' % self.doId, event = connectorEvent, otherTags = [
                            'Connectors-%s' % self.doId])

                    connectorEvent = 'connector-%s' % connectorId
                    self.acceptOnce(connectorEvent, connectorParentHere, extraArgs = [
                        connectorId,
                        parentId,
                        zoneId])
                    self.cr.addTaggedInterest(linkParentId, linkParentZoneId, self.cr.ITAG_GAME, 'ConnectorsParent-%s' % self.doId, event = connectorEvent, otherTags = [
                        'ConnectorsParent-%s' % self.doId])
                else:
                    self.reparentConnector(connectorId)
            not self.cr.doId2do.has_key(connectorId)
        

    loadConnectors = report(types = [
        'args',
        'deltaStamp'], dConfigParam = [
        'jail',
        'teleport'])(loadConnectors)
    
    def unloadConnectors(self):
        for (connectorId, connector) in self.connectors.iteritems():
            if connector:
                connector.setLoadedArea(None)
                connector.goOffStage()
                continue
        
        self.connectors = { }
        self.cr.removeInterestTag('Connectors-%s' % self.doId)
        self.cr.removeInterestTag('ConnectorsParent-%s' % self.doId)
        self.connectorInterests = set()

    unloadConnectors = report(types = [
        'args',
        'deltaStamp'], dConfigParam = [
        'jail',
        'teleport'])(unloadConnectors)
    
    def reparentConnector(self, connectorId):
        connector = self.cr.doId2do.get(connectorId)
        if connector:
            self.connectors[connectorId] = connector
            connector.reparentConnectorToArea(self)
            if self.isOnStage():
                connector.goOnStage()
            else:
                connector.goOffStage()
            if self.connectorsHereCallback and len(self.connectors) == len(self.links):
                self.connectorsHereCallback()
                self.connectorsHereCallback = None
            
        

    reparentConnector = report(types = [
        'args',
        'deltaStamp'], dConfigParam = [
        'jail',
        'teleport'])(reparentConnector)
    
    def setConnectorsHereCallback(self, callback):
        self.connectorsHereCallback = callback

    
    def handleEnterGameArea(self, collEntry = None):
        inventory = localAvatar.getInventory()
        if localAvatar.style.getTutorial() == PiratesGlobals.TUT_GOT_SEACHEST and self.uniqueId == LocationIds.RAMBLESHACK_ISLAND and len(inventory.getWeapons()) < 1 and base.localAvatar.showQuest:
            base.localAvatar.resetQuestShow()
            popupDialogText = [
                'showBlacksmith',
                'closeShowBlacksmith']
            self.popupDialog = NewTutorialPanel(popupDialogText)
            
            def closeTutorialWindow():
                messenger.send(self.popupDialog.closeMessage)

            self.popupDialog.setYesCommand(closeTutorialWindow)
            self.acceptOnce('closeTutorialWindow', closeTutorialWindow)
            self.popupDialog.activate()
        
        taskMgr.doMethodLater(1, self.showEnterMessage, 'showEnterMessage')
        UserFunnel.logSubmit(0, 'ENTERING_' + str(self.funnelDisplayName))
        UserFunnel.logSubmit(1, 'ENTERING_' + str(self.funnelDisplayName))
        self.storeLocationTime(self.funnelDisplayName, time.time())
        displayName = PLocalizer.LocationNames.get(self.uniqueId)
        base.setLocationCode(displayName)
        self.builder.initEffects()

    handleEnterGameArea = report(types = [
        'args',
        'deltaStamp'], dConfigParam = [
        'jail',
        'teleport'])(handleEnterGameArea)
    
    def storeLocationTime(self, loc, time):
        if loc == self.entryTime[0]:
            if self.entryTime[1] == 0:
                self.entryTime[1] = time
            
            return None
        else:
            self.entryTime = [
                loc,
                time]

    
    def readLocationTime(self):
        return self.entryTime[1]

    
    def showEnterMessage(self, task):
        displayName = PLocalizer.LocationNames.get(self.uniqueId)
        self.displayGameAreaName(displayName)

    
    def handleExitGameArea(self, collEntry = None):
        UserFunnel.logSubmit(0, 'EXITING_' + str(self.funnelDisplayName))
        UserFunnel.logSubmit(1, 'EXITING_' + str(self.funnelDisplayName))
        self.stopCustomEffects()
        self.previousDisplayName = None
        displayName = str(self.funnelDisplayName)
        timeSpent = int(time.time()) - int(self.readLocationTime())
        if int(self.timeCheck) + 1 == int(timeSpent) and int(self.timeCheck) - 1 == int(timeSpent) or int(self.timeCheck) == int(timeSpent):
            pass
        1
        base.cr.centralLogger.writeClientEvent('EXITING_AREA|%s|%d' % (displayName, timeSpent))
        self.timeCheck = timeSpent

    handleExitGameArea = report(types = [
        'args',
        'deltaStamp'], dConfigParam = [
        'jail',
        'teleport'])(handleExitGameArea)
    
    def displayGameAreaName(self, displayName):
        self.funnelDisplayName = displayName
        if self.previousDisplayName != displayName:
            self.previousDisplayName = displayName
            base.localAvatar.guiMgr.createTitle(displayName, PiratesGuiGlobals.TextFG2)
        

    
    def setPlayerBarrier(self, isOn):
        pass

    
    def setupCannonballLandColl(self, collNode, mask, index):
        if collNode and not collNode.isEmpty():
            collNode.node().setCollideMask(mask)
            collNode.setTag('objType', str(PiratesGlobals.COLL_LAND))
            collNode.setTag('groundCode', str(index))
            collNode.setTag('groundId', str(self.doId))
        

    
    def projectileWeaponHit(self, skillId, ammoSkillId, skillResult, targetEffects, pos, normal, codes, attacker, itemEffects = []):
        pass

    
    def startCustomEffects(self, interior = True, loadIslandMusic = False):
        if self.envEffects:
            self.envEffects.delete()
            self.envEffects = None
        
        if self.environment == 'Swamp':
            self.envEffects = SwampEffects.SwampEffects(self, self.modelPath)
            base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist = False)
            base.musicMgr.request(SoundGlobals.MUSIC_SWAMP, priority = 1, volume = 0.59999999999999998)
        elif self.environment == 'Jungle':
            self.envEffects = ForestEffects.ForestEffects(self, self.modelPath)
            base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist = False)
            base.musicMgr.request(SoundGlobals.MUSIC_JUNGLE, priority = 1, volume = 0.59999999999999998)
        elif self.environment == 'Cave':
            self.envEffects = CaveEffects.CaveEffects(self, self.modelPath)
            base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist = False)
            if self.uniqueId == LocationIds.RAVENS_COVE_MINE:
                base.musicMgr.request(SoundGlobals.getMainMusic(self.uniqueId), priority = 1, volume = 0.59999999999999998)
            else:
                base.musicMgr.request(SoundGlobals.MUSIC_CAVE, priority = 1, volume = 0.59999999999999998)
        elif self.uniqueId in ('1189479168.0sdnaik0', '1150922126.8akelts'):
            r = Reflection.getGlobalReflection()
            water = SeaPatch(self, reflection = r)
            water.loadSeaPatchFile('out.spf')
            self.water = water
            self.initializeIslandWaterParameters(self.geom)
        else:
            self.envEffects = EnvironmentEffects(self, self.modelPath)
            if interior:
                pass
            
        if loadIslandMusic:
            if not base.localAvatar.isInInvasion():
                base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_TORMENTA)
                base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_TORMENTA_COMBAT)
            
            
            def getCurrentIslandMusic():
                priZeros = []
                for music in base.musicMgr.playlist:
                    if music.priority == 0:
                        priZeros.append(music)
                        continue
                
                return priZeros

            
            def changeMusic(music, pri):
                for priZero in getCurrentIslandMusic():
                    base.musicMgr.requestFadeOut(priZero.name, removeFromPlaylist = True)
                
                base.musicMgr.request(music, priority = 0, volume = 0.59999999999999998)

            mainMusic = SoundGlobals.getMainMusic(self.uniqueId)
            altMusic = SoundGlobals.getAltMusic(self.uniqueId)
            if mainMusic and altMusic:
                base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist = True)
                todMgr = base.cr.timeOfDayManager
                todMgr.addTimeOfDayToggle('Day-Night Area Music', 6.0, 20.0, changeMusic, [
                    mainMusic,
                    0], changeMusic, [
                    altMusic,
                    0])
            elif mainMusic:
                base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist = True)
                base.musicMgr.request(mainMusic, volume = 0.59999999999999998)
            elif altMusic:
                base.musicMgr.requestCurMusicFadeOut(removeFromPlaylist = True)
                base.musicMgr.request(altMusic, volume = 0.59999999999999998)
            
        
        self.builder.initEffects()

    
    def stopCustomEffects(self):
        if self.envEffects:
            self.envEffects.delete()
            self.envEffects = None
        
        if 'swamp' in self.modelPath:
            base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_SWAMP, removeFromPlaylist = True)
        elif 'jungle' in self.modelPath:
            base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_JUNGLE, removeFromPlaylist = True)
        elif self.uniqueId in getLocationList(LocationIds.ANY_CAVE):
            base.musicMgr.requestFadeOut(SoundGlobals.MUSIC_CAVE, removeFromPlaylist = True)
            base.musicMgr.requestFadeOut(SoundGlobals.getMainMusic(self.uniqueId), removeFromPlaylist = True)
        elif self.uniqueId == '1189479168.0sdnaik0':
            self.water.delete()
            self.water = None
        
        if base.cr.timeOfDayManager:
            base.cr.timeOfDayManager.removeTimeOfDayToggle('Day-Night Area Music')
        

    
    def updateAvReturnLocation(self, av, uniqueId):
        pass

    
    def quickLoadOtherSide(self):
        connector = self.connectors.get(localAvatar.lastConnectorId)
        if connector:
            connector.quickLoadOtherSide()
        

    quickLoadOtherSide = report(types = [
        'frameCount',
        'args'], dConfigParam = [
        'jail',
        'teleport'])(quickLoadOtherSide)
    
    def addSpawnTriggers(self, triggerSpheres):
        for (x, y, z, triggerRadius, spawnPtId) in triggerSpheres:
            objectSphere = CollisionSphere(x, y, z, triggerRadius)
            objectName = uniqueName('spawnTriggerSphere')
            objectSphere.setTangible(0)
            objectSphereNode = CollisionNode(objectName)
            objectSphereNode.addSolid(objectSphere)
            objectSphereNode.setIntoCollideMask(PiratesGlobals.WallBitmask)
            objectSphereNodePath = self.builder.collisions.attachNewNode(objectSphereNode)
            self.accept('enter' + objectName, self.handleEnterSphere, extraArgs = [
                spawnPtId])
            self.spawnTriggers.append(objectSphereNodePath)
        

    
    def handleEnterSphere(self, spawnPtId, entry):
        if base.localAvatar:
            if hasattr(base.localAvatar, 'getDoId'):
                doId = base.localAvatar.getDoId()
                self.sendUpdate('spawnNPC', [
                    spawnPtId,
                    doId])
            
        

    
    def initBlockers(self, geom):
        self.disableBlockers = False
        if base.config.GetBool('disable-blockers', 0):
            self.disableBlockers = True
        
        blockerColls = geom.findAllMatches('**/blocker_*;+s')
        interior = False
        if not blockerColls.isEmpty():
            if blockerColls[0].getName().find('_i') != -1:
                interior = True
            
            for i in range(0, blockerColls.getNumPaths()):
                self.blockerColls.append(blockerColls[i])
                if self.disableBlockers:
                    blockerColls[i].stash()
                    continue
            
        
        if interior:
            self.accept('enterblocker_1_i', self.handleInteriorBlockerCollision)
        else:
            self.accept('enterblocker_1', self.handleBlockerCollision)
            self.accept('enterblocker_0', self.handleBlockerCollision)

    
    def stashSpecificBlocker(self, name):
        self.ignore('enter' + name)
        for blocker in self.blockerColls:
            if blocker.getName() == name:
                blocker.stash()
                continue
        

    
    def stashAllBlockers(self):
        self.ignore('enterblocker_1_i')
        self.ignore('enterblocker_1')
        self.ignore('enterblocker_0')
        for blocker in self.blockerColls:
            blocker.stash()
        

    
    def handleInteriorBlockerCollision(self, entry):
        questId = localAvatar.activeQuestId
        if base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_GOT_CUTLASS:
            questId = 'c2_visit_will_turner'
            localAvatar.guiMgr.messageStack.addTextMessage(PLocalizer.QuestStrings[questId]['blockerMessage'])
        else:
            self.stashAllBlockers()

    
    def handleBlockerCollision(self, entry):
        if base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_KILLED_1_SKELETON:
            questId = 'c2.2defeatSkeletons'
            localAvatar.guiMgr.messageStack.addTextMessage(PLocalizer.QuestStrings[questId]['blockerMessage'])
        elif base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_GOT_COMPASS:
            questId = 'c2_visit_tia_dalma'
            self.stashSpecificBlocker('blocker_1')
            if entry.getIntoNodePath().getName() != 'blocker_1':
                localAvatar.guiMgr.messageStack.addTextMessage(PLocalizer.QuestStrings[questId]['blockerMessage'])
            
        else:
            self.stashAllBlockers()

    
    def handleOnStage(self):
        StagedObject.handleOnStage(self)
        for (id, connector) in self.connectors.iteritems():
            if connector:
                connector.goOnStage()
                continue
        
        self.builder.addCutsceneOriginNode()

    handleOnStage = report(types = [
        'frameCount'], dConfigParam = 'connector')(handleOnStage)
    
    def handleOffStage(self):
        for (id, connector) in self.connectors.iteritems():
            if connector:
                connector.goOffStage()
                continue
        
        StagedObject.handleOffStage(self)

    handleOffStage = report(types = [
        'frameCount'], dConfigParam = 'connector')(handleOffStage)
    
    def getTeleportDestPosH(self, index = 0):
        pt = self._getTunnelSpawnPos(index)
        if not pt:
            self.notify.warning('could not find tunnel location %s' % self)
            return (0, 0, 0, 0)
        
        return (pt[0], pt[1], pt[2], 0)

    
    def _getTunnelSpawnPos(self, index = 0):
        connectorNodes = self.findAllMatches('**/portal_exterior*') + self.findAllMatches('**/portal_interior*')
        if not connectorNodes:
            return None
        
        return self.getRelativePoint(connectorNodes[index % len(connectorNodes)], Point3(40, 0, 0))

    _getTunnelSpawnPos = report(types = [
        'args'], dConfigParam = 'teleport')(_getTunnelSpawnPos)
    
    def initializeIslandWaterParameters(self, reference):
        debug = False
        island_water_parameters = IslandWaterParameters()
        world_position = self.getPos(render)
        world_x_offset = world_position[0]
        world_y_offset = world_position[1]
        world_z_offset = world_position[2]
        if debug:
            print self, '=', self.getName()
            print 'GAME AREA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
        
        self.swampAreaNode = reference.find('**/ocean')
        model = reference.find('**/water_color')
        if model:
            if debug:
                print 'WATER COLOR X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
            
            model.hide()
            min_point = Point3(0)
            max_point = Point3(0)
            model.calcTightBounds(min_point, max_point)
            size = max_point - min_point
            if self.getH() == 180 or self.getH() == -180:
                x = -min_point[0] + world_x_offset
                y = -min_point[1] + world_y_offset
                x_size = -size[0]
                y_size = -size[1]
            else:
                x = min_point[0] + world_x_offset
                y = min_point[1] + world_y_offset
                x_size = size[0]
                y_size = size[1]
            island_water_parameters.map_x_origin = x
            island_water_parameters.map_y_origin = y
            island_water_parameters.map_x_scale = x_size
            island_water_parameters.map_y_scale = y_size
            if debug:
                print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[1], x_size, y_size
            
            texture = model.findTexture('*')
            if texture:
                island_water_parameters.water_color_texture = texture
                if debug:
                    print 'WATER COLOR TEXTURE', texture
                
            
        elif debug:
            print '*** water_color NODE NOT FOUND'
        
        model = reference.find('**/water_alpha')
        if model:
            if debug:
                print 'WATER ALPHA X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
            
            model.hide()
            min_point = Point3(0)
            max_point = Point3(0)
            model.calcTightBounds(min_point, max_point)
            size = max_point - min_point
            if self.getH() == 180 or self.getH() == -180:
                x = -min_point[0] + world_x_offset
                y = -min_point[1] + world_y_offset
                x_size = -size[0]
                y_size = -size[1]
            else:
                x = min_point[0] + world_x_offset
                y = min_point[1] + world_y_offset
                x_size = size[0]
                y_size = size[1]
            island_water_parameters.alpha_map_x_origin = x
            island_water_parameters.alpha_map_y_origin = y
            island_water_parameters.alpha_map_x_scale = x_size
            island_water_parameters.alpha_map_y_scale = y_size
            if debug:
                print 'ALPHA X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[1], x_size, y_size
            
            texture = model.findTexture('*')
            if texture:
                island_water_parameters.water_alpha_texture = texture
                if debug:
                    print 'WATER ALPHA TEXTURE', texture
                
            
        elif debug:
            print '*** water_alpha NODE NOT FOUND'
        
        use_shader = False
        if base.config.GetBool('want-shaders', 1) and base.win and base.win.getGsg() and base.win.getGsg().getShaderModel() >= GraphicsStateGuardian.SM20:
            use_shader = True
        
        model_ns = reference.find('**/water_swamp_ns')
        if model_ns:
            if use_shader:
                model_ns.hide()
            else:
                model_ns.show()
                model = model_ns
                model.setBin('water', 1)
                parent = model.getParent()
                model.detachNode()
                stencil_one_node_path = NodePath('stencil_one')
                stencil_one_node_path.reparentTo(parent)
                model.instanceTo(stencil_one_node_path)
                mask = 0xFFFFFFFFL
                stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOKeep, 1, mask, mask)
                stencil_one_node_path.setAttrib(stencil_one, 100)
                stencil_one_node_path.setDepthTest(0)
                if not base.useStencils:
                    stencil_one_node_path.hide()
                
        
        model_alpha_texture = None
        model_alpha = reference.find('**/water_alpha_swamp')
        if model_alpha:
            model_alpha_texture = model_alpha.findTexture('*')
            model_alpha.hide()
            if debug:
                print 'model_alpha_texture', model_alpha_texture
            
            if False:
                texture = model_alpha_texture
                card_x_size = 0.5
                card_y_size = 0.5
                card = CardMaker('test_texture_card')
                card.setFrame(-card_x_size, card_x_size, -card_y_size, card_y_size)
                card_node_path = NodePath(card.generate())
                card_node_path.setTexture(texture, 1)
                card_node_path.node().setBounds(OmniBoundingVolume())
                card_node_path.node().setFinal(1)
                card_node_path.reparentTo(render2d)
            
        else:
            model_alpha = None
        model = reference.find('**/water_color_swamp')
        if model:
            if use_shader:
                model.show()
                model_texture = model.findTexture('*')
                if debug:
                    print 'WATER COLOR SWAMP X OFF, Y OFF, Z OFF = ', world_x_offset, world_y_offset, world_z_offset
                
                parent = model.getParent()
                model.detachNode()
                stencil_one_node_path = NodePath('stencil_one')
                stencil_one_node_path.reparentTo(parent)
                model.instanceTo(stencil_one_node_path)
                mask = 0xFFFFFFFFL
                stencil_one = StencilAttrib.make(1, StencilAttrib.SCFEqual, StencilAttrib.SOKeep, StencilAttrib.SOKeep, StencilAttrib.SOKeep, 1, mask, mask)
                stencil_one_node_path.setAttrib(stencil_one, 100)
                stencil_one_node_path.setDepthTest(0)
                if not base.useStencils:
                    stencil_one_node_path.hide()
                
                min_point = Point3(0)
                max_point = Point3(0)
                model.calcTightBounds(min_point, max_point)
                size = max_point - min_point
                if self.getH() == 180 or self.getH() == -180:
                    x = -min_point[0] + world_x_offset
                    y = -min_point[1] + world_y_offset
                    x_size = -size[0]
                    y_size = -size[1]
                else:
                    x = min_point[0] + world_x_offset
                    y = min_point[1] + world_y_offset
                    x_size = size[0]
                    y_size = size[1]
                if debug:
                    print 'min_point', min_point
                    print 'max_point', max_point
                    print 'size', size
                    print 'x y', x, y
                
                island_water_parameters.swamp_map_x_origin = x
                island_water_parameters.swamp_map_y_origin = y
                island_water_parameters.swamp_map_x_scale = x_size
                island_water_parameters.swamp_map_y_scale = y_size
                if debug:
                    print 'X, Y, X SIZE, Y SIZE = ', min_point[0], min_point[1], x_size, y_size
                
                texture = model.findTexture('*')
                if texture:
                    island_water_parameters.swamp_water_color_texture = texture
                    if debug:
                        print 'SWAMP WATER COLOR TEXTURE', texture
                    
                
                water_color_file_path = island_water_parameters.default_water_color_file_path
                alpha_texture_file_path = island_water_parameters.default_water_alpha_file_path
                opacity_texture_file_path = None
                shader_file_path = 'models/swamps/cuba_swamp001_2X.cg'
                reflection = Reflection.getGlobalReflection()
                self.swamp_water = Swamp(None, None, reflection, model, shader_file_path)
                island_water_parameters.swamp_water = self.swamp_water
                unload_previous_texture = True
                self.swamp_water.set_water_color_texture(water_color_file_path, unload_previous_texture, model_texture)
                self.swamp_water.set_water_alpha_texture(alpha_texture_file_path, unload_previous_texture, model_alpha_texture)
                self.swamp_water.set_wrap_or_clamp(True)
                r = 37.0
                g = 62.0
                b = 40.0
                self.swamp_water.water_r = r
                self.swamp_water.water_g = g
                self.swamp_water.water_b = b
                island_water_parameters.swamp_color_r = r
                island_water_parameters.swamp_color_g = g
                island_water_parameters.swamp_color_b = b
                x = 0.0
                y = 1.0
                speed = 3.2000000000000002
                island_water_parameters.swamp_direction_x = x
                island_water_parameters.swamp_direction_y = y
                island_water_parameters.swamp_speed = speed
                self.swamp_water.update_water_direction_and_speed(x, y, speed)
            else:
                model.hide()
        elif debug:
            print '*** water_color_swamp NODE NOT FOUND'
        
        self.islandWaterParameters = island_water_parameters

    
    def getLevel(self):
        return 1

    
    def announceGenerate(self):
        base.loadingScreen.tick()
        DistributedNode.announceGenerate(self)
        base.worldCreator.registerSpecialNodes(self, self.uniqueId)
        self.areaType = base.worldCreator.getFieldFromUid(self.uniqueId, 'Visibility')
        self.envSettings = base.worldCreator.getEnvSettingsByUid(self.uniqueId)
        self.builder = base.worldCreator.getBuilder(self, self.areaType)

    
    def retrieveFootprintNode(self):
        footprintCache = self.getFootprintCache()
        if footprintCache.hasData() and base.config.GetBool('want-disk-cache', 0):
            data = footprintCache.getData()
            newData = data.copySubgraph()
            footprintNode = NodePath(newData)
        else:
            footprintNode = self.buildFootprintNode()
        return footprintNode

    
    def getFootprintCache(self):
        return base.bamCache.lookup(Filename('/%s_footprint_%s.bam' % (self.uniqueId, base.gridDetail)), 'bam')

    
    def buildFootprintNode(self):
        footprintCache = self.getFootprintCache()
        footprintNode = self.builder.buildFootprintNode()
        footprintCache.setData(footprintNode.node(), 0)
        base.bamCache.store(footprintCache)
        return footprintNode

    
    def hideMapNodes(self):
        mapNodes = self.geom.findAllMatches('**/minimap_*')
        mapNodes.hide()

    hideMapNodes = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(hideMapNodes)
    
    def setFootstepSound(self, footstepSound):
        self.footstepSound = footstepSound
        if self.footstepSound and base.localAvatar:
            base.localAvatar.setAreaFootstep(self.footstepSound)
            base.localAvatar.setSurfaceIndexFromLevelDefault()
        

    
    def setEnvironment(self, environment):
        self.environment = environment

    
    def setMinimapPrefix(self, prefix):
        minimaps = self.geom.findAllMatches('**/minimap_*;+s')
        for map in minimaps:
            if prefix not in map.getName():
                map.detachNode()
                continue
        
        minimaps = sorted(self.geom.findAllMatches('**/minimap_*;+s'))
        for (x, map) in enumerate(minimaps):
            map.setName('minimap_%d' % x)
        

    setMinimapPrefix = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(setMinimapPrefix)
    
    def getMapNode(self):
        mapNode = self.geom.find('**/minimap_%s' % (self.minimapArea,))
        if not mapNode:
            minSide = 1500.0
            (a, b) = self.geom.getTightBounds()
            diff = b - a
            sideScale = 1
            if diff[0] > diff[1]:
                if diff[0] < minSide:
                    sideScale = minSide / diff[0]
                
            elif diff[1] < minSide:
                sideScale = minSide / diff[1]
            
            cm = CardMaker('minimap-card')
            cm.setFrame(VBase4(a[0], b[0], a[1], b[1]) * sideScale)
            modelNode = ModelNode('minimap_0')
            modelNode.setPreserveTransform(1)
            mapNode = self.geom.attachNewNode(modelNode)
            mapGeom = mapNode.attachNewNode(cm.generate())
            mapGeom.setP(-90)
            mapGeom.hide()
        
        return mapNode

    getMapNode = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(getMapNode)
    
    def getMapName(self):
        return 'map-' + self.getUniqueId()

    
    def getFootprintNode(self):
        if not self.footprintNode:
            self.footprintNode = self.retrieveFootprintNode()
        
        if not self.footprintNode.find('footprint_%s' % (self.minimapArea,)):
            pass
        return NodePath('footprint_%s' % (self.minimapArea,))

    
    def getShopNodes(self):
        shopNodes = self.builder.getMinimapShopNodes()
        mapNodes = NodePathCollection()
        for node in shopNodes:
            if not node.getTag('MinimapArea'):
                pass
            minimapArea = int('0')
            if minimapArea == self.minimapArea:
                mapNodes.addPath(node)
                continue
        
        return mapNodes

    
    def getCapturePointNodes(self, holidayName):
        capturePoints = self.builder.getMinimapCapturePointNodes(holidayName)
        mapNodes = NodePathCollection()
        for node in capturePoints:
            if not node.getTag('MinimapArea'):
                pass
            minimapArea = int('0')
            if minimapArea == self.minimapArea:
                mapNodes.addPath(node)
                continue
        
        return mapNodes

    
    def getZoomLevels(self):
        return ((150, 200, 300), 1)

    
    def addMinimapObject(self, obj):
        if self.minimap:
            self.minimap.addObject(obj)
        

    addMinimapObject = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(addMinimapObject)
    
    def removeMinimapObject(self, obj):
        if self.minimap:
            self.minimap.removeObject(obj)
        

    removeMinimapObject = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(removeMinimapObject)
    
    def ensureLoaded(self):
        pass

    
    def setMinimapArea(self, areaId):
        if areaId != self.minimapArea:
            self.minimapArea = areaId
            self.destroyMinimap()
            self.setupMinimap()
            self.minimap.addObject(localAvatar.getMinimapObject())
            self.loadConnectors()
            localAvatar.guiMgr.setMinimap(self.minimap)
        

    setMinimapArea = report(types = [
        'args'], dConfigParam = 'minimap')(setMinimapArea)
    
    def showTunnelOnMinimap(self, tunnelUid):
        return self.builder.getTunnelMinimap(tunnelUid) == self.minimapArea

    showTunnelOnMinimap = report(types = [
        'frameCount',
        'args'], dConfigParam = 'minimap')(showTunnelOnMinimap)
    
    def getConnectorNodeNamed(self, name):
        return self.find('**/' + name + '*')

    
    def handleHolidayStarted(self, holiday):
        if self.minimap:
            self.minimap.handleHolidayStarted(self, holiday)
        

    handleHolidayStarted = report(types = [
        'args'], dConfigParam = 'minimap')(handleHolidayStarted)
    
    def handleHolidayEnded(self, holiday):
        if self.minimap:
            self.minimap.handleHolidayEnded(self, holiday)
        

    handleHolidayEnded = report(types = [
        'args'], dConfigParam = 'minimap')(handleHolidayEnded)