Exemple #1
0
def load(sectorX, sectorY, instanceId, sectorSum, verbose=True):
    """ Load sectorX.sectorY.sec. Returns True/False """
          
    t = time.time()
    
    # Attempt to load a sector file
    try:
        with io.open("%s/%s/%s%d.%d.sec" % (config.dataDirectory, config.mapDirectory, instances[instanceId], sectorX, sectorY), "rb") as f:
            map = loadSectorMap(f.read(), instanceId, sectorX << sectorShiftX, sectorY << sectorShiftY)
            knownMap.update(map)
        sectors.add(sectorSum)
    except IOError:
        # No? Mark it as empty
        sectors.add(sectorSum)
        return False
        
    if verbose:
        print "Loading of %d.%d.sec took: %f" % (sectorX, sectorY, time.time() - t)    
    
    if config.performSectorUnload:
        reactor.callLater(config.performSectorUnloadEvery, _unloadMap, sectorX, sectorY, instanceId)
    
    scriptsystem.get('postLoadSector').runSync("%d.%d" % (sectorX, sectorY), None, None, sector=map, instanceId=instanceId)
    
    return True
Exemple #2
0
    def onDeath(self):
        # Remove master summons
        isSummon = self.isSummon()

        if self.master:
            self.master.activeSummons.remove(self)

        self.turnOffBrain()
        
        # Remove summons
        if self.activeSummons:
            for summon in self.activeSummons:
                summon.magicEffect(EFFECT_POFF)
                summon.despawn()
                summon.turnOffBrain()

        # Lose all conditions.
        self.loseAllConditions()
                
        # Transform
        tile = map.getTile(self.position)
        lootMsg = []
        if self.base.data["corpse"]:
            corpse = game.item.Item(self.base.data["corpse"], actions=self.base.corpseAction)
            
            corpse.movable = False
            def _move_corpse():
                corpse.movable = True

            callLater(config.moveCorpseAfter, _move_corpse)

            # Set owner.
            if self.lastDamagers:
                if self.getLastDamager().isPlayer():
                    corpse.owners = [self.getLastDamager()]
            
                    def _clear_private_loot():
                        del corpse.owners
                
                    # Callback to remove owner after config.privateLootFor seconds
                    callLater(config.privateLootFor, _clear_private_loot)
            if not isSummon and not self.lastDamagers or self.getLastDamager() != self.master:
                try:
                    maxSize = game.item.items[self.base.data["corpse"]]["containerSize"]
                except:
                    # Monsters with loot MUST have a container with some size in it.
                    if self.base.lootTable: 
                        print "[WARNING] Monster %s got a bad corpse" % self.name()
                    maxSize = 0
                drops = []
                if maxSize:
                    for loot in self.base.lootTable:
                        if config.lootDropRate*loot[1]*100 > random.randint(0, 10000): # [7363, 28.5, 4]
                            if len(drops)+1 == maxSize:
                                if config.stockLootInBagsIfNeeded:
                                    drops.insert(0, (config.stockLootBagId, None))
                                    maxSize += item.items[config.stockLootBagId]["containerSize"]
                                else:
                                    drops.append(loot)            
                                break
                            else:        
                                drops.append(loot)
                            
                        elif len(loot) == 4:
                            drops.append((loot[0], None, loot[4]))
                
                ret = scriptsystem.get("loot").runSync(self, self.getLastDamager() if self.lastDamagers else None, loot=drops, maxSize=maxSize)
                if type(ret) == list:
                    drops = ret

                for loot in drops:
                    lenLoot = len(loot)
                    ret = 0
                    if lenLoot == 2:
                        ritem = game.item.Item(random.choice(loot[0]) if isinstance(loot[0], list) else loot[0], 1)
                        lootMsg.append(ritem.name)
                        ret = corpse.placeItemRecursive(ritem)
                            
                    elif lenLoot == 3:
                        count = random.randint(1, loot[2]) * config.lootMaxRate
                        if count > 100:
                            while count:
                                depCount = min(count, 100)
                                ritem = game.item.Item(random.choice(loot[0]) if isinstance(loot[0], list) else loot[0], depCount)
                                lootMsg.append(ritem.name)
                                ret = corpse.placeItemRecursive(ritem)
                                count -= depCount
                        else:
                            ritem = game.item.Item(random.choice(loot[0]) if isinstance(loot[0], list) else loot[0], count)
                            lootMsg.append(ritem.name)
                            ret = corpse.placeItemRecursive(ritem)
                                
                    elif lenLoot == 4:
                        count = random.randint(loot[4], loot[2]) * config.lootMaxRate
                        if count > 100:
                            while count:
                                depCount = min(count, 100)
                                ritem = game.item.Item(random.choice(loot[0]) if isinstance(loot[0], list) else loot[0], depCount)
                                lootMsg.append(ritem.name)
                                ret = corpse.placeItemRecursive(ritem)
                                count -= depCount
                                    
                        else:
                            ritem = game.item.Item(random.choice(loot[0]) if isinstance(loot[0], list) else loot[0], count)
                            lootMsg.append(ritem.name)
                            ret = corpse.placeItemRecursive(ritem)
                                

                    if ret == None:
                        log.msg("Warning: Monster '%s' extends all possible loot space" % self.data['name'])
                        break

        else:
            corpse = None
            
        scriptsystem.get("death").runSync(self, self.getLastDamager() if self.lastDamagers else None, corpse=corpse)
        if self.alive or self.data["health"] > 0:
            print "[May bug] Death events brought us back to life?"
            return
        
        # Remove bpth small and full splashes on the tile.
        for item in tile.getItems():
            if item.itemId in SMALLSPLASHES or item.itemId in FULLSPLASHES:
                tile.removeItem(item)
        
        # Add full splash
        splash = Item(FULLSPLASH)
        splash.fluidSource = self.base.blood
        
        if corpse:
            corpse.place(self.position)
        splash.place(self.position)
        
        # Start decay
        if corpse:
            corpse.decay()
        splash.decay()
        
        # Remove me. This also refresh the tile.
        self.remove()

        if not isSummon and self.lastDamagers and self.getLastDamager().isPlayer() and self.getLastDamager() != self.master:
            if lootMsg:
                self.getLastDamager().message(_l(self.getLastDamager(), "loot of %(who)s: %(loot)s") % {"who": self.data["name"].lower(), "loot": ', '.join(lootMsg)}, MSG_LOOT)
            else:
                self.getLastDamager().message(_l(self.getLastDamager(), "loot of %s: nothing") % (self.data["name"]), MSG_LOOT)
                
            # Experience split.
            attackerParty = self.getLastDamager().party()
            if attackerParty and attackerParty.shareExperience and attackerParty.checkShareExperience():
                for member in attackerParty.members:
                    if member.data["stamina"] or config.noStaminaNoExp == False:
                        exp = (self.base.experience / len(attackerParty.members)) * config.partyExperienceFactor
                        member.modifyExperience(exp * member.getExperienceRate())
                        
                        if exp >= member.data["level"]:
                            member.soulGain()
            else:
                if self.getLastDamager().data["stamina"] or config.noStaminaNoExp == False:
                    self.getLastDamager().modifyExperience(self.base.experience *self.getLastDamager().getExperienceRate())

                    if self.base.experience >= self.getLastDamager().data["level"]:
                        self.getLastDamager().soulGain()
       
        # Begin respawn
        if self.respawn:
            self.position = self.spawnPosition
            self.target = None
            self.targetMode = 0
            if self.spawnTime != 0:
                if self.spawnTime:
                    reactor.callLater(self.spawnTime, self.base.spawn, self.spawnPosition, spawnTime = self.spawnTime, spawnDelay=0, check=False)
                else:
                    return
            else:
                reactor.callLater(self.base.spawnTime, self.base.spawn, self.spawnPosition, spawnDelay=0, check=False)
Exemple #3
0
    def onDeath(self):
        # Remove master summons
        isSummon = self.isSummon()

        if self.master:
            self.master.activeSummons.remove(self)

        self.turnOffBrain()

        # Remove summons
        if self.activeSummons:
            for summon in self.activeSummons:
                summon.magicEffect(EFFECT_POFF)
                summon.despawn()
                summon.turnOffBrain()

        # Lose all conditions.
        self.loseAllConditions()

        # Transform
        tile = map.getTile(self.position)
        lootMsg = []
        if self.base.data["corpse"]:
            corpse = game.item.Item(self.base.data["corpse"],
                                    actions=self.base.corpseAction)

            corpse.movable = False

            def _move_corpse():
                corpse.movable = True

            callLater(config.moveCorpseAfter, _move_corpse)

            # Set owner.
            if self.lastDamagers:
                if self.getLastDamager().isPlayer():
                    corpse.owners = [self.getLastDamager()]

                    def _clear_private_loot():
                        del corpse.owners

                    # Callback to remove owner after config.privateLootFor seconds
                    callLater(config.privateLootFor, _clear_private_loot)
            if not isSummon and not self.lastDamagers or self.getLastDamager(
            ) != self.master:
                try:
                    maxSize = game.item.items[
                        self.base.data["corpse"]]["containerSize"]
                except:
                    # Monsters with loot MUST have a container with some size in it.
                    if self.base.lootTable:
                        print "[WARNING] Monster %s got a bad corpse" % self.name(
                        )
                    maxSize = 0
                drops = []
                if maxSize:
                    for loot in self.base.lootTable:
                        if config.lootDropRate * loot[1] * 100 > random.randint(
                                0, 10000):  # [7363, 28.5, 4]
                            if len(drops) + 1 == maxSize:
                                if config.stockLootInBagsIfNeeded:
                                    drops.insert(0,
                                                 (config.stockLootBagId, None))
                                    maxSize += item.items[
                                        config.stockLootBagId]["containerSize"]
                                else:
                                    drops.append(loot)
                                break
                            else:
                                drops.append(loot)

                        elif len(loot) == 4:
                            drops.append((loot[0], None, loot[4]))

                ret = scriptsystem.get("loot").runSync(
                    self,
                    self.getLastDamager() if self.lastDamagers else None,
                    loot=drops,
                    maxSize=maxSize)
                if type(ret) == list:
                    drops = ret

                for loot in drops:
                    lenLoot = len(loot)
                    ret = 0
                    if lenLoot == 2:
                        ritem = game.item.Item(
                            random.choice(loot[0]) if isinstance(
                                loot[0], list) else loot[0], 1)
                        lootMsg.append(ritem.name)
                        ret = corpse.placeItemRecursive(ritem)

                    elif lenLoot == 3:
                        count = random.randint(1, loot[2]) * config.lootMaxRate
                        if count > 100:
                            while count:
                                depCount = min(count, 100)
                                ritem = game.item.Item(
                                    random.choice(loot[0]) if isinstance(
                                        loot[0], list) else loot[0], depCount)
                                lootMsg.append(ritem.name)
                                ret = corpse.placeItemRecursive(ritem)
                                count -= depCount
                        else:
                            ritem = game.item.Item(
                                random.choice(loot[0]) if isinstance(
                                    loot[0], list) else loot[0], count)
                            lootMsg.append(ritem.name)
                            ret = corpse.placeItemRecursive(ritem)

                    elif lenLoot == 4:
                        count = random.randint(loot[4],
                                               loot[2]) * config.lootMaxRate
                        if count > 100:
                            while count:
                                depCount = min(count, 100)
                                ritem = game.item.Item(
                                    random.choice(loot[0]) if isinstance(
                                        loot[0], list) else loot[0], depCount)
                                lootMsg.append(ritem.name)
                                ret = corpse.placeItemRecursive(ritem)
                                count -= depCount

                        else:
                            ritem = game.item.Item(
                                random.choice(loot[0]) if isinstance(
                                    loot[0], list) else loot[0], count)
                            lootMsg.append(ritem.name)
                            ret = corpse.placeItemRecursive(ritem)

                    if ret == None:
                        log.msg(
                            "Warning: Monster '%s' extends all possible loot space"
                            % self.data['name'])
                        break

        else:
            corpse = None

        scriptsystem.get("death").runSync(
            self,
            self.getLastDamager() if self.lastDamagers else None,
            corpse=corpse)
        if self.alive or self.data["health"] > 0:
            print "[May bug] Death events brought us back to life?"
            return

        # Remove bpth small and full splashes on the tile.
        for item in tile.getItems():
            if item.itemId in SMALLSPLASHES or item.itemId in FULLSPLASHES:
                tile.removeItem(item)

        # Add full splash
        splash = Item(FULLSPLASH)
        splash.fluidSource = self.base.blood

        if corpse:
            corpse.place(self.position)
        splash.place(self.position)

        # Start decay
        if corpse:
            corpse.decay()
        splash.decay()

        # Remove me. This also refresh the tile.
        self.remove()

        if not isSummon and self.lastDamagers and self.getLastDamager(
        ).isPlayer() and self.getLastDamager() != self.master:
            if lootMsg:
                self.getLastDamager().message(
                    _l(self.getLastDamager(), "loot of %(who)s: %(loot)s") % {
                        "who": self.data["name"].lower(),
                        "loot": ', '.join(lootMsg)
                    }, MSG_LOOT)
            else:
                self.getLastDamager().message(
                    _l(self.getLastDamager(), "loot of %s: nothing") %
                    (self.data["name"]), MSG_LOOT)

            # Experience split.
            attackerParty = self.getLastDamager().party()
            if attackerParty and attackerParty.shareExperience and attackerParty.checkShareExperience(
            ):
                for member in attackerParty.members:
                    if member.data["stamina"] or config.noStaminaNoExp == False:
                        exp = (self.base.experience /
                               len(attackerParty.members)
                               ) * config.partyExperienceFactor
                        member.modifyExperience(exp *
                                                member.getExperienceRate())

                        if exp >= member.data["level"]:
                            member.soulGain()
            else:
                if self.getLastDamager(
                ).data["stamina"] or config.noStaminaNoExp == False:
                    self.getLastDamager().modifyExperience(
                        self.base.experience *
                        self.getLastDamager().getExperienceRate())

                    if self.base.experience >= self.getLastDamager(
                    ).data["level"]:
                        self.getLastDamager().soulGain()

        # Begin respawn
        if self.respawn:
            self.position = self.spawnPosition
            self.target = None
            self.targetMode = 0
            if self.spawnTime != 0:
                if self.spawnTime:
                    reactor.callLater(self.spawnTime,
                                      self.base.spawn,
                                      self.spawnPosition,
                                      spawnTime=self.spawnTime,
                                      spawnDelay=0,
                                      check=False)
                else:
                    return
            else:
                reactor.callLater(self.base.spawnTime,
                                  self.base.spawn,
                                  self.spawnPosition,
                                  spawnDelay=0,
                                  check=False)