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
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)
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)