From d696338f5d4fd381280e67710131f72623ec917c Mon Sep 17 00:00:00 2001 From: John Date: Fri, 7 Aug 2015 23:27:54 +0300 Subject: [PATCH 01/38] Color shop crash fix --- toontown/makeatoon/ColorShop.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/toontown/makeatoon/ColorShop.py b/toontown/makeatoon/ColorShop.py index 3f004a6d..be3e0dd9 100755 --- a/toontown/makeatoon/ColorShop.py +++ b/toontown/makeatoon/ColorShop.py @@ -28,6 +28,7 @@ class ColorShop(StateData.StateData): self.allParts = (TTLocalizer.ColorAll, TTLocalizer.ColorShopHead, TTLocalizer.ColorShopBody, TTLocalizer.ColorShopGloves, TTLocalizer.ColorShopLegs) if not hasattr(self, 'headChoice'): self.headChoice = colorList.index(self.dna.headColor) + self.allChoice = self.headChoice self.armChoice = colorList.index(self.dna.armColor) self.gloveChoice = colorList.index(self.dna.gloveColor) self.legChoice = colorList.index(self.dna.legColor) @@ -217,15 +218,14 @@ class ColorShop(StateData.StateData): def __swapAllColor(self, offset): colorList = self.getColorList() length = len(colorList) - choice = (self.headChoice + offset) % length - self.__updateScrollButtons(choice, length, self.allLButton, self.allRButton) - self.__swapHeadColor(offset) - oldArmColorIndex = colorList.index(self.toon.style.armColor) - oldGloveColorIndex = colorList.index(self.toon.style.gloveColor) - oldLegColorIndex = colorList.index(self.toon.style.legColor) - self.__swapArmColor(choice - oldArmColorIndex) - self.__swapGloveColor(choice - oldGloveColorIndex) - self.__swapLegColor(choice - oldLegColorIndex) + self.allChoice = (self.allChoice + offset) % length + self.__updateScrollButtons(self.allChoice, length, self.allLButton, self.allRButton) + newColor = colorList[self.allChoice] + self.dna.headColor = newColor + self.dna.armColor = newColor + self.dna.gloveColor = newColor + self.dna.legColor = newColor + self.toon.swapToonColor(self.dna) def __swapHeadColor(self, offset): colorList = self.getColorList() From 56c9f71296694a661c55789e24b3418d0b9e6db7 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 7 Aug 2015 23:32:10 +0300 Subject: [PATCH 02/38] Yet another fix.. --- toontown/makeatoon/ColorShop.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/toontown/makeatoon/ColorShop.py b/toontown/makeatoon/ColorShop.py index be3e0dd9..9fc18865 100755 --- a/toontown/makeatoon/ColorShop.py +++ b/toontown/makeatoon/ColorShop.py @@ -220,6 +220,10 @@ class ColorShop(StateData.StateData): length = len(colorList) self.allChoice = (self.allChoice + offset) % length self.__updateScrollButtons(self.allChoice, length, self.allLButton, self.allRButton) + self.__updateScrollButtons(self.allChoice, length, self.headLButton, self.headRButton) + self.__updateScrollButtons(self.allChoice, length, self.armLButton, self.armRButton) + self.__updateScrollButtons(self.allChoice, length, self.gloveLButton, self.gloveRButton) + self.__updateScrollButtons(self.allChoice, length, self.legLButton, self.legRButton) newColor = colorList[self.allChoice] self.dna.headColor = newColor self.dna.armColor = newColor From 0718b91ed43a316d6f99ba633dc6f65e03eefafc Mon Sep 17 00:00:00 2001 From: John Date: Fri, 7 Aug 2015 23:54:53 +0300 Subject: [PATCH 03/38] Add the new shops and NPCs for the street --- toontown/toon/NPCToons.py | 57 +++++++++++++++++++++++++ toontown/toonbase/TTLocalizerEnglish.py | 6 +++ 2 files changed, 63 insertions(+) diff --git a/toontown/toon/NPCToons.py b/toontown/toon/NPCToons.py index c4652bb9..1c2f7344 100755 --- a/toontown/toon/NPCToons.py +++ b/toontown/toon/NPCToons.py @@ -11358,6 +11358,63 @@ NPCToonDict = {20000: (-1, 'm', 0, NPC_REGULAR), + 9322: (9821, + lnames[9322], + ('dss', + 'ms', + 'm', + 'm', + 15, + 0, + 15, + 15, + 5, + 6, + 5, + 6, + 7, + 9), + 'f', + 0, + NPC_REGULAR), + 9323: (9822, + lnames[9323], + ('css', + 'ms', + 's', + 'm', + 31, + 0, + 31, + 31, + 8, + 2, + 8, + 2, + 5, + 11), + 'm', + 0, + NPC_REGULAR), + 9324: (9806, + lnames[9324], + ('fss', + 'ls', + 'l', + 'm', + 16, + 0, + 16, + 16, + 2, + 9, + 2, + 9, + 7, + 20), + 'm', + 0, + NPC_REGULAR), 7001: (-1, lnames[7001], ('bss', diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index 0e22b7b8..ad1b818a 100755 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -6241,6 +6241,9 @@ NPCToonNames = {20000: 'Tutorial Tom', 9319: 'Psyche', 9320: 'Toony Bob', 9321: 'Sir Biscuit', + 9322: 'Glower', + 9323: 'Zedd', + 9324: 'Nacib', 7001: 'N. Prisoned', 7002: 'R.E. Leaseme', 7003: 'Lemmy Owte', @@ -6806,6 +6809,7 @@ zone2TitleDict = {2513: ('Toon Hall', ''), 3830: ('Wait and See Goggle Defogging', ''), 9802: ("Barbra's Bohemian Art Supplies", ''), 9804: ("Angry Dan's Garden Sprinklers", ''), + 9806: ("Nacib Niri", ''), 9808: ("Ori-O's Creamery and Dairy", ''), 9809: ('Rave of the Forks', ''), 9812: ('Louds Silent-Shop', ''), @@ -6816,6 +6820,8 @@ zone2TitleDict = {2513: ('Toon Hall', ''), 9817: ('The Psyche-Ologist', ''), 9819: ("Toony Bob's Fluffy Pillows", ''), 9820: ("Batty's Bat Supply", ''), + 9821: ("Milk or Sugar? Tea Shop", ''), + 9822: ("Zedd's Pasta", ''), 9824: ("Joe's Burnt Biscuits", ''), 9826: ("Juste-A-Cote Taxi Service", ''), 9827: ("Frekly Fred's Storage Shack", ''), From ce8d856ebe39372fa160dae8df0d846bed579e82 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 8 Aug 2015 12:08:45 +0300 Subject: [PATCH 04/38] Proper Fish Bingo implementation using News Manager --- toontown/ai/NewsManagerAI.py | 60 ++++++++++--- toontown/estate/DistributedEstateAI.py | 6 -- toontown/fishing/BingoCardGui.py | 5 -- toontown/fishing/DistributedFishingPondAI.py | 37 +++++++- .../fishing/DistributedPondBingoManager.py | 22 +---- .../fishing/DistributedPondBingoManagerAI.py | 86 ++++++------------- toontown/hood/HoodAI.py | 7 -- toontown/makeatoon/BodyShop.py | 1 - toontown/makeatoon/ShuffleButton.py | 1 - toontown/safezone/DistributedFishingSpot.py | 2 + 10 files changed, 111 insertions(+), 116 deletions(-) diff --git a/toontown/ai/NewsManagerAI.py b/toontown/ai/NewsManagerAI.py index 3062d24a..f55a8eaf 100755 --- a/toontown/ai/NewsManagerAI.py +++ b/toontown/ai/NewsManagerAI.py @@ -1,6 +1,7 @@ from direct.distributed.DistributedObjectAI import DistributedObjectAI from direct.distributed.ClockDelta import globalClockDelta from direct.task import Task +from otp.ai.MagicWordGlobal import * from toontown.effects.DistributedFireworkShowAI import DistributedFireworkShowAI from toontown.effects import FireworkShows from toontown.toonbase import ToontownGlobals @@ -18,19 +19,21 @@ class NewsManagerAI(DistributedObjectAI): def announceGenerate(self): DistributedObjectAI.announceGenerate(self) self.__checkHolidays() - self.checkTask = taskMgr.doMethodLater(15, self.__checkHolidays, 'holidayCheckTask') self.accept('avatarEntered', self.__handleAvatarEntered) + taskMgr.doMethodLater(15, self.__checkHolidays, 'holidayCheckTask') def delete(self): DistributedObjectAI.delete(self) - taskMgr.remove(self.checkTask) + self.deleteTasks() + + def deleteTasks(self): + taskMgr.remove('holidayCheckTask') self.deleteFireworkTasks() def deleteFireworkTasks(self): - if self.fireworkTasks: - for task in self.fireworkTasks: - taskMgr.remove(task) - self.fireworkTasks = [] + for task in self.fireworkTasks: + taskMgr.remove(task) + self.fireworkTasks = [] def __handleAvatarEntered(self, av): avId = av.getDoId() @@ -64,41 +67,44 @@ class NewsManagerAI(DistributedObjectAI): else: return HolidayGlobals.getStartDate(holiday) <= date <= HolidayGlobals.getEndDate(holiday) - def isHolidayRunning(self, id): - return id in self.activeHolidays + def isHolidayRunning(self, *args): + for id in args: + if id in self.activeHolidays: + return True def startHoliday(self, id): if id in self.activeHolidays or id not in HolidayGlobals.Holidays: - return + return False self.activeHolidays.append(id) self.startSpecialHoliday(id) self.sendUpdate('startHoliday', [id]) + return True def endHoliday(self, id): if id not in self.activeHolidays or id not in HolidayGlobals.Holidays: - return + return False self.activeHolidays.remove(id) self.endSpecialHoliday(id) self.sendUpdate('endHoliday', [id]) + return True def startSpecialHoliday(self, id): if id == ToontownGlobals.FISH_BINGO or id == ToontownGlobals.SILLY_SATURDAY: - messenger.send('checkBingoState') + messenger.send('startBingo') elif id in [ToontownGlobals.SUMMER_FIREWORKS, ToontownGlobals.NEW_YEAR_FIREWORKS]: self.fireworkTasks.append(taskMgr.doMethodLater((60 - datetime.datetime.now().minute) * 60, self.startFireworkTask, 'initialFireworkTask-%s' % id, extraArgs=[id])) def endSpecialHoliday(self, id): if id == ToontownGlobals.FISH_BINGO or id == ToontownGlobals.SILLY_SATURDAY: - messenger.send('checkBingoState') + messenger.send('stopBingo') elif id in [ToontownGlobals.SUMMER_FIREWORKS, ToontownGlobals.NEW_YEAR_FIREWORKS]: self.deleteFireworkTasks() def startFireworkTask(self, id, task=None): self.startFireworks(id) self.fireworkTasks.append(taskMgr.doMethodLater(3600, self.startFireworks, 'fireworkTask-%s' % id, extraArgs=[id])) - return Task.done def startFireworks(self, type, task=None): maxShow = len(FireworkShows.shows.get(type, [])) - 1 @@ -112,3 +118,31 @@ class NewsManagerAI(DistributedObjectAI): fireworkShow.b_startShow(type, random.randint(0, maxShow), globalClockDelta.getRealNetworkTime()) return Task.again + +@magicWord(category=CATEGORY_PROGRAMMER) +def newsShutdown(): + """ + Shutdown the news manager tasks. + """ + simbase.air.newsManager.deleteTasks() + return 'News manager shut down!' + +@magicWord(category=CATEGORY_PROGRAMMER, types=[int]) +def startHoliday(holiday): + """ + Start a holiday. + """ + if simbase.air.newsManager.startHoliday(holiday): + return 'Started holiday %s!' % holiday + + return 'Holiday %s is already running!' % holiday + +@magicWord(category=CATEGORY_PROGRAMMER, types=[int]) +def stopHoliday(holiday): + """ + Stop a holiday. + """ + if simbase.air.newsManager.endHoliday(holiday): + return 'Stopped holiday %s!' % holiday + + return 'Holiday %s is not running!' % holiday \ No newline at end of file diff --git a/toontown/estate/DistributedEstateAI.py b/toontown/estate/DistributedEstateAI.py index 172504a1..028a1c87 100755 --- a/toontown/estate/DistributedEstateAI.py +++ b/toontown/estate/DistributedEstateAI.py @@ -5,7 +5,6 @@ import HouseGlobals import time, random from toontown.fishing.DistributedFishingPondAI import DistributedFishingPondAI -from toontown.fishing.DistributedPondBingoManagerAI import DistributedPondBingoManagerAI from toontown.fishing import FishingTargetGlobals, FishGlobals from toontown.safezone import TreasureGlobals from toontown.safezone.SZTreasurePlannerAI import SZTreasurePlannerAI @@ -506,11 +505,6 @@ class DistributedEstateAI(DistributedObjectAI): self.pond.generateWithRequired(self.zoneId) self.pond.start() - self.pond.bingoMgr = DistributedPondBingoManagerAI(simbase.air) - self.pond.bingoMgr.setPondDoId(self.pond.getDoId()) - self.pond.bingoMgr.generateWithRequired(self.zoneId) - self.pond.bingoMgr.initTasks() - treasureType, healAmount, spawnPoints, spawnRate, maxTreasures = TreasureGlobals.SafeZoneTreasureSpawns[ToontownGlobals.MyEstate] self.treasurePlanner = SZTreasurePlannerAI(self.zoneId, treasureType, healAmount, spawnPoints, spawnRate, maxTreasures) self.treasurePlanner.start() diff --git a/toontown/fishing/BingoCardGui.py b/toontown/fishing/BingoCardGui.py index d0ce358f..b0cba51a 100755 --- a/toontown/fishing/BingoCardGui.py +++ b/toontown/fishing/BingoCardGui.py @@ -156,11 +156,6 @@ class BingoCardGui(DirectFrame): elif self.game.getGameState() & 1 << index: self.cellGuiList[index].disable() - def disableCard(self): - self.stopCellBlinking() - for index in xrange(self.game.getCardSize()): - self.cellGuiList[index].disable() - def enableCard(self, callback = None): self.notify.info('enable Bingo card') self.stopCellBlinking() diff --git a/toontown/fishing/DistributedFishingPondAI.py b/toontown/fishing/DistributedFishingPondAI.py index ad387d7b..ee98b379 100755 --- a/toontown/fishing/DistributedFishingPondAI.py +++ b/toontown/fishing/DistributedFishingPondAI.py @@ -1,8 +1,9 @@ from direct.directnotify.DirectNotifyGlobal import * from direct.distributed.DistributedObjectAI import DistributedObjectAI -from toontown.fishing import FishingTargetGlobals -from toontown.fishing.DistributedFishingTargetAI import DistributedFishingTargetAI - +from toontown.toonbase import ToontownGlobals +from DistributedFishingTargetAI import DistributedFishingTargetAI +from DistributedPondBingoManagerAI import DistributedPondBingoManagerAI +import FishingTargetGlobals class DistributedFishingPondAI(DistributedObjectAI): notify = directNotify.newCategory("DistributedFishingPondAI") @@ -14,12 +15,42 @@ class DistributedFishingPondAI(DistributedObjectAI): self.targets = {} self.spots = {} self.bingoMgr = None + + def announceGenerate(self): + if self.air.newsManager.isHolidayRunning(ToontownGlobals.FISH_BINGO, ToontownGlobals.SILLY_SATURDAY): + self.startBingo() + + self.accept('startBingo', self.startBingo) + self.accept('stopBingo', self.stopBingo) + DistributedObjectAI.announceGenerate(self) + + def delete(self): + self.ignoreAll() + DistributedObjectAI.delete(self) def start(self): for _ in xrange(FishingTargetGlobals.getNumTargets(self.area)): fishingTarget = DistributedFishingTargetAI(simbase.air) fishingTarget.setPondDoId(self.doId) fishingTarget.generateWithRequired(self.zoneId) + + def startBingo(self): + if self.bingoMgr: + self.notify.warning('Tried to start bingo while already started!') + return + + self.bingoMgr = DistributedPondBingoManagerAI(self.air) + self.bingoMgr.setPondDoId(self.getDoId()) + self.bingoMgr.generateWithRequired(self.zoneId) + self.bingoMgr.createGame() + + def stopBingo(self): + if not self.bingoMgr: + self.notify.warning('Tried to stop bingo but not started!') + return + + self.bingoMgr.requestDelete() + self.bingoMgr = None def hitTarget(self, target): avId = self.air.getAvatarIdFromSender() diff --git a/toontown/fishing/DistributedPondBingoManager.py b/toontown/fishing/DistributedPondBingoManager.py index ed07b643..5eaa61d0 100755 --- a/toontown/fishing/DistributedPondBingoManager.py +++ b/toontown/fishing/DistributedPondBingoManager.py @@ -49,6 +49,7 @@ class DistributedPondBingoManager(DistributedObject.DistributedObject, FSM.FSM): self.notify.debug('generate: DistributedPondBingoManager') def delete(self): + self.pond.resetSpotGui() del self.pond.pondBingoMgr self.pond.pondBingoMgr = None del self.pond @@ -58,7 +59,6 @@ class DistributedPondBingoManager(DistributedObject.DistributedObject, FSM.FSM): del self.card self.notify.debug('delete: Deleting Local PondManager %s' % self.doId) DistributedObject.DistributedObject.delete(self) - return def d_cardUpdate(self, cellId, genus, species): self.sendUpdate('cardUpdate', [self.cardId, @@ -121,7 +121,7 @@ class DistributedPondBingoManager(DistributedObject.DistributedObject, FSM.FSM): self.card.hide() def showCard(self): - if (self.state != 'Off' or self.state != 'CloseEvent') and self.card.getGame(): + if self.state != 'Off' and self.card.getGame() != None: self.card.loadCard() self.card.show() elif self.state == 'GameOver': @@ -283,8 +283,6 @@ class DistributedPondBingoManager(DistributedObject.DistributedObject, FSM.FSM): return (request, args) elif request == 'Intermission': return (request, args) - elif request == 'CloseEvent': - return 'CloseEvent' elif request == 'Off': return 'Off' else: @@ -305,8 +303,6 @@ class DistributedPondBingoManager(DistributedObject.DistributedObject, FSM.FSM): return (request, args) elif request == 'Intermission': return (request, args) - elif request == 'CloseEvent': - return 'CloseEvent' elif request == 'Off': return 'Off' else: @@ -338,17 +334,3 @@ class DistributedPondBingoManager(DistributedObject.DistributedObject, FSM.FSM): def exitIntermission(self): self.notify.debug('enterIntermission: Exit Intermission State') - - def enterCloseEvent(self, timestamp): - self.notify.debug('enterCloseEvent: Enter CloseEvent State') - self.card.hide() - self.pond.resetSpotGui() - - def filterCloseEvent(self, request, args): - if request == 'Off': - return 'Off' - else: - self.notify.warning('filterOff: Invalid State Transition from GameOver to %s' % request) - - def exitCloseEvent(self): - self.notify.debug('exitCloseEvent: Exit CloseEvent State') diff --git a/toontown/fishing/DistributedPondBingoManagerAI.py b/toontown/fishing/DistributedPondBingoManagerAI.py index f5d6e3e4..bcdab127 100755 --- a/toontown/fishing/DistributedPondBingoManagerAI.py +++ b/toontown/fishing/DistributedPondBingoManagerAI.py @@ -1,18 +1,16 @@ from direct.directnotify import DirectNotifyGlobal from direct.distributed.DistributedObjectAI import DistributedObjectAI +from direct.distributed.ClockDelta import * from toontown.fishing import BingoGlobals from toontown.fishing import FishGlobals -from toontown.toonbase import ToontownGlobals from toontown.fishing.NormalBingo import NormalBingo from toontown.fishing.ThreewayBingo import ThreewayBingo from toontown.fishing.DiagonalBingo import DiagonalBingo from toontown.fishing.BlockoutBingo import BlockoutBingo from toontown.fishing.FourCornerBingo import FourCornerBingo -from direct.task import Task -from direct.distributed.ClockDelta import * -import random, datetime -RequestCard = {} +import random +RequestCard = {} class DistributedPondBingoManagerAI(DistributedObjectAI): notify = DirectNotifyGlobal.directNotify.newCategory("DistributedPondBingoManagerAI") @@ -26,35 +24,14 @@ class DistributedPondBingoManagerAI(DistributedObjectAI): self.state = 'Off' self.pond = None self.canCall = False - self.shouldStop = False self.lastUpdate = globalClockDelta.getRealNetworkTime() self.cardId = 0 - - def initTasks(self): - now = datetime.datetime.now() - weekday = now.weekday() - targetday = 2 # Wednesday - if weekday in (3, 4): - targetday = 5 - togo = targetday - weekday - if togo < 0: - togo += 7 - s = now + datetime.timedelta(days=togo) - start = datetime.datetime(s.year, s.month, s.day) - secs = max(0, (start - now).total_seconds()) - self.notify.debug('Today it\'s %d, so we wait for %d, togo: %d %d' % (weekday, targetday, togo, secs)) - taskMgr.doMethodLater(secs, DistributedPondBingoManagerAI.startTask, self.taskName('start'), extraArgs=[self]) - - def startTask(self): - self.notify.debug('Starting game') - - def stop(task): - self.notify.debug('Stopping game') - self.shouldStop = True - return task.done - - taskMgr.doMethodLater(24 * 60 * 60, stop, self.taskName('stop')) - self.createGame() + + def delete(self): + taskMgr.remove(self.uniqueName('startWait')) + taskMgr.remove(self.uniqueName('createGame')) + taskMgr.remove(self.uniqueName('finishGame')) + DistributedObjectAI.delete(self) def setPondDoId(self, pondId): self.pond = self.air.doId2do[pondId] @@ -87,12 +64,16 @@ class DistributedPondBingoManagerAI(DistributedObjectAI): elif result == BingoGlobals.UPDATE: self.sendGameStateUpdate(cellId) - def d_enableBingo(self): - self.sendUpdate('enableBingo', []) - def handleBingoCall(self, cardId): avId = self.air.getAvatarIdFromSender() + av = self.air.doId2do.get(avId) + + if not av: + self.air.writeServerEvent('suspicious', avId, 'Toon tried to call bingo while not on district!') + return + spot = self.pond.hasToon(avId) + if not spot: self.air.writeServerEvent('suspicious', avId, 'Toon tried to call bingo while not fishing!') return @@ -102,7 +83,7 @@ class DistributedPondBingoManagerAI(DistributedObjectAI): if cardId != self.cardId: self.air.writeServerEvent('suspicious', avId, 'Toon tried to call bingo with an expired cardId!') return - av = self.air.doId2do[avId] + av.d_announceBingo() self.rewardAll() @@ -158,40 +139,25 @@ class DistributedPondBingoManagerAI(DistributedObjectAI): continue av = self.air.doId2do[self.pond.spots[spot].avId] av.addMoney(self.jackpot) - if self.shouldStop: - self.stopGame() - return - taskMgr.doMethodLater(5, DistributedPondBingoManagerAI.startWait, 'startWait%d' % self.getDoId(), [self]) - taskMgr.remove('finishGame%d' % self.getDoId()) + taskMgr.doMethodLater(5, self.startWait, self.uniqueName('startWait')) + taskMgr.remove(self.uniqueName('finishGame')) - def finishGame(self): + def finishGame(self, task=None): self.state = 'GameOver' self.sendStateUpdate() - if self.shouldStop: - self.stopGame() - return - taskMgr.doMethodLater(5, DistributedPondBingoManagerAI.startWait, 'startWait%d' % self.getDoId(), [self]) - - def stopGame(self): - self.state = 'CloseEvent' - self.sendStateUpdate() - taskMgr.doMethodLater(10, DistributedPondBingoManagerAI.turnOff, 'turnOff%d' % self.getDoId(), [self]) - - def turnOff(self): - self.state = 'Off' - self.sendStateUpdate() + taskMgr.doMethodLater(5, self.startWait, self.uniqueName('startWait')) def startIntermission(self): self.state = 'Intermission' self.sendStateUpdate() - taskMgr.doMethodLater(300, DistributedPondBingoManagerAI.startWait, 'startWait%d' % self.getDoId(), [self]) + taskMgr.doMethodLater(300, self.startWait, self.uniqueName('startWait')) - def startWait(self): + def startWait(self, task=None): self.state = 'WaitCountdown' self.sendStateUpdate() - taskMgr.doMethodLater(15, DistributedPondBingoManagerAI.createGame, 'createGame%d' % self.getDoId(), [self]) + taskMgr.doMethodLater(15, self.createGame, self.uniqueName('createGame')) - def createGame(self): + def createGame(self, task=None): self.canCall = False self.tileSeed = None self.typeId = None @@ -223,4 +189,4 @@ class DistributedPondBingoManagerAI(DistributedObjectAI): self.b_setJackpot(BingoGlobals.getJackpot(self.typeId)) self.state = 'Playing' self.sendStateUpdate() - taskMgr.doMethodLater(BingoGlobals.getGameTime(self.typeId), DistributedPondBingoManagerAI.finishGame, 'finishGame%d' % self.getDoId(), [self]) + taskMgr.doMethodLater(BingoGlobals.getGameTime(self.typeId), self.finishGame, self.uniqueName('finishGame')) diff --git a/toontown/hood/HoodAI.py b/toontown/hood/HoodAI.py index 8b0446ad..8ba9b854 100755 --- a/toontown/hood/HoodAI.py +++ b/toontown/hood/HoodAI.py @@ -5,7 +5,6 @@ from toontown.fishing.DistributedFishingPondAI import DistributedFishingPondAI from toontown.hood import ZoneUtil from toontown.safezone import TreasureGlobals from toontown.safezone.DistributedFishingSpotAI import DistributedFishingSpotAI -from toontown.fishing.DistributedPondBingoManagerAI import DistributedPondBingoManagerAI from toontown.safezone.DistributedPartyGateAI import DistributedPartyGateAI from toontown.safezone.SZTreasurePlannerAI import SZTreasurePlannerAI from toontown.suit import DistributedSuitPlannerAI @@ -90,12 +89,6 @@ class HoodAI: fishingPond.setArea(area) fishingPond.generateWithRequired(zoneId) fishingPond.start() - - fishingPond.bingoMgr = DistributedPondBingoManagerAI(simbase.air) - fishingPond.bingoMgr.setPondDoId(fishingPond.getDoId()) - fishingPond.bingoMgr.generateWithRequired(zoneId) - fishingPond.bingoMgr.initTasks() - fishingPonds.append(fishingPond) elif isinstance(dnaGroup, DNAVisGroup): zoneId = int(dnaGroup.getName().split(':')[0]) diff --git a/toontown/makeatoon/BodyShop.py b/toontown/makeatoon/BodyShop.py index 1ed6b4bd..9188e360 100755 --- a/toontown/makeatoon/BodyShop.py +++ b/toontown/makeatoon/BodyShop.py @@ -18,7 +18,6 @@ class BodyShop(StateData.StateData): self.legChoice = 0 self.headChoice = 0 self.speciesChoice = 0 - return def enter(self, toon, shopsVisited = []): base.disableMouse() diff --git a/toontown/makeatoon/ShuffleButton.py b/toontown/makeatoon/ShuffleButton.py index 47168fbc..46869042 100755 --- a/toontown/makeatoon/ShuffleButton.py +++ b/toontown/makeatoon/ShuffleButton.py @@ -51,7 +51,6 @@ class ShuffleButton: self.incBtnShowLerp = LerpColorInterval(self.incBtn, self.lerpDuration, Vec4(1, 1, 1, 1), Vec4(1, 1, 1, 0)) self.decBtnShowLerp = LerpColorInterval(self.decBtn, self.lerpDuration, Vec4(1, 1, 1, 1), Vec4(1, 1, 1, 0)) self.__updateArrows() - return def unload(self): if self.showLerp: diff --git a/toontown/safezone/DistributedFishingSpot.py b/toontown/safezone/DistributedFishingSpot.py index e757171c..078f197f 100755 --- a/toontown/safezone/DistributedFishingSpot.py +++ b/toontown/safezone/DistributedFishingSpot.py @@ -661,6 +661,8 @@ class DistributedFishingSpot(DistributedObject.DistributedObject): jar.setPos(0, 0, 0) def resetCastGui(self): + if not self.castGui: + return self.notify.debug('resetCastGui: Bingo Night Ends - resetting Gui') bucket = self.castGui.find('**/bucket') jar = self.castGui.find('**/jar') From 80b5e4c5489daf07c7659bacb64ec2d6a0b8092c Mon Sep 17 00:00:00 2001 From: John Date: Sat, 8 Aug 2015 13:32:48 +0300 Subject: [PATCH 05/38] New magic word: ~secondVP - skips to second battle --- toontown/suit/DistributedCashbotBoss.py | 2 +- toontown/suit/DistributedSellbotBossAI.py | 33 ++++++++++++++--------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/toontown/suit/DistributedCashbotBoss.py b/toontown/suit/DistributedCashbotBoss.py index 2b89025c..cda0e73a 100755 --- a/toontown/suit/DistributedCashbotBoss.py +++ b/toontown/suit/DistributedCashbotBoss.py @@ -38,7 +38,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM): def __init__(self, cr): DistributedBossCog.DistributedBossCog.__init__(self, cr) - FSM.FSM.__init__(self, 'DistributedSellbotBoss') + FSM.FSM.__init__(self, 'DistributedCashbotBoss') self.resistanceToon = None self.resistanceToonOnstage = 0 self.cranes = {} diff --git a/toontown/suit/DistributedSellbotBossAI.py b/toontown/suit/DistributedSellbotBossAI.py index 82a740a2..40f42cfa 100755 --- a/toontown/suit/DistributedSellbotBossAI.py +++ b/toontown/suit/DistributedSellbotBossAI.py @@ -403,18 +403,32 @@ class DistributedSellbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FS def enterReward(self): DistributedBossCogAI.DistributedBossCogAI.enterReward(self) +def getVP(invoker): + for do in simbase.air.doId2do.values(): + if isinstance(do, DistributedSellbotBossAI): + if invoker.doId in do.involvedToons: + return do + +@magicWord(category=CATEGORY_ADMINISTRATOR) +def secondVP(): + """ + Skips to the second round of the VP. + """ + invoker = spellbook.getInvoker() + boss = getVP(invoker) + if not boss: + return "You aren't in a VP!" + boss.exitIntroduction() + boss.b_setState('RollToBattleTwo') + return 'Skipping to the second round...' + @magicWord(category=CATEGORY_ADMINISTRATOR) def skipVP(): """ Skips to the final round of the VP. """ invoker = spellbook.getInvoker() - boss = None - for do in simbase.air.doId2do.values(): - if isinstance(do, DistributedSellbotBossAI): - if invoker.doId in do.involvedToons: - boss = do - break + boss = getVP(invoker) if not boss: return "You aren't in a VP!" if boss.state in ('PrepareBattleThree', 'BattleThree'): @@ -429,12 +443,7 @@ def killVP(): Kills the VP. """ invoker = spellbook.getInvoker() - boss = None - for do in simbase.air.doId2do.values(): - if isinstance(do, DistributedSellbotBossAI): - if invoker.doId in do.involvedToons: - boss = do - break + boss = getVP(invoker) if not boss: return "You aren't in a VP!" boss.b_setState('Victory') From a2d5b004c99e9fc332fc43d48898dc9b2fe886cf Mon Sep 17 00:00:00 2001 From: John Date: Sun, 9 Aug 2015 13:41:30 +0300 Subject: [PATCH 06/38] Holocaust fire cost --- toontown/battle/FireCogPanel.py | 15 ++++++++------- toontown/toon/InventoryNew.py | 2 +- toontown/town/TownBattle.py | 9 +-------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/toontown/battle/FireCogPanel.py b/toontown/battle/FireCogPanel.py index f6c7f564..45a94da7 100755 --- a/toontown/battle/FireCogPanel.py +++ b/toontown/battle/FireCogPanel.py @@ -47,7 +47,7 @@ class FireCogPanel(StateData.StateData): del self.backButton self.loaded = 0 - def enter(self, numAvatars, localNum = None, luredIndices = None, trappedIndices = None, track = None, fireCosts = None): + def enter(self, numAvatars, localNum = None, luredIndices = None, trappedIndices = None, track = None): if not self.loaded: self.load() self.frame.show() @@ -59,7 +59,7 @@ class FireCogPanel(StateData.StateData): if len(trappedIndices) > 0: if track == BattleBase.TRAP: invalidTargets += trappedIndices - self.__placeButtons(numAvatars, invalidTargets, localNum, fireCosts) + self.__placeButtons(numAvatars, invalidTargets, localNum) def exit(self): self.frame.hide() @@ -87,23 +87,24 @@ class FireCogPanel(StateData.StateData): def adjustToons(self, numToons, localNum): self.__placeButtons(numToons, [], localNum) - def __placeButtons(self, numAvatars, invalidTargets, localNum, fireCosts): - canfire = 0 + def __placeButtons(self, numAvatars, invalidTargets, localNum): + canFire = 0 + for i in xrange(4): if numAvatars > i and i not in invalidTargets and i != localNum: self.avatarButtons[i].show() self.avatarButtons[i]['text'] = '' - if fireCosts[i] <= localAvatar.getPinkSlips(): + if localAvatar.getPinkSlips(): self.avatarButtons[i]['state'] = DGG.NORMAL self.avatarButtons[i]['text_fg'] = (0, 0, 0, 1) - canfire = 1 + canFire = 1 else: self.avatarButtons[i]['state'] = DGG.DISABLED self.avatarButtons[i]['text_fg'] = (1.0, 0, 0, 1) else: self.avatarButtons[i].hide() - if canfire: + if canFire: self.textFrame['text'] = TTLocalizer.FireCogTitle % localAvatar.getPinkSlips() else: self.textFrame['text'] = TTLocalizer.FireCogLowTitle % localAvatar.getPinkSlips() diff --git a/toontown/toon/InventoryNew.py b/toontown/toon/InventoryNew.py index 4eb458fa..5e2585a8 100755 --- a/toontown/toon/InventoryNew.py +++ b/toontown/toon/InventoryNew.py @@ -773,7 +773,7 @@ class InventoryNew(InventoryBase.InventoryBase, DirectFrame): self.sosButton.show() self.passButton.show() self.fireButton.show() - if localAvatar.getPinkSlips() > 0: + if localAvatar.getPinkSlips(): self.fireButton['state'] = DGG.NORMAL self.fireButton['image_color'] = Vec4(0, 0.6, 1, 1) else: diff --git a/toontown/town/TownBattle.py b/toontown/town/TownBattle.py index 2f788092..e44e7862 100755 --- a/toontown/town/TownBattle.py +++ b/toontown/town/TownBattle.py @@ -122,10 +122,6 @@ class TownBattle(StateData.StateData): self.SOSPetInfoPanel = TownBattleSOSPetInfoPanel.TownBattleSOSPetInfoPanel(self.SOSPetInfoPanelDoneEvent) self.fireCogPanelDoneEvent = 'fire-cog-panel-done' self.FireCogPanel = FireCogPanel.FireCogPanel(self.fireCogPanelDoneEvent) - self.cogFireCosts = [None, - None, - None, - None] self.toonPanels = (TownBattleToonPanel.TownBattleToonPanel(0), TownBattleToonPanel.TownBattleToonPanel(1), TownBattleToonPanel.TownBattleToonPanel(2), @@ -460,11 +456,8 @@ class TownBattle(StateData.StateData): toonIds = map(lambda toon: toon.doId, toons) self.notify.debug('adjustCogsAndToons() toonIds: %s self.toons: %s' % (toonIds, self.toons)) maxSuitLevel = 0 - cogFireCostIndex = 0 for cog in cogs: maxSuitLevel = max(maxSuitLevel, cog.getActualLevel()) - self.cogFireCosts[cogFireCostIndex] = 1 - cogFireCostIndex += 1 creditLevel = maxSuitLevel resetActivateMode = 0 @@ -603,7 +596,7 @@ class TownBattle(StateData.StateData): def enterFire(self): canHeal, canTrap, canLure = self.checkHealTrapLure() - self.FireCogPanel.enter(self.numCogs, luredIndices=self.luredIndices, trappedIndices=self.trappedIndices, track=self.track, fireCosts=self.cogFireCosts) + self.FireCogPanel.enter(self.numCogs, luredIndices=self.luredIndices, trappedIndices=self.trappedIndices, track=self.track) self.accept(self.fireCogPanelDoneEvent, self.__handleCogFireDone) return None From 7019d1ba9a834a924bc17887f1a21bcb713128e1 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 9 Aug 2015 14:32:13 +0300 Subject: [PATCH 07/38] Rewritten (no pun intended) cog panel --- toontown/suit/Suit.py | 11 ++ toontown/suit/SuitHealthBar.py | 130 +++++++++++++++ toontown/town/TownBattle.py | 69 ++------ toontown/town/TownBattleCogPanel.py | 242 +++++----------------------- 4 files changed, 193 insertions(+), 259 deletions(-) create mode 100644 toontown/suit/SuitHealthBar.py diff --git a/toontown/suit/Suit.py b/toontown/suit/Suit.py index f2b734f5..9c32aa7e 100755 --- a/toontown/suit/Suit.py +++ b/toontown/suit/Suit.py @@ -773,3 +773,14 @@ class Suit(Avatar.Avatar): return SkelSuitDialogArray else: return SuitDialogArray + + def getTypeText(self): + if self.virtual: + return TTLocalizer.CogPanelVirtual + elif self.isWaiter: + return TTLocalizer.CogPanelWaiter + elif self.skeleRevives: + return TTLocalizer.CogPanelRevives % (self.skeleRevives + 1) + elif self.isSkelecog: + return TTLocalizer.CogPanelSkeleton + return '' \ No newline at end of file diff --git a/toontown/suit/SuitHealthBar.py b/toontown/suit/SuitHealthBar.py new file mode 100644 index 00000000..398bad44 --- /dev/null +++ b/toontown/suit/SuitHealthBar.py @@ -0,0 +1,130 @@ +from direct.task import Task +from toontown.battle import BattleProps + +class SuitHealthBar: + healthColors = ((0, 1, 0, 1), + (0.5, 1, 0, 1), + (0.75, 1, 0, 1), + (1, 1, 0, 1), + (1, 0.86, 0, 1), + (1, 0.6, 0, 1), + (1, 0.5, 0, 1), + (1, 0.25, 0, 1.0), + (1, 0, 0, 1), + (0.3, 0.3, 0.3, 1)) + healthGlowColors = ((0.25, 1, 0.25, 0.5), + (0.5, 1, 0.25, .5), + (0.75, 1, 0.25, .5), + (1, 1, 0.25, 0.5), + (1, 0.866, 0.25, .5), + (1, 0.6, 0.25, .5), + (1, 0.5, 0.25, 0.5), + (1, 0.25, 0.25, 0.5), + (1, 0.25, 0.25, 0.5), + (0.3, 0.3, 0.3, 0)) + + def __init__(self): + print 'New Healthbar' + self.geom = None + self.geomGlow = None + self.healthCondition = 0 + + def delete(self): + print 'Deleting' + if self.geom: + self.geom.removeNode() + self.geom = None + self.geomGlow = None + taskMgr.remove('blink-task-%s' % id(self)) + self.healthCondition = 0 + print 'Deleted' + + def generate(self): + print 'Generating' + self.delete() + model = loader.loadModel('phase_3.5/models/gui/matching_game_gui') + button = model.find('**/minnieCircle') + model.removeNode() + + button.setH(180.0) + button.setColor(self.healthColors[0]) + self.geom = button + + glow = BattleProps.globalPropPool.getProp('glow') + glow.reparentTo(self.geom) + glow.setScale(0.28) + glow.setPos(-0.005, 0.01, 0.015) + glow.setColor(self.healthGlowColors[0]) + + button.flattenLight() + self.geomGlow = glow + self.geom.hide() + self.healthCondition = 0 + print 'Generated' + + def getHealthCondition(self, health): + if health > 0.95: + return 0 + elif health > 0.9: + return 1 + elif health > 0.8: + return 2 + elif health > 0.7: + return 3 + elif health > 0.6: + return 4 + elif health > 0.5: + return 5 + elif health > 0.3: + return 6 + elif health > 0.15: + return 7 + elif health > 0.05: + return 8 + elif health > 0.0: + return 9 + return 10 + + def update(self, hp, forceUpdate = 0): + if not self.geom: + print 'Not generated yet' + return + print 'Updating: %s %s' % (hp, forceUpdate) + condition = self.getHealthCondition(hp) + + if self.healthCondition != condition or forceUpdate: + taskMgr.remove('blink-task-%s' % id(self)) + + if condition in (9, 10): + blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75 if condition == 9 else 0.25), Task(self.__blinkGray), Task.pause(0.1)) + taskMgr.add(blinkTask, 'blink-task-%s' % id(self)) + else: + self.geom.setColor(self.healthColors[condition], 1) + self.geomGlow.setColor(self.healthGlowColors[condition], 1) + + self.healthCondition = condition + print 'Updated' + + def __blinkRed(self, task): + if not self.geom: + return + + print 'Blinking Red' + self.geom.setColor(self.healthColors[8], 1) + self.geomGlow.setColor(self.healthGlowColors[8], 1) + + if self.healthCondition == 7: + self.geom.setScale(1.17) + print 'Blinked Red' + + def __blinkGray(self, task): + if not self.geom: + return + + print 'Blinking Gray' + self.geom.setColor(self.healthColors[9], 1) + self.geomGlow.setColor(self.healthGlowColors[9], 1) + + if self.healthCondition == 10: + self.geom.setScale(1.0) + print 'Blinked Gray' \ No newline at end of file diff --git a/toontown/town/TownBattle.py b/toontown/town/TownBattle.py index e44e7862..b44cdc32 100755 --- a/toontown/town/TownBattle.py +++ b/toontown/town/TownBattle.py @@ -122,19 +122,12 @@ class TownBattle(StateData.StateData): self.SOSPetInfoPanel = TownBattleSOSPetInfoPanel.TownBattleSOSPetInfoPanel(self.SOSPetInfoPanelDoneEvent) self.fireCogPanelDoneEvent = 'fire-cog-panel-done' self.FireCogPanel = FireCogPanel.FireCogPanel(self.fireCogPanelDoneEvent) - self.toonPanels = (TownBattleToonPanel.TownBattleToonPanel(0), - TownBattleToonPanel.TownBattleToonPanel(1), - TownBattleToonPanel.TownBattleToonPanel(2), - TownBattleToonPanel.TownBattleToonPanel(3)) - self.cogPanels = (TownBattleCogPanel.TownBattleCogPanel(0), - TownBattleCogPanel.TownBattleCogPanel(1), - TownBattleCogPanel.TownBattleCogPanel(2), - TownBattleCogPanel.TownBattleCogPanel(3)) + self.toonPanels = [TownBattleToonPanel.TownBattleToonPanel(i) for i in xrange(4)] + self.cogPanels = [TownBattleCogPanel.TownBattleCogPanel(i) for i in xrange(4)] self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.setScale(0.4) self.timer.hide() - return def cleanup(self): self.ignore(self.attackPanelDoneEvent) @@ -150,11 +143,9 @@ class TownBattle(StateData.StateData): del self.FireCogPanel del self.SOSPetSearchPanel del self.SOSPetInfoPanel - for toonPanel in self.toonPanels: - toonPanel.cleanup() - for cogPanel in self.cogPanels: - cogPanel.cleanup() + for panel in self.toonPanels + self.cogPanels: + panel.cleanup() del self.toonPanels del self.cogPanels @@ -167,7 +158,6 @@ class TownBattle(StateData.StateData): self.parentFSMState.addChild(self.fsm) if not self.isLoaded: self.load() - print 'Battle Event %s' % event self.battleEvent = event self.fsm.enterInitialState() base.localAvatar.laffMeter.start() @@ -182,7 +172,6 @@ class TownBattle(StateData.StateData): base.localAvatar.inventory.setBattleCreditMultiplier(self.creditMultiplier) base.localAvatar.inventory.setActivateMode('battle', heal=0, bldg=bldg, tutorialFlag=tutorialFlag) self.SOSPanel.bldg = bldg - return def exit(self): base.localAvatar.laffMeter.stop() @@ -231,44 +220,21 @@ class TownBattle(StateData.StateData): for toonPanel in self.toonPanels: toonPanel.hide() toonPanel.setPos(0, 0, -0.9) - - if num == 1: - self.toonPanels[0].setX(self.oddPos[1]) - self.toonPanels[0].show() - elif num == 2: - self.toonPanels[0].setX(self.evenPos[1]) - self.toonPanels[0].show() - self.toonPanels[1].setX(self.evenPos[2]) - self.toonPanels[1].show() - elif num == 3: - self.toonPanels[0].setX(self.oddPos[0]) - self.toonPanels[0].show() - self.toonPanels[1].setX(self.oddPos[1]) - self.toonPanels[1].show() - self.toonPanels[2].setX(self.oddPos[2]) - self.toonPanels[2].show() - elif num == 4: - self.toonPanels[0].setX(self.evenPos[0]) - self.toonPanels[0].show() - self.toonPanels[1].setX(self.evenPos[1]) - self.toonPanels[1].show() - self.toonPanels[2].setX(self.evenPos[2]) - self.toonPanels[2].show() - self.toonPanels[3].setX(self.evenPos[3]) - self.toonPanels[3].show() - else: - self.notify.error('Bad number of toons: %s' % num) - return None + + self.positionPanels(num, self.toonPanels) def __enterCogPanels(self, num): for cogPanel in self.cogPanels: cogPanel.hide() cogPanel.updateHealthBar() cogPanel.setPos(0, 0, 0.62) - + + self.positionPanels(num, self.cogPanels) + + def positionPanels(self, num, panels): pos = self.evenPos if num % 2 == 0 else self.oddPos - for i, panel in enumerate(self.cogPanels): + for i, panel in enumerate(panels): if num > i: panel.setX(pos[i if num >= 3 else i + 1]) panel.show() @@ -460,18 +426,7 @@ class TownBattle(StateData.StateData): maxSuitLevel = max(maxSuitLevel, cog.getActualLevel()) creditLevel = maxSuitLevel - resetActivateMode = 0 - if numCogs == self.numCogs and creditLevel == self.creditLevel and luredIndices == self.luredIndices and trappedIndices == self.trappedIndices and toonIds == self.toons: - for i in xrange(len(cogs)): - if cogs[i].getHP() == self.cogPanels[i].getDisplayedCurrHp(): - if cogs[i].getMaxHP() == self.cogPanels[i].getDisplayedMaxHp(): - if cogs[i] == self.cogPanels[i].getSuit(): - continue - else: - resetActivateMode = 1 - break - else: - resetActivateMode = 1 + resetActivateMode = numCogs != self.numCogs or creditLevel != self.creditLevel or luredIndices != self.luredIndices or trappedIndices != self.trappedIndices or toonIds != self.toons self.notify.debug('adjustCogsAndToons() resetActivateMode: %s' % resetActivateMode) self.numCogs = numCogs self.creditLevel = creditLevel diff --git a/toontown/town/TownBattleCogPanel.py b/toontown/town/TownBattleCogPanel.py index 07f04e35..f68b00c7 100755 --- a/toontown/town/TownBattleCogPanel.py +++ b/toontown/town/TownBattleCogPanel.py @@ -1,228 +1,66 @@ -from panda3d.core import * -from toontown.battle import BattleProps -from toontown.toonbase import ToontownGlobals -from toontown.toonbase.ToontownBattleGlobals import * -from direct.directnotify import DirectNotifyGlobal -import string -from toontown.suit import Suit from direct.gui.DirectGui import * +from toontown.suit import Suit, SuitHealthBar from toontown.toonbase import TTLocalizer -from direct.task.Task import Task class TownBattleCogPanel(DirectFrame): - notify = DirectNotifyGlobal.directNotify.newCategory('TownBattleCogPanel') - healthColors = (Vec4(0, 1, 0, 1),# 0 Green - Vec4(0.5, 1, 0, 1),#1 Green-Yellow - Vec4(0.75, 1, 0, 1),#2 Yellow-Green - Vec4(1, 1, 0, 1),#3 Yellow - Vec4(1, 0.866, 0, 1),#4 Yellow-Orange - Vec4(1, 0.6, 0, 1),#5 Orange-Yellow - Vec4(1, 0.5, 0, 1),#6 Orange - Vec4(1, 0.25, 0, 1.0),#7 Red-Orange - Vec4(1, 0, 0, 1),#8 Red - Vec4(0.3, 0.3, 0.3, 1))#9 Grey - healthGlowColors = (Vec4(0.25, 1, 0.25, 0.5),#Green - Vec4(0.5, 1, 0.25, .5),#1 Green-Yellow - Vec4(0.75, 1, 0.25, .5),#2 Yellow-Green - Vec4(1, 1, 0.25, 0.5),#Yellow - Vec4(1, 0.866, 0.25, .5),#4 Yellow-Orange - Vec4(1, 0.6, 0.25, .5),#5 Orange-Yellow - Vec4(1, 0.5, 0.25, 0.5),#6 Orange - Vec4(1, 0.25, 0.25, 0.5),#7 Red-Orange - Vec4(1, 0.25, 0.25, 0.5),#8 Red - Vec4(0.3, 0.3, 0.3, 0))#9 Grey def __init__(self, id): gui = loader.loadModel('phase_3.5/models/gui/battle_gui') - DirectFrame.__init__(self, relief=None, image=gui.find('**/ToonBtl_Status_BG'), image_color=Vec4(0.86, 0.86, 0.86, 0.7)) - self.setScale(0.8) + DirectFrame.__init__(self, relief=None, image=gui.find('**/ToonBtl_Status_BG'), image_color=(0.86, 0.86, 0.86, 0.7), scale=0.8) self.initialiseoptions(TownBattleCogPanel) self.levelText = DirectLabel(parent=self, text='', pos=(-0.06, 0, -0.075), text_scale=0.055) - self.suitType = DirectLabel(parent=self, text='', pos=(0.12, 0, -0.075), text_scale=0.045) - self.healthBar = None - self.healthBarGlow = None - self.hpChangeEvent = None - self.blinkTask = None - self.suit = None - self.head = None - self.maxHP = None - self.currHP = None - self.hpChangeEvent = None + self.typeText = DirectLabel(parent=self, text='', pos=(0.12, 0, -0.075), text_scale=0.045) + self.healthBar = SuitHealthBar.SuitHealthBar() self.generateHealthBar() + self.suit = None + self.suitHead = None self.hide() gui.removeNode() - return + + def cleanup(self): + self.ignoreAll() + self.cleanupHead() + self.levelText.removeNode() + self.typeText.removeNode() + self.healthBar.delete() + del self.levelText + del self.typeText + del self.healthBar + DirectFrame.destroy(self) + + def cleanupHead(self): + if self.suitHead: + self.suitHead.removeNode() + del self.suitHead def setSuit(self, suit): if self.suit == suit: messenger.send(self.suit.uniqueName('hpChange')) return + + self.ignoreAll() + self.cleanupHead() self.suit = suit - self.setLevelText(self.suit.getActualLevel()) - if self.head: - self.head.removeNode() - self.setSuitHead(self.suit.getStyleName()) - self.setMaxHp(self.suit.getMaxHP()) - self.setHp(self.suit.getHP()) - self.hpChangeEvent = self.suit.uniqueName('hpChange') - if self.blinkTask: - taskMgr.remove(self.blinkTask) - self.blinkTask = None - self.accept(self.hpChangeEvent, self.updateHealthBar) + self.generateSuitHead(suit.getStyleName()) self.updateHealthBar() - self.healthBar.show() - if self.suit.virtual: - self.setTypeText(TTLocalizer.CogPanelVirtual) - elif self.suit.isWaiter: - self.setTypeText(TTLocalizer.CogPanelWaiter) - elif self.suit.skeleRevives: - self.setTypeText(TTLocalizer.CogPanelRevives % (self.suit.skeleRevives + 1)) - elif self.suit.isSkelecog: - self.setTypeText(TTLocalizer.CogPanelSkeleton) - else: - self.setTypeText('') - - def getSuit(self, suit): - return self.suit - - def setLevelText(self, level): - self.levelText['text'] = TTLocalizer.CogPanelLevel % level - - def setTypeText(self, suitType): - self.suitType['text'] = suitType - - def setSuitHead(self, suitName): - self.head = Suit.attachSuitHead(self, suitName) - self.head.setX(0.1) - self.head.setZ(0.01) - self.head.setScale(0.05) + self.levelText['text'] = TTLocalizer.CogPanelLevel % suit.getActualLevel() + self.typeText['text'] = suit.getTypeText() + self.accept(suit.uniqueName('hpChange'), self.updateHealthBar) + def generateSuitHead(self, name): + self.suitHead = Suit.attachSuitHead(self, name) + self.suitHead.setScale(0.05) + self.suitHead.setPos(0.1, 0, 0.01) + def generateHealthBar(self): - model = loader.loadModel('phase_3.5/models/gui/matching_game_gui') - button = model.find('**/minnieCircle') - model.removeNode() - button.setScale(0.5) - button.setH(180.0) - button.setColor(self.healthColors[0]) - button.reparentTo(self) - button.setX(-0.065) - button.setZ(0.05) - self.healthBar = button - glow = BattleProps.globalPropPool.getProp('glow') - glow.reparentTo(self.healthBar) - glow.setScale(0.28) - glow.setPos(-0.005, 0.01, 0.015) - glow.setColor(self.healthGlowColors[0]) - button.flattenLight() - self.healthBarGlow = glow - self.healthBar.hide() - self.healthCondition = 0 + self.healthBar.generate() + self.healthBar.geom.reparentTo(self) + self.healthBar.geom.setScale(0.5) + self.healthBar.geom.setPos(-0.065, 0, 0.05) + self.healthBar.geom.show() def updateHealthBar(self): if not self.suit: return - self.setHp(self.suit.getHP()) - health = float(self.currHP) / float(self.maxHP) - if health > 0.95: - condition = 0 - elif health > 0.9: - condition = 1 - elif health > 0.8: - condition = 2 - elif health > 0.7: - condition = 3#Yellow - elif health > 0.6: - condition = 4 - elif health > 0.5: - condition = 5 - elif health > 0.3: - condition = 6#Orange - elif health > 0.15: - condition = 7 - elif health > 0.05: - condition = 8#Red - elif health > 0.0: - condition = 9#Blinking Red - else: - condition = 10 - if self.healthCondition != condition: - if condition == 9: - self.blinkTask = self.uniqueName('blink-task') - blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) - taskMgr.add(blinkTask, self.blinkTask) - elif condition == 10: - if self.healthCondition == 9: - self.blinkTask = self.uniqueName('blink-task') - taskMgr.remove(self.blinkTask) - self.blinkTask = None - blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) - taskMgr.add(blinkTask, self.blinkTask) - else: - if self.blinkTask: - taskMgr.remove(self.blinkTask) - self.blinkTask = None - self.healthBar.setColor(self.healthColors[condition], 1) - self.healthBarGlow.setColor(self.healthGlowColors[condition], 1) - self.healthCondition = condition - def __blinkRed(self, task): - if not self.blinkTask or not self.healthBar: - return Task.done - self.healthBar.setColor(self.healthColors[8], 1) - self.healthBarGlow.setColor(self.healthGlowColors[8], 1) - if self.healthCondition == 7: - self.healthBar.setScale(1.17) - return Task.done - - def __blinkGray(self, task): - if not self.blinkTask or not self.healthBar: - return Task.done - self.healthBar.setColor(self.healthColors[9], 1) - self.healthBarGlow.setColor(self.healthGlowColors[9], 1) - if self.healthCondition == 10: - self.healthBar.setScale(1.0) - return Task.done - - def removeHealthBar(self): - if self.healthCondition == 9 or self.healthCondition == 10: - if self.blinkTask: - taskMgr.remove(self.blinkTask) - self.blinkTask = None - if self.healthBar: - self.healthBar.removeNode() - self.healthBar = None - self.healthCondition = 0 - return - - def getDisplayedCurrHp(self): - return self.currHP - - def getDisplayedMaxHp(self): - return self.maxHP - - def setMaxHp(self, hp): - self.maxHP = hp - - def setHp(self, hp): - self.currHP = hp - - def show(self): - DirectFrame.show(self) - - def cleanup(self): - self.ignoreAll() - self.removeHealthBar() - if self.head is not None: - self.head.removeNode() - del self.head - self.levelText.destroy() - del self.levelText - del self.suitType - del self.healthBar - if self.healthBarGlow is not None: - self.healthBarGlow.removeNode() - del self.healthBarGlow - del self.suit - del self.maxHP - del self.currHP - DirectFrame.destroy(self) + self.healthBar.update(float(self.suit.getHP()) / float(self.suit.getMaxHP())) \ No newline at end of file From 1d8fe20587923746c7289a2167f8bae6040ca837 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 9 Aug 2015 15:23:35 +0300 Subject: [PATCH 08/38] Refactor suit health bar --- toontown/battle/MovieUtil.py | 2 +- toontown/suit/BossCog.py | 113 +++-------------------- toontown/suit/DistributedCashbotBoss.py | 2 +- toontown/suit/DistributedSuitBase.py | 4 +- toontown/suit/Suit.py | 118 ++---------------------- toontown/suit/SuitHealthBar.py | 93 ++++++++----------- 6 files changed, 66 insertions(+), 266 deletions(-) diff --git a/toontown/battle/MovieUtil.py b/toontown/battle/MovieUtil.py index 9d471241..9590761e 100755 --- a/toontown/battle/MovieUtil.py +++ b/toontown/battle/MovieUtil.py @@ -200,7 +200,7 @@ def removeReviveSuit(suit, deathSuit): if not deathSuit.isEmpty(): deathSuit.detachNode() suit.cleanupLoseActor() - suit.healthBar.show() + suit.healthBar.geom.show() suit.resetHealthBarForSkele() diff --git a/toontown/suit/BossCog.py b/toontown/suit/BossCog.py index a3d861a2..3c96a4f0 100755 --- a/toontown/suit/BossCog.py +++ b/toontown/suit/BossCog.py @@ -1,23 +1,16 @@ +from panda3d.core import * from direct.actor import Actor from direct.directnotify import DirectNotifyGlobal from direct.fsm import FSM -from direct.fsm import State from direct.interval.IntervalGlobal import * -from direct.showbase.PythonUtil import Functor from direct.task.Task import Task -from panda3d.core import * -import types -import random -import Suit -import SuitDNA from otp.avatar import Avatar -from toontown.battle import BattleParticles -from toontown.battle import BattleProps from otp.nametag.NametagGroup import NametagGroup from otp.nametag.NametagConstants import * -from toontown.toonbase import TTLocalizer -from toontown.toonbase import ToontownGlobals - +from toontown.battle import BattleParticles, BattleProps +from toontown.toonbase import TTLocalizer, ToontownGlobals +import Suit, SuitDNA, SuitHealthBar +import types, random GenericModel = 'phase_9/models/char/bossCog' ModelDict = {'s': 'phase_9/models/char/sellbotBoss', @@ -28,8 +21,6 @@ AnimList = ('Ff_speech', 'ltTurn2Wave', 'wave', 'Ff_lookRt', 'turn2Fb', 'Ff_neut class BossCog(Avatar.Avatar): notify = DirectNotifyGlobal.directNotify.newCategory('BossCog') - healthColors = Suit.Suit.healthColors - healthGlowColors = Suit.Suit.healthGlowColors def __init__(self): Avatar.Avatar.__init__(self) @@ -52,15 +43,14 @@ class BossCog(Avatar.Avatar): self.queuedAnimIvals = [] self.treadsLeftPos = 0 self.treadsRightPos = 0 - self.healthBar = None - self.healthCondition = 0 + self.healthBar = SuitHealthBar.SuitHealthBar() self.animDoneEvent = 'BossCogAnimDone' self.animIvalName = 'BossCogAnimIval' self.warningSfx = loader.loadSfx('phase_9/audio/sfx/CHQ_GOON_tractor_beam_alarmed.ogg') def delete(self): Avatar.Avatar.delete(self) - self.removeHealthBar() + self.healthBar.delete() self.setDizzy(0) self.stopAnimate() if self.doorA: @@ -155,92 +145,17 @@ class BossCog(Avatar.Avatar): self.collNode.setCollideMask(self.collNode.getIntoCollideMask() | ToontownGlobals.PieBitmask) def generateHealthBar(self): - self.removeHealthBar() - chestNull = self.find('**/joint_lifeMeter') - if chestNull.isEmpty(): - return - model = loader.loadModel('phase_3.5/models/gui/matching_game_gui') - button = model.find('**/minnieCircle') - button.setScale(6.0) - button.setP(-20) - button.setColor(self.healthColors[0]) - button.reparentTo(chestNull) - self.healthBar = button - glow = BattleProps.globalPropPool.getProp('glow') - glow.reparentTo(self.healthBar) - glow.setScale(0.28) - glow.setPos(-0.005, 0.01, 0.015) - glow.setColor(self.healthGlowColors[0]) - button.flattenLight() - self.healthBarGlow = glow - self.healthCondition = 0 + self.healthBar.generate() + self.healthBar.geom.reparentTo(self.find('**/joint_lifeMeter')) + self.healthBar.geom.setScale(6.0) + self.healthBar.geom.setHpr(0, -20, 0) + self.healthBar.geom.show() def updateHealthBar(self): - if self.healthBar == None: - return - health = 1.0 - float(self.bossDamage) / float(self.bossMaxDamage) - if health > 0.95: - condition = 0 - elif health > 0.9: - condition = 1 - elif health > 0.8: - condition = 2 - elif health > 0.7: - condition = 3#Yellow - elif health > 0.6: - condition = 4 - elif health > 0.5: - condition = 5 - elif health > 0.3: - condition = 6#Orange - elif health > 0.15: - condition = 7 - elif health > 0.05: - condition = 8#Red - elif health > 0.0: - condition = 9#Blinking Red - else: - condition = 10 - if self.healthCondition != condition: - if condition == 9: - blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) - taskMgr.add(blinkTask, self.uniqueName('blink-task')) - elif condition == 10: - if self.healthCondition == 9: - taskMgr.remove(self.uniqueName('blink-task')) - blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) - taskMgr.add(blinkTask, self.uniqueName('blink-task')) - else: - self.healthBar.setColor(self.healthColors[condition], 1) - self.healthBarGlow.setColor(self.healthGlowColors[condition], 1) - self.healthCondition = condition - - def __blinkRed(self, task): if not self.healthBar: return - self.healthBar.setColor(self.healthColors[8], 1) - self.healthBarGlow.setColor(self.healthGlowColors[8], 1) - if self.healthCondition == 10: - self.healthBar.setScale(1.17) - return Task.done - - def __blinkGray(self, task): - if not self.healthBar: - return - self.healthBar.setColor(self.healthColors[9], 1) - self.healthBarGlow.setColor(self.healthGlowColors[9], 1) - if self.healthCondition == 10: - self.healthBar.setScale(1.0) - return Task.done - - def removeHealthBar(self): - if self.healthBar: - self.healthBar.removeNode() - self.healthBar = None - if self.healthCondition == 9 or self.healthCondition == 10: - taskMgr.remove(self.uniqueName('blink-task')) - self.healthCondition = 0 - return + + self.healthBar.update(1.0 - float(self.bossDamage) / float(self.bossMaxDamage)) def reverseHead(self): self.neck.setHpr(self.neckReversedHpr) diff --git a/toontown/suit/DistributedCashbotBoss.py b/toontown/suit/DistributedCashbotBoss.py index cda0e73a..986214c9 100755 --- a/toontown/suit/DistributedCashbotBoss.py +++ b/toontown/suit/DistributedCashbotBoss.py @@ -784,7 +784,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM): self.stopAnimate() self.cleanupAttacks() self.setDizzy(0) - self.removeHealthBar() + self.healthBar.delete() localAvatar.setCameraFov(ToontownGlobals.CogHQCameraFov) if self.newState != 'Victory': self.battleThreeMusic.stop() diff --git a/toontown/suit/DistributedSuitBase.py b/toontown/suit/DistributedSuitBase.py index e73d727f..4006cfb4 100755 --- a/toontown/suit/DistributedSuitBase.py +++ b/toontown/suit/DistributedSuitBase.py @@ -326,12 +326,12 @@ class DistributedSuitBase(DistributedAvatar.DistributedAvatar, Suit.Suit, SuitBa self.loop('neutral', 0) self.disableBattleDetect() self.corpMedallion.hide() - self.healthBar.show() + self.healthBar.geom.show() if self.currHP < self.maxHP: self.updateHealthBar(0, 1) def exitBattle(self): - self.healthBar.hide() + self.healthBar.geom.hide() self.corpMedallion.show() self.currHP = self.maxHP self.interactivePropTrackBonus = -1 diff --git a/toontown/suit/Suit.py b/toontown/suit/Suit.py index 9c32aa7e..004f8f7b 100755 --- a/toontown/suit/Suit.py +++ b/toontown/suit/Suit.py @@ -2,11 +2,11 @@ from panda3d.core import * from direct.actor import Actor from direct.task.Task import Task from otp.avatar import Avatar -from toontown.battle import BattleProps, SuitBattleGlobals +from toontown.battle import SuitBattleGlobals from otp.nametag.NametagGroup import NametagGroup from toontown.toonbase import TTLocalizer, ToontownGlobals from toontown.suit import SuitGlobals -import SuitDNA, string +import SuitDNA, SuitHealthBar, string aSize = 6.06 bSize = 5.29 @@ -299,26 +299,6 @@ def attachSuitHead(node, suitName): class Suit(Avatar.Avatar): __module__ = __name__ - healthColors = (Vec4(0, 1, 0, 1),# 0 Green - Vec4(0.5, 1, 0, 1),#1 Green-Yellow - Vec4(0.75, 1, 0, 1),#2 Yellow-Green - Vec4(1, 1, 0, 1),#3 Yellow - Vec4(1, 0.866, 0, 1),#4 Yellow-Orange - Vec4(1, 0.6, 0, 1),#5 Orange-Yellow - Vec4(1, 0.5, 0, 1),#6 Orange - Vec4(1, 0.25, 0, 1.0),#7 Red-Orange - Vec4(1, 0, 0, 1),#8 Red - Vec4(0.3, 0.3, 0.3, 1))#9 Grey - healthGlowColors = (Vec4(0.25, 1, 0.25, 0.5),#Green - Vec4(0.5, 1, 0.25, .5),#1 Green-Yellow - Vec4(0.75, 1, 0.25, .5),#2 Yellow-Green - Vec4(1, 1, 0.25, 0.5),#Yellow - Vec4(1, 0.866, 0.25, .5),#4 Yellow-Orange - Vec4(1, 0.6, 0.25, .5),#5 Orange-Yellow - Vec4(1, 0.5, 0.25, 0.5),#6 Orange - Vec4(1, 0.25, 0.25, 0.5),#7 Red-Orange - Vec4(1, 0.25, 0.25, 0.5),#8 Red - Vec4(0.3, 0.3, 0.3, 0))#9 Grey medallionColors = {'c': Vec4(0.863, 0.776, 0.769, 1.0), 's': Vec4(0.843, 0.745, 0.745, 1.0), 'l': Vec4(0.749, 0.776, 0.824, 1.0), @@ -341,8 +321,7 @@ class Suit(Avatar.Avatar): self.shadowJoint = None self.nametagJoint = None self.headParts = [] - self.healthBar = None - self.healthCondition = 0 + self.healthBar = SuitHealthBar.SuitHealthBar() self.isDisguised = 0 self.isWaiter = 0 self.isRental = 0 @@ -368,7 +347,7 @@ class Suit(Avatar.Avatar): part.removeNode() self.headParts = [] - self.removeHealthBar() + self.healthBar.delete() Avatar.Avatar.delete(self) def setHeight(self, height): @@ -585,97 +564,18 @@ class Suit(Avatar.Avatar): icons.removeNode() def generateHealthBar(self): - self.removeHealthBar() - model = loader.loadModel('phase_3.5/models/gui/matching_game_gui') - button = model.find('**/minnieCircle') - model.removeNode() - - button.setScale(3.0) - button.setH(180.0) - button.setColor(self.healthColors[0]) - chestNull = self.find('**/joint_attachMeter') - button.reparentTo(chestNull) - self.healthBar = button - glow = BattleProps.globalPropPool.getProp('glow') - glow.reparentTo(self.healthBar) - glow.setScale(0.28) - glow.setPos(-0.005, 0.01, 0.015) - glow.setColor(self.healthGlowColors[0]) - button.flattenLight() - self.healthBarGlow = glow - self.healthBar.hide() - self.healthCondition = 0 + self.healthBar.generate() + self.healthBar.geom.reparentTo(self.find('**/joint_attachMeter')) + self.healthBar.geom.setScale(3.0) def resetHealthBarForSkele(self): - self.healthBar.setPos(0.0, 0.1, 0.0) + self.healthBar.geom.setPos(0.0, 0.1, 0.0) def updateHealthBar(self, hp, forceUpdate = 0): if hp > self.currHP: hp = self.currHP self.currHP -= hp - health = float(self.currHP) / float(self.maxHP) - if health > 0.95: - condition = 0 - elif health > 0.9: - condition = 1 - elif health > 0.8: - condition = 2 - elif health > 0.7: - condition = 3#Yellow - elif health > 0.6: - condition = 4 - elif health > 0.5: - condition = 5 - elif health > 0.3: - condition = 6#Orange - elif health > 0.15: - condition = 7 - elif health > 0.05: - condition = 8#Red - elif health > 0.0: - condition = 9#Blinking Red - else: - condition = 10 - if self.healthCondition != condition or forceUpdate: - if condition == 9: - blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) - taskMgr.add(blinkTask, self.uniqueName('blink-task')) - elif condition == 10: - if self.healthCondition == 9: - taskMgr.remove(self.uniqueName('blink-task')) - blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) - taskMgr.add(blinkTask, self.uniqueName('blink-task')) - else: - self.healthBar.setColor(self.healthColors[condition], 1) - self.healthBarGlow.setColor(self.healthGlowColors[condition], 1) - self.healthCondition = condition - - def __blinkRed(self, task): - if not self.healthBar: - return Task.done - self.healthBar.setColor(self.healthColors[8], 1) - self.healthBarGlow.setColor(self.healthGlowColors[8], 1) - if self.healthCondition == 7: - self.healthBar.setScale(1.17) - return Task.done - - def __blinkGray(self, task): - if not self.healthBar: - return Task.done - self.healthBar.setColor(self.healthColors[9], 1) - self.healthBarGlow.setColor(self.healthGlowColors[9], 1) - if self.healthCondition == 10: - self.healthBar.setScale(1.0) - return Task.done - - def removeHealthBar(self): - if self.healthBar: - self.healthBar.removeNode() - self.healthBar = None - if self.healthCondition == 9 or self.healthCondition == 10: - taskMgr.remove(self.uniqueName('blink-task')) - self.healthCondition = 0 - return + self.healthBar.update(float(self.currHP) / float(self.maxHP)) def getLoseActor(self): if self.loseActor == None: diff --git a/toontown/suit/SuitHealthBar.py b/toontown/suit/SuitHealthBar.py index 398bad44..def25e2b 100644 --- a/toontown/suit/SuitHealthBar.py +++ b/toontown/suit/SuitHealthBar.py @@ -1,66 +1,65 @@ -from direct.task import Task +from direct.task.Task import Task from toontown.battle import BattleProps +HEALTH_COLORS = ( + (0, 1, 0, 1), + (0.5, 1, 0, 1), + (0.75, 1, 0, 1), + (1, 1, 0, 1), + (1, 0.86, 0, 1), + (1, 0.6, 0, 1), + (1, 0.5, 0, 1), + (1, 0.25, 0, 1.0), + (1, 0, 0, 1), + (0.3, 0.3, 0.3, 1) +) +HEALTH_GLOW_COLORS = ( + (0.25, 1, 0.25, 0.5), + (0.5, 1, 0.25, .5), + (0.75, 1, 0.25, .5), + (1, 1, 0.25, 0.5), + (1, 0.866, 0.25, .5), + (1, 0.6, 0.25, .5), + (1, 0.5, 0.25, 0.5), + (1, 0.25, 0.25, 0.5), + (1, 0.25, 0.25, 0.5), + (0.3, 0.3, 0.3, 0)) + class SuitHealthBar: - healthColors = ((0, 1, 0, 1), - (0.5, 1, 0, 1), - (0.75, 1, 0, 1), - (1, 1, 0, 1), - (1, 0.86, 0, 1), - (1, 0.6, 0, 1), - (1, 0.5, 0, 1), - (1, 0.25, 0, 1.0), - (1, 0, 0, 1), - (0.3, 0.3, 0.3, 1)) - healthGlowColors = ((0.25, 1, 0.25, 0.5), - (0.5, 1, 0.25, .5), - (0.75, 1, 0.25, .5), - (1, 1, 0.25, 0.5), - (1, 0.866, 0.25, .5), - (1, 0.6, 0.25, .5), - (1, 0.5, 0.25, 0.5), - (1, 0.25, 0.25, 0.5), - (1, 0.25, 0.25, 0.5), - (0.3, 0.3, 0.3, 0)) def __init__(self): - print 'New Healthbar' self.geom = None self.geomGlow = None self.healthCondition = 0 def delete(self): - print 'Deleting' if self.geom: self.geom.removeNode() self.geom = None self.geomGlow = None taskMgr.remove('blink-task-%s' % id(self)) self.healthCondition = 0 - print 'Deleted' def generate(self): - print 'Generating' self.delete() model = loader.loadModel('phase_3.5/models/gui/matching_game_gui') button = model.find('**/minnieCircle') model.removeNode() button.setH(180.0) - button.setColor(self.healthColors[0]) + button.setColor(HEALTH_COLORS[0]) self.geom = button glow = BattleProps.globalPropPool.getProp('glow') glow.reparentTo(self.geom) glow.setScale(0.28) glow.setPos(-0.005, 0.01, 0.015) - glow.setColor(self.healthGlowColors[0]) + glow.setColor(HEALTH_GLOW_COLORS[0]) button.flattenLight() self.geomGlow = glow self.geom.hide() self.healthCondition = 0 - print 'Generated' def getHealthCondition(self, health): if health > 0.95: @@ -87,9 +86,7 @@ class SuitHealthBar: def update(self, hp, forceUpdate = 0): if not self.geom: - print 'Not generated yet' return - print 'Updating: %s %s' % (hp, forceUpdate) condition = self.getHealthCondition(hp) if self.healthCondition != condition or forceUpdate: @@ -99,32 +96,20 @@ class SuitHealthBar: blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75 if condition == 9 else 0.25), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, 'blink-task-%s' % id(self)) else: - self.geom.setColor(self.healthColors[condition], 1) - self.geomGlow.setColor(self.healthGlowColors[condition], 1) + self.geom.setColor(HEALTH_COLORS[condition], 1) + self.geomGlow.setColor(HEALTH_GLOW_COLORS[condition], 1) self.healthCondition = condition - print 'Updated' + def __blink(self, color): + if not self.geom: + return + + self.geom.setColor(HEALTH_COLORS[color], 1) + self.geomGlow.setColor(HEALTH_GLOW_COLORS[color], 1) + def __blinkRed(self, task): - if not self.geom: - return - - print 'Blinking Red' - self.geom.setColor(self.healthColors[8], 1) - self.geomGlow.setColor(self.healthGlowColors[8], 1) - - if self.healthCondition == 7: - self.geom.setScale(1.17) - print 'Blinked Red' - + self.__blink(8) + def __blinkGray(self, task): - if not self.geom: - return - - print 'Blinking Gray' - self.geom.setColor(self.healthColors[9], 1) - self.geomGlow.setColor(self.healthGlowColors[9], 1) - - if self.healthCondition == 10: - self.geom.setScale(1.0) - print 'Blinked Gray' \ No newline at end of file + self.__blink(9) \ No newline at end of file From e2d7b9b6740b177cc4541733391595205246c3cf Mon Sep 17 00:00:00 2001 From: John Date: Mon, 10 Aug 2015 16:33:28 +0300 Subject: [PATCH 09/38] POPSICLES --- dependencies/astron/dclass/stride.dc | 4 +++ toontown/estate/DistributedEstateAI.py | 4 +-- .../safezone/DistributedEFlyingTreasure.py | 30 +++++-------------- .../safezone/DistributedEFlyingTreasureAI.py | 4 +++ 4 files changed, 17 insertions(+), 25 deletions(-) create mode 100644 toontown/safezone/DistributedEFlyingTreasureAI.py diff --git a/dependencies/astron/dclass/stride.dc b/dependencies/astron/dclass/stride.dc index 1702b997..2667f6d4 100644 --- a/dependencies/astron/dclass/stride.dc +++ b/dependencies/astron/dclass/stride.dc @@ -237,6 +237,7 @@ from toontown.safezone import SafeZoneManager/AI from toontown.tutorial import TutorialManager/AI from toontown.catalog import CatalogManager/AI from toontown.safezone import DistributedTreasure/AI +from toontown.safezone import DistributedEFlyingTreasure/AI from toontown.coghq import DistributedCashbotBossTreasure/AI from toontown.building import DistributedTrophyMgr/AI from toontown.building import DistributedBuilding/AI @@ -1522,6 +1523,9 @@ dclass DistributedTreasure : DistributedObject { setReject() broadcast; }; +dclass DistributedEFlyingTreasure : DistributedTreasure { +}; + dclass DistributedCashbotBossTreasure : DistributedTreasure { setGoonId(uint32) required broadcast ram; setFinalPosition(int16/10, int16/10, int16/10) required broadcast ram; diff --git a/toontown/estate/DistributedEstateAI.py b/toontown/estate/DistributedEstateAI.py index 028a1c87..7582d146 100755 --- a/toontown/estate/DistributedEstateAI.py +++ b/toontown/estate/DistributedEstateAI.py @@ -8,7 +8,7 @@ from toontown.fishing.DistributedFishingPondAI import DistributedFishingPondAI from toontown.fishing import FishingTargetGlobals, FishGlobals from toontown.safezone import TreasureGlobals from toontown.safezone.SZTreasurePlannerAI import SZTreasurePlannerAI -from toontown.safezone import DistributedTreasureAI +from toontown.safezone import DistributedEFlyingTreasureAI from toontown.safezone import ButterflyGlobals from toontown.safezone import DistributedButterflyAI from toontown.safezone.DistributedFishingSpotAI import DistributedFishingSpotAI @@ -431,7 +431,7 @@ class CannonRental(Rental): for i in xrange(20): x = random.randint(100, 300) - 200 y = random.randint(100, 300) - 200 - treasure = DistributedTreasureAI.DistributedTreasureAI(self.estate.air, self, 7, x, y, z) + treasure = DistributedEFlyingTreasureAI.DistributedEFlyingTreasureAI(self.estate.air, self, 7, x, y, z) treasure.generateWithRequired(self.estate.zoneId) self.objects.add(treasure) doIds.append(treasure.doId) diff --git a/toontown/safezone/DistributedEFlyingTreasure.py b/toontown/safezone/DistributedEFlyingTreasure.py index fe4a347d..a398761d 100755 --- a/toontown/safezone/DistributedEFlyingTreasure.py +++ b/toontown/safezone/DistributedEFlyingTreasure.py @@ -1,42 +1,26 @@ -from panda3d.core import * -from toontown.toonbase.ToonBaseGlobal import * -import DistributedSZTreasure -from direct.task.Task import Task -import math -import random +from DistributedTreasure import DistributedTreasure +import math, random -class DistributedEFlyingTreasure(DistributedSZTreasure.DistributedSZTreasure): +class DistributedEFlyingTreasure(DistributedTreasure): def __init__(self, cr): - DistributedSZTreasure.DistributedSZTreasure.__init__(self, cr) - self.modelPath = 'phase_5.5/models/props/popsicle_treasure' - self.grabSoundPath = 'phase_4/audio/sfx/SZ_DD_treasure.ogg' + DistributedTreasure.__init__(self, cr) self.scale = 2 self.delT = math.pi * 2.0 * random.random() self.shadow = 0 def disable(self): - DistributedSZTreasure.DistributedSZTreasure.disable(self) + DistributedTreasure.disable(self) taskMgr.remove(self.taskName('flying-treasure')) - def generateInit(self): - DistributedSZTreasure.DistributedSZTreasure.generateInit(self) - def setPosition(self, x, y, z): - DistributedSZTreasure.DistributedSZTreasure.setPosition(self, x, y, z) + DistributedTreasure.setPosition(self, x, y, z) self.initPos = self.nodePath.getPos() - self.pos = self.nodePath.getPos() - - def startAnimation(self): taskMgr.add(self.animateTask, self.taskName('flying-treasure')) def animateTask(self, task): pos = self.initPos t = 0.5 * math.pi * globalClock.getFrameTime() dZ = 5.0 * math.sin(t + self.delT) - dY = 2.0 * math.cos(t + self.delT) self.nodePath.setPos(pos[0], pos[1], pos[2] + dZ) - if self.pos: - del self.pos - self.pos = self.nodePath.getPos() - return Task.cont + return task.cont diff --git a/toontown/safezone/DistributedEFlyingTreasureAI.py b/toontown/safezone/DistributedEFlyingTreasureAI.py new file mode 100644 index 00000000..06e9952c --- /dev/null +++ b/toontown/safezone/DistributedEFlyingTreasureAI.py @@ -0,0 +1,4 @@ +import DistributedTreasureAI + +class DistributedEFlyingTreasureAI(DistributedTreasureAI.DistributedTreasureAI): + pass \ No newline at end of file From 9d43264adc0e6dc9022ad4756f1e9d8bdccb3bc0 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 14:17:43 +0300 Subject: [PATCH 10/38] Friends list bug fix --- .../distributed/ToontownClientRepository.py | 13 ++++------ toontown/friends/FriendsListPanel.py | 6 ++--- toontown/friends/TTSFriendsManagerUD.py | 24 ++++++++++--------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/toontown/distributed/ToontownClientRepository.py b/toontown/distributed/ToontownClientRepository.py index 2a5cdbd8..f2aba06a 100755 --- a/toontown/distributed/ToontownClientRepository.py +++ b/toontown/distributed/ToontownClientRepository.py @@ -637,15 +637,13 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): if doId in self.friendsMap: teleportNotify.debug('friend %s in friendsMap' % doId) return self.friendsMap[doId] - avatar = None if doId in self.doId2do: teleportNotify.debug('found friend %s in doId2do' % doId) - avatar = self.doId2do[doId] + return self.doId2do[doId] elif self.cache.contains(doId): teleportNotify.debug('found friend %s in cache' % doId) - avatar = self.cache.dict[doId] + return self.cache.dict[doId] self.notify.warning("Don't know who friend %s is." % doId) - return def identifyAvatar(self, doId): if doId in self.doId2do: @@ -661,6 +659,7 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): if base.wantPets and base.localAvatar.hasPet(): if base.localAvatar.getPetId() not in self.friendsMap: return 0 + return 1 def removeFriend(self, avatarId): @@ -736,16 +735,14 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository): def handleFriendOnline(self, doId): self.notify.debug('Friend %d now online.' % doId) if doId not in self.friendsOnline: - self.friendsOnline[doId] = self.identifyFriend(doId) + self.friendsOnline[doId] = self.identifyAvatar(doId) messenger.send('friendOnline', [doId]) def handleFriendOffline(self, doId): self.notify.debug('Friend %d now offline.' % doId) - try: + if doId in self.friendsOnline: del self.friendsOnline[doId] messenger.send('friendOffline', [doId]) - except: - pass def handleGenerateWithRequiredOtherOwner(self, di): # Toontown only makes use of OwnerViews for LocalToon. diff --git a/toontown/friends/FriendsListPanel.py b/toontown/friends/FriendsListPanel.py index af2ff4e6..de38fe38 100755 --- a/toontown/friends/FriendsListPanel.py +++ b/toontown/friends/FriendsListPanel.py @@ -6,6 +6,7 @@ from toontown.friends import ToontownFriendSecret from toontown.toonbase import ToontownGlobals from toontown.toonbase import TTLocalizer from otp.nametag.NametagGroup import * +from otp.nametag.NametagConstants import * from otp.otpbase import OTPGlobals FLPPets = 1 FLPOnline = 2 @@ -241,7 +242,6 @@ class FriendsListPanel(DirectFrame, StateData.StateData): def __updateScrollList(self): petFriends = [] - admins = [] trueFriends = [] friends = [] @@ -257,9 +257,7 @@ class FriendsListPanel(DirectFrame, StateData.StateData): base.cr.fillUpFriendsMap() return - if handle.isAdmin(): - admins.insert(0, friendId) - elif base.localAvatar.isTrueFriends(friendId): + if base.localAvatar.isTrueFriends(friendId): trueFriends.insert(0, friendId) else: friends.insert(0, friendId) diff --git a/toontown/friends/TTSFriendsManagerUD.py b/toontown/friends/TTSFriendsManagerUD.py index 36e1bffc..bd78350c 100755 --- a/toontown/friends/TTSFriendsManagerUD.py +++ b/toontown/friends/TTSFriendsManagerUD.py @@ -65,7 +65,6 @@ class FriendsListOperation(OperationFSM): self.demand('Error', 'Friend was not a Toon') return friendId = self.friendsList[self.friendIndex] - self.realFriendsList.append([friendId, fields['setName'][0], fields['setDNAString'][0], fields['setAdminAccess'][0], fields['setPetId'][0]]) @@ -98,8 +97,10 @@ class RemoveFriendOperation(OperationFSM): self.demand('Retrieved', fields['setFriendsList'][0], fields['setTrueFriends'][0]) def enterRetrieved(self, friendsList, trueFriendsList): - friendsList.remove(self.target) - trueFriendsList.remove(self.target) + if self.target in friendsList: + friendsList.remove(self.target) + if self.target in trueFriendsList: + trueFriendsList.remove(self.target) if self.sender in self.mgr.onlineToons: dg = self.air.dclassesByName['DistributedToonUD'].aiFormatUpdate( 'setFriendsList', self.sender, self.sender, @@ -115,7 +116,7 @@ class RemoveFriendOperation(OperationFSM): self.air.dbInterface.updateObject(self.air.dbId, self.sender, self.air.dclassesByName['DistributedToonUD'], - {'setFriendsList' : [friendsList], 'setTrueFriends' : [trueFriendsList]}) + {'setFriendsList' : [friendsList], 'setTrueFriends': [trueFriendsList]}) self.demand('Off') # -- Clear List -- @@ -201,7 +202,7 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD): self.sendUpdateToAvatarId(senderId, 'friendDetails', [avId, inventory, trackAccess, trophies, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel]) self.air.dbInterface.queryObject(self.air.dbId, avId, handleToon) - + def getPetDetails(self, avId): senderId = self.air.getAvatarIdFromSender() def handlePet(dclass, fields): @@ -235,9 +236,10 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD): self.air.send(dg) for friend in friendsList: - if friend[0] in self.onlineToons: - self.sendUpdateToAvatarId(doId, 'friendOnline', [friend[0]]) - self.sendUpdateToAvatarId(friend[0], 'friendOnline', [doId]) + friendId = friend[0] + if friendId in self.onlineToons: + self.sendUpdateToAvatarId(doId, 'friendOnline', [friendId]) + self.sendUpdateToAvatarId(friendId, 'friendOnline', [doId]) def goingOffline(self, avId): self.toonOffline(avId) @@ -249,9 +251,9 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD): if dclass != self.air.dclassesByName['DistributedToonUD']: return friendsList = fields['setFriendsList'][0] - for friendId in friendsList: - if friendId in self.onlineToons: - self.sendUpdateToAvatarId(friendId, 'friendOffline', [doId]) + for friend in friendsList: + if friend in self.onlineToons: + self.sendUpdateToAvatarId(friend, 'friendOffline', [doId]) if doId in self.onlineToons: self.onlineToons.remove(doId) if doId in self.toon2data: From bacd4b365cfc7a1de32c69f00ced3e32efb90d5a Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 14:21:39 +0300 Subject: [PATCH 11/38] Boarding Group messages are now clickable --- toontown/building/DistributedBoardingParty.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/toontown/building/DistributedBoardingParty.py b/toontown/building/DistributedBoardingParty.py index c8267316..382b56b9 100755 --- a/toontown/building/DistributedBoardingParty.py +++ b/toontown/building/DistributedBoardingParty.py @@ -145,7 +145,7 @@ class DistributedBoardingParty(DistributedObject.DistributedObject, BoardingPart if removedMember: removedMemberName = removedMember.name messageText = TTLocalizer.BoardingMessageLeftGroup % removedMemberName - localAvatar.setSystemMessage(0, messageText, WTToontownBoardingGroup) + localAvatar.setSystemMessage(removedMemberId, messageText, WTToontownBoardingGroup) elif localAvatar.doId in oldMemberList and localAvatar.doId not in memberList: messenger.send('updateGroupStatus') @@ -172,7 +172,7 @@ class DistributedBoardingParty(DistributedObject.DistributedObject, BoardingPart def postKick(self, leaderId): self.notify.debug('%s was kicked out of the Boarding Group by %s' % (localAvatar.doId, leaderId)) - localAvatar.setSystemMessage(0, TTLocalizer.BoardingMessageKickedOut, WTToontownBoardingGroup) + localAvatar.setSystemMessage(leaderId, TTLocalizer.BoardingMessageKickedOut, WTToontownBoardingGroup) def postSizeReject(self, leaderId, inviterId, inviteeId): self.notify.debug('%s was not invited because the group is full' % inviteeId) @@ -252,7 +252,7 @@ class DistributedBoardingParty(DistributedObject.DistributedObject, BoardingPart if invitee: inviteeName = invitee.name messageText = TTLocalizer.BoardingMessageInvited % (inviterName, inviteeName) - localAvatar.setSystemMessage(0, messageText, WTToontownBoardingGroup) + localAvatar.setSystemMessage(inviteeId, messageText, WTToontownBoardingGroup) def postMessageInvitationFailed(self, inviterId): inviterName = '' @@ -261,7 +261,7 @@ class DistributedBoardingParty(DistributedObject.DistributedObject, BoardingPart inviterName = inviter.name if self.invitationFailedMessageOk(inviterId): messageText = TTLocalizer.BoardingMessageInvitationFailed % inviterName - localAvatar.setSystemMessage(0, messageText, WTToontownBoardingGroup) + localAvatar.setSystemMessage(inviterId, messageText, WTToontownBoardingGroup) def postMessageAcceptanceFailed(self, inviteeId, reason): inviteeName = '' @@ -271,7 +271,7 @@ class DistributedBoardingParty(DistributedObject.DistributedObject, BoardingPart inviteeName = invitee.name if reason == BoardingPartyBase.INVITE_ACCEPT_FAIL_GROUP_FULL: messageText = TTLocalizer.BoardingMessageGroupFull % inviteeName - localAvatar.setSystemMessage(0, messageText, WTToontownBoardingGroup) + localAvatar.setSystemMessage(inviteeId, messageText, WTToontownBoardingGroup) if self.inviterPanels.isInvitingPanelIdCorrect(inviteeId): self.inviterPanels.destroyInvitingPanel() @@ -364,17 +364,17 @@ class DistributedBoardingParty(DistributedObject.DistributedObject, BoardingPart if groupFormed: if leaderId == quitterId: if not localAvatar.doId == leaderId: - localAvatar.setSystemMessage(0, TTLocalizer.BoardingMessageGroupDissolved, WTToontownBoardingGroup) + localAvatar.setSystemMessage(leaderId, TTLocalizer.BoardingMessageGroupDissolved, WTToontownBoardingGroup) elif not kick: if not localAvatar.doId == quitterId: quitter = base.cr.doId2do.get(quitterId) if quitter: quitterName = quitter.name messageText = TTLocalizer.BoardingMessageLeftGroup % quitterName - localAvatar.setSystemMessage(0, messageText, WTToontownBoardingGroup) + localAvatar.setSystemMessage(quitterId, messageText, WTToontownBoardingGroup) else: messageText = TTLocalizer.BoardingMessageGroupDisbandedGeneric - localAvatar.setSystemMessage(0, messageText, WTToontownBoardingGroup) + localAvatar.setSystemMessage(quitterId, messageText, WTToontownBoardingGroup) return def requestInvite(self, inviteeId): From da0366d02a5a4ed172a27832be14081feb2279ca Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 14:39:31 +0300 Subject: [PATCH 12/38] TV proper loop --- toontown/estate/DistributedTV.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/toontown/estate/DistributedTV.py b/toontown/estate/DistributedTV.py index 97d10d71..c15be8d1 100644 --- a/toontown/estate/DistributedTV.py +++ b/toontown/estate/DistributedTV.py @@ -84,14 +84,21 @@ class DistributedTV(DistributedFurnitureItem): base.localAvatar.setSystemMessage(0, TTLocalizer.TVUnknownVideoPack % pack if pack else TTLocalizer.TVUnknownVideo) self.resetScreen() return - + + start = time.time() - startTime movie = loader.loadTexture(video) self.sound = loader.loadSfx(video) + length = self.sound.length() + + if start >= length: + start -= int(start / length) * length + movie.synchronizeTo(self.sound) self.screen.setColor(1, 1, 1, 1) self.screen.setTexture(movie) self.screen.setTexScale(TextureStage.getDefault(), movie.getTexScale()) - self.sound.setTime(min(self.sound.length(), int(time.time() - startTime))) + self.sound.setTime(start) + self.sound.setLoop(True) self.sound.play() def __enterSphere(self, collisionEntry): From 156752b4a721f93ea4a972451aa959af2993b941 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 14:45:48 +0300 Subject: [PATCH 13/38] Another friend fix --- otp/avatar/LocalAvatar.py | 6 +++--- toontown/friends/TTSFriendsManagerUD.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/otp/avatar/LocalAvatar.py b/otp/avatar/LocalAvatar.py index 6b4d393d..819e0cc3 100755 --- a/otp/avatar/LocalAvatar.py +++ b/otp/avatar/LocalAvatar.py @@ -1098,18 +1098,18 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis def __friendOnline(self, doId): friend = base.cr.identifyFriend(doId) - if friend != None: + if friend: self.setSystemMessage(doId, OTPLocalizer.WhisperFriendComingOnline % friend.getName()) def __friendOffline(self, doId): friend = base.cr.identifyFriend(doId) - if friend != None: + if friend: self.setSystemMessage(0, OTPLocalizer.WhisperFriendLoggedOut % friend.getName()) def clickedWhisper(self, doId): friend = base.cr.identifyFriend(doId) - if friend != None: + if friend: messenger.send('clickedNametag', [friend]) self.chatMgr.whisperTo(friend.getName(), doId) diff --git a/toontown/friends/TTSFriendsManagerUD.py b/toontown/friends/TTSFriendsManagerUD.py index bd78350c..1133cc90 100755 --- a/toontown/friends/TTSFriendsManagerUD.py +++ b/toontown/friends/TTSFriendsManagerUD.py @@ -239,7 +239,6 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD): friendId = friend[0] if friendId in self.onlineToons: self.sendUpdateToAvatarId(doId, 'friendOnline', [friendId]) - self.sendUpdateToAvatarId(friendId, 'friendOnline', [doId]) def goingOffline(self, avId): self.toonOffline(avId) From 41307f6a0f5ae030f3c51fccb38c137f3712be4f Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 14:51:07 +0300 Subject: [PATCH 14/38] Revert "Another friend fix" This reverts commit 156752b4a721f93ea4a972451aa959af2993b941. --- otp/avatar/LocalAvatar.py | 6 +++--- toontown/friends/TTSFriendsManagerUD.py | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/otp/avatar/LocalAvatar.py b/otp/avatar/LocalAvatar.py index 819e0cc3..6b4d393d 100755 --- a/otp/avatar/LocalAvatar.py +++ b/otp/avatar/LocalAvatar.py @@ -1098,18 +1098,18 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis def __friendOnline(self, doId): friend = base.cr.identifyFriend(doId) - if friend: + if friend != None: self.setSystemMessage(doId, OTPLocalizer.WhisperFriendComingOnline % friend.getName()) def __friendOffline(self, doId): friend = base.cr.identifyFriend(doId) - if friend: + if friend != None: self.setSystemMessage(0, OTPLocalizer.WhisperFriendLoggedOut % friend.getName()) def clickedWhisper(self, doId): friend = base.cr.identifyFriend(doId) - if friend: + if friend != None: messenger.send('clickedNametag', [friend]) self.chatMgr.whisperTo(friend.getName(), doId) diff --git a/toontown/friends/TTSFriendsManagerUD.py b/toontown/friends/TTSFriendsManagerUD.py index 1133cc90..bd78350c 100755 --- a/toontown/friends/TTSFriendsManagerUD.py +++ b/toontown/friends/TTSFriendsManagerUD.py @@ -239,6 +239,7 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD): friendId = friend[0] if friendId in self.onlineToons: self.sendUpdateToAvatarId(doId, 'friendOnline', [friendId]) + self.sendUpdateToAvatarId(friendId, 'friendOnline', [doId]) def goingOffline(self, avId): self.toonOffline(avId) From c7011bc75702d4ff76bda232c3f21fa6a16a0a1b Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 14:55:03 +0300 Subject: [PATCH 15/38] Don't send trophies on result --- dependencies/astron/dclass/stride.dc | 2 +- toontown/friends/TTSFriendsManager.py | 2 +- toontown/friends/TTSFriendsManagerUD.py | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dependencies/astron/dclass/stride.dc b/dependencies/astron/dclass/stride.dc index 2667f6d4..c52391d7 100644 --- a/dependencies/astron/dclass/stride.dc +++ b/dependencies/astron/dclass/stride.dc @@ -3201,7 +3201,7 @@ dclass TTSFriendsManager : DistributedObjectGlobal { goingOffline(uint32 avId); getAvatarDetails(uint32) clsend; - friendDetails(uint32, blob, uint16[], uint16, int16, int16, uint32, uint32, blob, blob, int8[]); + friendDetails(uint32, blob, uint16[], int16, int16, uint32, uint32, blob, blob, int8[]); getPetDetails(uint32) clsend; petDetails(uint32, uint32, string, uint32, uint32, uint16/1000[], PetTrait[], int8[], uint32); diff --git a/toontown/friends/TTSFriendsManager.py b/toontown/friends/TTSFriendsManager.py index 1a7c2f9b..566c0a2f 100755 --- a/toontown/friends/TTSFriendsManager.py +++ b/toontown/friends/TTSFriendsManager.py @@ -21,7 +21,7 @@ class TTSFriendsManager(DistributedObjectGlobal): def d_getAvatarDetails(self, avId): self.sendUpdate('getAvatarDetails', [avId]) - def friendDetails(self, avId, inventory, trackAccess, trophies, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel): + def friendDetails(self, avId, inventory, trackAccess, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel): fields = [ ['setExperience' , experience], ['setTrackAccess' , trackAccess], diff --git a/toontown/friends/TTSFriendsManagerUD.py b/toontown/friends/TTSFriendsManagerUD.py index bd78350c..d8a9d76e 100755 --- a/toontown/friends/TTSFriendsManagerUD.py +++ b/toontown/friends/TTSFriendsManagerUD.py @@ -191,7 +191,6 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD): return inventory = fields['setInventory'][0] trackAccess = fields['setTrackAccess'][0] - trophies = 0 # fields['setTrophyScore'][0] is not db hp = fields['setHp'][0] maxHp = fields['setMaxHp'][0] defaultShard = fields['setDefaultShard'][0] @@ -200,7 +199,7 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD): experience = fields['setExperience'][0] trackBonusLevel = fields['setTrackBonusLevel'][0] - self.sendUpdateToAvatarId(senderId, 'friendDetails', [avId, inventory, trackAccess, trophies, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel]) + self.sendUpdateToAvatarId(senderId, 'friendDetails', [avId, inventory, trackAccess, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel]) self.air.dbInterface.queryObject(self.air.dbId, avId, handleToon) def getPetDetails(self, avId): From 1dcba024d54b15e88b321d2caa9f6353629d6b4f Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 18:37:17 +0300 Subject: [PATCH 16/38] NPC fix!! --- toontown/coghq/DistributedStage.py | 4 ++-- toontown/toon/DistributedNPCToonBaseAI.py | 3 +++ toontown/toon/NPCToons.py | 21 +++++++-------------- toontown/toonbase/TTLocalizerEnglish.py | 4 ++-- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/toontown/coghq/DistributedStage.py b/toontown/coghq/DistributedStage.py index 5a5e53ac..1f44ec69 100755 --- a/toontown/coghq/DistributedStage.py +++ b/toontown/coghq/DistributedStage.py @@ -301,6 +301,6 @@ class DistributedStage(DistributedObject.DistributedObject): self.titleText.setText('') def elevatorAlert(self, avId): - if base.localAvatar.doId != avId: + if base.localAvatar.doId != avId and avId in base.cr.doId2do: name = base.cr.doId2do[avId].getName() - self.showInfoText(TTLocalizer.stageToonEnterElevator % name) + self.showInfoText(TTLocalizer.StageToonEnterElevator % name) diff --git a/toontown/toon/DistributedNPCToonBaseAI.py b/toontown/toon/DistributedNPCToonBaseAI.py index 4c5746f3..14010eca 100755 --- a/toontown/toon/DistributedNPCToonBaseAI.py +++ b/toontown/toon/DistributedNPCToonBaseAI.py @@ -61,3 +61,6 @@ class DistributedNPCToonBaseAI(DistributedToonAI.DistributedToonAI): def getPositionIndex(self): return self.posIndex + + def getStartAnimState(self): + return 'neutral' diff --git a/toontown/toon/NPCToons.py b/toontown/toon/NPCToons.py index 1c2f7344..e1dd1d80 100755 --- a/toontown/toon/NPCToons.py +++ b/toontown/toon/NPCToons.py @@ -134,10 +134,7 @@ def createNPC(air, npcId, desc, zoneId, posIndex = 0, questCallback = None): npc.setMaxHp(15) npc.setPositionIndex(posIndex) npc.generateWithRequired(zoneId) - if hasattr(npc, 'getStartAnimState'): - npc.d_setAnimState(npc.getStartAnimState(), 1.0) - else: - npc.d_setAnimState('neutral', 1.0) + npc.d_setAnimState(npc.getStartAnimState(), 1.0) return npc @@ -148,6 +145,7 @@ def createNpcsInZone(air, zoneId): for npcId in npcIdList: while npcIdList.count(npcId) > 1: npcIdList.remove(npcId) + npcIdList.sort() for i in xrange(len(npcIdList)): npcId = npcIdList[i] npcDesc = NPCToonDict.get(npcId) @@ -11927,6 +11925,9 @@ del lnames zone2NpcDict = {} def generateZone2NpcDict(): + if zone2NpcDict: + return + for id, npcDesc in NPCToonDict.items(): zoneId = npcDesc[0] if zoneId in zone2NpcDict: @@ -11937,20 +11938,12 @@ def generateZone2NpcDict(): def getNPCName(npcId): npc = NPCToonDict.get(npcId) - if npc: - return npc[1] - else: - return None - return None + return npc[1] if npc else None def getNPCZone(npcId): npc = NPCToonDict.get(npcId) - if npc: - return npc[0] - else: - return None - return None + return npc[0] if npc else None def getBuildingArticle(zoneId): diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index ad1b818a..66e11850 100755 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -4288,7 +4288,7 @@ HeadingToFactoryTitle = '%s' ForemanConfrontedMsg = '%s is battling the ' + Foreman + '!' MintBossConfrontedMsg = '%s is battling the Supervisor!' StageBossConfrontedMsg = '%s is battling the District Attorney!' -stageToonEnterElevator = '%s \nhas entered the elevator' +StageToonEnterElevator = '%s\nhas entered the elevator!' ForcedLeaveStageAckMsg = 'The Law Clerk was defeated before you could reach him. You did not recover any Jury Notices.' MinigameWaitingForOtherToons = 'Waiting for other toons to join...' MinigamePleaseWait = 'Please wait...' @@ -4701,7 +4701,7 @@ LawbotBossName = 'Chief Justice' BossbotBossName = 'C. E. O.' BossCogNameWithDept = '%(name)s\n%(dept)s' BossCogPromoteDoobers = 'You are hereby promoted to full-fledged %s. Congratulations!' -BossCogDoobersAway = {'s': 'Go! And make that sale!'} +BossCogDoobersAway = {'s': 'Go! And make that sale!'} BossCogWelcomeToons = 'Welcome, new Cogs!' BossCogPromoteToons = 'You are hereby promoted to full-fledged %s. Congratu--' CagedToonInterruptBoss = 'Hey! Hiya! Hey over there!' From f137f3f047125c5a797323cad6734984f914f02f Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 18:44:35 +0300 Subject: [PATCH 17/38] Toons now stop when greeted with a warning message while trying to go into a door instead of running in 1 place --- toontown/building/ToonInterior.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toontown/building/ToonInterior.py b/toontown/building/ToonInterior.py index 75de4494..24de1370 100755 --- a/toontown/building/ToonInterior.py +++ b/toontown/building/ToonInterior.py @@ -59,8 +59,8 @@ class ToonInterior(Place.Place): State.State('NPCFAReject', self.enterNPCFAReject, self.exitNPCFAReject, ['walk']), State.State('HFA', self.enterHFA, self.exitHFA, ['HFAReject', 'teleportOut', 'tunnelOut']), State.State('HFAReject', self.enterHFAReject, self.exitHFAReject, ['walk']), - State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), - State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk']), + State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk', 'stopped']), + State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk', 'stopped']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk']), State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn']), State.State('quest', self.enterQuest, self.exitQuest, ['walk', 'doorOut']), From 19608959c56600b34c8050176bcee1dac1eb4a5f Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 19:10:45 +0300 Subject: [PATCH 18/38] Tutorial fix --- toontown/building/DistributedDoor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toontown/building/DistributedDoor.py b/toontown/building/DistributedDoor.py index 059295bd..fe4227dc 100755 --- a/toontown/building/DistributedDoor.py +++ b/toontown/building/DistributedDoor.py @@ -233,9 +233,9 @@ class DistributedDoor(DistributedObject.DistributedObject, DelayDeletable): self.setupNametag() def getBuilding(self): - if not hasattr(self, 'building'): + if not hasattr(self, 'building') or not self.building: if self.doorType == DoorTypes.INT_STANDARD: - door = render.find('**/leftDoor;+s') + door = render.find('**/*leftDoor*') self.building = door.getParent() elif self.doorType == DoorTypes.INT_HQ: door = render.find('**/door_0') From 7a8552c10e99f784c58f2c350f9ebdb58d4380c2 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 19:14:40 +0300 Subject: [PATCH 19/38] More fixes --- toontown/coghq/CogHQLobby.py | 4 ++-- toontown/coghq/FactoryExterior.py | 4 ++-- toontown/estate/Estate.py | 4 ++-- toontown/estate/House.py | 4 ++-- toontown/safezone/Playground.py | 6 ++++-- toontown/town/Street.py | 4 ++-- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/toontown/coghq/CogHQLobby.py b/toontown/coghq/CogHQLobby.py index fc1377da..a198421c 100755 --- a/toontown/coghq/CogHQLobby.py +++ b/toontown/coghq/CogHQLobby.py @@ -22,8 +22,8 @@ class CogHQLobby(Place.Place): 'doorOut', 'stopped']), State.State('stopped', self.enterStopped, self.exitStopped, ['walk', 'teleportOut', 'elevator']), - State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), - State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk']), + State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk', 'stopped']), + State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk', 'stopped']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk']), State.State('elevator', self.enterElevator, self.exitElevator, ['walk', 'stopped']), State.State('final', self.enterFinal, self.exitFinal, ['start'])], 'start', 'final') diff --git a/toontown/coghq/FactoryExterior.py b/toontown/coghq/FactoryExterior.py index f29269ec..f1957ada 100755 --- a/toontown/coghq/FactoryExterior.py +++ b/toontown/coghq/FactoryExterior.py @@ -43,8 +43,8 @@ class FactoryExterior(BattlePlace.BattlePlace): State.State('battle', self.enterBattle, self.exitBattle, ['walk', 'teleportOut', 'died']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk']), State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn', 'final', 'WaitForBattle']), - State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), - State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk']), + State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk', 'stopped']), + State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk', 'stopped']), State.State('died', self.enterDied, self.exitDied, ['quietZone']), State.State('tunnelIn', self.enterTunnelIn, self.exitTunnelIn, ['walk']), State.State('tunnelOut', self.enterTunnelOut, self.exitTunnelOut, ['final']), diff --git a/toontown/estate/Estate.py b/toontown/estate/Estate.py index 8081a66b..7087b9e6 100755 --- a/toontown/estate/Estate.py +++ b/toontown/estate/Estate.py @@ -62,8 +62,8 @@ class Estate(Place.Place): 'activity']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk', 'petTutorial']), State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn', 'walk', 'final']), - State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), - State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['final', 'walk']), + State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk', 'stopped']), + State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['final', 'walk', 'stopped']), State.State('final', self.enterFinal, self.exitFinal, ['teleportIn']), State.State('quest', self.enterQuest, self.exitQuest, ['walk']), State.State('activity', self.enterActivity, self.exitActivity, ['walk', 'stopped']), diff --git a/toontown/estate/House.py b/toontown/estate/House.py index 9c563998..7e896de7 100755 --- a/toontown/estate/House.py +++ b/toontown/estate/House.py @@ -43,8 +43,8 @@ class House(Place.Place): 'banking', 'phone', 'stopped']), - State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), - State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk']), + State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk', 'stopped']), + State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk', 'stopped']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk']), State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn']), State.State('quest', self.enterQuest, self.exitQuest, ['walk', 'doorOut']), diff --git a/toontown/safezone/Playground.py b/toontown/safezone/Playground.py index e561689d..3701b780 100755 --- a/toontown/safezone/Playground.py +++ b/toontown/safezone/Playground.py @@ -75,11 +75,13 @@ class Playground(Place.Place): State.State('doorIn', self.enterDoorIn, self.exitDoorIn, [ - 'walk']), + 'walk', + 'stopped']), State.State('doorOut', self.enterDoorOut, self.exitDoorOut, [ - 'walk']), + 'walk', + 'stopped']), State.State('NPCFA', self.enterNPCFA, self.exitNPCFA, [ diff --git a/toontown/town/Street.py b/toontown/town/Street.py index 83bf4a2a..8544a5b0 100755 --- a/toontown/town/Street.py +++ b/toontown/town/Street.py @@ -67,8 +67,8 @@ class Street(BattlePlace.BattlePlace): 'purchase']), State.State('WaitForBattle', self.enterWaitForBattle, self.exitWaitForBattle, ['battle', 'walk']), State.State('battle', self.enterBattle, self.exitBattle, ['walk', 'teleportOut', 'died']), - State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), - State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk']), + State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk', 'stopped']), + State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk', 'stopped']), State.State('elevatorIn', self.enterElevatorIn, self.exitElevatorIn, ['walk']), State.State('elevator', self.enterElevator, self.exitElevator, ['walk']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk', From b3efea4a6d16b913be74184984117e0af1b3aa2d Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 20:17:34 +0300 Subject: [PATCH 20/38] Teleport button fixed --- .../building/DistributedBuildingQueryMgrAI.py | 8 +- toontown/building/ToonInterior.py | 4 +- toontown/quest/QuestParser.py | 2 +- toontown/quest/QuestPoster.py | 78 +++++-------------- toontown/toonbase/TTLocalizerEnglish.py | 2 + 5 files changed, 30 insertions(+), 64 deletions(-) diff --git a/toontown/building/DistributedBuildingQueryMgrAI.py b/toontown/building/DistributedBuildingQueryMgrAI.py index b17b13ed..15be996c 100755 --- a/toontown/building/DistributedBuildingQueryMgrAI.py +++ b/toontown/building/DistributedBuildingQueryMgrAI.py @@ -11,7 +11,7 @@ class DistributedBuildingQueryMgrAI(DistributedObjectAI.DistributedObjectAI): def isSuit(self, context, zoneId): avId = self.air.getAvatarIdFromSender() - building = self.buildings.get(zoneId) - if building is None: - return - self.sendUpdateToAvatarId(avId, 'response', [context, building.isSuitBlock()]) + if zoneId not in self.buildings: + self.sendUpdateToAvatarId(avId, 'response', [context, False]) + else: + self.sendUpdateToAvatarId(avId, 'response', [context, self.buildings[zoneId].isSuitBlock()]) diff --git a/toontown/building/ToonInterior.py b/toontown/building/ToonInterior.py index 24de1370..0e39640d 100755 --- a/toontown/building/ToonInterior.py +++ b/toontown/building/ToonInterior.py @@ -176,7 +176,9 @@ class ToonInterior(Place.Place): def enterTeleportIn(self, requestStatus): modelType = DistributedToonInterior.DistributedToonInterior(base.cr).getModelType(self.getZoneId()) - if ZoneUtil.isPetshop(self.zoneId): + if ZoneUtil.isHQ(self.zoneId): + base.localAvatar.setPosHpr(-5.5, -1.5, ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0) + elif ZoneUtil.isPetshop(self.zoneId): base.localAvatar.setPosHpr(0, 0, ToontownGlobals.FloorOffset, 45.0, 0.0, 0.0) else: if modelType in InteriorTypes: diff --git a/toontown/quest/QuestParser.py b/toontown/quest/QuestParser.py index 60abeccc..6cb24c87 100755 --- a/toontown/quest/QuestParser.py +++ b/toontown/quest/QuestParser.py @@ -137,7 +137,7 @@ class NPCMoviePlayer(DirectObject.DirectObject): elif varName in globalVarDict: return globalVarDict[varName] elif varName.find('tomDialogue') > -1 or varName.find('harryDialogue') > -1: - notify.warning('%s getting referenced. Tutorial Ack: %d Place: %s' % (varName, base.localAvatar.tutorialAck, base.cr.playGame.hood)) + notify.warning('%s getting referenced. Tutorial Ack: %d Place: %s' % (varName, base.localAvatar.tutorialAck, base.cr.playGame.hood)) return None else: notify.error('Variable not defined: %s' % varName) diff --git a/toontown/quest/QuestPoster.py b/toontown/quest/QuestPoster.py index 433d3f88..00029481 100755 --- a/toontown/quest/QuestPoster.py +++ b/toontown/quest/QuestPoster.py @@ -70,7 +70,7 @@ class QuestPoster(DirectFrame): self.questProgress.hide() self.funQuest = DirectLabel(parent=self.questFrame, relief=None, text=TTLocalizer.QuestPosterFun, text_fg=(0.0, 0.439, 1.0, 1.0), text_shadow=(0, 0, 0, 1), pos=(0, 0, -0.125), scale=0.04) self.funQuest.hide() - self.teleportButton = DirectButton(parent=self.questFrame, relief=None, image=circleModel, text="Teleport", text_scale=0.035, text_pos=(-0.0025, -0.015), pos=(0.175, 0, 0.125), scale=0.75) #, text_bg=(0, 0.75, 1, 1) + self.teleportButton = DirectButton(parent=self.questFrame, relief=None, image=circleModel, text=TTLocalizer.TeleportButton, text_scale=0.035, text_pos=(-0.0025, -0.015), pos=(0.175, 0, 0.125), scale=0.75) #, text_bg=(0, 0.75, 1, 1) self.teleportButton.hide() self.laffMeter = None return @@ -172,31 +172,25 @@ class QuestPoster(DirectFrame): suitDoorOrigin = building.find('**/*_door_origin') elevatorNodePath.reparentTo(suitDoorOrigin) elevatorNodePath.setPosHpr(0, 0, 0, 0, 0, 0) - return def teleportToShop(self, npcId): npcZone = NPCToons.getNPCZone(npcId) npcHood = ZoneUtil.getCanonicalHoodId(npcZone) - avZone = base.localAvatar.getZoneId() - avHood = ZoneUtil.getCanonicalHoodId(avZone) - avShard = base.localAvatar.defaultShard - avPlace = base.cr.playGame.getPlace() hqZone = {2000:2520, 1000:1507, 3000:3508, 4000:4504, 5000:5502, 7000:7503, 9000:9505} - def callback(flag): - if flag: - npcZone = None - base.cr.buildingQueryMgr.d_isSuit(npcZone, callback) - if avShard not in base.cr.activeDistrictMap: + + if npcZone in (-1, 0, None): + npcHood = ZoneUtil.getCanonicalHoodId(base.localAvatar.getZoneId()) + npcZone = hqZone.get(npcHood, 2520) + + base.cr.buildingQueryMgr.d_isSuit(npcZone, lambda isSuit: self.teleportToShopCallback(npcZone, npcHood, isSuit)) + + def teleportToShopCallback(self, npcZone, npcHood, flag): + if flag: + self.teleportButton.setColorScale(0.3, 0.3, 0.3, 1.0) return - if npcZone in [-1, 0, None]: - return - if not ZoneUtil.isInterior(npcZone): - return - if ZoneUtil.isHQ(npcZone): - args = (avHood, hqZone[avHood], avShard, -1) - else: - args = (npcHood, npcZone, avShard, -1) - avPlace.requestTeleport(*args) + + self.teleportButton.setColorScale(1.0, 1.0, 1.0, 1.0) + base.cr.playGame.getPlace().requestTeleport(npcHood, npcZone, base.localAvatar.defaultShard, -1) def fitGeometry(self, geom, fFlip = 0, dimension = 0.8): p1 = Point3() @@ -230,8 +224,6 @@ class QuestPoster(DirectFrame): self.lPictureFrame.hide() self.rPictureFrame.hide() self.questProgress.hide() - self.teleportButton.hide() - self.teleportButton.setPos(0.175, 0, -0.125) if hasattr(self, 'chooseButton'): self.chooseButton.destroy() del self.chooseButton @@ -305,30 +297,17 @@ class QuestPoster(DirectFrame): fComplete = quest.getCompletionStatus(base.localAvatar, questDesc) == Quests.COMPLETE - if Quests.isQuestJustForFun(questId, rewardId): - if fComplete: - self.funQuest.hide() - self.teleportButton.show() - else: - self.teleportButton.hide() - if toNpcId == Quests.ToonHQ: - self.teleportButton.show() - self.teleportButton.setPos(0.285, 0, -0.15) toNpcName = TTLocalizer.QuestPosterHQOfficer toNpcBuildingName = TTLocalizer.QuestPosterHQBuildingName toNpcStreetName = TTLocalizer.QuestPosterHQStreetName toNpcLocationName = TTLocalizer.QuestPosterHQLocationName elif toNpcId == Quests.ToonTailor: - self.teleportButton.show() - self.teleportButton.setPos(0.285, 0, -0.15) toNpcName = TTLocalizer.QuestPosterTailor toNpcBuildingName = TTLocalizer.QuestPosterTailorBuildingName toNpcStreetName = TTLocalizer.QuestPosterTailorStreetName toNpcLocationName = TTLocalizer.QuestPosterTailorLocationName else: - self.teleportButton.show() - self.teleportButton.setPos(0.285, 0, -0.15) toNpcName = NPCToons.getNPCName(toNpcId) toNpcZone = NPCToons.getNPCZone(toNpcId) toNpcHoodId = ZoneUtil.getCanonicalHoodId(toNpcZone) @@ -349,8 +328,13 @@ class QuestPoster(DirectFrame): objectiveStrings = quest.getObjectiveStrings() captions = map(string.capwords, quest.getObjectiveStrings()) imageColor = Vec4(*self.colors['white']) + self.teleportButton.hide() + + if base.localAvatar.tutorialAck and (fComplete or quest.getType() in (Quests.DeliverGagQuest, Quests.DeliverItemQuest, Quests.VisitQuest, Quests.TrackChoiceQuest)): + self.teleportButton.show() + self.teleportButton.setPos(0.3, 0, -0.15) + if isinstance(quest, Quests.TexturedQuest) and quest.hasFrame(): - self.teleportButton.hide() frame = quest.getFrame() frameBgColor = frame[1] lIconGeom = frame[0] @@ -361,9 +345,6 @@ class QuestPoster(DirectFrame): infoText = TTLocalizer.QuestPosterAnywhere elif quest.getType() == Quests.DeliverGagQuest or quest.getType() == Quests.DeliverItemQuest: frameBgColor = 'red' - if fComplete: - self.teleportButton.show() - self.teleportButton.setPos(0.175, 0, -0.125) if quest.getType() == Quests.DeliverGagQuest: invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons') track, item = quest.getGagType() @@ -382,7 +363,6 @@ class QuestPoster(DirectFrame): infoText = TTLocalizer.QuestPageDestination % (toNpcBuildingName, toNpcStreetName, toNpcLocationName) rIconGeom = self.createNpcToonHead(toNpcId) rIconGeomScale = IMAGE_SCALE_SMALL - self.teleportButton.setPos(0.285, 0, -0.15) elif quest.getType() == Quests.RecoverItemQuest: frameBgColor = 'green' bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') @@ -425,10 +405,7 @@ class QuestPoster(DirectFrame): infoText = quest.getLocationName() if infoText == '': infoText = TTLocalizer.QuestPosterAnywhere - else: - self.teleportButton.show() elif quest.getType() == Quests.VisitQuest: - self.teleportButton.show() frameBgColor = 'brown' captions[0] = '%s' % toNpcName lIconGeom = self.createNpcToonHead(toNpcId) @@ -436,7 +413,6 @@ class QuestPoster(DirectFrame): if not fComplete: infoText = TTLocalizer.QuestPageDestination % (toNpcBuildingName, toNpcStreetName, toNpcLocationName) elif quest.getType() == Quests.TrackChoiceQuest: - self.teleportButton.hide() frameBgColor = 'green' invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons') track1, track2 = quest.getChoices(base.localAvatar) @@ -455,7 +431,6 @@ class QuestPoster(DirectFrame): infoZ = -0.02 invModel.removeNode() elif quest.getType() == Quests.BuildingQuest: - self.teleportButton.hide() frameBgColor = 'blue' track = quest.getBuildingTrack() numFloors = quest.getNumFloors() @@ -483,7 +458,6 @@ class QuestPoster(DirectFrame): if infoText == '': infoText = TTLocalizer.QuestPosterAnywhere elif quest.getType() == Quests.FactoryQuest: - self.teleportButton.hide() frameBgColor = 'blue' bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') lIconGeom = bookModel.find('**/factoryIcon2') @@ -494,7 +468,6 @@ class QuestPoster(DirectFrame): if infoText == '': infoText = TTLocalizer.QuestPosterAnywhere elif quest.getType() == Quests.MintQuest: - self.teleportButton.hide() frameBgColor = 'blue' bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') lIconGeom = bookModel.find('**/CashBotMint') @@ -505,7 +478,6 @@ class QuestPoster(DirectFrame): if infoText == '': infoText = TTLocalizer.QuestPosterAnywhere elif quest.getType() == Quests.CogPartQuest: - self.teleportButton.hide() frameBgColor = 'green' bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') lIconGeom = bookModel.find('**/CogArmIcon2') @@ -516,7 +488,6 @@ class QuestPoster(DirectFrame): if infoText == '': infoText = TTLocalizer.QuestPosterAnywhere elif quest.getType() == Quests.ForemanQuest or quest.getType() == Quests.SupervisorQuest: - self.teleportButton.hide() frameBgColor = 'blue' bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') lIconGeom = bookModel.find('**/skelecog5') @@ -527,13 +498,11 @@ class QuestPoster(DirectFrame): if infoText == '': infoText = TTLocalizer.QuestPosterAnywhere elif quest.getType() == Quests.RescueQuest: - self.teleportButton.hide() frameBgColor = 'blue' lIconGeom = self.createNpcToonHead(random.choice(NPCToons.HQnpcFriends.keys())) lIconGeomScale = 0.13 infoText = quest.getLocationName().strip() elif quest.getType() == Quests.FriendQuest: - self.teleportButton.hide() frameBgColor = 'brown' gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui') lIconGeom = gui.find('**/FriendsBox_Closed') @@ -541,7 +510,6 @@ class QuestPoster(DirectFrame): gui.removeNode() infoText = TTLocalizer.QuestPosterAnywhere elif quest.getType() == Quests.TrolleyQuest: - self.teleportButton.hide() frameBgColor = 'lightBlue' gui = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') lIconGeom = gui.find('**/trolley') @@ -549,7 +517,6 @@ class QuestPoster(DirectFrame): gui.removeNode() infoText = TTLocalizer.QuestPosterPlayground elif quest.getType() == Quests.MailboxQuest: - self.teleportButton.hide() frameBgColor = 'lightBlue' bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') lIconGeom = bookModel.find('**/package') @@ -557,7 +524,6 @@ class QuestPoster(DirectFrame): bookModel.removeNode() infoText = TTLocalizer.QuestPosterAtHome elif quest.getType() == Quests.PhoneQuest: - self.teleportButton.hide() frameBgColor = 'lightBlue' bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui') lIconGeom = bookModel.find('**/clarabelleCow') @@ -565,7 +531,6 @@ class QuestPoster(DirectFrame): bookModel.removeNode() infoText = TTLocalizer.QuestPosterOnPhone else: - self.teleportButton.hide() frameBgColor = 'blue' if quest.getType() == Quests.CogTrackQuest: dept = quest.getCogTrack() @@ -619,7 +584,6 @@ class QuestPoster(DirectFrame): if infoText == '': infoText = TTLocalizer.QuestPosterAnywhere if fComplete: - self.teleportButton.show() textColor = (0, 0.3, 0, 1) imageColor = Vec4(*self.colors['lightGreen']) lPos.setX(-0.18) @@ -694,8 +658,6 @@ class QuestPoster(DirectFrame): self.questInfo['text'] = infoText self.questInfo.setZ(infoZ) self.fitLabel(self.questInfo) - if not Quests.QuestDict[questId][0] >= 11: - self.teleportButton.hide() return def unbindMouseEnter(self): diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index 66e11850..8bc24994 100755 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -8729,6 +8729,8 @@ ShardPagePreferred = 'Preferred' ShardPageShardTitle = '%s Population: %s' ShardPageTeleport = 'Teleport to\n%s' +TeleportButton = 'Teleport' + Blacklist = [ "$1ut", "$h1t", From 0489a156a36daf6726b276e26d75154579d1ae5c Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 21:37:20 +0300 Subject: [PATCH 21/38] Color drag --- toontown/makeatoon/ColorShop.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/toontown/makeatoon/ColorShop.py b/toontown/makeatoon/ColorShop.py index 9fc18865..d713c766 100755 --- a/toontown/makeatoon/ColorShop.py +++ b/toontown/makeatoon/ColorShop.py @@ -7,6 +7,7 @@ from toontown.toonbase import TTLocalizer, ToontownGlobals import ShuffleButton import random, colorsys from direct.directnotify import DirectNotifyGlobal +from direct.task import Task class ColorShop(StateData.StateData): notify = DirectNotifyGlobal.directNotify.newCategory('ColorShop') @@ -15,7 +16,6 @@ class ColorShop(StateData.StateData): StateData.StateData.__init__(self, doneEvent) self.toon = None self.colorAll = 1 - return def getColorList(self): return ToonDNA.allColorsList @@ -60,6 +60,7 @@ class ColorShop(StateData.StateData): print 'ColorShop: toon not found' self.hideButtons() + taskMgr.remove('colorDragTask') def load(self): self.gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui') @@ -95,7 +96,8 @@ class ColorShop(StateData.StateData): self.pickImage = PNMImage(int((ToontownGlobals.COLOR_SATURATION_MAX - ToontownGlobals.COLOR_SATURATION_MIN) * 100), int((ToontownGlobals.COLOR_VALUE_MAX - ToontownGlobals.COLOR_VALUE_MIN) * 100)) self.hueSlider = DirectSlider(parent=self.advancedFrame, relief=None, image='phase_3/maps/color_picker_hue.jpg', scale=0.3, pos=(-0.05, 0, -0.43), image_scale=(0.1, 1.0, 1.0), pageSize=5, orientation=DGG.VERTICAL, command=self.__chooseHue) self.pickButton = DirectButton(parent=self.advancedFrame, relief=None, image='phase_3/maps/color_picker_empty.png', scale=0.3, pos=(-0.45, 0, -0.43), frameColor=(1, 1, 1, 0.1), pressEffect=0) - self.pickButton.bind(DGG.B1CLICK, self.__pickColor) + self.pickButton.bind(DGG.B1PRESS, self.__startPickColor) + self.pickButton.bind(DGG.B1RELEASE, self.__stopPickColor) self.partsFrame = DirectFrame(parent=self.advancedFrame, image=shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(-0.395, 0, -0.85), hpr=(0, 0, -2), scale=0.9, frameColor=(1, 1, 1, 1), text=TTLocalizer.ColorAll, text_scale=0.0625, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1)) self.partLButton = DirectButton(parent=self.partsFrame, relief=None, image=shuffleImage, image_scale=halfButtonScale, image1_scale=halfButtonHoverScale, image2_scale=halfButtonHoverScale, pos=(-0.2, 0, 0), state=DGG.DISABLED, command=self.__swapPart, extraArgs=[-1]) self.partRButton = DirectButton(parent=self.partsFrame, relief=None, image=shuffleImage, image_scale=halfButtonInvertScale, image1_scale=halfButtonInvertHoverScale, image2_scale=halfButtonInvertHoverScale, pos=(0.2, 0, 0), command=self.__swapPart, extraArgs=[1]) @@ -184,8 +186,9 @@ class ColorShop(StateData.StateData): texture.load(self.pickImage) self.pickButton['image'] = texture - def __pickColor(self, pos): - x, y = pos.getMouse() + def __pickColor(self, task=None): + x = base.mouseWatcherNode.getMouseX() + y = base.mouseWatcherNode.getMouseY() win_w, win_h = base.win.getSize() if win_w < win_h: @@ -198,7 +201,12 @@ class ColorShop(StateData.StateData): image_scale = self.pickButton['image_scale'] x = (.5 + x / (2. * self.pickButton.getSx(aspect2d) * image_scale[0])) y = (.5 + y / -(2. * self.pickButton.getSz(aspect2d) * image_scale[2])) + + if not (0.0 <= x <= 1.0 and 0.0 <= y <= 1.0): + return Task.cont + rgb = colorsys.hsv_to_rgb(self.hueSlider['value'], self.calcRelative(x, 0.0, 1.0, 0.36, 0.7), self.calcRelative(y, 0.0, 1.0, 0.5, 0.8)) + (1,) + if self.partChoice in (0, 1): self.dna.headColor = rgb if self.partChoice in (0, 2): @@ -207,7 +215,16 @@ class ColorShop(StateData.StateData): self.dna.gloveColor = rgb if self.partChoice in (0, 4): self.dna.legColor = rgb + self.toon.swapToonColor(self.dna) + return Task.cont + + def __startPickColor(self, extra): + self.__stopPickColor(extra) + taskMgr.add(self.__pickColor, 'colorDragTask') + + def __stopPickColor(self, extra): + taskMgr.remove('colorDragTask') def __swapPart(self, offset): self.partChoice += offset From 929935734570e54ffc61a203f589e87521111670 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 21:49:51 +0300 Subject: [PATCH 22/38] Color picker fixes --- toontown/makeatoon/ColorShop.py | 5 ++++- toontown/toonbase/ToontownGlobals.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/toontown/makeatoon/ColorShop.py b/toontown/makeatoon/ColorShop.py index d713c766..f000a3ac 100755 --- a/toontown/makeatoon/ColorShop.py +++ b/toontown/makeatoon/ColorShop.py @@ -205,7 +205,10 @@ class ColorShop(StateData.StateData): if not (0.0 <= x <= 1.0 and 0.0 <= y <= 1.0): return Task.cont - rgb = colorsys.hsv_to_rgb(self.hueSlider['value'], self.calcRelative(x, 0.0, 1.0, 0.36, 0.7), self.calcRelative(y, 0.0, 1.0, 0.5, 0.8)) + (1,) + x = self.calcRelative(x, 0.0, 1.0, ToontownGlobals.COLOR_SATURATION_MIN, ToontownGlobals.COLOR_SATURATION_MAX) + y = self.calcRelative(y, 0.0, 1.0, ToontownGlobals.COLOR_VALUE_MIN, ToontownGlobals.COLOR_VALUE_MAX) + rgb = colorsys.hsv_to_rgb(self.hueSlider['value'], x, y) + (1,) + rgb = tuple([float('%.2f' % x) for x in rgb]) if self.partChoice in (0, 1): self.dna.headColor = rgb diff --git a/toontown/toonbase/ToontownGlobals.py b/toontown/toonbase/ToontownGlobals.py index d487e7e0..5250a993 100755 --- a/toontown/toonbase/ToontownGlobals.py +++ b/toontown/toonbase/ToontownGlobals.py @@ -1687,7 +1687,7 @@ TV_NOT_OWNER = 0 TV_INVALID_VIDEO = 1 TV_OK = 2 -COLOR_SATURATION_MIN = 0.36 +COLOR_SATURATION_MIN = 0.5 COLOR_SATURATION_MAX = 0.8 COLOR_VALUE_MIN = 0.5 -COLOR_VALUE_MAX = 0.9 \ No newline at end of file +COLOR_VALUE_MAX = 0.8 \ No newline at end of file From 2098275dfab4c1536a1ed07a409cdfd54498c390 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 22:03:58 +0300 Subject: [PATCH 23/38] Cog HQ teleport crash fix --- toontown/quest/QuestPoster.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/toontown/quest/QuestPoster.py b/toontown/quest/QuestPoster.py index 00029481..5b52716c 100755 --- a/toontown/quest/QuestPoster.py +++ b/toontown/quest/QuestPoster.py @@ -179,7 +179,10 @@ class QuestPoster(DirectFrame): hqZone = {2000:2520, 1000:1507, 3000:3508, 4000:4504, 5000:5502, 7000:7503, 9000:9505} if npcZone in (-1, 0, None): - npcHood = ZoneUtil.getCanonicalHoodId(base.localAvatar.getZoneId()) + zoneId = base.localAvatar.getZoneId() + if ZoneUtil.isDynamicZone(zoneId) or ZoneUtil.isCogHQZone(zoneId): + zoneId = 2000 + npcHood = ZoneUtil.getCanonicalHoodId(zoneId) npcZone = hqZone.get(npcHood, 2520) base.cr.buildingQueryMgr.d_isSuit(npcZone, lambda isSuit: self.teleportToShopCallback(npcZone, npcHood, isSuit)) From b155962dca025febf8fca912357e6c578d047ae9 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 12 Aug 2015 22:46:34 +0300 Subject: [PATCH 24/38] Fix a bug with the teleport button --- toontown/quest/QuestPoster.py | 1 + 1 file changed, 1 insertion(+) diff --git a/toontown/quest/QuestPoster.py b/toontown/quest/QuestPoster.py index 5b52716c..aeeb23ea 100755 --- a/toontown/quest/QuestPoster.py +++ b/toontown/quest/QuestPoster.py @@ -227,6 +227,7 @@ class QuestPoster(DirectFrame): self.lPictureFrame.hide() self.rPictureFrame.hide() self.questProgress.hide() + self.teleportButton.hide() if hasattr(self, 'chooseButton'): self.chooseButton.destroy() del self.chooseButton From 3d5a138a68ad51c96d3a3040e9f0d4ac6de0a626 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 03:19:58 +0300 Subject: [PATCH 25/38] SOS friends are now sorted by rarity --- toontown/toon/NPCFriendPanel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toontown/toon/NPCFriendPanel.py b/toontown/toon/NPCFriendPanel.py index cabb7b9a..a98ca2eb 100755 --- a/toontown/toon/NPCFriendPanel.py +++ b/toontown/toon/NPCFriendPanel.py @@ -66,7 +66,7 @@ class NPCFriendPanel(DirectFrame): self.update() def update(self): - friendList = self.friendDict.keys() + friendList = sorted(self.friendDict.keys(), reverse=True, key=lambda id: NPCToons.getNPCTrackLevelHpRarity(id)[3]) cardNum = 0 for i in xrange(self.pos, self.pos + 16): From 6bdc129b6714321865b194375b2fbd2f2a230786 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 03:55:51 +0300 Subject: [PATCH 26/38] Organic gag display in the battle GUI and better ~trackBonus command --- toontown/toon/DistributedToonAI.py | 10 ++++++---- toontown/town/TownBattleToonPanel.py | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/toontown/toon/DistributedToonAI.py b/toontown/toon/DistributedToonAI.py index 23330411..0f52a725 100755 --- a/toontown/toon/DistributedToonAI.py +++ b/toontown/toon/DistributedToonAI.py @@ -4878,18 +4878,20 @@ def givePies(pieType, numPies=0): else: target.b_setNumPies(ToontownGlobals.FullPies) -@magicWord(category=CATEGORY_PROGRAMMER, types=[int]) -def trackBonus(trackIndex): +@magicWord(category=CATEGORY_PROGRAMMER, types=[int, int]) +def trackBonus(trackIndex, level): """ Modify the invoker's track bonus level. """ invoker = spellbook.getInvoker() if not 0 <= trackIndex < 7: return 'Invalid track index!' + if not -1 <= level <= 6: + return 'Invalid level!' trackBonusLevel = [0] * 7 - trackBonusLevel[trackIndex] = 1 + trackBonusLevel[trackIndex] = level invoker.b_setTrackBonusLevel(trackBonusLevel) - return 'Your track bonus level has been set!' + return 'Your track bonus level has been set to %s!' % level @magicWord(category=CATEGORY_PROGRAMMER, types=[str, str, int]) def track(command, track, value=None): diff --git a/toontown/town/TownBattleToonPanel.py b/toontown/town/TownBattleToonPanel.py index 932e7c54..388ec7c6 100755 --- a/toontown/town/TownBattleToonPanel.py +++ b/toontown/town/TownBattleToonPanel.py @@ -126,6 +126,8 @@ class TownBattleToonPanel(DirectFrame): self.gag.setScale(0.8) self.gag.setPos(0, 0, 0.02) self.hasGag = 1 + if self.avatar is not None and self.avatar.checkGagBonus(track, level): + self.gag.setColor((1, 0, 0, 1) if track == 1 and level == 5 else (0, 1, 0, 1)) if numTargets is not None and targetIndex is not None and localNum is not None: self.whichText.show() self.whichText['text'] = self.determineWhichText(numTargets, targetIndex, localNum, index) From 3880d7e0324976ec5a7b4d99a3212443cf23b276 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 13:23:57 +0300 Subject: [PATCH 27/38] NPCToons cleanup --- toontown/toon/NPCToons.py | 12682 +++--------------------------------- 1 file changed, 757 insertions(+), 11925 deletions(-) diff --git a/toontown/toon/NPCToons.py b/toontown/toon/NPCToons.py index e1dd1d80..1074b855 100755 --- a/toontown/toon/NPCToons.py +++ b/toontown/toon/NPCToons.py @@ -1,20 +1,9 @@ from panda3d.core import * -import random -import string -import sys, os - -import ToonDNA -from toontown.hood import ZoneUtil from otp.nametag.NametagGroup import * -from toontown.toonbase import TTLocalizer -from toontown.toonbase import ToontownBattleGlobals -from toontown.toonbase import ToontownGlobals +from toontown.hood import ZoneUtil +from toontown.toonbase import TTLocalizer, ToontownBattleGlobals, ToontownGlobals +import ToonDNA - -try: - config = simbase.config -except: - config = base.config QUEST_MOVIE_CLEAR = 0 QUEST_MOVIE_REJECT = 1 QUEST_MOVIE_COMPLETE = 2 @@ -121,7 +110,7 @@ def createNPC(air, npcId, desc, zoneId, posIndex = 0, questCallback = None): elif type == NPC_LAFF_RESTOCK: npc = DistributedNPCLaffRestockAI.DistributedNPCLaffRestockAI(air, npcId) else: - print 'createNPC() error!!!' + print 'Invalid NPC type: %s' % type npc.setName(name) dna = ToonDNA.ToonDNA() if dnaType == 'r': @@ -137,32 +126,26 @@ def createNPC(air, npcId, desc, zoneId, posIndex = 0, questCallback = None): npc.d_setAnimState(npc.getStartAnimState(), 1.0) return npc - def createNpcsInZone(air, zoneId): npcs = [] - canonicalZoneId = ZoneUtil.getCanonicalZoneId(zoneId) - npcIdList = zone2NpcDict.get(canonicalZoneId, []) - for npcId in npcIdList: - while npcIdList.count(npcId) > 1: - npcIdList.remove(npcId) - npcIdList.sort() - for i in xrange(len(npcIdList)): - npcId = npcIdList[i] + npcIdList = sorted(zone2NpcDict.get(ZoneUtil.getCanonicalZoneId(zoneId), [])) + + for i, npcId in enumerate(npcIdList): npcDesc = NPCToonDict.get(npcId) - if npcDesc[5] == NPC_FISHERMAN: - if not air.wantFishing: - continue - if npcDesc[5] == NPC_PARTYPERSON: - if not air.wantParties: - continue + + if npcDesc[5] == NPC_FISHERMAN and not air.wantFishing: + continue + elif npcDesc[5] == NPC_PARTYPERSON and not air.wantParties: + continue + npcs.append(createNPC(air, npcId, npcDesc, zoneId, posIndex=i)) + return npcs - def createLocalNPC(npcId): - import Toon if npcId not in NPCToonDict: - return None + return + import Toon desc = NPCToonDict[npcId] canonicalZoneId, name, dnaType, gender, protected, type = desc npc = Toon.Toon() @@ -188,11733 +171,705 @@ badBlocks = [ def isZoneProtected(zoneId): if zoneId in badBlocks: return 1 - npcIdList = zone2NpcDict.get(zoneId, []) - for npcId in npcIdList: - npcDesc = NPCToonDict.get(npcId) - if npcDesc[4]: + + for npcId in zone2NpcDict.get(zoneId, []): + if NPCToonDict.get(npcId)[4]: return 1 + return 0 - lnames = TTLocalizer.NPCToonNames -NPCToonDict = {20000: (-1, - lnames[20000], - ('dls', - 'ms', - 'm', - 'm', - 7, - 0, - 7, - 7, - 2, - 6, - 2, - 6, - 2, - 16), - 'm', - 1, - NPC_SPECIALQUESTGIVER), - 999: (-1, - lnames[999], - 'r', - 'm', - 1, - NPC_TAILOR), - 1000: (-1, - lnames[1000], - 'r', - 'm', - 1, - NPC_HQ), - 20001: (-1, - lnames[20001], - ('dss', - 'ms', - 'm', - 'm', - 17, - 0, - 17, - 17, - 3, - 3, - 3, - 3, - 7, - 2), - 'm', - 1, - NPC_BLOCKER), - 20002: (-1, - TTLocalizer.TutorialHQOfficerName, - ('dls', - 'ms', - 'm', - 'm', - 6, - 0, - 6, - 6, - 0, - 10, - 0, - 10, - 2, - 9), - 'm', - 1, - NPC_SPECIALQUESTGIVER), - 2002: (2514, - lnames[2002], - ('hss', - 'ls', - 'l', - 'm', - 4, - 0, - 4, - 4, - 0, - 3, - 0, - 3, - 1, - 18), - 'm', - 1, - NPC_REGULAR), - 2003: (2516, - lnames[2003], - ('cll', - 'ms', - 'l', - 'm', - 18, - 0, - 18, - 18, - 0, - 4, - 0, - 4, - 1, - 15), - 'm', - 1, - NPC_REGULAR), - 2004: (2521, - lnames[2004], - ('rll', - 'md', - 'm', - 'f', - 15, - 0, - 5, - 7, - 3, - 5, - 3, - 5, - 0, - 3), - 'f', - 1, - NPC_TAILOR), - 2005: (2518, - lnames[2005], - ('cls', - 'ls', - 'l', - 'm', - 4, - 0, - 4, - 4, - 0, - 4, - 0, - 4, - 1, - 9), - 'm', - 1, - NPC_REGULAR), - 2006: (2519, - lnames[2006], - ('dsl', - 'ls', - 'l', - 'm', - 18, - 0, - 18, - 18, - 1, - 4, - 1, - 4, - 1, - 2), - 'm', - 1, - NPC_CLERK), - 2011: (2519, - lnames[2011], - ('rll', - 'ms', - 'l', - 'f', - 2, - 0, - 2, - 2, - 1, - 9, - 1, - 9, - 23, - 27), - 'f', - 1, - NPC_CLERK), - 2007: (2520, - lnames[2007], - ('dss', - 'ms', - 'l', - 'm', - 10, - 0, - 10, - 10, - 1, - 5, - 1, - 5, - 1, - 20), - 'm', - 1, - NPC_HQ), - 2008: (2520, - lnames[2008], - ('fll', - 'ss', - 'l', - 'm', - 3, - 0, - 3, - 3, - 1, - 5, - 1, - 5, - 1, - 17), - 'm', - 1, - NPC_HQ), - 2009: (2520, - lnames[2009], - ('fsl', - 'md', - 'l', - 'f', - 18, - 0, - 18, - 18, - 1, - 8, - 1, - 8, - 11, - 27), - 'f', - 1, - NPC_HQ), - 2010: (2520, - lnames[2010], - ('fls', - 'ls', - 'l', - 'f', - 11, - 0, - 11, - 11, - 1, - 8, - 1, - 8, - 8, - 4), - 'f', - 1, - NPC_HQ), - 2012: (2000, - lnames[2012], - ('rss', - 'ls', - 'l', - 'm', - 17, - 0, - 17, - 17, - 1, - 6, - 1, - 6, - 1, - 1), - 'm', - 1, - NPC_FISHERMAN), - 2013: (2522, - lnames[2013], - ('rls', - 'ms', - 'l', - 'm', - 9, - 0, - 9, - 9, - 0, - 7, - 0, - 7, - 1, - 19), - 'm', - 1, - NPC_PETCLERK), - 2014: (2522, - lnames[2014], - ('mls', - 'ms', - 'm', - 'f', - 2, - 0, - 2, - 2, - 0, - 12, - 0, - 12, - 1, - 0), - 'f', - 1, - NPC_PETCLERK), - 2015: (2522, - lnames[2015], - ('hsl', - 'ls', - 'm', - 'm', - 17, - 0, - 17, - 17, - 0, - 8, - 0, - 8, - 1, - 13), - 'm', - 1, - NPC_PETCLERK), - 2016: (2000, - lnames[2016], - ('sls', - 'ls', - 'm', - 'm', - 10, - 0, - 9, - 9, - 0, - 3, - 0, - 3, - 0, - 18), - 'm', - 1, - NPC_PARTYPERSON), - 2017: (2000, - lnames[2017], - ('sss', - 'ld', - 'm', - 'f', - 10, - 0, - 9, - 9, - 0, - 23, - 0, - 23, - 0, - 5), - 'f', - 1, - NPC_PARTYPERSON), - 2018: (2513, - lnames[2019], - ('fll', - 'ss', - 's', - 'm', - 15, - 0, - 15, - 15, - 99, - 27, - 86, - 27, - 39, - 27), - 'm', - 1, - NPC_SCIENTIST), - 2019: (2513, - lnames[2018], - ('pls', - 'ls', - 'l', - 'm', - 9, - 0, - 9, - 9, - 98, - 27, - 86, - 27, - 38, - 27), - 'm', - 1, - NPC_SCIENTIST), - 2020: (2513, - lnames[2020], - ('hss', - 'ms', - 'm', - 'm', - 20, - 0, - 20, - 20, - 97, - 27, - 86, - 27, - 37, - 27), - 'm', - 1, - NPC_SCIENTIST), - 2021: (2000, - lnames[2021], - ('dss', - 'ls', - 's', - 'm', - 13, - 0, - 13, - 13, - 1, - 6, - 1, - 6, - 0, - 18), - 'm', - 1, - NPC_GLOVE), - 2101: (2601, - lnames[2101], - ('rll', - 'ms', - 'l', - 'm', - 15, - 0, - 15, - 15, - 0, - 9, - 0, - 9, - 0, - 6), - 'm', - 1, - NPC_REGULAR), - 2102: (2619, - lnames[2102], - 'r', - 'f', - 0, - NPC_REGULAR), - 2103: (2616, - lnames[2103], - ('csl', - 'ss', - 's', - 'm', - 9, - 0, - 8, - 5, - 0, - 11, - 0, - 11, - 2, - 10), - 'm', - 0, - NPC_REGULAR), - 2104: (2671, - lnames[2104], - ('mls', - 'ms', - 'm', - 'm', - 15, - 0, - 15, - 15, - 1, - 10, - 1, - 10, - 0, - 16), - 'm', - 1, - NPC_HQ), - 2105: (2671, - lnames[2105], - ('hsl', - 'ss', - 'm', - 'm', - 7, - 0, - 7, - 7, - 1, - 10, - 1, - 10, - 0, - 13), - 'm', - 1, - NPC_HQ), - 2106: (2671, - lnames[2106], - ('hss', - 'ld', - 'm', - 'f', - 23, - 0, - 23, - 23, - 1, - 23, - 1, - 23, - 24, - 27), - 'f', - 1, - NPC_HQ), - 2107: (2671, - lnames[2107], - ('cll', - 'sd', - 'm', - 'f', - 14, - 0, - 14, - 14, - 1, - 24, - 1, - 24, - 7, - 4), - 'f', - 1, - NPC_HQ), - 2108: (2603, - lnames[2108], - ('csl', - 'ms', - 'm', - 'f', - 7, - 0, - 7, - 7, - 1, - 24, - 1, - 24, - 3, - 2), - 'f', - 1, - NPC_REGULAR), - 2109: (2604, - lnames[2109], - 'r', - 'm', - 1, - NPC_REGULAR), - 2110: (2605, - lnames[2110], - ('dll', - 'ls', - 'm', - 'm', - 14, - 0, - 14, - 14, - 0, - 27, - 0, - 27, - 0, - 15), - 'm', - 0, - NPC_REGULAR), - 2111: (2607, - lnames[2111], - 'r', - 'm', - 1, - NPC_REGULAR), - 2112: (2610, - lnames[2112], - ('fll', - 'ss', - 'm', - 'm', - 20, - 0, - 20, - 20, - 0, - 27, - 0, - 27, - 0, - 9), - 'm', - 1, - NPC_REGULAR), - 2113: (2617, - lnames[2113], - ('fsl', - 'ls', - 'm', - 'm', - 14, - 0, - 14, - 14, - 0, - 0, - 0, - 0, - 0, - 2), - 'm', - 0, - NPC_REGULAR), - 2114: (2618, - lnames[2114], - ('fls', - 'sd', - 'm', - 'f', - 6, - 0, - 6, - 6, - 0, - 0, - 0, - 0, - 23, - 27), - 'f', - 0, - NPC_REGULAR), - 2115: (2621, - lnames[2115], - ('rll', - 'ms', - 'l', - 'f', - 22, - 0, - 22, - 22, - 1, - 1, - 1, - 1, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 2116: (2624, - lnames[2116], - ('rss', - 'ls', - 'l', - 'm', - 13, - 0, - 13, - 13, - 1, - 1, - 1, - 1, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 2117: (2625, - lnames[2117], - ('rls', - 'sd', - 'l', - 'f', - 6, - 0, - 6, - 6, - 1, - 2, - 1, - 2, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 2118: (2626, - lnames[2118], - ('mls', - 'ss', - 'l', - 'm', - 20, - 0, - 20, - 20, - 1, - 1, - 1, - 1, - 1, - 6), - 'm', - 0, - NPC_REGULAR), - 2119: (2629, - lnames[2119], - ('hll', - 'ss', - 'l', - 'f', - 13, - 0, - 13, - 13, - 1, - 3, - 1, - 3, - 19, - 27), - 'f', - 1, - NPC_REGULAR), - 2120: (2632, - lnames[2120], - ('hss', - 'ls', - 'l', - 'm', - 5, - 0, - 5, - 5, - 1, - 2, - 1, - 2, - 1, - 19), - 'm', - 0, - NPC_REGULAR), - 2121: (2633, - lnames[2121], - ('cll', - 'ls', - 'l', - 'f', - 21, - 0, - 21, - 21, - 0, - 4, - 0, - 4, - 4, - 4), - 'f', - 0, - NPC_REGULAR), - 2122: (2639, - lnames[2122], - ('csl', - 'ss', - 'l', - 'm', - 13, - 0, - 13, - 13, - 0, - 3, - 0, - 3, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 2123: (2643, - lnames[2123], - ('cls', - 'md', - 'l', - 'f', - 4, - 0, - 4, - 4, - 0, - 5, - 0, - 5, - 14, - 27), - 'f', - 0, - NPC_REGULAR), - 2124: (2644, - lnames[2124], - ('dll', - 'sd', - 'l', - 'f', - 21, - 0, - 21, - 21, - 0, - 5, - 0, - 5, - 8, - 21), - 'f', - 0, - NPC_REGULAR), - 2125: (2649, - lnames[2125], - ('dss', - 'ss', - 'l', - 'm', - 12, - 0, - 12, - 12, - 0, - 4, - 0, - 4, - 1, - 0), - 'm', - 0, - NPC_REGULAR), - 2126: (2654, - lnames[2126], - ('dls', - 'ld', - 'l', - 'f', - 4, - 0, - 4, - 4, - 0, - 6, - 0, - 6, - 3, - 7), - 'f', - 1, - NPC_REGULAR), - 2127: (2655, - lnames[2127], - ('fsl', - 'ms', - 'l', - 'm', - 19, - 0, - 19, - 19, - 0, - 5, - 0, - 5, - 1, - 15), - 'm', - 1, - NPC_REGULAR), - 2128: (2656, - lnames[2128], - ('fss', - 'ss', - 'l', - 'm', - 12, - 0, - 12, - 12, - 1, - 5, - 1, - 5, - 1, - 12), - 'm', - 1, - NPC_REGULAR), - 2129: (2657, - lnames[2129], - ('rll', - 'ss', - 'l', - 'm', - 4, - 0, - 4, - 4, - 1, - 5, - 1, - 5, - 1, - 9), - 'm', - 0, - NPC_REGULAR), - 2130: (2659, - lnames[2130], - ('rss', - 'md', - 'l', - 'f', - 19, - 0, - 19, - 19, - 1, - 8, - 1, - 8, - 7, - 7), - 'f', - 0, - NPC_REGULAR), - 2131: (2660, - lnames[2131], - ('rls', - 'ls', - 'l', - 'f', - 12, - 0, - 12, - 12, - 1, - 8, - 1, - 8, - 1, - 26), - 'f', - 1, - NPC_REGULAR), - 2132: (2661, - lnames[2132], - ('mls', - 'ss', - 'l', - 'm', - 4, - 0, - 4, - 4, - 1, - 6, - 1, - 6, - 1, - 17), - 'm', - 0, - NPC_REGULAR), - 2133: (2662, - lnames[2133], - ('hll', - 'ls', - 'l', - 'm', - 18, - 0, - 18, - 18, - 1, - 6, - 1, - 6, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 2134: (2664, - lnames[2134], - 'r', - 'f', - 0, - NPC_REGULAR), - 2135: (2665, - lnames[2135], - ('hls', - 'ms', - 'l', - 'f', - 3, - 0, - 3, - 3, - 0, - 12, - 0, - 12, - 2, - 26), - 'f', - 1, - NPC_REGULAR), - 2136: (2666, - lnames[2136], - ('csl', - 'ls', - 'l', - 'm', - 18, - 0, - 18, - 18, - 0, - 8, - 0, - 8, - 1, - 1), - 'm', - 0, - NPC_REGULAR), - 2137: (2667, - lnames[2137], - ('css', - 'sd', - 'l', - 'f', - 11, - 0, - 11, - 11, - 0, - 21, - 0, - 21, - 24, - 27), - 'f', - 0, - NPC_REGULAR), - 2138: (2669, - lnames[2138], - ('dll', - 'ss', - 'l', - 'm', - 3, - 0, - 3, - 3, - 0, - 9, - 0, - 9, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 2139: (2670, - lnames[2139], - 'r', - 'm', - 0, - NPC_REGULAR), - 2140: (2156, - lnames[2140], - ('dls', - 'ls', - 'l', - 'm', - 10, - 0, - 10, - 10, - 1, - 9, - 1, - 9, - 1, - 10), - 'm', - 0, - NPC_FISHERMAN), - 2201: (2711, - lnames[2201], - ('dss', - 'ss', - 'l', - 'm', - 13, - 0, - 13, - 13, - 1, - 6, - 1, - 6, - 0, - 17), - 'm', - 1, - NPC_REGULAR), - 2202: (2718, - lnames[2202], - 'r', - 'f', - 1, - NPC_REGULAR), - 2203: (2742, - lnames[2203], - ('fss', - 'ms', - 's', - 'm', - 19, - 0, - 19, - 19, - 0, - 7, - 0, - 7, - 0, - 11), - 'm', - 1, - NPC_HQ), - 2204: (2742, - lnames[2204], - ('fls', - 'ss', - 's', - 'm', - 13, - 0, - 13, - 13, - 0, - 7, - 0, - 7, - 0, - 6), - 'm', - 1, - NPC_HQ), - 2205: (2742, - lnames[2205], - ('rsl', - 'md', - 's', - 'f', - 4, - 0, - 4, - 4, - 0, - 11, - 0, - 11, - 16, - 27), - 'f', - 1, - NPC_HQ), - 2206: (2742, - lnames[2206], - ('rss', - 'sd', - 's', - 'f', - 21, - 0, - 21, - 21, - 0, - 12, - 0, - 12, - 0, - 8), - 'f', - 1, - NPC_HQ), - 2207: (2705, - lnames[2207], - ('mss', - 'ss', - 's', - 'm', - 12, - 0, - 12, - 12, - 0, - 8, - 0, - 8, - 0, - 16), - 'm', - 1, - NPC_REGULAR), - 2208: (2708, - lnames[2208], - ('mls', - 'ls', - 's', - 'm', - 4, - 0, - 4, - 4, - 1, - 8, - 1, - 8, - 0, - 13), - 'm', - 1, - NPC_REGULAR), - 2209: (2712, - lnames[2209], - ('hsl', - 'ms', - 's', - 'm', - 19, - 0, - 19, - 19, - 1, - 8, - 1, - 8, - 0, - 10), - 'm', - 1, - NPC_REGULAR), - 2210: (2713, - lnames[2210], - ('hss', - 'ms', - 's', - 'f', - 12, - 0, - 12, - 12, - 1, - 21, - 1, - 21, - 1, - 24), - 'f', - 1, - NPC_REGULAR), - 2211: (2716, - lnames[2211], - ('cll', - 'ss', - 's', - 'f', - 3, - 0, - 3, - 3, - 1, - 22, - 1, - 22, - 25, - 27), - 'f', - 1, - NPC_REGULAR), - 2212: (2717, - lnames[2212], - ('css', - 'ls', - 's', - 'm', - 18, - 0, - 18, - 18, - 1, - 9, - 1, - 9, - 0, - 18), - 'm', - 0, - NPC_REGULAR), - 2213: (2720, - lnames[2213], - ('cls', - 'ls', - 's', - 'f', - 12, - 0, - 12, - 12, - 1, - 23, - 1, - 23, - 11, - 27), - 'f', - 1, - NPC_REGULAR), - 2214: (2723, - lnames[2214], - 'r', - 'm', - 0, - NPC_REGULAR), - 2215: (2727, - lnames[2215], - ('dss', - 'ls', - 'm', - 'm', - 18, - 0, - 18, - 18, - 0, - 11, - 0, - 11, - 0, - 9), - 'm', - 0, - NPC_REGULAR), - 2216: (2728, - lnames[2216], - ('fll', - 'sd', - 'm', - 'f', - 11, - 0, - 11, - 11, - 0, - 25, - 0, - 25, - 12, - 27), - 'f', - 0, - NPC_REGULAR), - 2217: (2729, - lnames[2217], - ('fsl', - 'ss', - 'm', - 'm', - 4, - 0, - 4, - 4, - 0, - 12, - 0, - 12, - 0, - 20), - 'm', - 1, - NPC_REGULAR), - 2218: (2730, - lnames[2218], - 'r', - 'f', - 0, - NPC_REGULAR), - 2219: (2732, - lnames[2219], - ('rll', - 'ms', - 'm', - 'm', - 10, - 0, - 10, - 10, - 0, - 27, - 0, - 27, - 0, - 14), - 'm', - 0, - NPC_REGULAR), - 2220: (2733, - lnames[2220], - ('rss', - 'ss', - 'm', - 'm', - 3, - 0, - 3, - 3, - 1, - 12, - 1, - 12, - 0, - 11), - 'm', - 0, - NPC_REGULAR), - 2221: (2734, - lnames[2221], - 'r', - 'f', - 0, - NPC_REGULAR), - 2222: (2735, - lnames[2222], - ('mls', - 'ls', - 'm', - 'm', - 10, - 0, - 10, - 10, - 1, - 0, - 1, - 0, - 0, - 1), - 'm', - 0, - NPC_REGULAR), - 2223: (2739, - lnames[2223], - 'r', - 'f', - 0, - NPC_REGULAR), - 2224: (2740, - lnames[2224], - ('hss', - 'ss', - 'm', - 'm', - 17, - 0, - 17, - 17, - 1, - 1, - 1, - 1, - 0, - 16), - 'm', - 0, - NPC_REGULAR), - 2225: (2236, - lnames[2225], - ('cll', - 'ls', - 'm', - 'm', - 9, - 0, - 9, - 9, - 1, - 1, - 1, - 1, - 0, - 13), - 'm', - 0, - NPC_FISHERMAN), - 2301: (2804, - lnames[2301], - ('cll', - 'ms', - 'm', - 'm', - 10, - 0, - 10, - 10, - 1, - 3, - 1, - 3, - 0, - 6), - 'm', - 1, - NPC_REGULAR), - 2302: (2831, - lnames[2302], - ('css', - 'ms', - 'm', - 'm', - 3, - 0, - 3, - 3, - 1, - 3, - 1, - 3, - 0, - 1), - 'm', - 1, - NPC_REGULAR), - 2303: (2834, - lnames[2303], - 'r', - 'f', - 0, - NPC_REGULAR), - 2304: (2832, - lnames[2304], - ('dss', - 'ss', - 'm', - 'm', - 9, - 0, - 9, - 9, - 0, - 10, - 0, - 10, - 1, - 12), - 'm', - 1, - NPC_HQ), - 2305: (2832, - lnames[2305], - ('dss', - 'ss', - 'm', - 'm', - 8, - 0, - 8, - 8, - 1, - 0, - 1, - 0, - 1, - 9), - 'm', - 1, - NPC_HQ), - 2306: (2832, - lnames[2306], - ('fll', - 'md', - 'm', - 'f', - 24, - 0, - 24, - 24, - 1, - 0, - 1, - 0, - 16, - 27), - 'f', - 1, - NPC_HQ), - 2307: (2832, - lnames[2307], - ('fsl', - 'ls', - 'm', - 'f', - 16, - 0, - 16, - 16, - 1, - 1, - 1, - 1, - 3, - 1), - 'f', - 1, - NPC_HQ), - 2308: (2801, - lnames[2308], - ('fls', - 'ss', - 'm', - 'f', - 8, - 0, - 8, - 8, - 1, - 1, - 1, - 1, - 14, - 27), - 'f', - 1, - NPC_REGULAR), - 2309: (2802, - lnames[2309], - ('rsl', - 'ls', - 'm', - 'm', - 22, - 0, - 22, - 22, - 1, - 1, - 1, - 1, - 1, - 14), - 'm', - 1, - NPC_REGULAR), - 2311: (2809, - lnames[2311], - ('mss', - 'ss', - 'm', - 'm', - 7, - 0, - 7, - 7, - 0, - 2, - 0, - 2, - 1, - 6), - 'm', - 1, - NPC_REGULAR), - 2312: (2837, - lnames[2312], - ('mls', - 'ld', - 'm', - 'f', - 24, - 0, - 24, - 24, - 0, - 3, - 0, - 3, - 4, - 6), - 'f', - 0, - NPC_REGULAR), - 2313: (2817, - lnames[2313], - 'r', - 'f', - 0, - NPC_REGULAR), - 2314: (2818, - lnames[2314], - ('hss', - 'ms', - 'm', - 'm', - 7, - 0, - 7, - 7, - 0, - 3, - 0, - 3, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 2315: (2822, - lnames[2315], - ('cll', - 'ss', - 'm', - 'm', - 21, - 0, - 21, - 21, - 0, - 3, - 0, - 3, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 2316: (2823, - lnames[2316], - ('csl', - 'md', - 'l', - 'f', - 15, - 0, - 15, - 15, - 0, - 5, - 0, - 5, - 0, - 23), - 'f', - 0, - NPC_REGULAR), - 2318: (2829, - lnames[2318], - ('dsl', - 'ss', - 'l', - 'm', - 21, - 0, - 21, - 21, - 1, - 4, - 1, - 4, - 1, - 0), - 'm', - 0, - NPC_REGULAR), - 2319: (2830, - lnames[2319], - ('dss', - 'ls', - 'l', - 'm', - 14, - 0, - 14, - 14, - 1, - 5, - 1, - 5, - 1, - 18), - 'm', - 0, - NPC_REGULAR), - 2320: (2839, - lnames[2320], - 'r', - 'm', - 0, - NPC_REGULAR), - 2321: (2341, - lnames[2321], - ('fsl', - 'ss', - 'l', - 'm', - 21, - 0, - 21, - 21, - 1, - 5, - 1, - 5, - 0, - 12), - 'm', - 0, - NPC_FISHERMAN), - 1001: (1506, - lnames[1001], - ('rss', - 'ms', - 'l', - 'm', - 10, - 0, - 10, - 10, - 0, - 11, - 0, - 11, - 0, - 0), - 'm', - 0, - NPC_CLERK), - 1002: (1506, - lnames[1002], - ('mss', - 'ss', - 'l', - 'm', - 3, - 0, - 3, - 3, - 1, - 10, - 1, - 10, - 0, - 18), - 'm', - 0, - NPC_CLERK), - 1003: (1507, - lnames[1003], - ('mls', - 'ss', - 'l', - 'm', - 17, - 0, - 17, - 17, - 1, - 11, - 1, - 11, - 0, - 15), - 'm', - 0, - NPC_HQ), - 1004: (1507, - lnames[1004], - ('hsl', - 'md', - 'l', - 'f', - 10, - 0, - 10, - 10, - 1, - 24, - 1, - 24, - 24, - 27), - 'f', - 0, - NPC_HQ), - 1005: (1507, - lnames[1005], - ('hss', - 'ms', - 'l', - 'm', - 3, - 0, - 3, - 3, - 1, - 11, - 1, - 11, - 0, - 9), - 'm', - 0, - NPC_HQ), - 1006: (1507, - lnames[1006], - ('cll', - 'ss', - 'l', - 'f', - 18, - 0, - 18, - 18, - 1, - 25, - 1, - 25, - 19, - 27), - 'f', - 0, - NPC_HQ), - 1007: (1508, - lnames[1007], - ('csl', - 'ls', - 'm', - 'm', - 9, - 0, - 9, - 9, - 1, - 12, - 1, - 12, - 0, - 20), - 'm', - 0, - NPC_TAILOR), - 1008: (1000, - lnames[1008], - ('cls', - 'ms', - 'm', - 'm', - 3, - 0, - 3, - 3, - 0, - 27, - 0, - 27, - 0, - 17), - 'm', - 0, - NPC_FISHERMAN), - 1009: (1510, - lnames[1009], - ('dsl', - 'ss', - 'm', - 'm', - 17, - 0, - 17, - 17, - 0, - 0, - 0, - 0, - 0, - 14), - 'm', - 0, - NPC_PETCLERK), - 1010: (1510, - lnames[1010], - ('dss', - 'ld', - 'm', - 'f', - 10, - 0, - 10, - 10, - 0, - 0, - 0, - 0, - 26, - 27), - 'f', - 0, - NPC_PETCLERK), - 1011: (1510, - lnames[1011], - ('fll', - 'sd', - 'm', - 'f', - 1, - 0, - 1, - 1, - 0, - 1, - 0, - 1, - 4, - 25), - 'f', - 0, - NPC_PETCLERK), - 1012: (1000, - lnames[1012], - ('fls', - 'ms', - 'l', - 'm', - 14, - 0, - 3, - 3, - 0, - 1, - 0, - 1, - 0, - 13), - 'm', - 1, - NPC_PARTYPERSON), - 1013: (1000, - lnames[1013], - ('fss', - 'ms', - 'm', - 'f', - 2, - 0, - 3, - 3, - 1, - 6, - 1, - 6, - 5, - 6), - 'f', - 1, - NPC_PARTYPERSON), - 1101: (1627, - lnames[1101], - ('fll', - 'ls', - 'm', - 'm', - 14, - 0, - 14, - 14, - 1, - 3, - 1, - 3, - 1, - 9), - 'm', - 0, - NPC_REGULAR), - 1102: (1612, - lnames[1102], - ('fsl', - 'ms', - 'm', - 'm', - 7, - 0, - 7, - 7, - 1, - 3, - 1, - 3, - 1, - 2), - 'm', - 0, - NPC_REGULAR), - 1103: (1626, - lnames[1103], - 'r', - 'm', - 0, - NPC_REGULAR), - 1104: (1617, - lnames[1104], - 'r', - 'm', - 0, - NPC_REGULAR), - 1105: (1606, - lnames[1105], - ('rss', - 'ms', - 'm', - 'm', - 6, - 0, - 6, - 6, - 0, - 4, - 0, - 4, - 1, - 14), - 'm', - 1, - NPC_REGULAR), - 1106: (1604, - lnames[1106], - 'r', - 'f', - 1, - NPC_REGULAR), - 1107: (1621, - lnames[1107], - 'r', - 'm', - 0, - NPC_REGULAR), - 1108: (1629, - lnames[1108], - ('hsl', - 'ls', - 'l', - 'm', - 6, - 0, - 6, - 6, - 0, - 6, - 0, - 6, - 1, - 1), - 'm', - 0, - NPC_HQ), - 1109: (1629, - lnames[1109], - ('hss', - 'ls', - 'l', - 'f', - 22, - 0, - 22, - 22, - 0, - 8, - 0, - 8, - 14, - 27), - 'f', - 0, - NPC_HQ), - 1110: (1629, - lnames[1110], - ('cll', - 'ss', - 'l', - 'm', - 13, - 0, - 13, - 13, - 1, - 6, - 1, - 6, - 1, - 16), - 'm', - 0, - NPC_HQ), - 1111: (1629, - lnames[1111], - ('csl', - 'ld', - 'l', - 'f', - 6, - 0, - 6, - 6, - 1, - 9, - 1, - 9, - 2, - 2), - 'f', - 0, - NPC_HQ), - 1112: (1602, - lnames[1112], - ('cls', - 'ms', - 'l', - 'm', - 20, - 0, - 20, - 20, - 1, - 7, - 1, - 7, - 1, - 10), - 'm', - 1, - NPC_REGULAR), - 1113: (1608, - lnames[1113], - ('dll', - 'ms', - 'l', - 'f', - 13, - 0, - 13, - 13, - 1, - 11, - 1, - 11, - 0, - 27), - 'f', - 1, - NPC_REGULAR), - 1114: (1609, - lnames[1114], - ('dss', - 'ls', - 'l', - 'm', - 5, - 0, - 5, - 5, - 1, - 7, - 1, - 7, - 1, - 0), - 'm', - 1, - NPC_REGULAR), - 1115: (1613, - lnames[1115], - ('fll', - 'sd', - 'l', - 'f', - 21, - 0, - 21, - 21, - 1, - 12, - 1, - 12, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 1116: (1614, - lnames[1116], - ('fsl', - 'ls', - 'l', - 'f', - 13, - 0, - 13, - 13, - 1, - 12, - 1, - 12, - 1, - 25), - 'f', - 0, - NPC_REGULAR), - 1117: (1615, - lnames[1117], - ('fls', - 'ss', - 'l', - 'm', - 5, - 0, - 5, - 5, - 0, - 9, - 0, - 9, - 1, - 12), - 'm', - 0, - NPC_REGULAR), - 1118: (1616, - lnames[1118], - ('rll', - 'ls', - 'l', - 'm', - 19, - 0, - 19, - 19, - 0, - 9, - 0, - 9, - 1, - 9), - 'm', - 0, - NPC_REGULAR), - 1121: (1619, - lnames[1121], - 'r', - 'f', - 0, - NPC_REGULAR), - 1122: (1620, - lnames[1122], - ('hll', - 'ms', - 'l', - 'm', - 12, - 0, - 12, - 12, - 0, - 11, - 0, - 11, - 0, - 14), - 'm', - 0, - NPC_REGULAR), - 1123: (1622, - lnames[1123], - ('hss', - 'ms', - 'l', - 'f', - 4, - 0, - 4, - 4, - 1, - 23, - 1, - 23, - 23, - 27), - 'f', - 0, - NPC_REGULAR), - 1124: (1624, - lnames[1124], - ('cll', - 'ls', - 'l', - 'm', - 19, - 0, - 19, - 19, - 1, - 11, - 1, - 11, - 0, - 6), - 'm', - 0, - NPC_REGULAR), - 1125: (1628, - lnames[1125], - ('csl', - 'sd', - 'l', - 'f', - 12, - 0, - 12, - 12, - 1, - 24, - 1, - 24, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 1126: (1129, - lnames[1126], - ('cls', - 'ms', - 'l', - 'm', - 4, - 0, - 4, - 4, - 1, - 11, - 1, - 11, - 0, - 19), - 'm', - 0, - NPC_FISHERMAN), - 1201: (1710, - lnames[1201], - ('css', - 'ls', - 's', - 'f', - 12, - 0, - 12, - 12, - 0, - 0, - 0, - 0, - 1, - 24), - 'f', - 0, - NPC_REGULAR), - 1202: (1713, - lnames[1202], - ('cls', - 'ss', - 's', - 'm', - 4, - 0, - 4, - 4, - 0, - 0, - 0, - 0, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 1203: (1725, - lnames[1203], - 'r', - 'm', - 0, - NPC_REGULAR), - 1204: (1712, - lnames[1204], - ('dss', - 'ms', - 's', - 'm', - 12, - 0, - 12, - 12, - 1, - 1, - 1, - 1, - 1, - 6), - 'm', - 0, - NPC_REGULAR), - 1205: (1729, - lnames[1205], - ('fll', - 'ss', - 's', - 'm', - 4, - 0, - 4, - 4, - 1, - 1, - 1, - 1, - 1, - 1), - 'm', - 0, - NPC_HQ), - 1206: (1729, - lnames[1206], - ('fss', - 'ld', - 's', - 'f', - 19, - 0, - 19, - 19, - 1, - 2, - 1, - 2, - 7, - 11), - 'f', - 0, - NPC_HQ), - 1207: (1729, - lnames[1207], - ('fls', - 'ms', - 's', - 'm', - 12, - 0, - 12, - 12, - 1, - 2, - 1, - 2, - 1, - 16), - 'm', - 0, - NPC_HQ), - 1208: (1729, - lnames[1208], - ('rsl', - 'ls', - 'm', - 'f', - 3, - 0, - 3, - 3, - 1, - 3, - 1, - 3, - 23, - 27), - 'f', - 0, - NPC_HQ), - 1209: (1701, - lnames[1209], - ('rss', - 'ss', - 'm', - 'f', - 19, - 0, - 19, - 19, - 0, - 4, - 0, - 4, - 17, - 27), - 'f', - 1, - NPC_REGULAR), - 1210: (1703, - lnames[1210], - 'r', - 'm', - 1, - NPC_REGULAR), - 1211: (1705, - lnames[1211], - ('mls', - 'ms', - 'm', - 'm', - 4, - 0, - 4, - 4, - 0, - 4, - 0, - 4, - 1, - 0), - 'm', - 1, - NPC_REGULAR), - 1212: (1706, - lnames[1212], - ('hsl', - 'ss', - 'm', - 'm', - 18, - 0, - 18, - 18, - 0, - 4, - 0, - 4, - 1, - 18), - 'm', - 1, - NPC_REGULAR), - 1213: (1707, - lnames[1213], - ('hss', - 'ls', - 'm', - 'm', - 10, - 0, - 10, - 10, - 0, - 4, - 0, - 4, - 1, - 15), - 'm', - 1, - NPC_REGULAR), - 1214: (1709, - lnames[1214], - ('cll', - 'sd', - 'm', - 'f', - 2, - 0, - 2, - 2, - 0, - 7, - 0, - 7, - 1, - 12), - 'f', - 1, - NPC_REGULAR), - 1215: (1711, - lnames[1215], - ('css', - 'ms', - 'm', - 'f', - 18, - 0, - 18, - 18, - 0, - 7, - 0, - 7, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 1216: (1714, - lnames[1216], - ('cls', - 'ls', - 'm', - 'm', - 10, - 0, - 10, - 10, - 1, - 5, - 1, - 5, - 1, - 2), - 'm', - 0, - NPC_REGULAR), - 1217: (1716, - lnames[1217], - 'r', - 'f', - 0, - NPC_REGULAR), - 1218: (1717, - lnames[1218], - ('dss', - 'ms', - 'm', - 'm', - 17, - 0, - 17, - 17, - 1, - 6, - 1, - 6, - 1, - 17), - 'm', - 0, - NPC_REGULAR), - 1219: (1718, - lnames[1219], - ('fll', - 'ss', - 'm', - 'm', - 9, - 0, - 9, - 9, - 1, - 6, - 1, - 6, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 1220: (1719, - lnames[1220], - ('fsl', - 'md', - 'm', - 'f', - 2, - 0, - 2, - 2, - 1, - 9, - 1, - 9, - 7, - 23), - 'f', - 0, - NPC_REGULAR), - 1221: (1720, - lnames[1221], - 'r', - 'm', - 0, - NPC_REGULAR), - 1222: (1721, - lnames[1222], - 'r', - 'm', - 0, - NPC_REGULAR), - 1223: (1723, - lnames[1223], - ('rss', - 'ls', - 'l', - 'm', - 2, - 0, - 2, - 2, - 0, - 8, - 0, - 8, - 1, - 19), - 'm', - 0, - NPC_REGULAR), - 1224: (1724, - lnames[1224], - ('mss', - 'sd', - 'l', - 'f', - 17, - 0, - 17, - 17, - 0, - 21, - 0, - 21, - 7, - 9), - 'f', - 0, - NPC_REGULAR), - 1225: (1726, - lnames[1225], - ('mls', - 'ss', - 'l', - 'm', - 9, - 0, - 9, - 9, - 0, - 9, - 0, - 9, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 1226: (1727, - lnames[1226], - ('hsl', - 'ls', - 'l', - 'm', - 2, - 0, - 2, - 2, - 0, - 9, - 0, - 9, - 1, - 10), - 'm', - 0, - NPC_REGULAR), - 1227: (1728, - lnames[1227], - ('hss', - 'sd', - 'l', - 'f', - 17, - 0, - 17, - 17, - 0, - 22, - 0, - 22, - 3, - 7), - 'f', - 0, - NPC_REGULAR), - 1228: (1236, - lnames[1228], - ('cll', - 'ms', - 'l', - 'm', - 8, - 0, - 8, - 8, - 1, - 9, - 1, - 9, - 1, - 0), - 'm', - 0, - NPC_FISHERMAN), - 1301: (1828, - lnames[1301], - ('mls', - 'md', - 'm', - 'f', - 16, - 0, - 16, - 16, - 1, - 8, - 1, - 8, - 14, - 27), - 'f', - 0, - NPC_REGULAR), - 1302: (1832, - lnames[1302], - ('hsl', - 'ms', - 'm', - 'm', - 8, - 0, - 8, - 8, - 1, - 6, - 1, - 6, - 0, - 18), - 'm', - 0, - NPC_REGULAR), - 1303: (1826, - lnames[1303], - ('hls', - 'ss', - 'm', - 'm', - 22, - 0, - 22, - 22, - 1, - 6, - 1, - 6, - 0, - 15), - 'm', - 0, - NPC_REGULAR), - 1304: (1804, - lnames[1304], - ('cll', - 'md', - 'm', - 'f', - 15, - 0, - 15, - 15, - 1, - 9, - 1, - 9, - 23, - 27), - 'f', - 1, - NPC_REGULAR), - 1305: (1835, - lnames[1305], - ('css', - 'ms', - 'm', - 'm', - 7, - 0, - 7, - 7, - 1, - 7, - 1, - 7, - 0, - 9), - 'm', - 0, - NPC_HQ), - 1306: (1835, - lnames[1306], - ('cls', - 'ms', - 'm', - 'f', - 24, - 0, - 24, - 24, - 0, - 12, - 0, - 12, - 0, - 7), - 'f', - 0, - NPC_HQ), - 1307: (1835, - lnames[1307], - ('dsl', - 'ls', - 'm', - 'm', - 15, - 0, - 15, - 15, - 0, - 8, - 0, - 8, - 0, - 20), - 'm', - 0, - NPC_HQ), - 1308: (1835, - lnames[1308], - ('dss', - 'sd', - 'm', - 'f', - 8, - 0, - 8, - 8, - 0, - 21, - 0, - 21, - 4, - 5), - 'f', - 0, - NPC_HQ), - 1309: (1802, - lnames[1309], - ('fll', - 'ms', - 'l', - 'f', - 23, - 0, - 23, - 23, - 0, - 21, - 0, - 21, - 1, - 12), - 'f', - 1, - NPC_REGULAR), - 1310: (1805, - lnames[1310], - ('fsl', - 'ss', - 'l', - 'm', - 15, - 0, - 15, - 15, - 0, - 9, - 0, - 9, - 0, - 11), - 'm', - 1, - NPC_REGULAR), - 1311: (1806, - lnames[1311], - 'r', - 'f', - 1, - NPC_REGULAR), - 1312: (1807, - lnames[1312], - ('rsl', - 'ms', - 'l', - 'm', - 21, - 0, - 21, - 21, - 1, - 9, - 1, - 9, - 0, - 1), - 'm', - 1, - NPC_REGULAR), - 1313: (1808, - lnames[1313], - ('rss', - 'ss', - 'l', - 'm', - 14, - 0, - 14, - 14, - 1, - 10, - 1, - 10, - 0, - 19), - 'm', - 1, - NPC_REGULAR), - 1314: (1809, - lnames[1314], - ('mss', - 'ls', - 'l', - 'm', - 6, - 0, - 6, - 6, - 1, - 10, - 1, - 10, - 0, - 16), - 'm', - 1, - NPC_REGULAR), - 1315: (1810, - lnames[1315], - 'r', - 'f', - 0, - NPC_REGULAR), - 1316: (1811, - lnames[1316], - ('hsl', - 'ms', - 'l', - 'f', - 14, - 0, - 14, - 14, - 1, - 24, - 1, - 24, - 7, - 7), - 'f', - 0, - NPC_REGULAR), - 1317: (1813, - lnames[1317], - ('hss', - 'ld', - 'l', - 'f', - 7, - 0, - 7, - 7, - 1, - 25, - 1, - 25, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 1318: (1814, - lnames[1318], - ('cll', - 'ms', - 'l', - 'm', - 20, - 0, - 20, - 20, - 0, - 12, - 0, - 12, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 1319: (1815, - lnames[1319], - ('csl', - 'ss', - 'l', - 'm', - 14, - 0, - 14, - 14, - 0, - 27, - 0, - 27, - 0, - 18), - 'm', - 0, - NPC_REGULAR), - 1320: (1818, - lnames[1320], - 'r', - 'm', - 0, - NPC_REGULAR), - 1321: (1819, - lnames[1321], - ('dsl', - 'md', - 'l', - 'f', - 22, - 0, - 22, - 22, - 0, - 27, - 0, - 27, - 7, - 5), - 'f', - 0, - NPC_REGULAR), - 1322: (1820, - lnames[1322], - ('dss', - 'ls', - 'm', - 'f', - 13, - 0, - 13, - 13, - 0, - 0, - 0, - 0, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 1323: (1821, - lnames[1323], - ('fll', - 'ss', - 'm', - 'm', - 6, - 0, - 6, - 6, - 0, - 0, - 0, - 0, - 1, - 2), - 'm', - 0, - NPC_REGULAR), - 1324: (1823, - lnames[1324], - ('fsl', - 'md', - 'm', - 'f', - 22, - 0, - 22, - 22, - 0, - 1, - 0, - 1, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 1325: (1824, - lnames[1325], - 'r', - 'm', - 0, - NPC_REGULAR), - 1326: (1825, - lnames[1326], - ('rll', - 'ms', - 'm', - 'f', - 6, - 0, - 6, - 6, - 1, - 2, - 1, - 2, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 1327: (1829, - lnames[1327], - 'r', - 'f', - 0, - NPC_REGULAR), - 1328: (1830, - lnames[1328], - ('rls', - 'ms', - 'm', - 'm', - 13, - 0, - 13, - 13, - 1, - 2, - 1, - 2, - 1, - 6), - 'm', - 0, - NPC_REGULAR), - 1329: (1831, - lnames[1329], - ('mls', - 'ms', - 'm', - 'f', - 4, - 0, - 4, - 4, - 1, - 3, - 1, - 3, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 1330: (1833, - lnames[1330], - ('hsl', - 'ls', - 'm', - 'm', - 19, - 0, - 19, - 19, - 1, - 3, - 1, - 3, - 1, - 19), - 'm', - 0, - NPC_REGULAR), - 1331: (1834, - lnames[1331], - ('hss', - 'ls', - 'm', - 'm', - 12, - 0, - 12, - 12, - 0, - 3, - 0, - 3, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 1332: (1330, - lnames[1332], - ('cll', - 'ms', - 'm', - 'm', - 5, - 0, - 5, - 5, - 0, - 4, - 0, - 4, - 1, - 13), - 'm', - 0, - NPC_FISHERMAN), - 3001: (3506, - lnames[3001], - 'r', - 'f', - 0, - NPC_REGULAR), - 3002: (3508, - lnames[3002], - ('cls', - 'ms', - 'm', - 'm', - 4, - 0, - 4, - 4, - 1, - 9, - 1, - 9, - 0, - 18), - 'm', - 0, - NPC_HQ), - 3003: (3508, - lnames[3003], - ('dsl', - 'ss', - 'm', - 'f', - 19, - 0, - 19, - 19, - 1, - 22, - 1, - 22, - 25, - 27), - 'f', - 0, - NPC_HQ), - 3004: (3508, - lnames[3004], - ('dss', - 'ls', - 'm', - 'm', - 12, - 0, - 12, - 12, - 1, - 10, - 1, - 10, - 0, - 12), - 'm', - 0, - NPC_HQ), - 3005: (3508, - lnames[3005], - ('fll', - 'ms', - 'm', - 'm', - 4, - 0, - 4, - 4, - 0, - 11, - 0, - 11, - 0, - 9), - 'm', - 0, - NPC_HQ), - 3006: (3507, - lnames[3006], - ('fsl', - 'ss', - 'm', - 'm', - 18, - 0, - 18, - 18, - 0, - 11, - 0, - 11, - 0, - 2), - 'm', - 0, - NPC_CLERK), - 3007: (3507, - lnames[3007], - ('fls', - 'ld', - 'm', - 'f', - 12, - 0, - 12, - 12, - 0, - 25, - 0, - 25, - 8, - 5), - 'f', - 0, - NPC_CLERK), - 3008: (3509, - lnames[3008], - ('rll', - 'ms', - 'l', - 'm', - 4, - 0, - 4, - 4, - 0, - 12, - 0, - 12, - 0, - 17), - 'm', - 0, - NPC_TAILOR), - 3009: (3000, - lnames[3009], - ('rss', - 'ls', - 'l', - 'f', - 19, - 0, - 19, - 19, - 0, - 26, - 0, - 26, - 4, - 23), - 'f', - 0, - NPC_FISHERMAN), - 3010: (3511, - lnames[3010], - ('rls', - 'ss', - 'l', - 'm', - 10, - 0, - 10, - 10, - 0, - 12, - 0, - 12, - 0, - 11), - 'm', - 0, - NPC_PETCLERK), - 3011: (3511, - lnames[3011], - ('mls', - 'md', - 'l', - 'f', - 3, - 0, - 3, - 3, - 1, - 26, - 1, - 26, - 26, - 27), - 'f', - 0, - NPC_PETCLERK), - 3012: (3511, - lnames[3012], - ('hsl', - 'ms', - 'l', - 'm', - 18, - 0, - 18, - 18, - 1, - 12, - 1, - 12, - 0, - 1), - 'm', - 0, - NPC_PETCLERK), - 3013: (3000, - lnames[3013], - ('cls', - 'ss', - 'm', - 'm', - 18, - 0, - 17, - 17, - 1, - 7, - 1, - 7, - 1, - 9), - 'm', - 1, - NPC_PARTYPERSON), - 3014: (3000, - lnames[3014], - ('css', - 'sd', - 'm', - 'f', - 17, - 0, - 16, - 16, - 0, - 24, - 0, - 24, - 0, - 9), - 'f', - 1, - NPC_PARTYPERSON), - 3101: (3611, - lnames[3101], - ('mls', - 'ls', - 'l', - 'm', - 16, - 0, - 16, - 16, - 1, - 1, - 1, - 1, - 1, - 6), - 'm', - 0, - NPC_REGULAR), - 3102: (3625, - lnames[3102], - 'r', - 'f', - 0, - NPC_REGULAR), - 3103: (3641, - lnames[3103], - 'r', - 'm', - 0, - NPC_REGULAR), - 3104: (3602, - lnames[3104], - ('cll', - 'ss', - 'l', - 'f', - 16, - 0, - 16, - 16, - 0, - 4, - 0, - 4, - 3, - 2), - 'f', - 1, - NPC_REGULAR), - 3105: (3651, - lnames[3105], - 'r', - 'm', - 0, - NPC_REGULAR), - 3106: (3636, - lnames[3106], - ('fll', - 'ls', - 'l', - 'm', - 8, - 2, - 8, - 8, - 10, - 27, - 0, - 27, - 7, - 11), - 'm', - 0, - NPC_REGULAR), - 3107: (3630, - lnames[3107], - ('dll', - 'ms', - 'l', - 'f', - 15, - 0, - 15, - 15, - 0, - 5, - 0, - 5, - 4, - 4), - 'f', - 0, - NPC_REGULAR), - 3108: (3638, - lnames[3108], - 'r', - 'm', - 0, - NPC_REGULAR), - 3109: (3637, - lnames[3109], - ('fll', - 'sd', - 'm', - 'f', - 23, - 0, - 23, - 23, - 1, - 6, - 1, - 6, - 12, - 27), - 'f', - 0, - NPC_REGULAR), - 3110: (3629, - lnames[3110], - ('fss', - 'ms', - 'l', - 'm', - 10, - 10, - 10, - 10, - 16, - 4, - 0, - 4, - 5, - 4), - 'm', - 0, - NPC_REGULAR), - 3111: (3627, - lnames[3111], - ('dsl', - 'ls', - 's', - 'm', - 6, - 0, - 6, - 6, - 14, - 27, - 10, - 27, - 1, - 14), - 'm', - 1, - NPC_REGULAR), - 3112: (3607, - lnames[3112], - ('rll', - 'ls', - 'm', - 'm', - 21, - 0, - 21, - 21, - 1, - 5, - 1, - 5, - 1, - 9), - 'm', - 1, - NPC_REGULAR), - 3113: (3618, - lnames[3113], - ('rss', - 'ms', - 'm', - 'm', - 14, - 0, - 14, - 14, - 1, - 5, - 1, - 5, - 0, - 2), - 'm', - 0, - NPC_REGULAR), - 3114: (3620, - lnames[3114], - ('rls', - 'ss', - 'm', - 'm', - 7, - 0, - 7, - 7, - 0, - 6, - 0, - 6, - 0, - 20), - 'm', - 0, - NPC_REGULAR), - 3115: (3654, - lnames[3115], - ('mls', - 'ls', - 'm', - 'm', - 21, - 0, - 21, - 21, - 0, - 7, - 0, - 7, - 0, - 17), - 'm', - 0, - NPC_HQ), - 3116: (3654, - lnames[3116], - ('hll', - 'ls', - 'm', - 'f', - 14, - 0, - 14, - 14, - 0, - 11, - 0, - 11, - 0, - 12), - 'f', - 0, - NPC_HQ), - 3117: (3654, - lnames[3117], - ('hss', - 'ss', - 'm', - 'm', - 6, - 0, - 6, - 6, - 0, - 7, - 0, - 7, - 0, - 11), - 'm', - 0, - NPC_HQ), - 3118: (3654, - lnames[3118], - ('cll', - 'ls', - 'm', - 'm', - 20, - 0, - 20, - 20, - 0, - 8, - 0, - 8, - 0, - 6), - 'm', - 0, - NPC_HQ), - 3119: (3653, - lnames[3119], - ('csl', - 'ms', - 'm', - 'm', - 14, - 0, - 14, - 14, - 0, - 8, - 0, - 8, - 0, - 1), - 'm', - 0, - NPC_REGULAR), - 3120: (3610, - lnames[3120], - ('cls', - 'ss', - 'm', - 'm', - 6, - 0, - 6, - 6, - 1, - 8, - 1, - 8, - 0, - 19), - 'm', - 0, - NPC_REGULAR), - 3121: (3601, - lnames[3121], - ('dll', - 'ls', - 'm', - 'm', - 20, - 0, - 20, - 20, - 1, - 8, - 1, - 8, - 0, - 16), - 'm', - 1, - NPC_REGULAR), - 3122: (3608, - lnames[3122], - ('dss', - 'md', - 'l', - 'f', - 13, - 0, - 13, - 13, - 1, - 21, - 1, - 21, - 10, - 27), - 'f', - 1, - NPC_REGULAR), - 3123: (3612, - lnames[3123], - ('dls', - 'ms', - 'l', - 'm', - 6, - 0, - 6, - 6, - 1, - 9, - 1, - 9, - 0, - 10), - 'm', - 0, - NPC_REGULAR), - 3124: (3613, - lnames[3124], - ('fsl', - 'ss', - 'l', - 'm', - 20, - 0, - 20, - 20, - 1, - 9, - 1, - 9, - 0, - 4), - 'm', - 0, - NPC_REGULAR), - 3125: (3614, - lnames[3125], - ('fls', - 'ls', - 'l', - 'm', - 13, - 0, - 13, - 13, - 1, - 9, - 1, - 9, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 3126: (3615, - lnames[3126], - ('rll', - 'ls', - 'l', - 'f', - 6, - 0, - 6, - 6, - 0, - 24, - 0, - 24, - 17, - 27), - 'f', - 0, - NPC_REGULAR), - 3127: (3617, - lnames[3127], - ('rss', - 'ms', - 'l', - 'f', - 21, - 0, - 21, - 21, - 0, - 24, - 0, - 24, - 19, - 27), - 'f', - 0, - NPC_REGULAR), - 3128: (3621, - lnames[3128], - ('rls', - 'ls', - 'l', - 'm', - 13, - 0, - 13, - 13, - 0, - 11, - 0, - 11, - 0, - 12), - 'm', - 0, - NPC_REGULAR), - 3129: (3623, - lnames[3129], - ('mls', - 'sd', - 'l', - 'f', - 4, - 0, - 4, - 4, - 0, - 25, - 0, - 25, - 23, - 27), - 'f', - 0, - NPC_REGULAR), - 3130: (3624, - lnames[3130], - ('hll', - 'ms', - 'l', - 'f', - 21, - 0, - 21, - 21, - 0, - 26, - 0, - 26, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 3131: (3634, - lnames[3131], - ('hss', - 'ls', - 'l', - 'm', - 12, - 0, - 12, - 12, - 0, - 12, - 0, - 12, - 0, - 20), - 'm', - 0, - NPC_REGULAR), - 3132: (3635, - lnames[3132], - 'r', - 'f', - 0, - NPC_REGULAR), - 3133: (3642, - lnames[3133], - ('csl', - 'ms', - 'l', - 'm', - 19, - 0, - 19, - 19, - 1, - 12, - 1, - 12, - 0, - 14), - 'm', - 0, - NPC_REGULAR), - 3134: (3643, - lnames[3134], - ('cls', - 'ss', - 'l', - 'm', - 12, - 0, - 12, - 12, - 1, - 0, - 1, - 0, - 0, - 11), - 'm', - 0, - NPC_REGULAR), - 3135: (3644, - lnames[3135], - ('dll', - 'md', - 'l', - 'f', - 4, - 0, - 4, - 4, - 1, - 0, - 1, - 0, - 4, - 12), - 'f', - 0, - NPC_REGULAR), - 3136: (3647, - lnames[3136], - ('dss', - 'ls', - 'l', - 'f', - 19, - 0, - 19, - 19, - 1, - 1, - 1, - 1, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 3137: (3648, - lnames[3137], - ('dls', - 'ss', - 'l', - 'm', - 12, - 0, - 12, - 12, - 1, - 1, - 1, - 1, - 0, - 19), - 'm', - 0, - NPC_REGULAR), - 3138: (3649, - lnames[3138], - ('fsl', - 'ld', - 'l', - 'f', - 3, - 0, - 3, - 3, - 1, - 2, - 1, - 2, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 3139: (3650, - lnames[3139], - ('fss', - 'sd', - 'l', - 'f', - 19, - 0, - 19, - 19, - 0, - 2, - 0, - 2, - 16, - 27), - 'f', - 0, - NPC_REGULAR), - 3140: (3136, - lnames[3140], - ('rll', - 'ms', - 'l', - 'f', - 11, - 0, - 11, - 11, - 0, - 3, - 0, - 3, - 12, - 27), - 'f', - 0, - NPC_FISHERMAN), - 3201: (3715, - lnames[3201], - 'r', - 'f', - 0, - NPC_REGULAR), - 3202: (3723, - lnames[3202], - ('rsl', - 'ss', - 'l', - 'm', - 6, - 0, - 6, - 6, - 1, - 12, - 1, - 12, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 3203: (3712, - lnames[3203], - ('rss', - 'ls', - 'l', - 'm', - 20, - 0, - 20, - 20, - 1, - 12, - 1, - 12, - 1, - 10), - 'm', - 0, - NPC_REGULAR), - 3204: (3734, - lnames[3204], - ('mss', - 'md', - 'l', - 'f', - 13, - 0, - 13, - 13, - 1, - 26, - 1, - 26, - 4, - 5), - 'f', - 0, - NPC_REGULAR), - 3205: (3721, - lnames[3205], - 'r', - 'm', - 0, - NPC_REGULAR), - 3206: (3722, - lnames[3206], - ('hsl', - 'ss', - 'l', - 'f', - 21, - 0, - 21, - 21, - 1, - 0, - 1, - 0, - 11, - 27), - 'f', - 0, - NPC_REGULAR), - 3207: (3713, - lnames[3207], - ('hss', - 'ls', - 'l', - 'm', - 13, - 0, - 13, - 13, - 0, - 0, - 0, - 0, - 1, - 15), - 'm', - 0, - NPC_REGULAR), - 3208: (3732, - lnames[3208], - ('cll', - 'ms', - 'l', - 'm', - 5, - 0, - 5, - 5, - 0, - 1, - 0, - 1, - 1, - 12), - 'm', - 0, - NPC_REGULAR), - 3209: (3737, - lnames[3209], - ('css', - 'ss', - 'l', - 'm', - 19, - 0, - 19, - 19, - 0, - 1, - 0, - 1, - 1, - 9), - 'm', - 0, - NPC_REGULAR), - 3210: (3728, - lnames[3210], - ('pls', - 'ls', - 's', - 'm', - 13, - 0, - 13, - 13, - 2, - 1, - 2, - 1, - 5, - 2), - 'm', - 0, - NPC_REGULAR), - 3211: (3710, - lnames[3211], - 'r', - 'f', - 0, - NPC_REGULAR), - 3212: (3707, - lnames[3212], - ('dss', - 'ss', - 's', - 'm', - 19, - 0, - 19, - 19, - 0, - 2, - 0, - 2, - 1, - 17), - 'm', - 1, - NPC_REGULAR), - 3213: (3739, - lnames[3213], - ('fll', - 'ls', - 's', - 'm', - 12, - 0, - 12, - 12, - 1, - 2, - 1, - 2, - 1, - 14), - 'm', - 0, - NPC_HQ), - 3214: (3739, - lnames[3214], - ('fsl', - 'md', - 's', - 'f', - 4, - 0, - 4, - 4, - 1, - 4, - 1, - 4, - 3, - 1), - 'f', - 0, - NPC_HQ), - 3215: (3739, - lnames[3215], - ('fls', - 'ms', - 's', - 'm', - 19, - 0, - 19, - 19, - 1, - 3, - 1, - 3, - 1, - 6), - 'm', - 0, - NPC_HQ), - 3216: (3739, - lnames[3216], - ('rll', - 'ss', - 's', - 'm', - 12, - 0, - 12, - 12, - 1, - 4, - 1, - 4, - 1, - 1), - 'm', - 0, - NPC_HQ), - 3217: (3738, - lnames[3217], - ('rss', - 'ls', - 's', - 'm', - 4, - 0, - 4, - 4, - 1, - 4, - 1, - 4, - 1, - 19), - 'm', - 0, - NPC_REGULAR), - 3218: (3702, - lnames[3218], - ('mss', - 'ms', - 's', - 'm', - 18, - 0, - 18, - 18, - 1, - 4, - 1, - 4, - 1, - 16), - 'm', - 1, - NPC_REGULAR), - 3219: (3705, - lnames[3219], - ('mls', - 'ss', - 's', - 'm', - 12, - 0, - 12, - 12, - 0, - 5, - 0, - 5, - 1, - 13), - 'm', - 1, - NPC_REGULAR), - 3220: (3706, - lnames[3220], - ('hsl', - 'ls', - 's', - 'm', - 4, - 0, - 4, - 4, - 0, - 5, - 0, - 5, - 1, - 10), - 'm', - 1, - NPC_REGULAR), - 3221: (3708, - lnames[3221], - ('hss', - 'sd', - 's', - 'f', - 19, - 0, - 19, - 19, - 0, - 8, - 0, - 8, - 7, - 12), - 'f', - 1, - NPC_REGULAR), - 3222: (3716, - lnames[3222], - 'r', - 'f', - 0, - NPC_REGULAR), - 3223: (3718, - lnames[3223], - ('csl', - 'ls', - 'm', - 'm', - 4, - 0, - 4, - 4, - 0, - 6, - 0, - 6, - 1, - 18), - 'm', - 0, - NPC_REGULAR), - 3224: (3719, - lnames[3224], - ('cls', - 'md', - 'm', - 'f', - 18, - 0, - 18, - 18, - 0, - 9, - 0, - 9, - 17, - 27), - 'f', - 0, - NPC_REGULAR), - 3225: (3724, - lnames[3225], - 'r', - 'm', - 0, - NPC_REGULAR), - 3226: (3725, - lnames[3226], - ('dss', - 'ss', - 'm', - 'm', - 3, - 0, - 3, - 3, - 1, - 7, - 1, - 7, - 1, - 9), - 'm', - 0, - NPC_REGULAR), - 3227: (3726, - lnames[3227], - ('fll', - 'ls', - 'm', - 'm', - 17, - 0, - 17, - 17, - 1, - 7, - 1, - 7, - 1, - 2), - 'm', - 0, - NPC_REGULAR), - 3228: (3730, - lnames[3228], - ('fsl', - 'ls', - 'm', - 'f', - 11, - 0, - 11, - 11, - 1, - 12, - 1, - 12, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 3229: (3731, - lnames[3229], - ('fls', - 'ms', - 'm', - 'f', - 2, - 0, - 2, - 2, - 1, - 12, - 1, - 12, - 0, - 7), - 'f', - 0, - NPC_REGULAR), - 3230: (3735, - lnames[3230], - ('rll', - 'ls', - 'm', - 'm', - 17, - 0, - 17, - 17, - 1, - 8, - 1, - 8, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 3231: (3736, - lnames[3231], - ('rss', - 'ms', - 'm', - 'm', - 9, - 0, - 9, - 9, - 0, - 9, - 0, - 9, - 1, - 12), - 'm', - 0, - NPC_REGULAR), - 3232: (3236, - lnames[3232], - ('rls', - 'ss', - 'm', - 'm', - 3, - 0, - 3, - 3, - 0, - 10, - 0, - 10, - 1, - 9), - 'm', - 0, - NPC_FISHERMAN), - 3301: (3810, - lnames[3301], - ('dsl', - 'ms', - 'm', - 'f', - 11, - 0, - 11, - 11, - 0, - 22, - 0, - 22, - 2, - 11), - 'f', - 0, - NPC_REGULAR), - 3302: (3806, - lnames[3302], - ('dls', - 'ls', - 'm', - 'm', - 4, - 0, - 4, - 4, - 0, - 10, - 0, - 10, - 1, - 1), - 'm', - 1, - NPC_REGULAR), - 3303: (3830, - lnames[3303], - ('fll', - 'ms', - 'm', - 'm', - 18, - 0, - 18, - 18, - 0, - 10, - 0, - 10, - 1, - 19), - 'm', - 0, - NPC_REGULAR), - 3304: (3828, - lnames[3304], - ('pll', - 'ls', - 'l', - 'm', - 0, - 0, - 0, - 0, - 1, - 5, - 1, - 5, - 1, - 6), - 'f', - 0, - NPC_REGULAR), - 3305: (3812, - lnames[3305], - ('fls', - 'ls', - 'm', - 'm', - 3, - 0, - 3, - 3, - 0, - 11, - 0, - 11, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 3306: (3821, - lnames[3306], - ('bss', - 'sd', - 'm', - 'f', - 0, - 0, - 0, - 0, - 31, - 27, - 22, - 27, - 8, - 11), - 'f', - 0, - NPC_REGULAR), - 3307: (3329, - lnames[3307], - ('rss', - 'ls', - 'm', - 'f', - 11, - 0, - 11, - 11, - 1, - 24, - 1, - 24, - 1, - 9), - 'f', - 0, - NPC_FISHERMAN), - 3308: (3815, - lnames[3308], - ('mss', - 'ss', - 'm', - 'm', - 3, - 0, - 3, - 3, - 1, - 11, - 1, - 11, - 1, - 0), - 'm', - 0, - NPC_REGULAR), - 3309: (3826, - lnames[3309], - ('hll', - 'ls', - 'm', - 'm', - 17, - 0, - 17, - 17, - 1, - 11, - 1, - 11, - 1, - 18), - 'm', - 0, - NPC_REGULAR), - 3310: (3823, - lnames[3310], - ('pll', - 'ms', - 'm', - 'm', - 10, - 0, - 10, - 10, - 60, - 27, - 49, - 27, - 0, - 13), - 'm', - 0, - NPC_REGULAR), - 3311: (3829, - lnames[3311], - 'r', - 'f', - 0, - NPC_REGULAR), - 3312: (3813, - lnames[3312], - ('rss', - 'ms', - 'l', - 'm', - 4, - 0, - 4, - 4, - 5, - 2, - 5, - 2, - 1, - 10), - 'm', - 0, - NPC_REGULAR), - 3313: (3801, - lnames[3313], - ('css', - 'ms', - 'l', - 'm', - 9, - 0, - 9, - 9, - 0, - 0, - 0, - 0, - 1, - 2), - 'm', - 0, - NPC_HQ), - 3314: (3801, - lnames[3314], - ('cls', - 'ms', - 'l', - 'f', - 1, - 0, - 1, - 1, - 0, - 0, - 0, - 0, - 3, - 25), - 'f', - 0, - NPC_HQ), - 3315: (3801, - lnames[3315], - ('dsl', - 'ls', - 'l', - 'm', - 17, - 0, - 17, - 17, - 0, - 0, - 0, - 0, - 1, - 17), - 'm', - 0, - NPC_HQ), - 3316: (3801, - lnames[3316], - ('dss', - 'md', - 'l', - 'f', - 10, - 0, - 10, - 10, - 0, - 1, - 0, - 1, - 10, - 27), - 'f', - 0, - NPC_HQ), - 3317: (3816, - lnames[3317], - ('fll', - 'ls', - 'l', - 'f', - 1, - 0, - 1, - 1, - 0, - 2, - 0, - 2, - 3, - 24), - 'f', - 0, - NPC_REGULAR), - 3318: (3808, - lnames[3318], - ('dss', - 'ms', - 'm', - 'm', - 18, - 0, - 18, - 18, - 57, - 1, - 46, - 1, - 12, - 1), - 'm', - 1, - NPC_REGULAR), - 3319: (3825, - lnames[3319], - ('fls', - 'ls', - 'l', - 'm', - 9, - 0, - 9, - 9, - 1, - 2, - 1, - 2, - 1, - 1), - 'm', - 0, - NPC_REGULAR), - 3320: (3814, - lnames[3320], - ('rsl', - 'ls', - 'l', - 'f', - 1, - 0, - 1, - 1, - 1, - 3, - 1, - 3, - 12, - 27), - 'f', - 0, - NPC_REGULAR), - 3321: (3818, - lnames[3321], - ('rss', - 'ss', - 'l', - 'm', - 16, - 0, - 16, - 16, - 1, - 2, - 1, - 2, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 3322: (3819, - lnames[3322], - 'r', - 'm', - 0, - NPC_REGULAR), - 3323: (3811, - lnames[3323], - ('mls', - 'ms', - 'l', - 'm', - 22, - 0, - 22, - 22, - 1, - 3, - 1, - 3, - 1, - 10), - 'm', - 0, - NPC_REGULAR), - 3324: (3809, - lnames[3324], - 'r', - 'm', - 1, - NPC_REGULAR), - 3325: (3827, - lnames[3325], - ('hss', - 'ls', - 'l', - 'm', - 8, - 0, - 8, - 8, - 0, - 4, - 0, - 4, - 1, - 0), - 'm', - 0, - NPC_REGULAR), - 3326: (3820, - lnames[3326], - ('cll', - 'md', - 'l', - 'f', - 24, - 0, - 24, - 24, - 0, - 6, - 0, - 6, - 12, - 27), - 'f', - 0, - NPC_REGULAR), - 3327: (3824, - lnames[3327], - ('css', - 'ms', - 'l', - 'm', - 15, - 0, - 15, - 15, - 0, - 5, - 0, - 5, - 1, - 15), - 'm', - 0, - NPC_REGULAR), - 3328: (3807, - lnames[3328], - ('dll', - 'sd', - 'l', - 'f', - 8, - 0, - 8, - 8, - 0, - 25, - 0, - 25, - 14, - 27), - 'f', - 1, - NPC_REGULAR), - 3329: (3817, - lnames[3329], - ('dll', - 'ms', - 'l', - 'm', - 6, - 0, - 6, - 6, - 0, - 1, - 0, - 1, - 1, - 1), - 'm', - 0, - NPC_REGULAR), - 4001: (4502, - lnames[4001], - 'r', - 'f', - 0, - NPC_REGULAR), - 4002: (4504, - lnames[4002], - ('fll', - 'ss', - 'm', - 'm', - 5, - 0, - 5, - 5, - 0, - 2, - 0, - 2, - 1, - 17), - 'm', - 0, - NPC_HQ), - 4003: (4504, - lnames[4003], - ('fsl', - 'md', - 'm', - 'f', - 21, - 0, - 21, - 21, - 0, - 3, - 0, - 3, - 10, - 27), - 'f', - 0, - NPC_HQ), - 4004: (4504, - lnames[4004], - ('fls', - 'ls', - 'm', - 'f', - 13, - 0, - 13, - 13, - 1, - 3, - 1, - 3, - 2, - 11), - 'f', - 0, - NPC_HQ), - 4005: (4504, - lnames[4005], - ('rll', - 'ss', - 'm', - 'f', - 4, - 0, - 4, - 4, - 1, - 4, - 1, - 4, - 24, - 27), - 'f', - 0, - NPC_HQ), - 4006: (4503, - lnames[4006], - ('rss', - 'md', - 'm', - 'f', - 21, - 0, - 21, - 21, - 1, - 4, - 1, - 4, - 8, - 8), - 'f', - 0, - NPC_CLERK), - 4007: (4503, - lnames[4007], - ('rls', - 'ms', - 'm', - 'm', - 12, - 0, - 12, - 12, - 1, - 3, - 1, - 3, - 1, - 19), - 'm', - 0, - NPC_CLERK), - 4008: (4506, - lnames[4008], - ('mls', - 'ms', - 'm', - 'f', - 4, - 0, - 4, - 4, - 1, - 5, - 1, - 5, - 7, - 9), - 'f', - 0, - NPC_TAILOR), - 4009: (4000, - lnames[4009], - ('hsl', - 'ld', - 'm', - 'f', - 19, - 0, - 19, - 19, - 1, - 6, - 1, - 6, - 12, - 27), - 'f', - 0, - NPC_FISHERMAN), - 4010: (4508, - lnames[4010], - ('hss', - 'ms', - 'm', - 'm', - 12, - 0, - 12, - 12, - 0, - 5, - 0, - 5, - 1, - 10), - 'm', - 0, - NPC_PETCLERK), - 4011: (4508, - lnames[4011], - ('cll', - 'ss', - 'm', - 'm', - 4, - 0, - 4, - 4, - 0, - 5, - 0, - 5, - 1, - 4), - 'm', - 0, - NPC_PETCLERK), - 4012: (4508, - lnames[4012], - ('csl', - 'ss', - 'm', - 'f', - 19, - 0, - 19, - 19, - 0, - 8, - 0, - 8, - 10, - 27), - 'f', - 0, - NPC_PETCLERK), - 4013: (4000, - lnames[4013], - ('bll', - 'ls', - 's', - 'm', - 3, - 0, - 19, - 19, - 0, - 8, - 0, - 8, - 1, - 12), - 'm', - 1, - NPC_PARTYPERSON), - 4014: (4000, - lnames[4014], - ('bss', - 'md', - 'm', - 'f', - 24, - 0, - 19, - 19, - 0, - 24, - 0, - 24, - 0, - 12), - 'f', - 1, - NPC_PARTYPERSON), - 4101: (4603, - lnames[4101], - ('cll', - 'ms', - 'm', - 'm', - 16, - 0, - 16, - 16, - 1, - 7, - 1, - 7, - 0, - 6), - 'm', - 1, - NPC_REGULAR), - 4102: (4605, - lnames[4102], - ('csl', - 'ms', - 'm', - 'f', - 9, - 0, - 9, - 9, - 1, - 11, - 1, - 11, - 10, - 27), - 'f', - 1, - NPC_REGULAR), - 4103: (4612, - lnames[4103], - ('cls', - 'ls', - 'l', - 'm', - 2, - 0, - 2, - 2, - 1, - 8, - 1, - 8, - 0, - 19), - 'm', - 0, - NPC_REGULAR), - 4104: (4659, - lnames[4104], - ('dll', - 'ms', - 'l', - 'm', - 16, - 0, - 16, - 16, - 1, - 8, - 1, - 8, - 0, - 16), - 'm', - 0, - NPC_HQ), - 4105: (4659, - lnames[4105], - ('dss', - 'ls', - 'l', - 'f', - 9, - 0, - 9, - 9, - 1, - 21, - 1, - 21, - 11, - 27), - 'f', - 0, - NPC_HQ), - 4106: (4659, - lnames[4106], - ('fll', - 'ss', - 'l', - 'f', - 24, - 0, - 24, - 24, - 0, - 22, - 0, - 22, - 19, - 27), - 'f', - 0, - NPC_HQ), - 4107: (4659, - lnames[4107], - ('fsl', - 'md', - 'l', - 'f', - 16, - 0, - 16, - 16, - 0, - 22, - 0, - 22, - 17, - 27), - 'f', - 0, - NPC_HQ), - 4108: (4626, - lnames[4108], - ('fls', - 'ms', - 'l', - 'm', - 8, - 0, - 8, - 8, - 0, - 10, - 0, - 10, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 4109: (4606, - lnames[4109], - ('rll', - 'ss', - 'l', - 'm', - 22, - 0, - 22, - 22, - 0, - 11, - 0, - 11, - 0, - 18), - 'm', - 1, - NPC_REGULAR), - 4110: (4604, - lnames[4110], - ('rss', - 'ld', - 'l', - 'f', - 16, - 0, - 16, - 16, - 0, - 24, - 0, - 24, - 3, - 2), - 'f', - 1, - NPC_REGULAR), - 4111: (4607, - lnames[4111], - 'r', - 'm', - 1, - NPC_REGULAR), - 4112: (4609, - lnames[4112], - ('mls', - 'ms', - 'l', - 'f', - 24, - 0, - 24, - 24, - 0, - 25, - 0, - 25, - 11, - 27), - 'f', - 1, - NPC_REGULAR), - 4113: (4610, - lnames[4113], - ('hsl', - 'ld', - 'l', - 'f', - 15, - 0, - 15, - 15, - 1, - 25, - 1, - 25, - 14, - 27), - 'f', - 0, - NPC_REGULAR), - 4114: (4611, - lnames[4114], - ('hss', - 'ms', - 'l', - 'm', - 7, - 0, - 7, - 7, - 1, - 11, - 1, - 11, - 1, - 20), - 'm', - 0, - NPC_REGULAR), - 4115: (4614, - lnames[4115], - ('cll', - 'ls', - 'l', - 'f', - 23, - 0, - 23, - 23, - 1, - 26, - 1, - 26, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 4116: (4615, - lnames[4116], - ('csl', - 'ss', - 'm', - 'm', - 15, - 0, - 15, - 15, - 1, - 12, - 1, - 12, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 4117: (4617, - lnames[4117], - ('cls', - 'md', - 'm', - 'f', - 7, - 0, - 7, - 7, - 1, - 0, - 1, - 0, - 1, - 25), - 'f', - 0, - NPC_REGULAR), - 4118: (4618, - lnames[4118], - 'r', - 'm', - 0, - NPC_REGULAR), - 4119: (4619, - lnames[4119], - ('dss', - 'ss', - 'm', - 'm', - 14, - 0, - 14, - 14, - 0, - 0, - 0, - 0, - 1, - 1), - 'm', - 0, - NPC_REGULAR), - 4120: (4622, - lnames[4120], - ('dls', - 'ld', - 'm', - 'f', - 7, - 0, - 7, - 7, - 0, - 1, - 0, - 1, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 4121: (4623, - lnames[4121], - ('fsl', - 'ms', - 'm', - 'm', - 21, - 0, - 21, - 21, - 0, - 1, - 0, - 1, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 4122: (4625, - lnames[4122], - ('fls', - 'ms', - 'm', - 'f', - 14, - 0, - 14, - 14, - 0, - 2, - 0, - 2, - 17, - 27), - 'f', - 0, - NPC_REGULAR), - 4123: (4628, - lnames[4123], - ('rll', - 'ls', - 'm', - 'm', - 6, - 0, - 6, - 6, - 0, - 2, - 0, - 2, - 1, - 10), - 'm', - 0, - NPC_REGULAR), - 4124: (4629, - lnames[4124], - ('rss', - 'ms', - 'm', - 'm', - 20, - 0, - 20, - 20, - 0, - 2, - 0, - 2, - 1, - 4), - 'm', - 0, - NPC_REGULAR), - 4125: (4630, - lnames[4125], - ('rls', - 'ls', - 'm', - 'f', - 14, - 0, - 14, - 14, - 1, - 3, - 1, - 3, - 8, - 6), - 'f', - 0, - NPC_REGULAR), - 4126: (4631, - lnames[4126], - ('mls', - 'ss', - 'm', - 'm', - 6, - 0, - 6, - 6, - 1, - 3, - 1, - 3, - 1, - 18), - 'm', - 0, - NPC_REGULAR), - 4127: (4632, - lnames[4127], - ('hll', - 'md', - 'm', - 'f', - 22, - 0, - 22, - 22, - 1, - 4, - 1, - 4, - 23, - 27), - 'f', - 0, - NPC_REGULAR), - 4128: (4635, - lnames[4128], - ('hss', - 'ms', - 'm', - 'm', - 13, - 0, - 13, - 13, - 1, - 3, - 1, - 3, - 1, - 12), - 'm', - 0, - NPC_REGULAR), - 4129: (4637, - lnames[4129], - ('hls', - 'ss', - 'l', - 'f', - 6, - 0, - 6, - 6, - 1, - 5, - 1, - 5, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 4130: (4638, - lnames[4130], - 'r', - 'm', - 0, - NPC_REGULAR), - 4131: (4639, - lnames[4131], - 'r', - 'm', - 0, - NPC_REGULAR), - 4132: (4641, - lnames[4132], - ('dll', - 'ms', - 'l', - 'f', - 6, - 0, - 6, - 6, - 0, - 7, - 0, - 7, - 17, - 27), - 'f', - 0, - NPC_REGULAR), - 4133: (4642, - lnames[4133], - ('dss', - 'ls', - 'l', - 'm', - 20, - 0, - 20, - 20, - 0, - 5, - 0, - 5, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 4134: (4645, - lnames[4134], - 'r', - 'm', - 0, - NPC_REGULAR), - 4135: (4648, - lnames[4135], - ('fsl', - 'ms', - 'l', - 'm', - 5, - 0, - 5, - 5, - 0, - 6, - 0, - 6, - 1, - 6), - 'm', - 0, - NPC_REGULAR), - 4136: (4652, - lnames[4136], - ('fss', - 'ss', - 'l', - 'f', - 21, - 0, - 21, - 21, - 0, - 9, - 0, - 9, - 7, - 4), - 'f', - 0, - NPC_REGULAR), - 4137: (4654, - lnames[4137], - ('rll', - 'ls', - 'l', - 'm', - 13, - 0, - 13, - 13, - 1, - 6, - 1, - 6, - 1, - 19), - 'm', - 0, - NPC_REGULAR), - 4138: (4655, - lnames[4138], - ('rsl', - 'ms', - 'l', - 'm', - 5, - 0, - 5, - 5, - 1, - 7, - 1, - 7, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 4139: (4657, - lnames[4139], - ('rls', - 'ss', - 'l', - 'f', - 21, - 0, - 21, - 21, - 1, - 11, - 1, - 11, - 14, - 27), - 'f', - 0, - NPC_REGULAR), - 4140: (4658, - lnames[4140], - ('mls', - 'ls', - 'l', - 'm', - 12, - 0, - 12, - 12, - 1, - 7, - 1, - 7, - 1, - 10), - 'm', - 0, - NPC_REGULAR), - 4141: (4148, - lnames[4141], - ('hll', - 'ms', - 'l', - 'm', - 4, - 0, - 4, - 4, - 1, - 8, - 1, - 8, - 1, - 4), - 'm', - 0, - NPC_FISHERMAN), - 4201: (4704, - lnames[4201], - ('mss', - 'ss', - 'l', - 'f', - 14, - 0, - 14, - 14, - 0, - 6, - 0, - 6, - 11, - 27), - 'f', - 1, - NPC_REGULAR), - 4202: (4725, - lnames[4202], - ('mls', - 'ls', - 'l', - 'm', - 6, - 0, - 6, - 6, - 0, - 5, - 0, - 5, - 0, - 13), - 'm', - 0, - NPC_REGULAR), - 4203: (4702, - lnames[4203], - ('hsl', - 'ms', - 'l', - 'm', - 21, - 0, - 21, - 21, - 0, - 5, - 0, - 5, - 0, - 10), - 'm', - 1, - NPC_REGULAR), - 4204: (4739, - lnames[4204], - ('hss', - 'ss', - 'l', - 'm', - 14, - 0, - 14, - 14, - 0, - 6, - 0, - 6, - 0, - 4), - 'm', - 0, - NPC_HQ), - 4205: (4739, - lnames[4205], - ('cll', - 'ld', - 'l', - 'f', - 6, - 0, - 6, - 6, - 1, - 8, - 1, - 8, - 10, - 27), - 'f', - 0, - NPC_HQ), - 4206: (4739, - lnames[4206], - ('css', - 'sd', - 'l', - 'f', - 22, - 0, - 22, - 22, - 1, - 8, - 1, - 8, - 25, - 27), - 'f', - 0, - NPC_HQ), - 4207: (4739, - lnames[4207], - ('cls', - 'ls', - 'l', - 'f', - 14, - 0, - 14, - 14, - 1, - 9, - 1, - 9, - 17, - 27), - 'f', - 0, - NPC_HQ), - 4208: (4730, - lnames[4208], - ('dsl', - 'ss', - 'l', - 'f', - 6, - 0, - 6, - 6, - 1, - 9, - 1, - 9, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 4209: (4701, - lnames[4209], - ('dss', - 'md', - 'l', - 'f', - 22, - 0, - 22, - 22, - 1, - 11, - 1, - 11, - 1, - 9), - 'f', - 1, - NPC_REGULAR), - 4211: (4703, - lnames[4211], - ('fsl', - 'ss', - 'l', - 'm', - 5, - 0, - 5, - 5, - 1, - 8, - 1, - 8, - 0, - 20), - 'm', - 1, - NPC_REGULAR), - 4212: (4705, - lnames[4212], - ('fls', - 'ls', - 'l', - 'm', - 20, - 0, - 20, - 20, - 0, - 9, - 0, - 9, - 0, - 17), - 'm', - 1, - NPC_REGULAR), - 4213: (4707, - lnames[4213], - ('rll', - 'sd', - 'l', - 'f', - 13, - 0, - 13, - 13, - 0, - 21, - 0, - 21, - 24, - 27), - 'f', - 1, - NPC_REGULAR), - 4214: (4709, - lnames[4214], - 'r', - 'f', - 1, - NPC_REGULAR), - 4215: (4710, - lnames[4215], - ('mss', - 'ls', - 'l', - 'm', - 19, - 0, - 19, - 19, - 0, - 10, - 0, - 10, - 0, - 6), - 'm', - 0, - NPC_REGULAR), - 4216: (4712, - lnames[4216], - ('mls', - 'ms', - 's', - 'm', - 13, - 0, - 13, - 13, - 0, - 10, - 0, - 10, - 0, - 1), - 'm', - 0, - NPC_REGULAR), - 4217: (4713, - lnames[4217], - ('hsl', - 'ms', - 's', - 'm', - 5, - 0, - 5, - 5, - 0, - 10, - 0, - 10, - 0, - 19), - 'm', - 0, - NPC_REGULAR), - 4218: (4716, - lnames[4218], - ('hss', - 'ss', - 's', - 'f', - 21, - 0, - 21, - 21, - 1, - 23, - 1, - 23, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 4219: (4717, - lnames[4219], - 'r', - 'm', - 0, - NPC_REGULAR), - 4220: (4718, - lnames[4220], - 'r', - 'm', - 0, - NPC_REGULAR), - 4221: (4719, - lnames[4221], - ('cls', - 'ss', - 's', - 'm', - 19, - 0, - 19, - 19, - 1, - 11, - 1, - 11, - 0, - 4), - 'm', - 0, - NPC_REGULAR), - 4222: (4720, - lnames[4222], - ('dsl', - 'ls', - 's', - 'm', - 12, - 0, - 12, - 12, - 1, - 11, - 1, - 11, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 4223: (4722, - lnames[4223], - ('dss', - 'sd', - 's', - 'f', - 3, - 0, - 3, - 3, - 1, - 25, - 1, - 25, - 24, - 27), - 'f', - 0, - NPC_REGULAR), - 4224: (4723, - lnames[4224], - 'r', - 'm', - 0, - NPC_REGULAR), - 4225: (4724, - lnames[4225], - ('fsl', - 'ld', - 's', - 'f', - 12, - 0, - 12, - 12, - 0, - 27, - 0, - 27, - 11, - 27), - 'f', - 0, - NPC_REGULAR), - 4226: (4727, - lnames[4226], - ('fls', - 'sd', - 's', - 'f', - 3, - 0, - 3, - 3, - 0, - 0, - 0, - 0, - 11, - 27), - 'f', - 0, - NPC_REGULAR), - 4227: (4728, - lnames[4227], - ('rll', - 'ls', - 's', - 'f', - 19, - 0, - 19, - 19, - 0, - 0, - 0, - 0, - 23, - 27), - 'f', - 0, - NPC_REGULAR), - 4228: (4729, - lnames[4228], - ('rss', - 'ss', - 's', - 'f', - 11, - 0, - 11, - 11, - 0, - 1, - 0, - 1, - 0, - 1), - 'f', - 0, - NPC_REGULAR), - 4229: (4731, - lnames[4229], - ('rls', - 'md', - 'm', - 'f', - 3, - 0, - 3, - 3, - 0, - 1, - 0, - 1, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 4230: (4732, - lnames[4230], - ('mls', - 'ms', - 'm', - 'm', - 18, - 0, - 18, - 18, - 1, - 1, - 1, - 1, - 0, - 14), - 'm', - 0, - NPC_REGULAR), - 4231: (4735, - lnames[4231], - ('hsl', - 'ss', - 'm', - 'f', - 11, - 0, - 11, - 11, - 1, - 2, - 1, - 2, - 8, - 0), - 'f', - 0, - NPC_REGULAR), - 4232: (4736, - lnames[4232], - ('hss', - 'ls', - 'm', - 'm', - 3, - 0, - 3, - 3, - 1, - 2, - 1, - 2, - 1, - 6), - 'm', - 0, - NPC_REGULAR), - 4233: (4737, - lnames[4233], - ('cll', - 'ms', - 'm', - 'm', - 17, - 0, - 17, - 17, - 1, - 2, - 1, - 2, - 1, - 1), - 'm', - 0, - NPC_REGULAR), - 4234: (4738, - lnames[4234], - 'r', - 'm', - 0, - NPC_REGULAR), - 4235: (4240, - lnames[4235], - ('cls', - 'ls', - 'm', - 'm', - 3, - 0, - 3, - 3, - 1, - 3, - 1, - 3, - 1, - 16), - 'm', - 0, - NPC_FISHERMAN), - 4301: (4819, - lnames[4301], - ('fss', - 'md', - 'l', - 'f', - 12, - 0, - 12, - 12, - 1, - 2, - 1, - 2, - 17, - 27), - 'f', - 0, - NPC_REGULAR), - 4302: (4821, - lnames[4302], - ('fls', - 'ls', - 'l', - 'f', - 3, - 0, - 3, - 3, - 1, - 2, - 1, - 2, - 2, - 3), - 'f', - 0, - NPC_REGULAR), - 4303: (4853, - lnames[4303], - ('rsl', - 'ss', - 'l', - 'm', - 18, - 0, - 18, - 18, - 1, - 2, - 1, - 2, - 0, - 18), - 'm', - 0, - NPC_REGULAR), - 4304: (4873, - lnames[4304], - ('rss', - 'ls', - 'm', - 'm', - 12, - 0, - 12, - 12, - 0, - 2, - 0, - 2, - 0, - 15), - 'm', - 0, - NPC_HQ), - 4305: (4873, - lnames[4305], - ('mss', - 'sd', - 'm', - 'f', - 3, - 0, - 3, - 3, - 0, - 4, - 0, - 4, - 26, - 27), - 'f', - 0, - NPC_HQ), - 4306: (4873, - lnames[4306], - ('hll', - 'ms', - 'm', - 'f', - 19, - 0, - 19, - 19, - 0, - 5, - 0, - 5, - 4, - 25), - 'f', - 0, - NPC_HQ), - 4307: (4873, - lnames[4307], - ('hsl', - 'ld', - 'm', - 'f', - 11, - 0, - 11, - 11, - 0, - 5, - 0, - 5, - 17, - 27), - 'f', - 0, - NPC_HQ), - 4308: (4835, - lnames[4308], - ('css', - 'md', - 'm', - 'f', - 6, - 0, - 6, - 6, - 3, - 5, - 3, - 5, - 0, - 14), - 'f', - 0, - NPC_REGULAR), - 4309: (4801, - lnames[4309], - ('cll', - 'ms', - 'm', - 'm', - 18, - 0, - 18, - 18, - 0, - 4, - 0, - 4, - 0, - 17), - 'm', - 1, - NPC_REGULAR), - 4310: (4803, - lnames[4310], - 'r', - 'f', - 1, - NPC_REGULAR), - 4311: (4804, - lnames[4311], - 'r', - 'f', - 1, - NPC_REGULAR), - 4312: (4807, - lnames[4312], - ('dsl', - 'ms', - 'm', - 'm', - 18, - 0, - 18, - 18, - 1, - 5, - 1, - 5, - 0, - 9), - 'm', - 1, - NPC_REGULAR), - 4313: (4809, - lnames[4313], - ('dss', - 'ss', - 'm', - 'm', - 10, - 0, - 10, - 10, - 1, - 5, - 1, - 5, - 0, - 2), - 'm', - 1, - NPC_REGULAR), - 4314: (4817, - lnames[4314], - ('fll', - 'ld', - 'm', - 'f', - 2, - 0, - 2, - 2, - 1, - 8, - 1, - 8, - 12, - 27), - 'f', - 0, - NPC_REGULAR), - 4315: (4827, - lnames[4315], - ('fss', - 'sd', - 'm', - 'f', - 18, - 0, - 18, - 18, - 1, - 9, - 1, - 9, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 4316: (4828, - lnames[4316], - ('fls', - 'ss', - 'm', - 'm', - 9, - 0, - 9, - 9, - 1, - 6, - 1, - 6, - 0, - 14), - 'm', - 0, - NPC_REGULAR), - 4317: (4829, - lnames[4317], - ('rsl', - 'ls', - 'l', - 'm', - 3, - 0, - 3, - 3, - 0, - 7, - 0, - 7, - 0, - 11), - 'm', - 0, - NPC_REGULAR), - 4318: (4836, - lnames[4318], - ('rss', - 'ms', - 'l', - 'm', - 17, - 0, - 17, - 17, - 0, - 8, - 0, - 8, - 0, - 6), - 'm', - 0, - NPC_REGULAR), - 4319: (4838, - lnames[4319], - ('mss', - 'ls', - 'l', - 'f', - 10, - 0, - 10, - 10, - 0, - 12, - 0, - 12, - 1, - 23), - 'f', - 0, - NPC_REGULAR), - 4320: (4840, - lnames[4320], - ('mls', - 'ss', - 'l', - 'f', - 1, - 0, - 1, - 1, - 0, - 21, - 0, - 21, - 11, - 27), - 'f', - 0, - NPC_REGULAR), - 4321: (4841, - lnames[4321], - ('hsl', - 'ls', - 'l', - 'm', - 17, - 0, - 17, - 17, - 0, - 9, - 0, - 9, - 0, - 16), - 'm', - 0, - NPC_REGULAR), - 4322: (4842, - lnames[4322], - ('hls', - 'ms', - 'l', - 'm', - 9, - 0, - 9, - 9, - 0, - 9, - 0, - 9, - 0, - 13), - 'm', - 0, - NPC_REGULAR), - 4323: (4844, - lnames[4323], - ('cll', - 'ss', - 'l', - 'f', - 1, - 0, - 1, - 1, - 1, - 21, - 1, - 21, - 24, - 27), - 'f', - 0, - NPC_REGULAR), - 4324: (4845, - lnames[4324], - ('css', - 'ld', - 'l', - 'f', - 17, - 0, - 17, - 17, - 1, - 22, - 1, - 22, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 4325: (4848, - lnames[4325], - ('cls', - 'ms', - 'l', - 'm', - 9, - 0, - 9, - 9, - 1, - 9, - 1, - 9, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 4326: (4850, - lnames[4326], - ('dsl', - 'ms', - 'l', - 'f', - 1, - 0, - 1, - 1, - 1, - 23, - 1, - 23, - 14, - 27), - 'f', - 0, - NPC_REGULAR), - 4327: (4852, - lnames[4327], - ('dss', - 'ld', - 'l', - 'f', - 16, - 0, - 16, - 16, - 1, - 23, - 1, - 23, - 7, - 1), - 'f', - 0, - NPC_REGULAR), - 4328: (4854, - lnames[4328], - ('fll', - 'ms', - 'l', - 'm', - 8, - 0, - 8, - 8, - 1, - 11, - 1, - 11, - 0, - 12), - 'm', - 0, - NPC_REGULAR), - 4329: (4855, - lnames[4329], - ('fsl', - 'ls', - 'l', - 'f', - 24, - 0, - 24, - 24, - 0, - 25, - 0, - 25, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 4330: (4862, - lnames[4330], - 'r', - 'm', - 0, - NPC_REGULAR), - 4331: (4867, - lnames[4331], - 'r', - 'm', - 0, - NPC_REGULAR), - 4332: (4870, - lnames[4332], - ('rss', - 'ms', - 'l', - 'm', - 22, - 0, - 22, - 22, - 0, - 27, - 0, - 27, - 0, - 17), - 'm', - 0, - NPC_REGULAR), - 4333: (4871, - lnames[4333], - ('mss', - 'ss', - 'l', - 'm', - 15, - 0, - 15, - 15, - 0, - 27, - 0, - 27, - 0, - 14), - 'm', - 0, - NPC_REGULAR), - 4334: (4872, - lnames[4334], - ('mls', - 'ls', - 'l', - 'm', - 8, - 0, - 8, - 8, - 0, - 0, - 0, - 0, - 0, - 11), - 'm', - 0, - NPC_REGULAR), - 4335: (4345, - lnames[4335], - ('hsl', - 'ms', - 'l', - 'm', - 22, - 0, - 22, - 22, - 1, - 0, - 1, - 0, - 0, - 6), - 'm', - 0, - NPC_FISHERMAN), - 5001: (5502, - lnames[5001], - ('fls', - 'ls', - 's', - 'm', - 14, - 0, - 14, - 14, - 1, - 7, - 1, - 7, - 0, - 20), - 'm', - 0, - NPC_HQ), - 5002: (5502, - lnames[5002], - ('rll', - 'ms', - 's', - 'm', - 6, - 0, - 6, - 6, - 0, - 8, - 0, - 8, - 0, - 17), - 'm', - 0, - NPC_HQ), - 5003: (5502, - lnames[5003], - ('rss', - 'ms', - 's', - 'f', - 22, - 0, - 22, - 22, - 0, - 12, - 0, - 12, - 26, - 27), - 'f', - 0, - NPC_HQ), - 5004: (5502, - lnames[5004], - ('rls', - 'ld', - 's', - 'f', - 13, - 0, - 13, - 13, - 0, - 21, - 0, - 21, - 4, - 11), - 'f', - 0, - NPC_HQ), - 5005: (5501, - lnames[5005], - ('mls', - 'md', - 's', - 'f', - 6, - 0, - 6, - 6, - 0, - 21, - 0, - 21, - 2, - 3), - 'f', - 0, - NPC_CLERK), - 5006: (5501, - lnames[5006], - ('hsl', - 'ms', - 's', - 'm', - 20, - 0, - 20, - 20, - 0, - 9, - 0, - 9, - 0, - 1), - 'm', - 0, - NPC_CLERK), - 5007: (5503, - lnames[5007], - ('hss', - 'ss', - 's', - 'f', - 13, - 0, - 13, - 13, - 0, - 22, - 0, - 22, - 3, - 2), - 'f', - 0, - NPC_TAILOR), - 5008: (5000, - lnames[5008], - ('cll', - 'md', - 's', - 'f', - 4, - 0, - 4, - 4, - 1, - 22, - 1, - 22, - 19, - 27), - 'f', - 0, - NPC_FISHERMAN), - 5009: (5505, - lnames[5009], - ('csl', - 'ls', - 'm', - 'f', - 21, - 0, - 21, - 21, - 1, - 23, - 1, - 23, - 8, - 23), - 'f', - 0, - NPC_PETCLERK), - 5010: (5505, - lnames[5010], - ('cls', - 'ss', - 'm', - 'm', - 13, - 0, - 13, - 13, - 1, - 10, - 1, - 10, - 0, - 10), - 'm', - 0, - NPC_PETCLERK), - 5011: (5505, - lnames[5011], - ('dll', - 'ls', - 'm', - 'm', - 5, - 0, - 5, - 5, - 1, - 10, - 1, - 10, - 0, - 4), - 'm', - 0, - NPC_PETCLERK), - 5012: (5000, - lnames[5012], - ('dls', - 'ms', - 'm', - 'm', - 13, - 0, - 12, - 12, - 0, - 1, - 0, - 1, - 0, - 6), - 'm', - 1, - NPC_PARTYPERSON), - 5013: (5000, - lnames[5013], - ('dss', - 'md', - 'm', - 'f', - 1, - 0, - 3, - 3, - 1, - 5, - 1, - 5, - 0, - 5), - 'f', - 1, - NPC_PARTYPERSON), - 5101: (5602, - lnames[5101], - ('dsl', - 'ms', - 'l', - 'm', - 10, - 0, - 10, - 10, - 1, - 4, - 1, - 4, - 0, - 11), - 'm', - 1, - NPC_REGULAR), - 5102: (5610, - lnames[5102], - 'r', - 'f', - 0, - NPC_REGULAR), - 5103: (5615, - lnames[5103], - ('fll', - 'ls', - 'l', - 'm', - 18, - 0, - 18, - 18, - 1, - 5, - 1, - 5, - 0, - 1), - 'm', - 0, - NPC_REGULAR), - 5104: (5617, - lnames[5104], - ('fsl', - 'ms', - 'l', - 'm', - 10, - 0, - 10, - 10, - 1, - 5, - 1, - 5, - 0, - 19), - 'm', - 0, - NPC_REGULAR), - 5105: (5619, - lnames[5105], - 'r', - 'm', - 0, - NPC_REGULAR), - 5106: (5613, - lnames[5106], - ('rsl', - 'ls', - 'l', - 'm', - 18, - 0, - 18, - 18, - 1, - 6, - 1, - 6, - 0, - 13), - 'm', - 0, - NPC_REGULAR), - 5107: (5607, - lnames[5107], - 'r', - 'm', - 1, - NPC_REGULAR), - 5108: (5616, - lnames[5108], - ('mss', - 'ls', - 'l', - 'f', - 2, - 0, - 2, - 2, - 0, - 11, - 0, - 11, - 24, - 27), - 'f', - 0, - NPC_REGULAR), - 5109: (5627, - lnames[5109], - ('mls', - 'ss', - 'l', - 'm', - 17, - 0, - 17, - 17, - 0, - 7, - 0, - 7, - 0, - 0), - 'm', - 1, - NPC_HQ), - 5110: (5627, - lnames[5110], - ('hsl', - 'ls', - 'l', - 'm', - 10, - 0, - 10, - 10, - 0, - 8, - 0, - 8, - 0, - 18), - 'm', - 1, - NPC_HQ), - 5111: (5627, - lnames[5111], - ('hss', - 'ls', - 'l', - 'f', - 2, - 0, - 2, - 2, - 0, - 12, - 0, - 12, - 7, - 4), - 'f', - 1, - NPC_HQ), - 5112: (5627, - lnames[5112], - ('cll', - 'ms', - 'l', - 'f', - 17, - 0, - 17, - 17, - 0, - 21, - 0, - 21, - 14, - 27), - 'f', - 1, - NPC_HQ), - 5113: (5601, - lnames[5113], - ('css', - 'ld', - 'l', - 'f', - 10, - 0, - 10, - 10, - 0, - 21, - 0, - 21, - 3, - 2), - 'f', - 1, - NPC_REGULAR), - 5114: (5603, - lnames[5114], - ('cls', - 'ms', - 'l', - 'm', - 2, - 0, - 2, - 2, - 1, - 9, - 1, - 9, - 0, - 2), - 'm', - 1, - NPC_REGULAR), - 5115: (5604, - lnames[5115], - ('dsl', - 'ms', - 'l', - 'f', - 17, - 0, - 17, - 17, - 1, - 22, - 1, - 22, - 10, - 27), - 'f', - 1, - NPC_REGULAR), - 5116: (5605, - lnames[5116], - ('dss', - 'ls', - 'l', - 'm', - 9, - 0, - 9, - 9, - 1, - 9, - 1, - 9, - 0, - 17), - 'm', - 1, - NPC_REGULAR), - 5117: (5606, - lnames[5117], - ('fll', - 'md', - 'l', - 'f', - 1, - 0, - 1, - 1, - 1, - 23, - 1, - 23, - 17, - 27), - 'f', - 1, - NPC_REGULAR), - 5118: (5608, - lnames[5118], - ('fsl', - 'ms', - 'l', - 'm', - 16, - 0, - 16, - 16, - 1, - 10, - 1, - 10, - 0, - 11), - 'm', - 1, - NPC_REGULAR), - 5119: (5609, - lnames[5119], - ('fls', - 'ss', - 'l', - 'm', - 9, - 0, - 9, - 9, - 1, - 10, - 1, - 10, - 0, - 6), - 'm', - 1, - NPC_REGULAR), - 5120: (5611, - lnames[5120], - ('rsl', - 'ss', - 'l', - 'm', - 22, - 0, - 22, - 22, - 1, - 3, - 1, - 3, - 1, - 19), - 'm', - 0, - NPC_REGULAR), - 5121: (5618, - lnames[5121], - ('rss', - 'ss', - 'l', - 'f', - 23, - 0, - 23, - 23, - 1, - 9, - 1, - 9, - 0, - 25), - 'f', - 0, - NPC_REGULAR), - 5122: (5620, - lnames[5122], - 'r', - 'm', - 0, - NPC_REGULAR), - 5123: (5621, - lnames[5123], - ('mls', - 'sd', - 'm', - 'f', - 7, - 0, - 7, - 7, - 1, - 11, - 1, - 11, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 5124: (5622, - lnames[5124], - ('hll', - 'ss', - 'm', - 'm', - 21, - 0, - 21, - 21, - 0, - 8, - 0, - 8, - 0, - 4), - 'm', - 0, - NPC_REGULAR), - 5125: (5623, - lnames[5125], - ('hss', - 'ls', - 'm', - 'm', - 14, - 0, - 14, - 14, - 0, - 9, - 0, - 9, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 5126: (5624, - lnames[5126], - ('hls', - 'sd', - 'm', - 'f', - 7, - 0, - 7, - 7, - 0, - 21, - 0, - 21, - 14, - 27), - 'f', - 0, - NPC_REGULAR), - 5127: (5625, - lnames[5127], - ('csl', - 'ms', - 'm', - 'f', - 23, - 0, - 23, - 23, - 0, - 22, - 0, - 22, - 2, - 2), - 'f', - 0, - NPC_REGULAR), - 5128: (5626, - lnames[5128], - 'r', - 'f', - 0, - NPC_REGULAR), - 5129: (5139, - lnames[5129], - ('dll', - 'md', - 'm', - 'f', - 7, - 0, - 7, - 7, - 0, - 23, - 0, - 23, - 17, - 27), - 'f', - 0, - NPC_FISHERMAN), - 5201: (5702, - lnames[5201], - ('hls', - 'ls', - 'l', - 'm', - 15, - 0, - 15, - 15, - 1, - 10, - 1, - 10, - 1, - 16), - 'm', - 1, - NPC_REGULAR), - 5202: (5703, - lnames[5202], - ('cll', - 'ls', - 'l', - 'f', - 7, - 0, - 7, - 7, - 1, - 23, - 1, - 23, - 11, - 27), - 'f', - 1, - NPC_REGULAR), - 5203: (5704, - lnames[5203], - ('css', - 'ss', - 'l', - 'f', - 23, - 0, - 23, - 23, - 1, - 24, - 1, - 24, - 19, - 27), - 'f', - 1, - NPC_REGULAR), - 5204: (5726, - lnames[5204], - ('cls', - 'ls', - 'l', - 'm', - 14, - 0, - 14, - 14, - 0, - 12, - 0, - 12, - 1, - 4), - 'm', - 0, - NPC_REGULAR), - 5205: (5718, - lnames[5205], - 'r', - 'm', - 0, - NPC_REGULAR), - 5206: (5720, - lnames[5206], - ('dss', - 'ss', - 'l', - 'm', - 21, - 0, - 21, - 21, - 0, - 27, - 0, - 27, - 1, - 18), - 'm', - 0, - NPC_REGULAR), - 5207: (5717, - lnames[5207], - ('fll', - 'ld', - 'l', - 'f', - 14, - 0, - 14, - 14, - 0, - 27, - 0, - 27, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 5208: (5719, - lnames[5208], - ('fsl', - 'sd', - 'l', - 'f', - 7, - 0, - 7, - 7, - 0, - 27, - 0, - 27, - 1, - 12), - 'f', - 0, - NPC_REGULAR), - 5209: (5728, - lnames[5209], - ('fls', - 'ss', - 'l', - 'm', - 21, - 0, - 21, - 21, - 0, - 0, - 0, - 0, - 1, - 9), - 'm', - 1, - NPC_HQ), - 5210: (5728, - lnames[5210], - ('rsl', - 'ss', - 'l', - 'm', - 14, - 0, - 14, - 14, - 1, - 0, - 1, - 0, - 1, - 2), - 'm', - 1, - NPC_HQ), - 5211: (5728, - lnames[5211], - ('rss', - 'md', - 'l', - 'f', - 6, - 0, - 6, - 6, - 1, - 1, - 1, - 1, - 23, - 27), - 'f', - 1, - NPC_HQ), - 5212: (5728, - lnames[5212], - ('mss', - 'ls', - 'l', - 'f', - 22, - 0, - 22, - 22, - 1, - 1, - 1, - 1, - 10, - 27), - 'f', - 1, - NPC_HQ), - 5213: (5701, - lnames[5213], - ('mls', - 'ss', - 'l', - 'm', - 13, - 0, - 13, - 13, - 1, - 1, - 1, - 1, - 1, - 14), - 'm', - 1, - NPC_REGULAR), - 5214: (5705, - lnames[5214], - ('hsl', - 'md', - 'l', - 'f', - 6, - 0, - 6, - 6, - 1, - 2, - 1, - 2, - 17, - 27), - 'f', - 1, - NPC_REGULAR), - 5215: (5706, - lnames[5215], - 'r', - 'f', - 1, - NPC_REGULAR), - 5216: (5707, - lnames[5216], - ('cll', - 'ss', - 'l', - 'm', - 13, - 0, - 13, - 13, - 0, - 2, - 0, - 2, - 1, - 1), - 'm', - 1, - NPC_REGULAR), - 5217: (5708, - lnames[5217], - ('csl', - 'ls', - 'l', - 'm', - 5, - 0, - 5, - 5, - 0, - 3, - 0, - 3, - 1, - 19), - 'm', - 1, - NPC_REGULAR), - 5218: (5709, - lnames[5218], - 'r', - 'm', - 1, - NPC_REGULAR), - 5219: (5710, - lnames[5219], - ('dsl', - 'ss', - 'l', - 'm', - 13, - 0, - 13, - 13, - 0, - 3, - 0, - 3, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 5220: (5711, - lnames[5220], - 'r', - 'f', - 0, - NPC_REGULAR), - 5221: (5712, - lnames[5221], - ('fll', - 'md', - 'l', - 'f', - 21, - 0, - 21, - 21, - 0, - 6, - 0, - 6, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 5222: (5713, - lnames[5222], - 'r', - 'f', - 0, - NPC_REGULAR), - 5223: (5714, - lnames[5223], - ('fls', - 'ss', - 's', - 'm', - 5, - 0, - 5, - 5, - 1, - 4, - 1, - 4, - 1, - 18), - 'm', - 0, - NPC_REGULAR), - 5224: (5715, - lnames[5224], - ('rll', - 'ls', - 's', - 'm', - 19, - 0, - 19, - 19, - 1, - 5, - 1, - 5, - 1, - 15), - 'm', - 0, - NPC_REGULAR), - 5225: (5716, - lnames[5225], - ('rss', - 'sd', - 's', - 'f', - 12, - 0, - 12, - 12, - 1, - 7, - 1, - 7, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 5226: (5721, - lnames[5226], - ('rls', - 'ss', - 's', - 'm', - 4, - 0, - 4, - 4, - 1, - 5, - 1, - 5, - 1, - 9), - 'm', - 0, - NPC_REGULAR), - 5227: (5725, - lnames[5227], - ('mls', - 'ld', - 's', - 'f', - 19, - 0, - 19, - 19, - 1, - 8, - 1, - 8, - 23, - 27), - 'f', - 0, - NPC_REGULAR), - 5228: (5727, - lnames[5228], - ('hsl', - 'ms', - 's', - 'm', - 12, - 0, - 12, - 12, - 1, - 6, - 1, - 6, - 1, - 20), - 'm', - 0, - NPC_REGULAR), - 5229: (5245, - lnames[5229], - ('hss', - 'ms', - 's', - 'f', - 3, - 0, - 3, - 3, - 0, - 11, - 0, - 11, - 16, - 27), - 'f', - 0, - NPC_FISHERMAN), - 5301: (5802, - lnames[5301], - ('rss', - 'ms', - 'l', - 'f', - 13, - 0, - 13, - 13, - 0, - 11, - 0, - 11, - 1, - 12), - 'f', - 1, - NPC_HQ), - 5302: (5802, - lnames[5302], - ('mss', - 'ss', - 'l', - 'f', - 4, - 0, - 4, - 4, - 0, - 12, - 0, - 12, - 17, - 27), - 'f', - 1, - NPC_HQ), - 5303: (5802, - lnames[5303], - ('hll', - 'ls', - 'l', - 'm', - 19, - 0, - 19, - 19, - 1, - 8, - 1, - 8, - 1, - 18), - 'm', - 1, - NPC_HQ), - 5304: (5802, - lnames[5304], - ('hsl', - 'ls', - 'l', - 'f', - 12, - 0, - 12, - 12, - 1, - 12, - 1, - 12, - 19, - 27), - 'f', - 1, - NPC_HQ), - 5305: (5804, - lnames[5305], - ('hls', - 'ss', - 'l', - 'f', - 4, - 0, - 4, - 4, - 1, - 21, - 1, - 21, - 16, - 27), - 'f', - 1, - NPC_REGULAR), - 5306: (5805, - lnames[5306], - 'r', - 'm', - 1, - NPC_REGULAR), - 5307: (5809, - lnames[5307], - ('css', - 'ms', - 'l', - 'm', - 12, - 0, - 12, - 12, - 1, - 9, - 1, - 9, - 1, - 2), - 'm', - 1, - NPC_REGULAR), - 5308: (5810, - lnames[5308], - ('cls', - 'ms', - 'l', - 'f', - 4, - 0, - 4, - 4, - 1, - 22, - 1, - 22, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 5309: (5811, - lnames[5309], - 'r', - 'f', - 0, - NPC_REGULAR), - 5310: (5815, - lnames[5310], - ('dls', - 'ms', - 'l', - 'm', - 12, - 0, - 12, - 12, - 0, - 11, - 0, - 11, - 1, - 14), - 'm', - 0, - NPC_REGULAR), - 5311: (5817, - lnames[5311], - ('fll', - 'ms', - 'm', - 'f', - 3, - 0, - 3, - 3, - 0, - 24, - 0, - 24, - 12, - 27), - 'f', - 0, - NPC_REGULAR), - 5312: (5819, - lnames[5312], - ('fss', - 'ss', - 'm', - 'm', - 18, - 0, - 18, - 18, - 0, - 12, - 0, - 12, - 1, - 6), - 'm', - 0, - NPC_REGULAR), - 5313: (5821, - lnames[5313], - ('fls', - 'ls', - 'm', - 'm', - 10, - 0, - 10, - 10, - 0, - 12, - 0, - 12, - 1, - 1), - 'm', - 0, - NPC_REGULAR), - 5314: (5826, - lnames[5314], - 'r', - 'f', - 0, - NPC_REGULAR), - 5315: (5827, - lnames[5315], - ('rss', - 'ss', - 'm', - 'm', - 18, - 0, - 18, - 18, - 1, - 12, - 1, - 12, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 5316: (5828, - lnames[5316], - ('mss', - 'ls', - 'm', - 'm', - 10, - 0, - 10, - 10, - 1, - 12, - 1, - 12, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 5317: (5830, - lnames[5317], - 'r', - 'm', - 0, - NPC_REGULAR), - 5318: (5833, - lnames[5318], - ('hsl', - 'ss', - 'm', - 'm', - 18, - 0, - 18, - 18, - 1, - 0, - 1, - 0, - 1, - 4), - 'm', - 0, - NPC_REGULAR), - 5319: (5835, - lnames[5319], - 'r', - 'f', - 0, - NPC_REGULAR), - 5320: (5836, - lnames[5320], - ('cll', - 'sd', - 'm', - 'f', - 2, - 0, - 2, - 2, - 1, - 1, - 1, - 1, - 17, - 27), - 'f', - 0, - NPC_REGULAR), - 5321: (5837, - lnames[5321], - ('css', - 'ms', - 'm', - 'f', - 18, - 0, - 18, - 18, - 1, - 1, - 1, - 1, - 17, - 27), - 'f', - 0, - NPC_REGULAR), - 5322: (5318, - lnames[5322], - ('cls', - 'ss', - 'm', - 'f', - 10, - 0, - 10, - 10, - 0, - 2, - 0, - 2, - 11, - 27), - 'f', - 0, - NPC_FISHERMAN), - 6000: (6000, - lnames[6000], - ('hsl', - 'ms', - 'm', - 'm', - 8, - 0, - 8, - 8, - 1, - 6, - 1, - 6, - 0, - 18), - 'm', - 0, - NPC_FISHERMAN), - 8001: (8501, - lnames[8001], - ('psl', - 'ms', - 'm', - 'm', - 13, - 0, - 13, - 13, - 0, - 11, - 0, - 11, - 2, - 10), - 'm', - 0, - NPC_KARTCLERK), - 8002: (8501, - lnames[8002], - ('psl', - 'ld', - 's', - 'f', - 23, - 0, - 23, - 23, - 0, - 11, - 0, - 11, - 2, - 10), - 'f', - 0, - NPC_KARTCLERK), - 8003: (8501, - lnames[8003], - ('pll', - 'ss', - 'l', - 'f', - 1, - 0, - 1, - 1, - 0, - 11, - 0, - 11, - 2, - 10), - 'f', - 0, - NPC_KARTCLERK), - 8004: (8501, - lnames[8004], - ('pls', - 'ms', - 'l', - 'm', - 16, - 0, - 16, - 16, - 0, - 11, - 0, - 11, - 2, - 10), - 'm', - 0, - NPC_KARTCLERK), - 9001: (9503, - lnames[9001], - ('fll', - 'ss', - 'l', - 'f', - 16, - 0, - 16, - 16, - 0, - 6, - 0, - 6, - 26, - 27), - 'f', - 0, - NPC_REGULAR), - 9002: (9502, - lnames[9002], - 'r', - 'm', - 0, - NPC_REGULAR), - 9003: (9501, - lnames[9003], - ('fls', - 'ms', - 'l', - 'm', - 22, - 0, - 22, - 22, - 1, - 5, - 1, - 5, - 0, - 14), - 'm', - 0, - NPC_REGULAR), - 9004: (9505, - lnames[9004], - ('rll', - 'ms', - 'l', - 'f', - 16, - 0, - 16, - 16, - 1, - 7, - 1, - 7, - 3, - 8), - 'f', - 1, - NPC_HQ), - 9005: (9505, - lnames[9005], - ('rss', - 'ld', - 'l', - 'f', - 9, - 0, - 9, - 9, - 1, - 8, - 1, - 8, - 19, - 27), - 'f', - 1, - NPC_HQ), - 9006: (9505, - lnames[9006], - ('rls', - 'ms', - 'l', - 'm', - 22, - 0, - 22, - 22, - 1, - 6, - 1, - 6, - 0, - 1), - 'm', - 1, - NPC_HQ), - 9007: (9505, - lnames[9007], - ('mls', - 'ms', - 'l', - 'm', - 15, - 0, - 15, - 15, - 1, - 6, - 1, - 6, - 0, - 19), - 'm', - 1, - NPC_HQ), - 9008: (9504, - lnames[9008], - ('hll', - 'ss', - 'l', - 'f', - 8, - 0, - 8, - 8, - 1, - 9, - 1, - 9, - 12, - 27), - 'f', - 0, - NPC_CLERK), - 9009: (9504, - lnames[9009], - ('hss', - 'ls', - 'l', - 'm', - 22, - 0, - 22, - 22, - 0, - 7, - 0, - 7, - 0, - 13), - 'm', - 0, - NPC_CLERK), - 9010: (9506, - lnames[9010], - ('cll', - 'ms', - 'l', - 'm', - 15, - 0, - 15, - 15, - 0, - 8, - 0, - 8, - 0, - 10), - 'm', - 0, - NPC_TAILOR), - 9011: (9000, - lnames[9011], - ('csl', - 'ss', - 'l', - 'm', - 7, - 0, - 7, - 7, - 0, - 8, - 0, - 8, - 0, - 4), - 'm', - 0, - NPC_FISHERMAN), - 9012: (9508, - lnames[9012], - ('cls', - 'ld', - 'l', - 'f', - 23, - 0, - 23, - 23, - 0, - 21, - 0, - 21, - 10, - 27), - 'f', - 0, - NPC_PETCLERK), - 9013: (9508, - lnames[9013], - ('dll', - 'sd', - 'l', - 'f', - 15, - 0, - 15, - 15, - 0, - 21, - 0, - 21, - 10, - 27), - 'f', - 0, - NPC_PETCLERK), - 9014: (9508, - lnames[9014], - ('dss', - 'ss', - 'l', - 'm', - 7, - 0, - 7, - 7, - 0, - 9, - 0, - 9, - 1, - 15), - 'm', - 0, - NPC_PETCLERK), - 9015: (9000, - lnames[9015], - ('rss', - 'ls', - 'l', - 'm', - 21, - 0, - 20, - 20, - 0, - 12, - 0, - 12, - 0, - 11), - 'm', - 1, - NPC_PARTYPERSON), - 9016: (9000, - lnames[9016], - ('rls', - 'md', - 'l', - 'f', - 6, - 0, - 21, - 21, - 1, - 11, - 1, - 11, - 0, - 11), - 'f', - 1, - NPC_PARTYPERSON), - 9101: (9604, - lnames[9101], - ('css', - 'ls', - 'l', - 'm', - 14, - 0, - 14, - 14, - 1, - 1, - 1, - 1, - 0, - 11), - 'm', - 1, - NPC_REGULAR), - 9102: (9607, - lnames[9102], - 'r', - 'f', - 1, - NPC_REGULAR), - 9103: (9620, - lnames[9103], - ('dsl', - 'ss', - 'l', - 'm', - 20, - 0, - 20, - 20, - 0, - 2, - 0, - 2, - 0, - 1), - 'm', - 0, - NPC_REGULAR), - 9104: (9642, - lnames[9104], - ('dss', - 'ld', - 'l', - 'f', - 14, - 0, - 14, - 14, - 0, - 3, - 0, - 3, - 0, - 23), - 'f', - 0, - NPC_REGULAR), - 9105: (9609, - lnames[9105], - 'r', - 'm', - 1, - NPC_REGULAR), - 9106: (9619, - lnames[9106], - ('fsl', - 'ss', - 'l', - 'm', - 20, - 0, - 20, - 20, - 0, - 3, - 0, - 3, - 0, - 13), - 'm', - 0, - NPC_REGULAR), - 9107: (9601, - lnames[9107], - ('fls', - 'ld', - 'l', - 'f', - 13, - 0, - 13, - 13, - 0, - 5, - 0, - 5, - 3, - 2), - 'f', - 1, - NPC_REGULAR), - 9108: (9602, - lnames[9108], - ('rll', - 'ms', - 'l', - 'm', - 6, - 0, - 6, - 6, - 1, - 4, - 1, - 4, - 0, - 4), - 'm', - 1, - NPC_REGULAR), - 9109: (9605, - lnames[9109], - ('rss', - 'ls', - 'l', - 'f', - 22, - 0, - 22, - 22, - 1, - 6, - 1, - 6, - 10, - 27), - 'f', - 1, - NPC_REGULAR), - 9110: (9608, - lnames[9110], - ('mss', - 'ss', - 'l', - 'f', - 13, - 0, - 13, - 13, - 1, - 6, - 1, - 6, - 25, - 27), - 'f', - 1, - NPC_REGULAR), - 9111: (9616, - lnames[9111], - 'r', - 'f', - 0, - NPC_REGULAR), - 9112: (9617, - lnames[9112], - ('hsl', - 'ms', - 'm', - 'm', - 19, - 0, - 19, - 19, - 1, - 5, - 1, - 5, - 0, - 12), - 'm', - 0, - NPC_REGULAR), - 9113: (9622, - lnames[9113], - ('hss', - 'ss', - 'm', - 'm', - 13, - 0, - 13, - 13, - 1, - 5, - 1, - 5, - 0, - 9), - 'm', - 0, - NPC_REGULAR), - 9114: (9625, - lnames[9114], - ('cll', - 'ld', - 'm', - 'f', - 4, - 0, - 4, - 4, - 0, - 8, - 0, - 8, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 9115: (9626, - lnames[9115], - 'r', - 'm', - 0, - NPC_REGULAR), - 9116: (9627, - lnames[9116], - ('cls', - 'ss', - 'm', - 'm', - 12, - 0, - 12, - 12, - 0, - 7, - 0, - 7, - 0, - 17), - 'm', - 0, - NPC_REGULAR), - 9117: (9628, - lnames[9117], - ('dsl', - 'ld', - 'm', - 'f', - 4, - 0, - 4, - 4, - 0, - 11, - 0, - 11, - 2, - 9), - 'f', - 0, - NPC_REGULAR), - 9118: (9629, - lnames[9118], - 'r', - 'f', - 0, - NPC_REGULAR), - 9119: (9630, - lnames[9119], - ('fll', - 'ms', - 'm', - 'm', - 12, - 0, - 12, - 12, - 0, - 8, - 0, - 8, - 0, - 6), - 'm', - 0, - NPC_REGULAR), - 9120: (9631, - lnames[9120], - 'r', - 'f', - 0, - NPC_REGULAR), - 9121: (9634, - lnames[9121], - ('fls', - 'md', - 'm', - 'f', - 19, - 0, - 19, - 19, - 1, - 12, - 1, - 12, - 16, - 27), - 'f', - 0, - NPC_REGULAR), - 9122: (9636, - lnames[9122], - ('rll', - 'ms', - 'm', - 'm', - 12, - 0, - 12, - 12, - 1, - 8, - 1, - 8, - 0, - 16), - 'm', - 0, - NPC_REGULAR), - 9123: (9639, - lnames[9123], - ('rss', - 'ss', - 'm', - 'm', - 4, - 0, - 4, - 4, - 1, - 9, - 1, - 9, - 0, - 13), - 'm', - 0, - NPC_REGULAR), - 9124: (9640, - lnames[9124], - ('rls', - 'md', - 'm', - 'f', - 19, - 0, - 19, - 19, - 1, - 22, - 1, - 22, - 8, - 9), - 'f', - 0, - NPC_REGULAR), - 9125: (9643, - lnames[9125], - ('mls', - 'ms', - 'l', - 'm', - 10, - 0, - 10, - 10, - 1, - 9, - 1, - 9, - 0, - 4), - 'm', - 0, - NPC_REGULAR), - 9126: (9644, - lnames[9126], - ('hsl', - 'ms', - 'l', - 'f', - 3, - 0, - 3, - 3, - 1, - 23, - 1, - 23, - 23, - 27), - 'f', - 0, - NPC_REGULAR), - 9127: (9645, - lnames[9127], - ('hss', - 'ld', - 'l', - 'f', - 19, - 0, - 19, - 19, - 0, - 24, - 0, - 24, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 9128: (9647, - lnames[9128], - ('cll', - 'ms', - 'l', - 'm', - 10, - 0, - 10, - 10, - 0, - 11, - 0, - 11, - 0, - 15), - 'm', - 0, - NPC_REGULAR), - 9129: (9649, - lnames[9129], - ('csl', - 'ms', - 'l', - 'f', - 3, - 0, - 3, - 3, - 0, - 25, - 0, - 25, - 25, - 27), - 'f', - 0, - NPC_REGULAR), - 9130: (9650, - lnames[9130], - ('cls', - 'ss', - 'l', - 'm', - 18, - 0, - 18, - 18, - 0, - 12, - 0, - 12, - 0, - 9), - 'm', - 0, - NPC_REGULAR), - 9131: (9651, - lnames[9131], - 'r', - 'f', - 0, - NPC_REGULAR), - 9132: (9652, - lnames[9132], - ('dss', - 'ls', - 'l', - 'f', - 2, - 0, - 2, - 2, - 0, - 27, - 0, - 27, - 0, - 0), - 'f', - 0, - NPC_HQ), - 9133: (9652, - lnames[9133], - ('dls', - 'ss', - 'l', - 'm', - 17, - 0, - 17, - 17, - 1, - 12, - 1, - 12, - 0, - 17), - 'm', - 0, - NPC_HQ), - 9134: (9652, - lnames[9134], - ('fsl', - 'ls', - 'l', - 'm', - 10, - 0, - 10, - 10, - 1, - 0, - 1, - 0, - 0, - 14), - 'm', - 0, - NPC_HQ), - 9135: (9652, - lnames[9135], - ('fls', - 'ms', - 'l', - 'm', - 3, - 0, - 3, - 3, - 1, - 0, - 1, - 0, - 0, - 11), - 'm', - 0, - NPC_HQ), - 9136: (9153, - lnames[9136], - ('rll', - 'ss', - 'l', - 'm', - 17, - 0, - 17, - 17, - 1, - 0, - 1, - 0, - 1, - 6), - 'm', - 0, - NPC_FISHERMAN), - 9201: (9752, - lnames[9201], - ('psl', - 'ss', - 'm', - 'm', - 9, - 0, - 9, - 9, - 17, - 11, - 0, - 11, - 7, - 20), - 'm', - 0, - NPC_REGULAR), - 9202: (9703, - lnames[9202], - ('dss', - 'ss', - 's', - 'm', - 21, - 0, - 21, - 21, - 8, - 3, - 8, - 3, - 1, - 17), - 'm', - 1, - NPC_REGULAR), - 9203: (9741, - lnames[9203], - ('pls', - 'ls', - 's', - 'm', - 5, - 0, - 5, - 5, - 37, - 27, - 26, - 27, - 7, - 4), - 'm', - 0, - NPC_REGULAR), - 9204: (9704, - lnames[9204], - ('fsl', - 'sd', - 's', - 'f', - 19, - 0, - 19, - 19, - 21, - 10, - 0, - 10, - 8, - 23), - 'f', - 1, - NPC_REGULAR), - 9205: (9736, - lnames[9205], - ('dsl', - 'ms', - 'm', - 'm', - 15, - 0, - 15, - 15, - 45, - 27, - 34, - 27, - 2, - 17), - 'm', - 0, - NPC_REGULAR), - 9206: (9727, - lnames[9206], - ('rls', - 'ld', - 'l', - 'f', - 8, - 0, - 8, - 8, - 25, - 27, - 16, - 27, - 10, - 27), - 'f', - 0, - NPC_REGULAR), - 9207: (9709, - lnames[9207], - ('hss', - 'ss', - 's', - 'f', - 24, - 0, - 24, - 24, - 36, - 27, - 25, - 27, - 9, - 27), - 'f', - 1, - NPC_REGULAR), - 9208: (9705, - lnames[9208], - ('dsl', - 'ms', - 's', - 'm', - 20, - 0, - 20, - 20, - 46, - 27, - 35, - 27, - 6, - 27), - 'm', - 1, - NPC_REGULAR), - 9209: (9706, - lnames[9209], - ('pll', - 'ss', - 'm', - 'm', - 13, - 0, - 13, - 13, - 8, - 12, - 8, - 12, - 1, - 12), - 'm', - 1, - NPC_REGULAR), - 9210: (9740, - lnames[9210], - ('hsl', - 'ls', - 'l', - 'm', - 6, - 0, - 6, - 6, - 1, - 0, - 1, - 0, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 9211: (9707, - lnames[9211], - ('rll', - 'ss', - 's', - 'f', - 3, - 0, - 3, - 3, - 22, - 22, - 0, - 22, - 6, - 22), - 'f', - 1, - NPC_REGULAR), - 9212: (9753, - lnames[9212], - ('pss', - 'md', - 'm', - 'f', - 16, - 0, - 16, - 16, - 45, - 27, - 34, - 27, - 0, - 3), - 'f', - 0, - NPC_REGULAR), - 9213: (9711, - lnames[9213], - ('fsl', - 'ss', - 'm', - 'm', - 2, - 0, - 2, - 2, - 37, - 27, - 26, - 27, - 7, - 18), - 'm', - 0, - NPC_REGULAR), - 9214: (9710, - lnames[9214], - ('rll', - 'ls', - 'l', - 'm', - 18, - 0, - 18, - 18, - 10, - 27, - 0, - 27, - 0, - 13), - 'm', - 0, - NPC_REGULAR), - 9215: (9744, - lnames[9215], - ('csl', - 'ls', - 'l', - 'm', - 18, - 0, - 18, - 18, - 11, - 4, - 0, - 4, - 0, - 4), - 'm', - 0, - NPC_REGULAR), - 9216: (9725, - lnames[9216], - ('csl', - 'sd', - 'm', - 'f', - 14, - 0, - 14, - 14, - 1, - 7, - 1, - 7, - 3, - 7), - 'f', - 0, - NPC_REGULAR), - 9217: (9713, - lnames[9217], - ('mss', - 'ms', - 'm', - 'f', - 17, - 0, - 17, - 17, - 20, - 26, - 0, - 26, - 5, - 12), - 'f', - 0, - NPC_REGULAR), - 9218: (9737, - lnames[9218], - ('dss', - 'md', - 'l', - 'f', - 23, - 0, - 23, - 23, - 24, - 27, - 15, - 27, - 11, - 27), - 'f', - 0, - NPC_REGULAR), - 9219: (9712, - lnames[9219], - ('hll', - 'sd', - 'l', - 'f', - 10, - 0, - 10, - 10, - 9, - 22, - 9, - 22, - 12, - 27), - 'f', - 0, - NPC_REGULAR), - 9220: (9716, - lnames[9220], - ('mls', - 'ms', - 'l', - 'm', - 7, - 0, - 7, - 7, - 0, - 27, - 0, - 27, - 1, - 10), - 'm', - 0, - NPC_REGULAR), - 9221: (9738, - lnames[9221], - ('fss', - 'md', - 'l', - 'f', - 22, - 0, - 22, - 22, - 45, - 27, - 34, - 27, - 0, - 6), - 'f', - 0, - NPC_REGULAR), - 9222: (9754, - lnames[9222], - ('hsl', - 'ls', - 'l', - 'm', - 10, - 0, - 10, - 10, - 52, - 27, - 41, - 27, - 12, - 27), - 'm', - 0, - NPC_REGULAR), - 9223: (9714, - lnames[9223], - ('fsl', - 'ms', - 'm', - 'm', - 20, - 0, - 20, - 20, - 43, - 27, - 32, - 27, - 0, - 0), - 'm', - 0, - NPC_REGULAR), - 9224: (9718, - lnames[9224], - ('css', - 'ms', - 'm', - 'f', - 1, - 0, - 1, - 1, - 6, - 8, - 6, - 8, - 6, - 8), - 'f', - 0, - NPC_REGULAR), - 9225: (9717, - lnames[9225], - ('rss', - 'md', - 'm', - 'f', - 11, - 0, - 11, - 11, - 40, - 27, - 29, - 27, - 0, - 27), - 'f', - 0, - NPC_REGULAR), - 9226: (9715, - lnames[9226], - ('mls', - 'ms', - 's', - 'm', - 12, - 0, - 12, - 12, - 3, - 10, - 3, - 10, - 6, - 10), - 'm', - 0, - NPC_REGULAR), - 9227: (9721, - lnames[9227], - ('cls', - 'ss', - 's', - 'm', - 13, - 0, - 13, - 13, - 8, - 5, - 8, - 5, - 3, - 18), - 'm', - 0, - NPC_REGULAR), - 9228: (9720, - lnames[9228], - ('fss', - 'sd', - 's', - 'f', - 4, - 0, - 4, - 4, - 15, - 5, - 11, - 5, - 8, - 5), - 'f', - 0, - NPC_REGULAR), - 9229: (9708, - lnames[9229], - ('css', - 'ld', - 'm', - 'f', - 4, - 0, - 4, - 4, - 22, - 21, - 0, - 21, - 4, - 21), - 'f', - 1, - NPC_REGULAR), - 9230: (9719, - lnames[9230], - ('mss', - 'ss', - 's', - 'm', - 8, - 0, - 8, - 8, - 53, - 27, - 42, - 27, - 13, - 27), - 'm', - 0, - NPC_REGULAR), - 9231: (9722, - lnames[9231], - ('dll', - 'ss', - 's', - 'm', - 6, - 0, - 6, - 6, - 27, - 27, - 18, - 27, - 3, - 8), - 'm', - 0, - NPC_REGULAR), - 9232: (9759, - lnames[9232], - ('pss', - 'ld', - 'm', - 'f', - 21, - 0, - 21, - 21, - 0, - 27, - 0, - 27, - 13, - 27), - 'f', - 0, - NPC_REGULAR), - 9233: (9756, - lnames[9233], - ('csl', - 'ls', - 'l', - 'f', - 22, - 0, - 22, - 22, - 1, - 7, - 1, - 7, - 12, - 27), - 'f', - 0, - NPC_HQ), - 9234: (9756, - lnames[9234], - ('cls', - 'ss', - 'l', - 'm', - 14, - 0, - 14, - 14, - 1, - 5, - 1, - 5, - 0, - 19), - 'm', - 0, - NPC_HQ), - 9235: (9756, - lnames[9235], - ('dll', - 'ls', - 'l', - 'm', - 6, - 0, - 6, - 6, - 1, - 6, - 1, - 6, - 0, - 16), - 'm', - 0, - NPC_HQ), - 9236: (9756, - lnames[9236], - ('dss', - 'ms', - 'l', - 'm', - 20, - 0, - 20, - 20, - 0, - 6, - 0, - 6, - 0, - 13), - 'm', - 0, - NPC_HQ), - 9237: (9255, - lnames[9237], - ('dls', - 'ss', - 'l', - 'm', - 14, - 0, - 14, - 14, - 0, - 7, - 0, - 7, - 0, - 10), - 'm', - 0, - NPC_FISHERMAN), - 9301: (9329, - lnames[9301], - 'r', - 'm', - 0, - NPC_FISHERMAN), - 9302: (9802, - lnames[9302], - ('dss', - 'ld', - 'l', - 'f', - 17, - 0, - 17, - 17, - 5, - 21, - 5, - 21, - 8, - 26), - 'f', - 0, - NPC_REGULAR), - 9303: (9826, - lnames[9303], - 'r', - 'm', - 0, - NPC_REGULAR), - 9304: (9804, - lnames[9304], - ('dss', - 'ls', - 's', - 'm', - 16, - 0, - 16, - 16, - 14, - 10, - 10, - 10, - 3, - 19), - 'm', - 0, - NPC_REGULAR), - 9305: (9829, - lnames[9305], - 'r', - 'm', - 0, - NPC_HQ), - 9306: (9829, - lnames[9306], - 'r', - 'm', - 0, - NPC_HQ), - 9307: (9829, - lnames[9307], - 'r', - 'f', - 0, - NPC_HQ), - 9308: (9829, - lnames[9308], - 'r', - 'f', - 0, - NPC_HQ), - 9309: (9808, - lnames[9309], - ('css', - 'ms', - 'm', - 'm', - 26, - 0, - 26, - 26, - 8, - 4, - 8, - 4, - 7, - 4), - 'm', - 0, - NPC_REGULAR), - 9310: (9820, - lnames[9310], - 'r', - 'm', - 0, - NPC_REGULAR), - 9311: (9809, - lnames[9311], - ('dls', - 'ls', - 'm', - 'm', - 24, - 0, - 18, - 18, - 11, - 7, - 0, - 7, - 1, - 11), - 'm', - 0, - NPC_REGULAR), - 9312: (9828, - lnames[9312], - 'r', - 'f', - 0, - NPC_REGULAR), - 9313: (9827, - lnames[9313], - 'r', - 'm', - 0, - NPC_REGULAR), - 9314: (9812, - lnames[9314], - 'r', - 'm', - 0, - NPC_REGULAR), - 9315: (9813, - lnames[9315], - 'r', - 'f', - 0, - NPC_REGULAR), - 9316: (9814, - lnames[9316], - 'r', - 'f', - 0, - NPC_REGULAR), - 9317: (9815, - lnames[9317], - ('css', - 'md', - 's', - 'f', - 22, - 0, - 22, - 22, - 7, - 4, - 7, - 4, - 8, - 11), - 'f', - 0, - NPC_REGULAR), - 9318: (9816, - lnames[9318], - 'r', - 'm', - 0, - NPC_REGULAR), - 9319: (9817, - lnames[9319], - ('css', - 'ls', - 'm', - 'm', - 26, - 0, - 26, - 26, - 5, - 11, - 5, - 11, - 5, - 11), - 'm', - 0, - NPC_REGULAR), - 9320: (9819, - lnames[9320], - 'r', - 'm', - 0, - NPC_REGULAR), - 9321: (9824, - lnames[9321], - ('dss', - 'ms', - 'm', - 'm', - 2, - 0, - 2, - 2, - 4, - 1, - 4, - 1, - 2, - 16), - 'm', - 0, - NPC_REGULAR), - 9322: (9821, - lnames[9322], - ('dss', - 'ms', - 'm', - 'm', - 15, - 0, - 15, - 15, - 5, - 6, - 5, - 6, - 7, - 9), - 'f', - 0, - NPC_REGULAR), - 9323: (9822, - lnames[9323], - ('css', - 'ms', - 's', - 'm', - 31, - 0, - 31, - 31, - 8, - 2, - 8, - 2, - 5, - 11), - 'm', - 0, - NPC_REGULAR), - 9324: (9806, - lnames[9324], - ('fss', - 'ls', - 'l', - 'm', - 16, - 0, - 16, - 16, - 2, - 9, - 2, - 9, - 7, - 20), - 'm', - 0, - NPC_REGULAR), - 7001: (-1, - lnames[7001], - ('bss', - 'md', - 'm', - 'f', - 25, - 0, - 25, - 25, - 6, - 12, - 0, - 0, - 0, - 2), - 'f', - 0, - NPC_REGULAR), - 7002: (-1, - lnames[7002], - ('sss', - 'ms', - 'l', - 'm', - 7, - 0, - 7, - 7, - 18, - 11, - 0, - 0, - 4, - 3), - 'm', - 0, - NPC_REGULAR), - 7003: (-1, - lnames[7003], - ('sss', - 'md', - 'm', - 'f', - 21, - 0, - 21, - 21, - 45, - 0, - 0, - 0, - 7, - 6), - 'f', - 0, - NPC_REGULAR), - 7004: (-1, - lnames[7004], - ('pss', - 'ls', - 'l', - 'm', - 16, - 0, - 16, - 16, - 27, - 0, - 0, - 0, - 7, - 16), - 'm', - 0, - NPC_REGULAR), - 7005: (-1, - lnames[7005], - ('pls', - 'ld', - 's', - 'f', - 5, - 0, - 5, - 5, - 25, - 0, - 0, - 0, - 10, - 0), - 'f', - 0, - NPC_REGULAR), - 7006: (-1, - lnames[7006], - ('bll', - 'ms', - 's', - 'm', - 18, - 0, - 18, - 18, - 15, - 4, - 0, - 0, - 9, - 3), - 'm', - 0, - NPC_REGULAR), - 7007: (-1, - lnames[7007], - ('pls', - 'ls', - 's', - 'm', - 11, - 0, - 11, - 11, - 46, - 0, - 0, - 0, - 5, - 16), - 'm', - 0, - NPC_REGULAR), - 7008: (-1, - lnames[7008], - ('bls', - 'ld', - 's', - 'f', - 23, - 0, - 23, - 23, - 15, - 6, - 0, - 0, - 0, - 18), - 'f', - 0, - NPC_REGULAR), - 7009: (-1, - lnames[7009], - ('sll', - 'ss', - 's', - 'm', - 1, - 0, - 1, - 1, - 1, - 6, - 0, - 0, - 0, - 6), - 'm', - 0, - NPC_REGULAR), - 7010: (-1, - lnames[7010], - ('rll', - 'ms', - 'm', - 'm', - 2, - 0, - 2, - 2, - 19, - 10, - 13, - 10, - 7, - 14, - 0), - 'm', - 0, - NPC_REGULAR), - 7011: (-1, - lnames[7011], - ('fll', - 'ls', - 'm', - 'm', - 0, - 0, - 9, - 0, - 10, - 10, - 0, - 10, - 5, - 27), - 'm', - 0, - NPC_REGULAR), - 7012: (-1, - lnames[7012], - ('pss', - 'ms', - 'l', - 'm', - 20, - 0, - 20, - 20, - 26, - 0, - 0, - 0, - 15), - 'm', - 0, - NPC_REGULAR), - 7013: (-1, - lnames[7013], - ('bsl', - 'ms', - 'm', - 'f', - 20, - 0, - 20, - 20, - 3, - 4, - 0, - 0, - 5, - 18), - 'f', - 0, - NPC_REGULAR), - 7014: (-1, - lnames[7014], - ('bll', - 'ss', - 's', - 'm', - 11, - 0, - 11, - 11, - 3, - 6, - 0, - 0, - 1, - 2), - 'm', - 0, - NPC_REGULAR), - 7015: (-1, - lnames[7015], - ('ssl', - 'sd', - 'l', - 'f', - 13, - 0, - 13, - 13, - 1, - 2, - 0, - 0, - 0, - 10), - 'f', - 0, - NPC_REGULAR), - 7016: (-1, - lnames[7016], - ('hll', - 'ls', - 'l', - 'm', - 8, - 0, - 8, - 8, - 1, - 3, - 0, - 0, - 1, - 16), - 'm', - 0, - NPC_REGULAR), - 7017: (-1, - lnames[7017], - ('dsl', - 'ms', - 's', - 'm', - 5, - 0, - 5, - 5, - 1, - 0, - 0, - 0, - 0, - 4), - 'm', - 0, - NPC_REGULAR), - 7018: (-1, - lnames[7018], - ('pls', - 'ls', - 's', - 'f', - 14, - 0, - 14, - 14, - 0, - 11, - 0, - 0, - 5, - 9), - 'f', - 0, - NPC_REGULAR), - 7019: (-1, - lnames[7019], - ('bsl', - 'ls', - 'l', - 'm', - 12, - 0, - 12, - 12, - 1, - 10, - 0, - 0, - 1, - 13), - 'm', - 0, - NPC_REGULAR), - 7020: (-1, - lnames[7020], - ('sss', - 'ms', - 'l', - 'm', - 2, - 0, - 2, - 2, - 0, - 4, - 0, - 0, - 0, - 6), - 'm', - 0, - NPC_REGULAR), - 7021: (-1, - lnames[7021], - ('fsl', - 'ls', - 'm', - 'm', - 17, - 0, - 17, - 17, - 4, - 4, - 0, - 0, - 0, - 10), - 'm', - 0, - NPC_REGULAR), - 7022: (-1, - lnames[7022], - ('mss', - 'sd', - 's', - 'f', - 24, - 0, - 24, - 24, - 3, - 1, - 0, - 0, - 0, - 13), - 'f', - 0, - NPC_REGULAR), - 7023: (-1, - lnames[7023], - ('pss', - 'sd', - 'l', - 'f', - 9, - 0, - 9, - 9, - 0, - 8, - 0, - 0, - 11, - 0), - 'f', - 0, - NPC_REGULAR), - 10001: (10000, - lnames[10001], - 'r', - 'f', - 0, - NPC_LAFF_RESTOCK), - 11001: (11000, - lnames[11001], - 'r', - 'm', - 0, - NPC_LAFF_RESTOCK), - 12001: (12000, - lnames[12001], - 'r', - 'm', - 0, - NPC_LAFF_RESTOCK), - 13001: (13000, - lnames[13001], - 'r', - 'f', - 0, - NPC_LAFF_RESTOCK)} +NPCToonDict = { + 20000: (-1, lnames[20000], ('dls', 'ms', 'm', 'm', 7, 0, 7, 7, 2, 6, 2, 6, 2, 16), 'm', 1, NPC_SPECIALQUESTGIVER), + 999: (-1, lnames[999], 'r', 'm', 1, NPC_TAILOR), + 1000: (-1, lnames[1000], 'r', 'm', 1, NPC_HQ), + 20001: (-1, lnames[20001], ('dss', 'ms', 'm', 'm', 17, 0, 17, 17, 3, 3, 3, 3, 7, 2), 'm', 1, NPC_BLOCKER), + 20002: (-1, TTLocalizer.TutorialHQOfficerName, ('dls', 'ms', 'm', 'm', 6, 0, 6, 6, 0, 10, 0, 10, 2, 9), 'm', 1, NPC_SPECIALQUESTGIVER), + 2002: (2514, lnames[2002], ('hss', 'ls', 'l', 'm', 4, 0, 4, 4, 0, 3, 0, 3, 1, 18), 'm', 1, NPC_REGULAR), + 2003: (2516, lnames[2003], ('cll', 'ms', 'l', 'm', 18, 0, 18, 18, 0, 4, 0, 4, 1, 15), 'm', 1, NPC_REGULAR), + 2004: (2521, lnames[2004], ('rll', 'md', 'm', 'f', 15, 0, 5, 7, 3, 5, 3, 5, 0, 3), 'f', 1, NPC_TAILOR), + 2005: (2518, lnames[2005], ('cls', 'ls', 'l', 'm', 4, 0, 4, 4, 0, 4, 0, 4, 1, 9), 'm', 1, NPC_REGULAR), + 2006: (2519, lnames[2006], ('dsl', 'ls', 'l', 'm', 18, 0, 18, 18, 1, 4, 1, 4, 1, 2), 'm', 1, NPC_CLERK), + 2011: (2519, lnames[2011], ('rll', 'ms', 'l', 'f', 2, 0, 2, 2, 1, 9, 1, 9, 23, 27), 'f', 1, NPC_CLERK), + 2007: (2520, lnames[2007], ('dss', 'ms', 'l', 'm', 10, 0, 10, 10, 1, 5, 1, 5, 1, 20), 'm', 1, NPC_HQ), + 2008: (2520, lnames[2008], ('fll', 'ss', 'l', 'm', 3, 0, 3, 3, 1, 5, 1, 5, 1, 17), 'm', 1, NPC_HQ), + 2009: (2520, lnames[2009], ('fsl', 'md', 'l', 'f', 18, 0, 18, 18, 1, 8, 1, 8, 11, 27), 'f', 1, NPC_HQ), + 2010: (2520, lnames[2010], ('fls', 'ls', 'l', 'f', 11, 0, 11, 11, 1, 8, 1, 8, 8, 4), 'f', 1, NPC_HQ), + 2012: (2000, lnames[2012], ('rss', 'ls', 'l', 'm', 17, 0, 17, 17, 1, 6, 1, 6, 1, 1), 'm', 1, NPC_FISHERMAN), + 2013: (2522, lnames[2013], ('rls', 'ms', 'l', 'm', 9, 0, 9, 9, 0, 7, 0, 7, 1, 19), 'm', 1, NPC_PETCLERK), + 2014: (2522, lnames[2014], ('mls', 'ms', 'm', 'f', 2, 0, 2, 2, 0, 12, 0, 12, 1, 0), 'f', 1, NPC_PETCLERK), + 2015: (2522, lnames[2015], ('hsl', 'ls', 'm', 'm', 17, 0, 17, 17, 0, 8, 0, 8, 1, 13), 'm', 1, NPC_PETCLERK), + 2016: (2000, lnames[2016], ('sls', 'ls', 'm', 'm', 10, 0, 9, 9, 0, 3, 0, 3, 0, 18), 'm', 1, NPC_PARTYPERSON), + 2017: (2000, lnames[2017], ('sss', 'ld', 'm', 'f', 10, 0, 9, 9, 0, 23, 0, 23, 0, 5), 'f', 1, NPC_PARTYPERSON), + 2018: (2513, lnames[2019], ('fll', 'ss', 's', 'm', 15, 0, 15, 15, 99, 27, 86, 27, 39, 27), 'm', 1, NPC_SCIENTIST), + 2019: (2513, lnames[2018], ('pls', 'ls', 'l', 'm', 9, 0, 9, 9, 98, 27, 86, 27, 38, 27), 'm', 1, NPC_SCIENTIST), + 2020: (2513, lnames[2020], ('hss', 'ms', 'm', 'm', 20, 0, 20, 20, 97, 27, 86, 27, 37, 27), 'm', 1, NPC_SCIENTIST), + 2021: (2000, lnames[2021], ('dss', 'ls', 's', 'm', 13, 0, 13, 13, 1, 6, 1, 6, 0, 18), 'm', 1, NPC_GLOVE), + 2101: (2601, lnames[2101], ('rll', 'ms', 'l', 'm', 15, 0, 15, 15, 0, 9, 0, 9, 0, 6), 'm', 1, NPC_REGULAR), + 2102: (2619, lnames[2102], 'r', 'f', 0, NPC_REGULAR), + 2103: (2616, lnames[2103], ('csl', 'ss', 's', 'm', 9, 0, 8, 5, 0, 11, 0, 11, 2, 10), 'm', 0, NPC_REGULAR), + 2104: (2671, lnames[2104], ('mls', 'ms', 'm', 'm', 15, 0, 15, 15, 1, 10, 1, 10, 0, 16), 'm', 1, NPC_HQ), + 2105: (2671, lnames[2105], ('hsl', 'ss', 'm', 'm', 7, 0, 7, 7, 1, 10, 1, 10, 0, 13), 'm', 1, NPC_HQ), + 2106: (2671, lnames[2106], ('hss', 'ld', 'm', 'f', 23, 0, 23, 23, 1, 23, 1, 23, 24, 27), 'f', 1, NPC_HQ), + 2107: (2671, lnames[2107], ('cll', 'sd', 'm', 'f', 14, 0, 14, 14, 1, 24, 1, 24, 7, 4), 'f', 1, NPC_HQ), + 2108: (2603, lnames[2108], ('csl', 'ms', 'm', 'f', 7, 0, 7, 7, 1, 24, 1, 24, 3, 2), 'f', 1, NPC_REGULAR), + 2109: (2604, lnames[2109], 'r', 'm', 1, NPC_REGULAR), + 2110: (2605, lnames[2110], ('dll', 'ls', 'm', 'm', 14, 0, 14, 14, 0, 27, 0, 27, 0, 15), 'm', 0, NPC_REGULAR), + 2111: (2607, lnames[2111], 'r', 'm', 1, NPC_REGULAR), + 2112: (2610, lnames[2112], ('fll', 'ss', 'm', 'm', 20, 0, 20, 20, 0, 27, 0, 27, 0, 9), 'm', 1, NPC_REGULAR), + 2113: (2617, lnames[2113], ('fsl', 'ls', 'm', 'm', 14, 0, 14, 14, 0, 0, 0, 0, 0, 2), 'm', 0, NPC_REGULAR), + 2114: (2618, lnames[2114], ('fls', 'sd', 'm', 'f', 6, 0, 6, 6, 0, 0, 0, 0, 23, 27), 'f', 0, NPC_REGULAR), + 2115: (2621, lnames[2115], ('rll', 'ms', 'l', 'f', 22, 0, 22, 22, 1, 1, 1, 1, 26, 27), 'f', 0, NPC_REGULAR), + 2116: (2624, lnames[2116], ('rss', 'ls', 'l', 'm', 13, 0, 13, 13, 1, 1, 1, 1, 1, 14), 'm', 0, NPC_REGULAR), + 2117: (2625, lnames[2117], ('rls', 'sd', 'l', 'f', 6, 0, 6, 6, 1, 2, 1, 2, 25, 27), 'f', 0, NPC_REGULAR), + 2118: (2626, lnames[2118], ('mls', 'ss', 'l', 'm', 20, 0, 20, 20, 1, 1, 1, 1, 1, 6), 'm', 0, NPC_REGULAR), + 2119: (2629, lnames[2119], ('hll', 'ss', 'l', 'f', 13, 0, 13, 13, 1, 3, 1, 3, 19, 27), 'f', 1, NPC_REGULAR), + 2120: (2632, lnames[2120], ('hss', 'ls', 'l', 'm', 5, 0, 5, 5, 1, 2, 1, 2, 1, 19), 'm', 0, NPC_REGULAR), + 2121: (2633, lnames[2121], ('cll', 'ls', 'l', 'f', 21, 0, 21, 21, 0, 4, 0, 4, 4, 4), 'f', 0, NPC_REGULAR), + 2122: (2639, lnames[2122], ('csl', 'ss', 'l', 'm', 13, 0, 13, 13, 0, 3, 0, 3, 1, 13), 'm', 0, NPC_REGULAR), + 2123: (2643, lnames[2123], ('cls', 'md', 'l', 'f', 4, 0, 4, 4, 0, 5, 0, 5, 14, 27), 'f', 0, NPC_REGULAR), + 2124: (2644, lnames[2124], ('dll', 'sd', 'l', 'f', 21, 0, 21, 21, 0, 5, 0, 5, 8, 21), 'f', 0, NPC_REGULAR), + 2125: (2649, lnames[2125], ('dss', 'ss', 'l', 'm', 12, 0, 12, 12, 0, 4, 0, 4, 1, 0), 'm', 0, NPC_REGULAR), + 2126: (2654, lnames[2126], ('dls', 'ld', 'l', 'f', 4, 0, 4, 4, 0, 6, 0, 6, 3, 7), 'f', 1, NPC_REGULAR), + 2127: (2655, lnames[2127], ('fsl', 'ms', 'l', 'm', 19, 0, 19, 19, 0, 5, 0, 5, 1, 15), 'm', 1, NPC_REGULAR), + 2128: (2656, lnames[2128], ('fss', 'ss', 'l', 'm', 12, 0, 12, 12, 1, 5, 1, 5, 1, 12), 'm', 1, NPC_REGULAR), + 2129: (2657, lnames[2129], ('rll', 'ss', 'l', 'm', 4, 0, 4, 4, 1, 5, 1, 5, 1, 9), 'm', 0, NPC_REGULAR), + 2130: (2659, lnames[2130], ('rss', 'md', 'l', 'f', 19, 0, 19, 19, 1, 8, 1, 8, 7, 7), 'f', 0, NPC_REGULAR), + 2131: (2660, lnames[2131], ('rls', 'ls', 'l', 'f', 12, 0, 12, 12, 1, 8, 1, 8, 1, 26), 'f', 1, NPC_REGULAR), + 2132: (2661, lnames[2132], ('mls', 'ss', 'l', 'm', 4, 0, 4, 4, 1, 6, 1, 6, 1, 17), 'm', 0, NPC_REGULAR), + 2133: (2662, lnames[2133], ('hll', 'ls', 'l', 'm', 18, 0, 18, 18, 1, 6, 1, 6, 1, 14), 'm', 0, NPC_REGULAR), + 2134: (2664, lnames[2134], 'r', 'f', 0, NPC_REGULAR), + 2135: (2665, lnames[2135], ('hls', 'ms', 'l', 'f', 3, 0, 3, 3, 0, 12, 0, 12, 2, 26), 'f', 1, NPC_REGULAR), + 2136: (2666, lnames[2136], ('csl', 'ls', 'l', 'm', 18, 0, 18, 18, 0, 8, 0, 8, 1, 1), 'm', 0, NPC_REGULAR), + 2137: (2667, lnames[2137], ('css', 'sd', 'l', 'f', 11, 0, 11, 11, 0, 21, 0, 21, 24, 27), 'f', 0, NPC_REGULAR), + 2138: (2669, lnames[2138], ('dll', 'ss', 'l', 'm', 3, 0, 3, 3, 0, 9, 0, 9, 1, 16), 'm', 0, NPC_REGULAR), + 2139: (2670, lnames[2139], 'r', 'm', 0, NPC_REGULAR), + 2140: (2156, lnames[2140], ('dls', 'ls', 'l', 'm', 10, 0, 10, 10, 1, 9, 1, 9, 1, 10), 'm', 0, NPC_FISHERMAN), + 2201: (2711, lnames[2201], ('dss', 'ss', 'l', 'm', 13, 0, 13, 13, 1, 6, 1, 6, 0, 17), 'm', 1, NPC_REGULAR), + 2202: (2718, lnames[2202], 'r', 'f', 1, NPC_REGULAR), + 2203: (2742, lnames[2203], ('fss', 'ms', 's', 'm', 19, 0, 19, 19, 0, 7, 0, 7, 0, 11), 'm', 1, NPC_HQ), + 2204: (2742, lnames[2204], ('fls', 'ss', 's', 'm', 13, 0, 13, 13, 0, 7, 0, 7, 0, 6), 'm', 1, NPC_HQ), + 2205: (2742, lnames[2205], ('rsl', 'md', 's', 'f', 4, 0, 4, 4, 0, 11, 0, 11, 16, 27), 'f', 1, NPC_HQ), + 2206: (2742, lnames[2206], ('rss', 'sd', 's', 'f', 21, 0, 21, 21, 0, 12, 0, 12, 0, 8), 'f', 1, NPC_HQ), + 2207: (2705, lnames[2207], ('mss', 'ss', 's', 'm', 12, 0, 12, 12, 0, 8, 0, 8, 0, 16), 'm', 1, NPC_REGULAR), + 2208: (2708, lnames[2208], ('mls', 'ls', 's', 'm', 4, 0, 4, 4, 1, 8, 1, 8, 0, 13), 'm', 1, NPC_REGULAR), + 2209: (2712, lnames[2209], ('hsl', 'ms', 's', 'm', 19, 0, 19, 19, 1, 8, 1, 8, 0, 10), 'm', 1, NPC_REGULAR), + 2210: (2713, lnames[2210], ('hss', 'ms', 's', 'f', 12, 0, 12, 12, 1, 21, 1, 21, 1, 24), 'f', 1, NPC_REGULAR), + 2211: (2716, lnames[2211], ('cll', 'ss', 's', 'f', 3, 0, 3, 3, 1, 22, 1, 22, 25, 27), 'f', 1, NPC_REGULAR), + 2212: (2717, lnames[2212], ('css', 'ls', 's', 'm', 18, 0, 18, 18, 1, 9, 1, 9, 0, 18), 'm', 0, NPC_REGULAR), + 2213: (2720, lnames[2213], ('cls', 'ls', 's', 'f', 12, 0, 12, 12, 1, 23, 1, 23, 11, 27), 'f', 1, NPC_REGULAR), + 2214: (2723, lnames[2214], 'r', 'm', 0, NPC_REGULAR), + 2215: (2727, lnames[2215], ('dss', 'ls', 'm', 'm', 18, 0, 18, 18, 0, 11, 0, 11, 0, 9), 'm', 0, NPC_REGULAR), + 2216: (2728, lnames[2216], ('fll', 'sd', 'm', 'f', 11, 0, 11, 11, 0, 25, 0, 25, 12, 27), 'f', 0, NPC_REGULAR), + 2217: (2729, lnames[2217], ('fsl', 'ss', 'm', 'm', 4, 0, 4, 4, 0, 12, 0, 12, 0, 20), 'm', 1, NPC_REGULAR), + 2218: (2730, lnames[2218], 'r', 'f', 0, NPC_REGULAR), + 2219: (2732, lnames[2219], ('rll', 'ms', 'm', 'm', 10, 0, 10, 10, 0, 27, 0, 27, 0, 14), 'm', 0, NPC_REGULAR), + 2220: (2733, lnames[2220], ('rss', 'ss', 'm', 'm', 3, 0, 3, 3, 1, 12, 1, 12, 0, 11), 'm', 0, NPC_REGULAR), + 2221: (2734, lnames[2221], 'r', 'f', 0, NPC_REGULAR), + 2222: (2735, lnames[2222], ('mls', 'ls', 'm', 'm', 10, 0, 10, 10, 1, 0, 1, 0, 0, 1), 'm', 0, NPC_REGULAR), + 2223: (2739, lnames[2223], 'r', 'f', 0, NPC_REGULAR), + 2224: (2740, lnames[2224], ('hss', 'ss', 'm', 'm', 17, 0, 17, 17, 1, 1, 1, 1, 0, 16), 'm', 0, NPC_REGULAR), + 2225: (2236, lnames[2225], ('cll', 'ls', 'm', 'm', 9, 0, 9, 9, 1, 1, 1, 1, 0, 13), 'm', 0, NPC_FISHERMAN), + 2301: (2804, lnames[2301], ('cll', 'ms', 'm', 'm', 10, 0, 10, 10, 1, 3, 1, 3, 0, 6), 'm', 1, NPC_REGULAR), + 2302: (2831, lnames[2302], ('css', 'ms', 'm', 'm', 3, 0, 3, 3, 1, 3, 1, 3, 0, 1), 'm', 1, NPC_REGULAR), + 2303: (2834, lnames[2303], 'r', 'f', 0, NPC_REGULAR), + 2304: (2832, lnames[2304], ('dss', 'ss', 'm', 'm', 9, 0, 9, 9, 0, 10, 0, 10, 1, 12), 'm', 1, NPC_HQ), + 2305: (2832, lnames[2305], ('dss', 'ss', 'm', 'm', 8, 0, 8, 8, 1, 0, 1, 0, 1, 9), 'm', 1, NPC_HQ), + 2306: (2832, lnames[2306], ('fll', 'md', 'm', 'f', 24, 0, 24, 24, 1, 0, 1, 0, 16, 27), 'f', 1, NPC_HQ), + 2307: (2832, lnames[2307], ('fsl', 'ls', 'm', 'f', 16, 0, 16, 16, 1, 1, 1, 1, 3, 1), 'f', 1, NPC_HQ), + 2308: (2801, lnames[2308], ('fls', 'ss', 'm', 'f', 8, 0, 8, 8, 1, 1, 1, 1, 14, 27), 'f', 1, NPC_REGULAR), + 2309: (2802, lnames[2309], ('rsl', 'ls', 'm', 'm', 22, 0, 22, 22, 1, 1, 1, 1, 1, 14), 'm', 1, NPC_REGULAR), + 2311: (2809, lnames[2311], ('mss', 'ss', 'm', 'm', 7, 0, 7, 7, 0, 2, 0, 2, 1, 6), 'm', 1, NPC_REGULAR), + 2312: (2837, lnames[2312], ('mls', 'ld', 'm', 'f', 24, 0, 24, 24, 0, 3, 0, 3, 4, 6), 'f', 0, NPC_REGULAR), + 2313: (2817, lnames[2313], 'r', 'f', 0, NPC_REGULAR), + 2314: (2818, lnames[2314], ('hss', 'ms', 'm', 'm', 7, 0, 7, 7, 0, 3, 0, 3, 1, 16), 'm', 0, NPC_REGULAR), + 2315: (2822, lnames[2315], ('cll', 'ss', 'm', 'm', 21, 0, 21, 21, 0, 3, 0, 3, 1, 13), 'm', 0, NPC_REGULAR), + 2316: (2823, lnames[2316], ('csl', 'md', 'l', 'f', 15, 0, 15, 15, 0, 5, 0, 5, 0, 23), 'f', 0, NPC_REGULAR), + 2318: (2829, lnames[2318], ('dsl', 'ss', 'l', 'm', 21, 0, 21, 21, 1, 4, 1, 4, 1, 0), 'm', 0, NPC_REGULAR), + 2319: (2830, lnames[2319], ('dss', 'ls', 'l', 'm', 14, 0, 14, 14, 1, 5, 1, 5, 1, 18), 'm', 0, NPC_REGULAR), + 2320: (2839, lnames[2320], 'r', 'm', 0, NPC_REGULAR), + 2321: (2341, lnames[2321], ('fsl', 'ss', 'l', 'm', 21, 0, 21, 21, 1, 5, 1, 5, 0, 12), 'm', 0, NPC_FISHERMAN), + 1001: (1506, lnames[1001], ('rss', 'ms', 'l', 'm', 10, 0, 10, 10, 0, 11, 0, 11, 0, 0), 'm', 0, NPC_CLERK), + 1002: (1506, lnames[1002], ('mss', 'ss', 'l', 'm', 3, 0, 3, 3, 1, 10, 1, 10, 0, 18), 'm', 0, NPC_CLERK), + 1003: (1507, lnames[1003], ('mls', 'ss', 'l', 'm', 17, 0, 17, 17, 1, 11, 1, 11, 0, 15), 'm', 0, NPC_HQ), + 1004: (1507, lnames[1004], ('hsl', 'md', 'l', 'f', 10, 0, 10, 10, 1, 24, 1, 24, 24, 27), 'f', 0, NPC_HQ), + 1005: (1507, lnames[1005], ('hss', 'ms', 'l', 'm', 3, 0, 3, 3, 1, 11, 1, 11, 0, 9), 'm', 0, NPC_HQ), + 1006: (1507, lnames[1006], ('cll', 'ss', 'l', 'f', 18, 0, 18, 18, 1, 25, 1, 25, 19, 27), 'f', 0, NPC_HQ), + 1007: (1508, lnames[1007], ('csl', 'ls', 'm', 'm', 9, 0, 9, 9, 1, 12, 1, 12, 0, 20), 'm', 0, NPC_TAILOR), + 1008: (1000, lnames[1008], ('cls', 'ms', 'm', 'm', 3, 0, 3, 3, 0, 27, 0, 27, 0, 17), 'm', 0, NPC_FISHERMAN), + 1009: (1510, lnames[1009], ('dsl', 'ss', 'm', 'm', 17, 0, 17, 17, 0, 0, 0, 0, 0, 14), 'm', 0, NPC_PETCLERK), + 1010: (1510, lnames[1010], ('dss', 'ld', 'm', 'f', 10, 0, 10, 10, 0, 0, 0, 0, 26, 27), 'f', 0, NPC_PETCLERK), + 1011: (1510, lnames[1011], ('fll', 'sd', 'm', 'f', 1, 0, 1, 1, 0, 1, 0, 1, 4, 25), 'f', 0, NPC_PETCLERK), + 1012: (1000, lnames[1012], ('fls', 'ms', 'l', 'm', 14, 0, 3, 3, 0, 1, 0, 1, 0, 13), 'm', 1, NPC_PARTYPERSON), + 1013: (1000, lnames[1013], ('fss', 'ms', 'm', 'f', 2, 0, 3, 3, 1, 6, 1, 6, 5, 6), 'f', 1, NPC_PARTYPERSON), + 1101: (1627, lnames[1101], ('fll', 'ls', 'm', 'm', 14, 0, 14, 14, 1, 3, 1, 3, 1, 9), 'm', 0, NPC_REGULAR), + 1102: (1612, lnames[1102], ('fsl', 'ms', 'm', 'm', 7, 0, 7, 7, 1, 3, 1, 3, 1, 2), 'm', 0, NPC_REGULAR), + 1103: (1626, lnames[1103], 'r', 'm', 0, NPC_REGULAR), + 1104: (1617, lnames[1104], 'r', 'm', 0, NPC_REGULAR), + 1105: (1606, lnames[1105], ('rss', 'ms', 'm', 'm', 6, 0, 6, 6, 0, 4, 0, 4, 1, 14), 'm', 1, NPC_REGULAR), + 1106: (1604, lnames[1106], 'r', 'f', 1, NPC_REGULAR), + 1107: (1621, lnames[1107], 'r', 'm', 0, NPC_REGULAR), + 1108: (1629, lnames[1108], ('hsl', 'ls', 'l', 'm', 6, 0, 6, 6, 0, 6, 0, 6, 1, 1), 'm', 0, NPC_HQ), + 1109: (1629, lnames[1109], ('hss', 'ls', 'l', 'f', 22, 0, 22, 22, 0, 8, 0, 8, 14, 27), 'f', 0, NPC_HQ), + 1110: (1629, lnames[1110], ('cll', 'ss', 'l', 'm', 13, 0, 13, 13, 1, 6, 1, 6, 1, 16), 'm', 0, NPC_HQ), + 1111: (1629, lnames[1111], ('csl', 'ld', 'l', 'f', 6, 0, 6, 6, 1, 9, 1, 9, 2, 2), 'f', 0, NPC_HQ), + 1112: (1602, lnames[1112], ('cls', 'ms', 'l', 'm', 20, 0, 20, 20, 1, 7, 1, 7, 1, 10), 'm', 1, NPC_REGULAR), + 1113: (1608, lnames[1113], ('dll', 'ms', 'l', 'f', 13, 0, 13, 13, 1, 11, 1, 11, 0, 27), 'f', 1, NPC_REGULAR), + 1114: (1609, lnames[1114], ('dss', 'ls', 'l', 'm', 5, 0, 5, 5, 1, 7, 1, 7, 1, 0), 'm', 1, NPC_REGULAR), + 1115: (1613, lnames[1115], ('fll', 'sd', 'l', 'f', 21, 0, 21, 21, 1, 12, 1, 12, 25, 27), 'f', 0, NPC_REGULAR), + 1116: (1614, lnames[1116], ('fsl', 'ls', 'l', 'f', 13, 0, 13, 13, 1, 12, 1, 12, 1, 25), 'f', 0, NPC_REGULAR), + 1117: (1615, lnames[1117], ('fls', 'ss', 'l', 'm', 5, 0, 5, 5, 0, 9, 0, 9, 1, 12), 'm', 0, NPC_REGULAR), + 1118: (1616, lnames[1118], ('rll', 'ls', 'l', 'm', 19, 0, 19, 19, 0, 9, 0, 9, 1, 9), 'm', 0, NPC_REGULAR), + 1121: (1619, lnames[1121], 'r', 'f', 0, NPC_REGULAR), + 1122: (1620, lnames[1122], ('hll', 'ms', 'l', 'm', 12, 0, 12, 12, 0, 11, 0, 11, 0, 14), 'm', 0, NPC_REGULAR), + 1123: (1622, lnames[1123], ('hss', 'ms', 'l', 'f', 4, 0, 4, 4, 1, 23, 1, 23, 23, 27), 'f', 0, NPC_REGULAR), + 1124: (1624, lnames[1124], ('cll', 'ls', 'l', 'm', 19, 0, 19, 19, 1, 11, 1, 11, 0, 6), 'm', 0, NPC_REGULAR), + 1125: (1628, lnames[1125], ('csl', 'sd', 'l', 'f', 12, 0, 12, 12, 1, 24, 1, 24, 25, 27), 'f', 0, NPC_REGULAR), + 1126: (1129, lnames[1126], ('cls', 'ms', 'l', 'm', 4, 0, 4, 4, 1, 11, 1, 11, 0, 19), 'm', 0, NPC_FISHERMAN), + 1201: (1710, lnames[1201], ('css', 'ls', 's', 'f', 12, 0, 12, 12, 0, 0, 0, 0, 1, 24), 'f', 0, NPC_REGULAR), + 1202: (1713, lnames[1202], ('cls', 'ss', 's', 'm', 4, 0, 4, 4, 0, 0, 0, 0, 1, 14), 'm', 0, NPC_REGULAR), + 1203: (1725, lnames[1203], 'r', 'm', 0, NPC_REGULAR), + 1204: (1712, lnames[1204], ('dss', 'ms', 's', 'm', 12, 0, 12, 12, 1, 1, 1, 1, 1, 6), 'm', 0, NPC_REGULAR), + 1205: (1729, lnames[1205], ('fll', 'ss', 's', 'm', 4, 0, 4, 4, 1, 1, 1, 1, 1, 1), 'm', 0, NPC_HQ), + 1206: (1729, lnames[1206], ('fss', 'ld', 's', 'f', 19, 0, 19, 19, 1, 2, 1, 2, 7, 11), 'f', 0, NPC_HQ), + 1207: (1729, lnames[1207], ('fls', 'ms', 's', 'm', 12, 0, 12, 12, 1, 2, 1, 2, 1, 16), 'm', 0, NPC_HQ), + 1208: (1729, lnames[1208], ('rsl', 'ls', 'm', 'f', 3, 0, 3, 3, 1, 3, 1, 3, 23, 27), 'f', 0, NPC_HQ), + 1209: (1701, lnames[1209], ('rss', 'ss', 'm', 'f', 19, 0, 19, 19, 0, 4, 0, 4, 17, 27), 'f', 1, NPC_REGULAR), + 1210: (1703, lnames[1210], 'r', 'm', 1, NPC_REGULAR), + 1211: (1705, lnames[1211], ('mls', 'ms', 'm', 'm', 4, 0, 4, 4, 0, 4, 0, 4, 1, 0), 'm', 1, NPC_REGULAR), + 1212: (1706, lnames[1212], ('hsl', 'ss', 'm', 'm', 18, 0, 18, 18, 0, 4, 0, 4, 1, 18), 'm', 1, NPC_REGULAR), + 1213: (1707, lnames[1213], ('hss', 'ls', 'm', 'm', 10, 0, 10, 10, 0, 4, 0, 4, 1, 15), 'm', 1, NPC_REGULAR), + 1214: (1709, lnames[1214], ('cll', 'sd', 'm', 'f', 2, 0, 2, 2, 0, 7, 0, 7, 1, 12), 'f', 1, NPC_REGULAR), + 1215: (1711, lnames[1215], ('css', 'ms', 'm', 'f', 18, 0, 18, 18, 0, 7, 0, 7, 25, 27), 'f', 0, NPC_REGULAR), + 1216: (1714, lnames[1216], ('cls', 'ls', 'm', 'm', 10, 0, 10, 10, 1, 5, 1, 5, 1, 2), 'm', 0, NPC_REGULAR), + 1217: (1716, lnames[1217], 'r', 'f', 0, NPC_REGULAR), + 1218: (1717, lnames[1218], ('dss', 'ms', 'm', 'm', 17, 0, 17, 17, 1, 6, 1, 6, 1, 17), 'm', 0, NPC_REGULAR), + 1219: (1718, lnames[1219], ('fll', 'ss', 'm', 'm', 9, 0, 9, 9, 1, 6, 1, 6, 1, 14), 'm', 0, NPC_REGULAR), + 1220: (1719, lnames[1220], ('fsl', 'md', 'm', 'f', 2, 0, 2, 2, 1, 9, 1, 9, 7, 23), 'f', 0, NPC_REGULAR), + 1221: (1720, lnames[1221], 'r', 'm', 0, NPC_REGULAR), + 1222: (1721, lnames[1222], 'r', 'm', 0, NPC_REGULAR), + 1223: (1723, lnames[1223], ('rss', 'ls', 'l', 'm', 2, 0, 2, 2, 0, 8, 0, 8, 1, 19), 'm', 0, NPC_REGULAR), + 1224: (1724, lnames[1224], ('mss', 'sd', 'l', 'f', 17, 0, 17, 17, 0, 21, 0, 21, 7, 9), 'f', 0, NPC_REGULAR), + 1225: (1726, lnames[1225], ('mls', 'ss', 'l', 'm', 9, 0, 9, 9, 0, 9, 0, 9, 1, 13), 'm', 0, NPC_REGULAR), + 1226: (1727, lnames[1226], ('hsl', 'ls', 'l', 'm', 2, 0, 2, 2, 0, 9, 0, 9, 1, 10), 'm', 0, NPC_REGULAR), + 1227: (1728, lnames[1227], ('hss', 'sd', 'l', 'f', 17, 0, 17, 17, 0, 22, 0, 22, 3, 7), 'f', 0, NPC_REGULAR), + 1228: (1236, lnames[1228], ('cll', 'ms', 'l', 'm', 8, 0, 8, 8, 1, 9, 1, 9, 1, 0), 'm', 0, NPC_FISHERMAN), + 1301: (1828, lnames[1301], ('mls', 'md', 'm', 'f', 16, 0, 16, 16, 1, 8, 1, 8, 14, 27), 'f', 0, NPC_REGULAR), + 1302: (1832, lnames[1302], ('hsl', 'ms', 'm', 'm', 8, 0, 8, 8, 1, 6, 1, 6, 0, 18), 'm', 0, NPC_REGULAR), + 1303: (1826, lnames[1303], ('hls', 'ss', 'm', 'm', 22, 0, 22, 22, 1, 6, 1, 6, 0, 15), 'm', 0, NPC_REGULAR), + 1304: (1804, lnames[1304], ('cll', 'md', 'm', 'f', 15, 0, 15, 15, 1, 9, 1, 9, 23, 27), 'f', 1, NPC_REGULAR), + 1305: (1835, lnames[1305], ('css', 'ms', 'm', 'm', 7, 0, 7, 7, 1, 7, 1, 7, 0, 9), 'm', 0, NPC_HQ), + 1306: (1835, lnames[1306], ('cls', 'ms', 'm', 'f', 24, 0, 24, 24, 0, 12, 0, 12, 0, 7), 'f', 0, NPC_HQ), + 1307: (1835, lnames[1307], ('dsl', 'ls', 'm', 'm', 15, 0, 15, 15, 0, 8, 0, 8, 0, 20), 'm', 0, NPC_HQ), + 1308: (1835, lnames[1308], ('dss', 'sd', 'm', 'f', 8, 0, 8, 8, 0, 21, 0, 21, 4, 5), 'f', 0, NPC_HQ), + 1309: (1802, lnames[1309], ('fll', 'ms', 'l', 'f', 23, 0, 23, 23, 0, 21, 0, 21, 1, 12), 'f', 1, NPC_REGULAR), + 1310: (1805, lnames[1310], ('fsl', 'ss', 'l', 'm', 15, 0, 15, 15, 0, 9, 0, 9, 0, 11), 'm', 1, NPC_REGULAR), + 1311: (1806, lnames[1311], 'r', 'f', 1, NPC_REGULAR), + 1312: (1807, lnames[1312], ('rsl', 'ms', 'l', 'm', 21, 0, 21, 21, 1, 9, 1, 9, 0, 1), 'm', 1, NPC_REGULAR), + 1313: (1808, lnames[1313], ('rss', 'ss', 'l', 'm', 14, 0, 14, 14, 1, 10, 1, 10, 0, 19), 'm', 1, NPC_REGULAR), + 1314: (1809, lnames[1314], ('mss', 'ls', 'l', 'm', 6, 0, 6, 6, 1, 10, 1, 10, 0, 16), 'm', 1, NPC_REGULAR), + 1315: (1810, lnames[1315], 'r', 'f', 0, NPC_REGULAR), + 1316: (1811, lnames[1316], ('hsl', 'ms', 'l', 'f', 14, 0, 14, 14, 1, 24, 1, 24, 7, 7), 'f', 0, NPC_REGULAR), + 1317: (1813, lnames[1317], ('hss', 'ld', 'l', 'f', 7, 0, 7, 7, 1, 25, 1, 25, 26, 27), 'f', 0, NPC_REGULAR), + 1318: (1814, lnames[1318], ('cll', 'ms', 'l', 'm', 20, 0, 20, 20, 0, 12, 0, 12, 0, 0), 'm', 0, NPC_REGULAR), + 1319: (1815, lnames[1319], ('csl', 'ss', 'l', 'm', 14, 0, 14, 14, 0, 27, 0, 27, 0, 18), 'm', 0, NPC_REGULAR), + 1320: (1818, lnames[1320], 'r', 'm', 0, NPC_REGULAR), + 1321: (1819, lnames[1321], ('dsl', 'md', 'l', 'f', 22, 0, 22, 22, 0, 27, 0, 27, 7, 5), 'f', 0, NPC_REGULAR), + 1322: (1820, lnames[1322], ('dss', 'ls', 'm', 'f', 13, 0, 13, 13, 0, 0, 0, 0, 26, 27), 'f', 0, NPC_REGULAR), + 1323: (1821, lnames[1323], ('fll', 'ss', 'm', 'm', 6, 0, 6, 6, 0, 0, 0, 0, 1, 2), 'm', 0, NPC_REGULAR), + 1324: (1823, lnames[1324], ('fsl', 'md', 'm', 'f', 22, 0, 22, 22, 0, 1, 0, 1, 10, 27), 'f', 0, NPC_REGULAR), + 1325: (1824, lnames[1325], 'r', 'm', 0, NPC_REGULAR), + 1326: (1825, lnames[1326], ('rll', 'ms', 'm', 'f', 6, 0, 6, 6, 1, 2, 1, 2, 10, 27), 'f', 0, NPC_REGULAR), + 1327: (1829, lnames[1327], 'r', 'f', 0, NPC_REGULAR), + 1328: (1830, lnames[1328], ('rls', 'ms', 'm', 'm', 13, 0, 13, 13, 1, 2, 1, 2, 1, 6), 'm', 0, NPC_REGULAR), + 1329: (1831, lnames[1329], ('mls', 'ms', 'm', 'f', 4, 0, 4, 4, 1, 3, 1, 3, 25, 27), 'f', 0, NPC_REGULAR), + 1330: (1833, lnames[1330], ('hsl', 'ls', 'm', 'm', 19, 0, 19, 19, 1, 3, 1, 3, 1, 19), 'm', 0, NPC_REGULAR), + 1331: (1834, lnames[1331], ('hss', 'ls', 'm', 'm', 12, 0, 12, 12, 0, 3, 0, 3, 1, 16), 'm', 0, NPC_REGULAR), + 1332: (1330, lnames[1332], ('cll', 'ms', 'm', 'm', 5, 0, 5, 5, 0, 4, 0, 4, 1, 13), 'm', 0, NPC_FISHERMAN), + 3001: (3506, lnames[3001], 'r', 'f', 0, NPC_REGULAR), + 3002: (3508, lnames[3002], ('cls', 'ms', 'm', 'm', 4, 0, 4, 4, 1, 9, 1, 9, 0, 18), 'm', 0, NPC_HQ), + 3003: (3508, lnames[3003], ('dsl', 'ss', 'm', 'f', 19, 0, 19, 19, 1, 22, 1, 22, 25, 27), 'f', 0, NPC_HQ), + 3004: (3508, lnames[3004], ('dss', 'ls', 'm', 'm', 12, 0, 12, 12, 1, 10, 1, 10, 0, 12), 'm', 0, NPC_HQ), + 3005: (3508, lnames[3005], ('fll', 'ms', 'm', 'm', 4, 0, 4, 4, 0, 11, 0, 11, 0, 9), 'm', 0, NPC_HQ), + 3006: (3507, lnames[3006], ('fsl', 'ss', 'm', 'm', 18, 0, 18, 18, 0, 11, 0, 11, 0, 2), 'm', 0, NPC_CLERK), + 3007: (3507, lnames[3007], ('fls', 'ld', 'm', 'f', 12, 0, 12, 12, 0, 25, 0, 25, 8, 5), 'f', 0, NPC_CLERK), + 3008: (3509, lnames[3008], ('rll', 'ms', 'l', 'm', 4, 0, 4, 4, 0, 12, 0, 12, 0, 17), 'm', 0, NPC_TAILOR), + 3009: (3000, lnames[3009], ('rss', 'ls', 'l', 'f', 19, 0, 19, 19, 0, 26, 0, 26, 4, 23), 'f', 0, NPC_FISHERMAN), + 3010: (3511, lnames[3010], ('rls', 'ss', 'l', 'm', 10, 0, 10, 10, 0, 12, 0, 12, 0, 11), 'm', 0, NPC_PETCLERK), + 3011: (3511, lnames[3011], ('mls', 'md', 'l', 'f', 3, 0, 3, 3, 1, 26, 1, 26, 26, 27), 'f', 0, NPC_PETCLERK), + 3012: (3511, lnames[3012], ('hsl', 'ms', 'l', 'm', 18, 0, 18, 18, 1, 12, 1, 12, 0, 1), 'm', 0, NPC_PETCLERK), + 3013: (3000, lnames[3013], ('cls', 'ss', 'm', 'm', 18, 0, 17, 17, 1, 7, 1, 7, 1, 9), 'm', 1, NPC_PARTYPERSON), + 3014: (3000, lnames[3014], ('css', 'sd', 'm', 'f', 17, 0, 16, 16, 0, 24, 0, 24, 0, 9), 'f', 1, NPC_PARTYPERSON), + 3101: (3611, lnames[3101], ('mls', 'ls', 'l', 'm', 16, 0, 16, 16, 1, 1, 1, 1, 1, 6), 'm', 0, NPC_REGULAR), + 3102: (3625, lnames[3102], 'r', 'f', 0, NPC_REGULAR), + 3103: (3641, lnames[3103], 'r', 'm', 0, NPC_REGULAR), + 3104: (3602, lnames[3104], ('cll', 'ss', 'l', 'f', 16, 0, 16, 16, 0, 4, 0, 4, 3, 2), 'f', 1, NPC_REGULAR), + 3105: (3651, lnames[3105], 'r', 'm', 0, NPC_REGULAR), + 3106: (3636, lnames[3106], ('fll', 'ls', 'l', 'm', 8, 2, 8, 8, 10, 27, 0, 27, 7, 11), 'm', 0, NPC_REGULAR), + 3107: (3630, lnames[3107], ('dll', 'ms', 'l', 'f', 15, 0, 15, 15, 0, 5, 0, 5, 4, 4), 'f', 0, NPC_REGULAR), + 3108: (3638, lnames[3108], 'r', 'm', 0, NPC_REGULAR), + 3109: (3637, lnames[3109], ('fll', 'sd', 'm', 'f', 23, 0, 23, 23, 1, 6, 1, 6, 12, 27), 'f', 0, NPC_REGULAR), + 3110: (3629, lnames[3110], ('fss', 'ms', 'l', 'm', 10, 10, 10, 10, 16, 4, 0, 4, 5, 4), 'm', 0, NPC_REGULAR), + 3111: (3627, lnames[3111], ('dsl', 'ls', 's', 'm', 6, 0, 6, 6, 14, 27, 10, 27, 1, 14), 'm', 1, NPC_REGULAR), + 3112: (3607, lnames[3112], ('rll', 'ls', 'm', 'm', 21, 0, 21, 21, 1, 5, 1, 5, 1, 9), 'm', 1, NPC_REGULAR), + 3113: (3618, lnames[3113], ('rss', 'ms', 'm', 'm', 14, 0, 14, 14, 1, 5, 1, 5, 0, 2), 'm', 0, NPC_REGULAR), + 3114: (3620, lnames[3114], ('rls', 'ss', 'm', 'm', 7, 0, 7, 7, 0, 6, 0, 6, 0, 20), 'm', 0, NPC_REGULAR), + 3115: (3654, lnames[3115], ('mls', 'ls', 'm', 'm', 21, 0, 21, 21, 0, 7, 0, 7, 0, 17), 'm', 0, NPC_HQ), + 3116: (3654, lnames[3116], ('hll', 'ls', 'm', 'f', 14, 0, 14, 14, 0, 11, 0, 11, 0, 12), 'f', 0, NPC_HQ), + 3117: (3654, lnames[3117], ('hss', 'ss', 'm', 'm', 6, 0, 6, 6, 0, 7, 0, 7, 0, 11), 'm', 0, NPC_HQ), + 3118: (3654, lnames[3118], ('cll', 'ls', 'm', 'm', 20, 0, 20, 20, 0, 8, 0, 8, 0, 6), 'm', 0, NPC_HQ), + 3119: (3653, lnames[3119], ('csl', 'ms', 'm', 'm', 14, 0, 14, 14, 0, 8, 0, 8, 0, 1), 'm', 0, NPC_REGULAR), + 3120: (3610, lnames[3120], ('cls', 'ss', 'm', 'm', 6, 0, 6, 6, 1, 8, 1, 8, 0, 19), 'm', 0, NPC_REGULAR), + 3121: (3601, lnames[3121], ('dll', 'ls', 'm', 'm', 20, 0, 20, 20, 1, 8, 1, 8, 0, 16), 'm', 1, NPC_REGULAR), + 3122: (3608, lnames[3122], ('dss', 'md', 'l', 'f', 13, 0, 13, 13, 1, 21, 1, 21, 10, 27), 'f', 1, NPC_REGULAR), + 3123: (3612, lnames[3123], ('dls', 'ms', 'l', 'm', 6, 0, 6, 6, 1, 9, 1, 9, 0, 10), 'm', 0, NPC_REGULAR), + 3124: (3613, lnames[3124], ('fsl', 'ss', 'l', 'm', 20, 0, 20, 20, 1, 9, 1, 9, 0, 4), 'm', 0, NPC_REGULAR), + 3125: (3614, lnames[3125], ('fls', 'ls', 'l', 'm', 13, 0, 13, 13, 1, 9, 1, 9, 0, 0), 'm', 0, NPC_REGULAR), + 3126: (3615, lnames[3126], ('rll', 'ls', 'l', 'f', 6, 0, 6, 6, 0, 24, 0, 24, 17, 27), 'f', 0, NPC_REGULAR), + 3127: (3617, lnames[3127], ('rss', 'ms', 'l', 'f', 21, 0, 21, 21, 0, 24, 0, 24, 19, 27), 'f', 0, NPC_REGULAR), + 3128: (3621, lnames[3128], ('rls', 'ls', 'l', 'm', 13, 0, 13, 13, 0, 11, 0, 11, 0, 12), 'm', 0, NPC_REGULAR), + 3129: (3623, lnames[3129], ('mls', 'sd', 'l', 'f', 4, 0, 4, 4, 0, 25, 0, 25, 23, 27), 'f', 0, NPC_REGULAR), + 3130: (3624, lnames[3130], ('hll', 'ms', 'l', 'f', 21, 0, 21, 21, 0, 26, 0, 26, 25, 27), 'f', 0, NPC_REGULAR), + 3131: (3634, lnames[3131], ('hss', 'ls', 'l', 'm', 12, 0, 12, 12, 0, 12, 0, 12, 0, 20), 'm', 0, NPC_REGULAR), + 3132: (3635, lnames[3132], 'r', 'f', 0, NPC_REGULAR), + 3133: (3642, lnames[3133], ('csl', 'ms', 'l', 'm', 19, 0, 19, 19, 1, 12, 1, 12, 0, 14), 'm', 0, NPC_REGULAR), + 3134: (3643, lnames[3134], ('cls', 'ss', 'l', 'm', 12, 0, 12, 12, 1, 0, 1, 0, 0, 11), 'm', 0, NPC_REGULAR), + 3135: (3644, lnames[3135], ('dll', 'md', 'l', 'f', 4, 0, 4, 4, 1, 0, 1, 0, 4, 12), 'f', 0, NPC_REGULAR), + 3136: (3647, lnames[3136], ('dss', 'ls', 'l', 'f', 19, 0, 19, 19, 1, 1, 1, 1, 25, 27), 'f', 0, NPC_REGULAR), + 3137: (3648, lnames[3137], ('dls', 'ss', 'l', 'm', 12, 0, 12, 12, 1, 1, 1, 1, 0, 19), 'm', 0, NPC_REGULAR), + 3138: (3649, lnames[3138], ('fsl', 'ld', 'l', 'f', 3, 0, 3, 3, 1, 2, 1, 2, 26, 27), 'f', 0, NPC_REGULAR), + 3139: (3650, lnames[3139], ('fss', 'sd', 'l', 'f', 19, 0, 19, 19, 0, 2, 0, 2, 16, 27), 'f', 0, NPC_REGULAR), + 3140: (3136, lnames[3140], ('rll', 'ms', 'l', 'f', 11, 0, 11, 11, 0, 3, 0, 3, 12, 27), 'f', 0, NPC_FISHERMAN), + 3201: (3715, lnames[3201], 'r', 'f', 0, NPC_REGULAR), + 3202: (3723, lnames[3202], ('rsl', 'ss', 'l', 'm', 6, 0, 6, 6, 1, 12, 1, 12, 1, 13), 'm', 0, NPC_REGULAR), + 3203: (3712, lnames[3203], ('rss', 'ls', 'l', 'm', 20, 0, 20, 20, 1, 12, 1, 12, 1, 10), 'm', 0, NPC_REGULAR), + 3204: (3734, lnames[3204], ('mss', 'md', 'l', 'f', 13, 0, 13, 13, 1, 26, 1, 26, 4, 5), 'f', 0, NPC_REGULAR), + 3205: (3721, lnames[3205], 'r', 'm', 0, NPC_REGULAR), + 3206: (3722, lnames[3206], ('hsl', 'ss', 'l', 'f', 21, 0, 21, 21, 1, 0, 1, 0, 11, 27), 'f', 0, NPC_REGULAR), + 3207: (3713, lnames[3207], ('hss', 'ls', 'l', 'm', 13, 0, 13, 13, 0, 0, 0, 0, 1, 15), 'm', 0, NPC_REGULAR), + 3208: (3732, lnames[3208], ('cll', 'ms', 'l', 'm', 5, 0, 5, 5, 0, 1, 0, 1, 1, 12), 'm', 0, NPC_REGULAR), + 3209: (3737, lnames[3209], ('css', 'ss', 'l', 'm', 19, 0, 19, 19, 0, 1, 0, 1, 1, 9), 'm', 0, NPC_REGULAR), + 3210: (3728, lnames[3210], ('pls', 'ls', 's', 'm', 13, 0, 13, 13, 2, 1, 2, 1, 5, 2), 'm', 0, NPC_REGULAR), + 3211: (3710, lnames[3211], 'r', 'f', 0, NPC_REGULAR), + 3212: (3707, lnames[3212], ('dss', 'ss', 's', 'm', 19, 0, 19, 19, 0, 2, 0, 2, 1, 17), 'm', 1, NPC_REGULAR), + 3213: (3739, lnames[3213], ('fll', 'ls', 's', 'm', 12, 0, 12, 12, 1, 2, 1, 2, 1, 14), 'm', 0, NPC_HQ), + 3214: (3739, lnames[3214], ('fsl', 'md', 's', 'f', 4, 0, 4, 4, 1, 4, 1, 4, 3, 1), 'f', 0, NPC_HQ), + 3215: (3739, lnames[3215], ('fls', 'ms', 's', 'm', 19, 0, 19, 19, 1, 3, 1, 3, 1, 6), 'm', 0, NPC_HQ), + 3216: (3739, lnames[3216], ('rll', 'ss', 's', 'm', 12, 0, 12, 12, 1, 4, 1, 4, 1, 1), 'm', 0, NPC_HQ), + 3217: (3738, lnames[3217], ('rss', 'ls', 's', 'm', 4, 0, 4, 4, 1, 4, 1, 4, 1, 19), 'm', 0, NPC_REGULAR), + 3218: (3702, lnames[3218], ('mss', 'ms', 's', 'm', 18, 0, 18, 18, 1, 4, 1, 4, 1, 16), 'm', 1, NPC_REGULAR), + 3219: (3705, lnames[3219], ('mls', 'ss', 's', 'm', 12, 0, 12, 12, 0, 5, 0, 5, 1, 13), 'm', 1, NPC_REGULAR), + 3220: (3706, lnames[3220], ('hsl', 'ls', 's', 'm', 4, 0, 4, 4, 0, 5, 0, 5, 1, 10), 'm', 1, NPC_REGULAR), + 3221: (3708, lnames[3221], ('hss', 'sd', 's', 'f', 19, 0, 19, 19, 0, 8, 0, 8, 7, 12), 'f', 1, NPC_REGULAR), + 3222: (3716, lnames[3222], 'r', 'f', 0, NPC_REGULAR), + 3223: (3718, lnames[3223], ('csl', 'ls', 'm', 'm', 4, 0, 4, 4, 0, 6, 0, 6, 1, 18), 'm', 0, NPC_REGULAR), + 3224: (3719, lnames[3224], ('cls', 'md', 'm', 'f', 18, 0, 18, 18, 0, 9, 0, 9, 17, 27), 'f', 0, NPC_REGULAR), + 3225: (3724, lnames[3225], 'r', 'm', 0, NPC_REGULAR), + 3226: (3725, lnames[3226], ('dss', 'ss', 'm', 'm', 3, 0, 3, 3, 1, 7, 1, 7, 1, 9), 'm', 0, NPC_REGULAR), + 3227: (3726, lnames[3227], ('fll', 'ls', 'm', 'm', 17, 0, 17, 17, 1, 7, 1, 7, 1, 2), 'm', 0, NPC_REGULAR), + 3228: (3730, lnames[3228], ('fsl', 'ls', 'm', 'f', 11, 0, 11, 11, 1, 12, 1, 12, 25, 27), 'f', 0, NPC_REGULAR), + 3229: (3731, lnames[3229], ('fls', 'ms', 'm', 'f', 2, 0, 2, 2, 1, 12, 1, 12, 0, 7), 'f', 0, NPC_REGULAR), + 3230: (3735, lnames[3230], ('rll', 'ls', 'm', 'm', 17, 0, 17, 17, 1, 8, 1, 8, 1, 14), 'm', 0, NPC_REGULAR), + 3231: (3736, lnames[3231], ('rss', 'ms', 'm', 'm', 9, 0, 9, 9, 0, 9, 0, 9, 1, 12), 'm', 0, NPC_REGULAR), + 3232: (3236, lnames[3232], ('rls', 'ss', 'm', 'm', 3, 0, 3, 3, 0, 10, 0, 10, 1, 9), 'm', 0, NPC_FISHERMAN), + 3301: (3810, lnames[3301], ('dsl', 'ms', 'm', 'f', 11, 0, 11, 11, 0, 22, 0, 22, 2, 11), 'f', 0, NPC_REGULAR), + 3302: (3806, lnames[3302], ('dls', 'ls', 'm', 'm', 4, 0, 4, 4, 0, 10, 0, 10, 1, 1), 'm', 1, NPC_REGULAR), + 3303: (3830, lnames[3303], ('fll', 'ms', 'm', 'm', 18, 0, 18, 18, 0, 10, 0, 10, 1, 19), 'm', 0, NPC_REGULAR), + 3304: (3828, lnames[3304], ('pll', 'ls', 'l', 'm', 0, 0, 0, 0, 1, 5, 1, 5, 1, 6), 'f', 0, NPC_REGULAR), + 3305: (3812, lnames[3305], ('fls', 'ls', 'm', 'm', 3, 0, 3, 3, 0, 11, 0, 11, 1, 13), 'm', 0, NPC_REGULAR), + 3306: (3821, lnames[3306], ('bss', 'sd', 'm', 'f', 0, 0, 0, 0, 31, 27, 22, 27, 8, 11), 'f', 0, NPC_REGULAR), + 3307: (3329, lnames[3307], ('rss', 'ls', 'm', 'f', 11, 0, 11, 11, 1, 24, 1, 24, 1, 9), 'f', 0, NPC_FISHERMAN), + 3308: (3815, lnames[3308], ('mss', 'ss', 'm', 'm', 3, 0, 3, 3, 1, 11, 1, 11, 1, 0), 'm', 0, NPC_REGULAR), + 3309: (3826, lnames[3309], ('hll', 'ls', 'm', 'm', 17, 0, 17, 17, 1, 11, 1, 11, 1, 18), 'm', 0, NPC_REGULAR), + 3310: (3823, lnames[3310], ('pll', 'ms', 'm', 'm', 10, 0, 10, 10, 60, 27, 49, 27, 0, 13), 'm', 0, NPC_REGULAR), + 3311: (3829, lnames[3311], 'r', 'f', 0, NPC_REGULAR), + 3312: (3813, lnames[3312], ('rss', 'ms', 'l', 'm', 4, 0, 4, 4, 5, 2, 5, 2, 1, 10), 'm', 0, NPC_REGULAR), + 3313: (3801, lnames[3313], ('css', 'ms', 'l', 'm', 9, 0, 9, 9, 0, 0, 0, 0, 1, 2), 'm', 0, NPC_HQ), + 3314: (3801, lnames[3314], ('cls', 'ms', 'l', 'f', 1, 0, 1, 1, 0, 0, 0, 0, 3, 25), 'f', 0, NPC_HQ), + 3315: (3801, lnames[3315], ('dsl', 'ls', 'l', 'm', 17, 0, 17, 17, 0, 0, 0, 0, 1, 17), 'm', 0, NPC_HQ), + 3316: (3801, lnames[3316], ('dss', 'md', 'l', 'f', 10, 0, 10, 10, 0, 1, 0, 1, 10, 27), 'f', 0, NPC_HQ), + 3317: (3816, lnames[3317], ('fll', 'ls', 'l', 'f', 1, 0, 1, 1, 0, 2, 0, 2, 3, 24), 'f', 0, NPC_REGULAR), + 3318: (3808, lnames[3318], ('dss', 'ms', 'm', 'm', 18, 0, 18, 18, 57, 1, 46, 1, 12, 1), 'm', 1, NPC_REGULAR), + 3319: (3825, lnames[3319], ('fls', 'ls', 'l', 'm', 9, 0, 9, 9, 1, 2, 1, 2, 1, 1), 'm', 0, NPC_REGULAR), + 3320: (3814, lnames[3320], ('rsl', 'ls', 'l', 'f', 1, 0, 1, 1, 1, 3, 1, 3, 12, 27), 'f', 0, NPC_REGULAR), + 3321: (3818, lnames[3321], ('rss', 'ss', 'l', 'm', 16, 0, 16, 16, 1, 2, 1, 2, 1, 16), 'm', 0, NPC_REGULAR), + 3322: (3819, lnames[3322], 'r', 'm', 0, NPC_REGULAR), + 3323: (3811, lnames[3323], ('mls', 'ms', 'l', 'm', 22, 0, 22, 22, 1, 3, 1, 3, 1, 10), 'm', 0, NPC_REGULAR), + 3324: (3809, lnames[3324], 'r', 'm', 1, NPC_REGULAR), + 3325: (3827, lnames[3325], ('hss', 'ls', 'l', 'm', 8, 0, 8, 8, 0, 4, 0, 4, 1, 0), 'm', 0, NPC_REGULAR), + 3326: (3820, lnames[3326], ('cll', 'md', 'l', 'f', 24, 0, 24, 24, 0, 6, 0, 6, 12, 27), 'f', 0, NPC_REGULAR), + 3327: (3824, lnames[3327], ('css', 'ms', 'l', 'm', 15, 0, 15, 15, 0, 5, 0, 5, 1, 15), 'm', 0, NPC_REGULAR), + 3328: (3807, lnames[3328], ('dll', 'sd', 'l', 'f', 8, 0, 8, 8, 0, 25, 0, 25, 14, 27), 'f', 1, NPC_REGULAR), + 3329: (3817, lnames[3329], ('dll', 'ms', 'l', 'm', 6, 0, 6, 6, 0, 1, 0, 1, 1, 1), 'm', 0, NPC_REGULAR), + 4001: (4502, lnames[4001], 'r', 'f', 0, NPC_REGULAR), + 4002: (4504, lnames[4002], ('fll', 'ss', 'm', 'm', 5, 0, 5, 5, 0, 2, 0, 2, 1, 17), 'm', 0, NPC_HQ), + 4003: (4504, lnames[4003], ('fsl', 'md', 'm', 'f', 21, 0, 21, 21, 0, 3, 0, 3, 10, 27), 'f', 0, NPC_HQ), + 4004: (4504, lnames[4004], ('fls', 'ls', 'm', 'f', 13, 0, 13, 13, 1, 3, 1, 3, 2, 11), 'f', 0, NPC_HQ), + 4005: (4504, lnames[4005], ('rll', 'ss', 'm', 'f', 4, 0, 4, 4, 1, 4, 1, 4, 24, 27), 'f', 0, NPC_HQ), + 4006: (4503, lnames[4006], ('rss', 'md', 'm', 'f', 21, 0, 21, 21, 1, 4, 1, 4, 8, 8), 'f', 0, NPC_CLERK), + 4007: (4503, lnames[4007], ('rls', 'ms', 'm', 'm', 12, 0, 12, 12, 1, 3, 1, 3, 1, 19), 'm', 0, NPC_CLERK), + 4008: (4506, lnames[4008], ('mls', 'ms', 'm', 'f', 4, 0, 4, 4, 1, 5, 1, 5, 7, 9), 'f', 0, NPC_TAILOR), + 4009: (4000, lnames[4009], ('hsl', 'ld', 'm', 'f', 19, 0, 19, 19, 1, 6, 1, 6, 12, 27), 'f', 0, NPC_FISHERMAN), + 4010: (4508, lnames[4010], ('hss', 'ms', 'm', 'm', 12, 0, 12, 12, 0, 5, 0, 5, 1, 10), 'm', 0, NPC_PETCLERK), + 4011: (4508, lnames[4011], ('cll', 'ss', 'm', 'm', 4, 0, 4, 4, 0, 5, 0, 5, 1, 4), 'm', 0, NPC_PETCLERK), + 4012: (4508, lnames[4012], ('csl', 'ss', 'm', 'f', 19, 0, 19, 19, 0, 8, 0, 8, 10, 27), 'f', 0, NPC_PETCLERK), + 4013: (4000, lnames[4013], ('bll', 'ls', 's', 'm', 3, 0, 19, 19, 0, 8, 0, 8, 1, 12), 'm', 1, NPC_PARTYPERSON), + 4014: (4000, lnames[4014], ('bss', 'md', 'm', 'f', 24, 0, 19, 19, 0, 24, 0, 24, 0, 12), 'f', 1, NPC_PARTYPERSON), + 4101: (4603, lnames[4101], ('cll', 'ms', 'm', 'm', 16, 0, 16, 16, 1, 7, 1, 7, 0, 6), 'm', 1, NPC_REGULAR), + 4102: (4605, lnames[4102], ('csl', 'ms', 'm', 'f', 9, 0, 9, 9, 1, 11, 1, 11, 10, 27), 'f', 1, NPC_REGULAR), + 4103: (4612, lnames[4103], ('cls', 'ls', 'l', 'm', 2, 0, 2, 2, 1, 8, 1, 8, 0, 19), 'm', 0, NPC_REGULAR), + 4104: (4659, lnames[4104], ('dll', 'ms', 'l', 'm', 16, 0, 16, 16, 1, 8, 1, 8, 0, 16), 'm', 0, NPC_HQ), + 4105: (4659, lnames[4105], ('dss', 'ls', 'l', 'f', 9, 0, 9, 9, 1, 21, 1, 21, 11, 27), 'f', 0, NPC_HQ), + 4106: (4659, lnames[4106], ('fll', 'ss', 'l', 'f', 24, 0, 24, 24, 0, 22, 0, 22, 19, 27), 'f', 0, NPC_HQ), + 4107: (4659, lnames[4107], ('fsl', 'md', 'l', 'f', 16, 0, 16, 16, 0, 22, 0, 22, 17, 27), 'f', 0, NPC_HQ), + 4108: (4626, lnames[4108], ('fls', 'ms', 'l', 'm', 8, 0, 8, 8, 0, 10, 0, 10, 0, 0), 'm', 0, NPC_REGULAR), + 4109: (4606, lnames[4109], ('rll', 'ss', 'l', 'm', 22, 0, 22, 22, 0, 11, 0, 11, 0, 18), 'm', 1, NPC_REGULAR), + 4110: (4604, lnames[4110], ('rss', 'ld', 'l', 'f', 16, 0, 16, 16, 0, 24, 0, 24, 3, 2), 'f', 1, NPC_REGULAR), + 4111: (4607, lnames[4111], 'r', 'm', 1, NPC_REGULAR), + 4112: (4609, lnames[4112], ('mls', 'ms', 'l', 'f', 24, 0, 24, 24, 0, 25, 0, 25, 11, 27), 'f', 1, NPC_REGULAR), + 4113: (4610, lnames[4113], ('hsl', 'ld', 'l', 'f', 15, 0, 15, 15, 1, 25, 1, 25, 14, 27), 'f', 0, NPC_REGULAR), + 4114: (4611, lnames[4114], ('hss', 'ms', 'l', 'm', 7, 0, 7, 7, 1, 11, 1, 11, 1, 20), 'm', 0, NPC_REGULAR), + 4115: (4614, lnames[4115], ('cll', 'ls', 'l', 'f', 23, 0, 23, 23, 1, 26, 1, 26, 10, 27), 'f', 0, NPC_REGULAR), + 4116: (4615, lnames[4116], ('csl', 'ss', 'm', 'm', 15, 0, 15, 15, 1, 12, 1, 12, 1, 14), 'm', 0, NPC_REGULAR), + 4117: (4617, lnames[4117], ('cls', 'md', 'm', 'f', 7, 0, 7, 7, 1, 0, 1, 0, 1, 25), 'f', 0, NPC_REGULAR), + 4118: (4618, lnames[4118], 'r', 'm', 0, NPC_REGULAR), + 4119: (4619, lnames[4119], ('dss', 'ss', 'm', 'm', 14, 0, 14, 14, 0, 0, 0, 0, 1, 1), 'm', 0, NPC_REGULAR), + 4120: (4622, lnames[4120], ('dls', 'ld', 'm', 'f', 7, 0, 7, 7, 0, 1, 0, 1, 26, 27), 'f', 0, NPC_REGULAR), + 4121: (4623, lnames[4121], ('fsl', 'ms', 'm', 'm', 21, 0, 21, 21, 0, 1, 0, 1, 1, 16), 'm', 0, NPC_REGULAR), + 4122: (4625, lnames[4122], ('fls', 'ms', 'm', 'f', 14, 0, 14, 14, 0, 2, 0, 2, 17, 27), 'f', 0, NPC_REGULAR), + 4123: (4628, lnames[4123], ('rll', 'ls', 'm', 'm', 6, 0, 6, 6, 0, 2, 0, 2, 1, 10), 'm', 0, NPC_REGULAR), + 4124: (4629, lnames[4124], ('rss', 'ms', 'm', 'm', 20, 0, 20, 20, 0, 2, 0, 2, 1, 4), 'm', 0, NPC_REGULAR), + 4125: (4630, lnames[4125], ('rls', 'ls', 'm', 'f', 14, 0, 14, 14, 1, 3, 1, 3, 8, 6), 'f', 0, NPC_REGULAR), + 4126: (4631, lnames[4126], ('mls', 'ss', 'm', 'm', 6, 0, 6, 6, 1, 3, 1, 3, 1, 18), 'm', 0, NPC_REGULAR), + 4127: (4632, lnames[4127], ('hll', 'md', 'm', 'f', 22, 0, 22, 22, 1, 4, 1, 4, 23, 27), 'f', 0, NPC_REGULAR), + 4128: (4635, lnames[4128], ('hss', 'ms', 'm', 'm', 13, 0, 13, 13, 1, 3, 1, 3, 1, 12), 'm', 0, NPC_REGULAR), + 4129: (4637, lnames[4129], ('hls', 'ss', 'l', 'f', 6, 0, 6, 6, 1, 5, 1, 5, 26, 27), 'f', 0, NPC_REGULAR), + 4130: (4638, lnames[4130], 'r', 'm', 0, NPC_REGULAR), + 4131: (4639, lnames[4131], 'r', 'm', 0, NPC_REGULAR), + 4132: (4641, lnames[4132], ('dll', 'ms', 'l', 'f', 6, 0, 6, 6, 0, 7, 0, 7, 17, 27), 'f', 0, NPC_REGULAR), + 4133: (4642, lnames[4133], ('dss', 'ls', 'l', 'm', 20, 0, 20, 20, 0, 5, 0, 5, 1, 14), 'm', 0, NPC_REGULAR), + 4134: (4645, lnames[4134], 'r', 'm', 0, NPC_REGULAR), + 4135: (4648, lnames[4135], ('fsl', 'ms', 'l', 'm', 5, 0, 5, 5, 0, 6, 0, 6, 1, 6), 'm', 0, NPC_REGULAR), + 4136: (4652, lnames[4136], ('fss', 'ss', 'l', 'f', 21, 0, 21, 21, 0, 9, 0, 9, 7, 4), 'f', 0, NPC_REGULAR), + 4137: (4654, lnames[4137], ('rll', 'ls', 'l', 'm', 13, 0, 13, 13, 1, 6, 1, 6, 1, 19), 'm', 0, NPC_REGULAR), + 4138: (4655, lnames[4138], ('rsl', 'ms', 'l', 'm', 5, 0, 5, 5, 1, 7, 1, 7, 1, 16), 'm', 0, NPC_REGULAR), + 4139: (4657, lnames[4139], ('rls', 'ss', 'l', 'f', 21, 0, 21, 21, 1, 11, 1, 11, 14, 27), 'f', 0, NPC_REGULAR), + 4140: (4658, lnames[4140], ('mls', 'ls', 'l', 'm', 12, 0, 12, 12, 1, 7, 1, 7, 1, 10), 'm', 0, NPC_REGULAR), + 4141: (4148, lnames[4141], ('hll', 'ms', 'l', 'm', 4, 0, 4, 4, 1, 8, 1, 8, 1, 4), 'm', 0, NPC_FISHERMAN), + 4201: (4704, lnames[4201], ('mss', 'ss', 'l', 'f', 14, 0, 14, 14, 0, 6, 0, 6, 11, 27), 'f', 1, NPC_REGULAR), + 4202: (4725, lnames[4202], ('mls', 'ls', 'l', 'm', 6, 0, 6, 6, 0, 5, 0, 5, 0, 13), 'm', 0, NPC_REGULAR), + 4203: (4702, lnames[4203], ('hsl', 'ms', 'l', 'm', 21, 0, 21, 21, 0, 5, 0, 5, 0, 10), 'm', 1, NPC_REGULAR), + 4204: (4739, lnames[4204], ('hss', 'ss', 'l', 'm', 14, 0, 14, 14, 0, 6, 0, 6, 0, 4), 'm', 0, NPC_HQ), + 4205: (4739, lnames[4205], ('cll', 'ld', 'l', 'f', 6, 0, 6, 6, 1, 8, 1, 8, 10, 27), 'f', 0, NPC_HQ), + 4206: (4739, lnames[4206], ('css', 'sd', 'l', 'f', 22, 0, 22, 22, 1, 8, 1, 8, 25, 27), 'f', 0, NPC_HQ), + 4207: (4739, lnames[4207], ('cls', 'ls', 'l', 'f', 14, 0, 14, 14, 1, 9, 1, 9, 17, 27), 'f', 0, NPC_HQ), + 4208: (4730, lnames[4208], ('dsl', 'ss', 'l', 'f', 6, 0, 6, 6, 1, 9, 1, 9, 10, 27), 'f', 0, NPC_REGULAR), + 4209: (4701, lnames[4209], ('dss', 'md', 'l', 'f', 22, 0, 22, 22, 1, 11, 1, 11, 1, 9), 'f', 1, NPC_REGULAR), + 4211: (4703, lnames[4211], ('fsl', 'ss', 'l', 'm', 5, 0, 5, 5, 1, 8, 1, 8, 0, 20), 'm', 1, NPC_REGULAR), + 4212: (4705, lnames[4212], ('fls', 'ls', 'l', 'm', 20, 0, 20, 20, 0, 9, 0, 9, 0, 17), 'm', 1, NPC_REGULAR), + 4213: (4707, lnames[4213], ('rll', 'sd', 'l', 'f', 13, 0, 13, 13, 0, 21, 0, 21, 24, 27), 'f', 1, NPC_REGULAR), + 4214: (4709, lnames[4214], 'r', 'f', 1, NPC_REGULAR), + 4215: (4710, lnames[4215], ('mss', 'ls', 'l', 'm', 19, 0, 19, 19, 0, 10, 0, 10, 0, 6), 'm', 0, NPC_REGULAR), + 4216: (4712, lnames[4216], ('mls', 'ms', 's', 'm', 13, 0, 13, 13, 0, 10, 0, 10, 0, 1), 'm', 0, NPC_REGULAR), + 4217: (4713, lnames[4217], ('hsl', 'ms', 's', 'm', 5, 0, 5, 5, 0, 10, 0, 10, 0, 19), 'm', 0, NPC_REGULAR), + 4218: (4716, lnames[4218], ('hss', 'ss', 's', 'f', 21, 0, 21, 21, 1, 23, 1, 23, 26, 27), 'f', 0, NPC_REGULAR), + 4219: (4717, lnames[4219], 'r', 'm', 0, NPC_REGULAR), + 4220: (4718, lnames[4220], 'r', 'm', 0, NPC_REGULAR), + 4221: (4719, lnames[4221], ('cls', 'ss', 's', 'm', 19, 0, 19, 19, 1, 11, 1, 11, 0, 4), 'm', 0, NPC_REGULAR), + 4222: (4720, lnames[4222], ('dsl', 'ls', 's', 'm', 12, 0, 12, 12, 1, 11, 1, 11, 0, 0), 'm', 0, NPC_REGULAR), + 4223: (4722, lnames[4223], ('dss', 'sd', 's', 'f', 3, 0, 3, 3, 1, 25, 1, 25, 24, 27), 'f', 0, NPC_REGULAR), + 4224: (4723, lnames[4224], 'r', 'm', 0, NPC_REGULAR), + 4225: (4724, lnames[4225], ('fsl', 'ld', 's', 'f', 12, 0, 12, 12, 0, 27, 0, 27, 11, 27), 'f', 0, NPC_REGULAR), + 4226: (4727, lnames[4226], ('fls', 'sd', 's', 'f', 3, 0, 3, 3, 0, 0, 0, 0, 11, 27), 'f', 0, NPC_REGULAR), + 4227: (4728, lnames[4227], ('rll', 'ls', 's', 'f', 19, 0, 19, 19, 0, 0, 0, 0, 23, 27), 'f', 0, NPC_REGULAR), + 4228: (4729, lnames[4228], ('rss', 'ss', 's', 'f', 11, 0, 11, 11, 0, 1, 0, 1, 0, 1), 'f', 0, NPC_REGULAR), + 4229: (4731, lnames[4229], ('rls', 'md', 'm', 'f', 3, 0, 3, 3, 0, 1, 0, 1, 26, 27), 'f', 0, NPC_REGULAR), + 4230: (4732, lnames[4230], ('mls', 'ms', 'm', 'm', 18, 0, 18, 18, 1, 1, 1, 1, 0, 14), 'm', 0, NPC_REGULAR), + 4231: (4735, lnames[4231], ('hsl', 'ss', 'm', 'f', 11, 0, 11, 11, 1, 2, 1, 2, 8, 0), 'f', 0, NPC_REGULAR), + 4232: (4736, lnames[4232], ('hss', 'ls', 'm', 'm', 3, 0, 3, 3, 1, 2, 1, 2, 1, 6), 'm', 0, NPC_REGULAR), + 4233: (4737, lnames[4233], ('cll', 'ms', 'm', 'm', 17, 0, 17, 17, 1, 2, 1, 2, 1, 1), 'm', 0, NPC_REGULAR), + 4234: (4738, lnames[4234], 'r', 'm', 0, NPC_REGULAR), + 4235: (4240, lnames[4235], ('cls', 'ls', 'm', 'm', 3, 0, 3, 3, 1, 3, 1, 3, 1, 16), 'm', 0, NPC_FISHERMAN), + 4301: (4819, lnames[4301], ('fss', 'md', 'l', 'f', 12, 0, 12, 12, 1, 2, 1, 2, 17, 27), 'f', 0, NPC_REGULAR), + 4302: (4821, lnames[4302], ('fls', 'ls', 'l', 'f', 3, 0, 3, 3, 1, 2, 1, 2, 2, 3), 'f', 0, NPC_REGULAR), + 4303: (4853, lnames[4303], ('rsl', 'ss', 'l', 'm', 18, 0, 18, 18, 1, 2, 1, 2, 0, 18), 'm', 0, NPC_REGULAR), + 4304: (4873, lnames[4304], ('rss', 'ls', 'm', 'm', 12, 0, 12, 12, 0, 2, 0, 2, 0, 15), 'm', 0, NPC_HQ), + 4305: (4873, lnames[4305], ('mss', 'sd', 'm', 'f', 3, 0, 3, 3, 0, 4, 0, 4, 26, 27), 'f', 0, NPC_HQ), + 4306: (4873, lnames[4306], ('hll', 'ms', 'm', 'f', 19, 0, 19, 19, 0, 5, 0, 5, 4, 25), 'f', 0, NPC_HQ), + 4307: (4873, lnames[4307], ('hsl', 'ld', 'm', 'f', 11, 0, 11, 11, 0, 5, 0, 5, 17, 27), 'f', 0, NPC_HQ), + 4308: (4835, lnames[4308], ('css', 'md', 'm', 'f', 6, 0, 6, 6, 3, 5, 3, 5, 0, 14), 'f', 0, NPC_REGULAR), + 4309: (4801, lnames[4309], ('cll', 'ms', 'm', 'm', 18, 0, 18, 18, 0, 4, 0, 4, 0, 17), 'm', 1, NPC_REGULAR), + 4310: (4803, lnames[4310], 'r', 'f', 1, NPC_REGULAR), + 4311: (4804, lnames[4311], 'r', 'f', 1, NPC_REGULAR), + 4312: (4807, lnames[4312], ('dsl', 'ms', 'm', 'm', 18, 0, 18, 18, 1, 5, 1, 5, 0, 9), 'm', 1, NPC_REGULAR), + 4313: (4809, lnames[4313], ('dss', 'ss', 'm', 'm', 10, 0, 10, 10, 1, 5, 1, 5, 0, 2), 'm', 1, NPC_REGULAR), + 4314: (4817, lnames[4314], ('fll', 'ld', 'm', 'f', 2, 0, 2, 2, 1, 8, 1, 8, 12, 27), 'f', 0, NPC_REGULAR), + 4315: (4827, lnames[4315], ('fss', 'sd', 'm', 'f', 18, 0, 18, 18, 1, 9, 1, 9, 26, 27), 'f', 0, NPC_REGULAR), + 4316: (4828, lnames[4316], ('fls', 'ss', 'm', 'm', 9, 0, 9, 9, 1, 6, 1, 6, 0, 14), 'm', 0, NPC_REGULAR), + 4317: (4829, lnames[4317], ('rsl', 'ls', 'l', 'm', 3, 0, 3, 3, 0, 7, 0, 7, 0, 11), 'm', 0, NPC_REGULAR), + 4318: (4836, lnames[4318], ('rss', 'ms', 'l', 'm', 17, 0, 17, 17, 0, 8, 0, 8, 0, 6), 'm', 0, NPC_REGULAR), + 4319: (4838, lnames[4319], ('mss', 'ls', 'l', 'f', 10, 0, 10, 10, 0, 12, 0, 12, 1, 23), 'f', 0, NPC_REGULAR), + 4320: (4840, lnames[4320], ('mls', 'ss', 'l', 'f', 1, 0, 1, 1, 0, 21, 0, 21, 11, 27), 'f', 0, NPC_REGULAR), + 4321: (4841, lnames[4321], ('hsl', 'ls', 'l', 'm', 17, 0, 17, 17, 0, 9, 0, 9, 0, 16), 'm', 0, NPC_REGULAR), + 4322: (4842, lnames[4322], ('hls', 'ms', 'l', 'm', 9, 0, 9, 9, 0, 9, 0, 9, 0, 13), 'm', 0, NPC_REGULAR), + 4323: (4844, lnames[4323], ('cll', 'ss', 'l', 'f', 1, 0, 1, 1, 1, 21, 1, 21, 24, 27), 'f', 0, NPC_REGULAR), + 4324: (4845, lnames[4324], ('css', 'ld', 'l', 'f', 17, 0, 17, 17, 1, 22, 1, 22, 10, 27), 'f', 0, NPC_REGULAR), + 4325: (4848, lnames[4325], ('cls', 'ms', 'l', 'm', 9, 0, 9, 9, 1, 9, 1, 9, 0, 0), 'm', 0, NPC_REGULAR), + 4326: (4850, lnames[4326], ('dsl', 'ms', 'l', 'f', 1, 0, 1, 1, 1, 23, 1, 23, 14, 27), 'f', 0, NPC_REGULAR), + 4327: (4852, lnames[4327], ('dss', 'ld', 'l', 'f', 16, 0, 16, 16, 1, 23, 1, 23, 7, 1), 'f', 0, NPC_REGULAR), + 4328: (4854, lnames[4328], ('fll', 'ms', 'l', 'm', 8, 0, 8, 8, 1, 11, 1, 11, 0, 12), 'm', 0, NPC_REGULAR), + 4329: (4855, lnames[4329], ('fsl', 'ls', 'l', 'f', 24, 0, 24, 24, 0, 25, 0, 25, 26, 27), 'f', 0, NPC_REGULAR), + 4330: (4862, lnames[4330], 'r', 'm', 0, NPC_REGULAR), + 4331: (4867, lnames[4331], 'r', 'm', 0, NPC_REGULAR), + 4332: (4870, lnames[4332], ('rss', 'ms', 'l', 'm', 22, 0, 22, 22, 0, 27, 0, 27, 0, 17), 'm', 0, NPC_REGULAR), + 4333: (4871, lnames[4333], ('mss', 'ss', 'l', 'm', 15, 0, 15, 15, 0, 27, 0, 27, 0, 14), 'm', 0, NPC_REGULAR), + 4334: (4872, lnames[4334], ('mls', 'ls', 'l', 'm', 8, 0, 8, 8, 0, 0, 0, 0, 0, 11), 'm', 0, NPC_REGULAR), + 4335: (4345, lnames[4335], ('hsl', 'ms', 'l', 'm', 22, 0, 22, 22, 1, 0, 1, 0, 0, 6), 'm', 0, NPC_FISHERMAN), + 5001: (5502, lnames[5001], ('fls', 'ls', 's', 'm', 14, 0, 14, 14, 1, 7, 1, 7, 0, 20), 'm', 0, NPC_HQ), + 5002: (5502, lnames[5002], ('rll', 'ms', 's', 'm', 6, 0, 6, 6, 0, 8, 0, 8, 0, 17), 'm', 0, NPC_HQ), + 5003: (5502, lnames[5003], ('rss', 'ms', 's', 'f', 22, 0, 22, 22, 0, 12, 0, 12, 26, 27), 'f', 0, NPC_HQ), + 5004: (5502, lnames[5004], ('rls', 'ld', 's', 'f', 13, 0, 13, 13, 0, 21, 0, 21, 4, 11), 'f', 0, NPC_HQ), + 5005: (5501, lnames[5005], ('mls', 'md', 's', 'f', 6, 0, 6, 6, 0, 21, 0, 21, 2, 3), 'f', 0, NPC_CLERK), + 5006: (5501, lnames[5006], ('hsl', 'ms', 's', 'm', 20, 0, 20, 20, 0, 9, 0, 9, 0, 1), 'm', 0, NPC_CLERK), + 5007: (5503, lnames[5007], ('hss', 'ss', 's', 'f', 13, 0, 13, 13, 0, 22, 0, 22, 3, 2), 'f', 0, NPC_TAILOR), + 5008: (5000, lnames[5008], ('cll', 'md', 's', 'f', 4, 0, 4, 4, 1, 22, 1, 22, 19, 27), 'f', 0, NPC_FISHERMAN), + 5009: (5505, lnames[5009], ('csl', 'ls', 'm', 'f', 21, 0, 21, 21, 1, 23, 1, 23, 8, 23), 'f', 0, NPC_PETCLERK), + 5010: (5505, lnames[5010], ('cls', 'ss', 'm', 'm', 13, 0, 13, 13, 1, 10, 1, 10, 0, 10), 'm', 0, NPC_PETCLERK), + 5011: (5505, lnames[5011], ('dll', 'ls', 'm', 'm', 5, 0, 5, 5, 1, 10, 1, 10, 0, 4), 'm', 0, NPC_PETCLERK), + 5012: (5000, lnames[5012], ('dls', 'ms', 'm', 'm', 13, 0, 12, 12, 0, 1, 0, 1, 0, 6), 'm', 1, NPC_PARTYPERSON), + 5013: (5000, lnames[5013], ('dss', 'md', 'm', 'f', 1, 0, 3, 3, 1, 5, 1, 5, 0, 5), 'f', 1, NPC_PARTYPERSON), + 5101: (5602, lnames[5101], ('dsl', 'ms', 'l', 'm', 10, 0, 10, 10, 1, 4, 1, 4, 0, 11), 'm', 1, NPC_REGULAR), + 5102: (5610, lnames[5102], 'r', 'f', 0, NPC_REGULAR), + 5103: (5615, lnames[5103], ('fll', 'ls', 'l', 'm', 18, 0, 18, 18, 1, 5, 1, 5, 0, 1), 'm', 0, NPC_REGULAR), + 5104: (5617, lnames[5104], ('fsl', 'ms', 'l', 'm', 10, 0, 10, 10, 1, 5, 1, 5, 0, 19), 'm', 0, NPC_REGULAR), + 5105: (5619, lnames[5105], 'r', 'm', 0, NPC_REGULAR), + 5106: (5613, lnames[5106], ('rsl', 'ls', 'l', 'm', 18, 0, 18, 18, 1, 6, 1, 6, 0, 13), 'm', 0, NPC_REGULAR), + 5107: (5607, lnames[5107], 'r', 'm', 1, NPC_REGULAR), + 5108: (5616, lnames[5108], ('mss', 'ls', 'l', 'f', 2, 0, 2, 2, 0, 11, 0, 11, 24, 27), 'f', 0, NPC_REGULAR), + 5109: (5627, lnames[5109], ('mls', 'ss', 'l', 'm', 17, 0, 17, 17, 0, 7, 0, 7, 0, 0), 'm', 1, NPC_HQ), + 5110: (5627, lnames[5110], ('hsl', 'ls', 'l', 'm', 10, 0, 10, 10, 0, 8, 0, 8, 0, 18), 'm', 1, NPC_HQ), + 5111: (5627, lnames[5111], ('hss', 'ls', 'l', 'f', 2, 0, 2, 2, 0, 12, 0, 12, 7, 4), 'f', 1, NPC_HQ), + 5112: (5627, lnames[5112], ('cll', 'ms', 'l', 'f', 17, 0, 17, 17, 0, 21, 0, 21, 14, 27), 'f', 1, NPC_HQ), + 5113: (5601, lnames[5113], ('css', 'ld', 'l', 'f', 10, 0, 10, 10, 0, 21, 0, 21, 3, 2), 'f', 1, NPC_REGULAR), + 5114: (5603, lnames[5114], ('cls', 'ms', 'l', 'm', 2, 0, 2, 2, 1, 9, 1, 9, 0, 2), 'm', 1, NPC_REGULAR), + 5115: (5604, lnames[5115], ('dsl', 'ms', 'l', 'f', 17, 0, 17, 17, 1, 22, 1, 22, 10, 27), 'f', 1, NPC_REGULAR), + 5116: (5605, lnames[5116], ('dss', 'ls', 'l', 'm', 9, 0, 9, 9, 1, 9, 1, 9, 0, 17), 'm', 1, NPC_REGULAR), + 5117: (5606, lnames[5117], ('fll', 'md', 'l', 'f', 1, 0, 1, 1, 1, 23, 1, 23, 17, 27), 'f', 1, NPC_REGULAR), + 5118: (5608, lnames[5118], ('fsl', 'ms', 'l', 'm', 16, 0, 16, 16, 1, 10, 1, 10, 0, 11), 'm', 1, NPC_REGULAR), + 5119: (5609, lnames[5119], ('fls', 'ss', 'l', 'm', 9, 0, 9, 9, 1, 10, 1, 10, 0, 6), 'm', 1, NPC_REGULAR), + 5120: (5611, lnames[5120], ('rsl', 'ss', 'l', 'm', 22, 0, 22, 22, 1, 3, 1, 3, 1, 19), 'm', 0, NPC_REGULAR), + 5121: (5618, lnames[5121], ('rss', 'ss', 'l', 'f', 23, 0, 23, 23, 1, 9, 1, 9, 0, 25), 'f', 0, NPC_REGULAR), + 5122: (5620, lnames[5122], 'r', 'm', 0, NPC_REGULAR), + 5123: (5621, lnames[5123], ('mls', 'sd', 'm', 'f', 7, 0, 7, 7, 1, 11, 1, 11, 25, 27), 'f', 0, NPC_REGULAR), + 5124: (5622, lnames[5124], ('hll', 'ss', 'm', 'm', 21, 0, 21, 21, 0, 8, 0, 8, 0, 4), 'm', 0, NPC_REGULAR), + 5125: (5623, lnames[5125], ('hss', 'ls', 'm', 'm', 14, 0, 14, 14, 0, 9, 0, 9, 0, 0), 'm', 0, NPC_REGULAR), + 5126: (5624, lnames[5126], ('hls', 'sd', 'm', 'f', 7, 0, 7, 7, 0, 21, 0, 21, 14, 27), 'f', 0, NPC_REGULAR), + 5127: (5625, lnames[5127], ('csl', 'ms', 'm', 'f', 23, 0, 23, 23, 0, 22, 0, 22, 2, 2), 'f', 0, NPC_REGULAR), + 5128: (5626, lnames[5128], 'r', 'f', 0, NPC_REGULAR), + 5129: (5139, lnames[5129], ('dll', 'md', 'm', 'f', 7, 0, 7, 7, 0, 23, 0, 23, 17, 27), 'f', 0, NPC_FISHERMAN), + 5201: (5702, lnames[5201], ('hls', 'ls', 'l', 'm', 15, 0, 15, 15, 1, 10, 1, 10, 1, 16), 'm', 1, NPC_REGULAR), + 5202: (5703, lnames[5202], ('cll', 'ls', 'l', 'f', 7, 0, 7, 7, 1, 23, 1, 23, 11, 27), 'f', 1, NPC_REGULAR), + 5203: (5704, lnames[5203], ('css', 'ss', 'l', 'f', 23, 0, 23, 23, 1, 24, 1, 24, 19, 27), 'f', 1, NPC_REGULAR), + 5204: (5726, lnames[5204], ('cls', 'ls', 'l', 'm', 14, 0, 14, 14, 0, 12, 0, 12, 1, 4), 'm', 0, NPC_REGULAR), + 5205: (5718, lnames[5205], 'r', 'm', 0, NPC_REGULAR), + 5206: (5720, lnames[5206], ('dss', 'ss', 'l', 'm', 21, 0, 21, 21, 0, 27, 0, 27, 1, 18), 'm', 0, NPC_REGULAR), + 5207: (5717, lnames[5207], ('fll', 'ld', 'l', 'f', 14, 0, 14, 14, 0, 27, 0, 27, 26, 27), 'f', 0, NPC_REGULAR), + 5208: (5719, lnames[5208], ('fsl', 'sd', 'l', 'f', 7, 0, 7, 7, 0, 27, 0, 27, 1, 12), 'f', 0, NPC_REGULAR), + 5209: (5728, lnames[5209], ('fls', 'ss', 'l', 'm', 21, 0, 21, 21, 0, 0, 0, 0, 1, 9), 'm', 1, NPC_HQ), + 5210: (5728, lnames[5210], ('rsl', 'ss', 'l', 'm', 14, 0, 14, 14, 1, 0, 1, 0, 1, 2), 'm', 1, NPC_HQ), + 5211: (5728, lnames[5211], ('rss', 'md', 'l', 'f', 6, 0, 6, 6, 1, 1, 1, 1, 23, 27), 'f', 1, NPC_HQ), + 5212: (5728, lnames[5212], ('mss', 'ls', 'l', 'f', 22, 0, 22, 22, 1, 1, 1, 1, 10, 27), 'f', 1, NPC_HQ), + 5213: (5701, lnames[5213], ('mls', 'ss', 'l', 'm', 13, 0, 13, 13, 1, 1, 1, 1, 1, 14), 'm', 1, NPC_REGULAR), + 5214: (5705, lnames[5214], ('hsl', 'md', 'l', 'f', 6, 0, 6, 6, 1, 2, 1, 2, 17, 27), 'f', 1, NPC_REGULAR), + 5215: (5706, lnames[5215], 'r', 'f', 1, NPC_REGULAR), + 5216: (5707, lnames[5216], ('cll', 'ss', 'l', 'm', 13, 0, 13, 13, 0, 2, 0, 2, 1, 1), 'm', 1, NPC_REGULAR), + 5217: (5708, lnames[5217], ('csl', 'ls', 'l', 'm', 5, 0, 5, 5, 0, 3, 0, 3, 1, 19), 'm', 1, NPC_REGULAR), + 5218: (5709, lnames[5218], 'r', 'm', 1, NPC_REGULAR), + 5219: (5710, lnames[5219], ('dsl', 'ss', 'l', 'm', 13, 0, 13, 13, 0, 3, 0, 3, 1, 13), 'm', 0, NPC_REGULAR), + 5220: (5711, lnames[5220], 'r', 'f', 0, NPC_REGULAR), + 5221: (5712, lnames[5221], ('fll', 'md', 'l', 'f', 21, 0, 21, 21, 0, 6, 0, 6, 25, 27), 'f', 0, NPC_REGULAR), + 5222: (5713, lnames[5222], 'r', 'f', 0, NPC_REGULAR), + 5223: (5714, lnames[5223], ('fls', 'ss', 's', 'm', 5, 0, 5, 5, 1, 4, 1, 4, 1, 18), 'm', 0, NPC_REGULAR), + 5224: (5715, lnames[5224], ('rll', 'ls', 's', 'm', 19, 0, 19, 19, 1, 5, 1, 5, 1, 15), 'm', 0, NPC_REGULAR), + 5225: (5716, lnames[5225], ('rss', 'sd', 's', 'f', 12, 0, 12, 12, 1, 7, 1, 7, 10, 27), 'f', 0, NPC_REGULAR), + 5226: (5721, lnames[5226], ('rls', 'ss', 's', 'm', 4, 0, 4, 4, 1, 5, 1, 5, 1, 9), 'm', 0, NPC_REGULAR), + 5227: (5725, lnames[5227], ('mls', 'ld', 's', 'f', 19, 0, 19, 19, 1, 8, 1, 8, 23, 27), 'f', 0, NPC_REGULAR), + 5228: (5727, lnames[5228], ('hsl', 'ms', 's', 'm', 12, 0, 12, 12, 1, 6, 1, 6, 1, 20), 'm', 0, NPC_REGULAR), + 5229: (5245, lnames[5229], ('hss', 'ms', 's', 'f', 3, 0, 3, 3, 0, 11, 0, 11, 16, 27), 'f', 0, NPC_FISHERMAN), + 5301: (5802, lnames[5301], ('rss', 'ms', 'l', 'f', 13, 0, 13, 13, 0, 11, 0, 11, 1, 12), 'f', 1, NPC_HQ), + 5302: (5802, lnames[5302], ('mss', 'ss', 'l', 'f', 4, 0, 4, 4, 0, 12, 0, 12, 17, 27), 'f', 1, NPC_HQ), + 5303: (5802, lnames[5303], ('hll', 'ls', 'l', 'm', 19, 0, 19, 19, 1, 8, 1, 8, 1, 18), 'm', 1, NPC_HQ), + 5304: (5802, lnames[5304], ('hsl', 'ls', 'l', 'f', 12, 0, 12, 12, 1, 12, 1, 12, 19, 27), 'f', 1, NPC_HQ), + 5305: (5804, lnames[5305], ('hls', 'ss', 'l', 'f', 4, 0, 4, 4, 1, 21, 1, 21, 16, 27), 'f', 1, NPC_REGULAR), + 5306: (5805, lnames[5306], 'r', 'm', 1, NPC_REGULAR), + 5307: (5809, lnames[5307], ('css', 'ms', 'l', 'm', 12, 0, 12, 12, 1, 9, 1, 9, 1, 2), 'm', 1, NPC_REGULAR), + 5308: (5810, lnames[5308], ('cls', 'ms', 'l', 'f', 4, 0, 4, 4, 1, 22, 1, 22, 10, 27), 'f', 0, NPC_REGULAR), + 5309: (5811, lnames[5309], 'r', 'f', 0, NPC_REGULAR), + 5310: (5815, lnames[5310], ('dls', 'ms', 'l', 'm', 12, 0, 12, 12, 0, 11, 0, 11, 1, 14), 'm', 0, NPC_REGULAR), + 5311: (5817, lnames[5311], ('fll', 'ms', 'm', 'f', 3, 0, 3, 3, 0, 24, 0, 24, 12, 27), 'f', 0, NPC_REGULAR), + 5312: (5819, lnames[5312], ('fss', 'ss', 'm', 'm', 18, 0, 18, 18, 0, 12, 0, 12, 1, 6), 'm', 0, NPC_REGULAR), + 5313: (5821, lnames[5313], ('fls', 'ls', 'm', 'm', 10, 0, 10, 10, 0, 12, 0, 12, 1, 1), 'm', 0, NPC_REGULAR), + 5314: (5826, lnames[5314], 'r', 'f', 0, NPC_REGULAR), + 5315: (5827, lnames[5315], ('rss', 'ss', 'm', 'm', 18, 0, 18, 18, 1, 12, 1, 12, 1, 16), 'm', 0, NPC_REGULAR), + 5316: (5828, lnames[5316], ('mss', 'ls', 'm', 'm', 10, 0, 10, 10, 1, 12, 1, 12, 1, 13), 'm', 0, NPC_REGULAR), + 5317: (5830, lnames[5317], 'r', 'm', 0, NPC_REGULAR), + 5318: (5833, lnames[5318], ('hsl', 'ss', 'm', 'm', 18, 0, 18, 18, 1, 0, 1, 0, 1, 4), 'm', 0, NPC_REGULAR), + 5319: (5835, lnames[5319], 'r', 'f', 0, NPC_REGULAR), + 5320: (5836, lnames[5320], ('cll', 'sd', 'm', 'f', 2, 0, 2, 2, 1, 1, 1, 1, 17, 27), 'f', 0, NPC_REGULAR), + 5321: (5837, lnames[5321], ('css', 'ms', 'm', 'f', 18, 0, 18, 18, 1, 1, 1, 1, 17, 27), 'f', 0, NPC_REGULAR), + 5322: (5318, lnames[5322], ('cls', 'ss', 'm', 'f', 10, 0, 10, 10, 0, 2, 0, 2, 11, 27), 'f', 0, NPC_FISHERMAN), + 6000: (6000, lnames[6000], ('hsl', 'ms', 'm', 'm', 8, 0, 8, 8, 1, 6, 1, 6, 0, 18), 'm', 0, NPC_FISHERMAN), + 8001: (8501, lnames[8001], ('psl', 'ms', 'm', 'm', 13, 0, 13, 13, 0, 11, 0, 11, 2, 10), 'm', 0, NPC_KARTCLERK), + 8002: (8501, lnames[8002], ('psl', 'ld', 's', 'f', 23, 0, 23, 23, 0, 11, 0, 11, 2, 10), 'f', 0, NPC_KARTCLERK), + 8003: (8501, lnames[8003], ('pll', 'ss', 'l', 'f', 1, 0, 1, 1, 0, 11, 0, 11, 2, 10), 'f', 0, NPC_KARTCLERK), + 8004: (8501, lnames[8004], ('pls', 'ms', 'l', 'm', 16, 0, 16, 16, 0, 11, 0, 11, 2, 10), 'm', 0, NPC_KARTCLERK), + 9001: (9503, lnames[9001], ('fll', 'ss', 'l', 'f', 16, 0, 16, 16, 0, 6, 0, 6, 26, 27), 'f', 0, NPC_REGULAR), + 9002: (9502, lnames[9002], 'r', 'm', 0, NPC_REGULAR), + 9003: (9501, lnames[9003], ('fls', 'ms', 'l', 'm', 22, 0, 22, 22, 1, 5, 1, 5, 0, 14), 'm', 0, NPC_REGULAR), + 9004: (9505, lnames[9004], ('rll', 'ms', 'l', 'f', 16, 0, 16, 16, 1, 7, 1, 7, 3, 8), 'f', 1, NPC_HQ), + 9005: (9505, lnames[9005], ('rss', 'ld', 'l', 'f', 9, 0, 9, 9, 1, 8, 1, 8, 19, 27), 'f', 1, NPC_HQ), + 9006: (9505, lnames[9006], ('rls', 'ms', 'l', 'm', 22, 0, 22, 22, 1, 6, 1, 6, 0, 1), 'm', 1, NPC_HQ), + 9007: (9505, lnames[9007], ('mls', 'ms', 'l', 'm', 15, 0, 15, 15, 1, 6, 1, 6, 0, 19), 'm', 1, NPC_HQ), + 9008: (9504, lnames[9008], ('hll', 'ss', 'l', 'f', 8, 0, 8, 8, 1, 9, 1, 9, 12, 27), 'f', 0, NPC_CLERK), + 9009: (9504, lnames[9009], ('hss', 'ls', 'l', 'm', 22, 0, 22, 22, 0, 7, 0, 7, 0, 13), 'm', 0, NPC_CLERK), + 9010: (9506, lnames[9010], ('cll', 'ms', 'l', 'm', 15, 0, 15, 15, 0, 8, 0, 8, 0, 10), 'm', 0, NPC_TAILOR), + 9011: (9000, lnames[9011], ('csl', 'ss', 'l', 'm', 7, 0, 7, 7, 0, 8, 0, 8, 0, 4), 'm', 0, NPC_FISHERMAN), + 9012: (9508, lnames[9012], ('cls', 'ld', 'l', 'f', 23, 0, 23, 23, 0, 21, 0, 21, 10, 27), 'f', 0, NPC_PETCLERK), + 9013: (9508, lnames[9013], ('dll', 'sd', 'l', 'f', 15, 0, 15, 15, 0, 21, 0, 21, 10, 27), 'f', 0, NPC_PETCLERK), + 9014: (9508, lnames[9014], ('dss', 'ss', 'l', 'm', 7, 0, 7, 7, 0, 9, 0, 9, 1, 15), 'm', 0, NPC_PETCLERK), + 9015: (9000, lnames[9015], ('rss', 'ls', 'l', 'm', 21, 0, 20, 20, 0, 12, 0, 12, 0, 11), 'm', 1, NPC_PARTYPERSON), + 9016: (9000, lnames[9016], ('rls', 'md', 'l', 'f', 6, 0, 21, 21, 1, 11, 1, 11, 0, 11), 'f', 1, NPC_PARTYPERSON), + 9101: (9604, lnames[9101], ('css', 'ls', 'l', 'm', 14, 0, 14, 14, 1, 1, 1, 1, 0, 11), 'm', 1, NPC_REGULAR), + 9102: (9607, lnames[9102], 'r', 'f', 1, NPC_REGULAR), + 9103: (9620, lnames[9103], ('dsl', 'ss', 'l', 'm', 20, 0, 20, 20, 0, 2, 0, 2, 0, 1), 'm', 0, NPC_REGULAR), + 9104: (9642, lnames[9104], ('dss', 'ld', 'l', 'f', 14, 0, 14, 14, 0, 3, 0, 3, 0, 23), 'f', 0, NPC_REGULAR), + 9105: (9609, lnames[9105], 'r', 'm', 1, NPC_REGULAR), + 9106: (9619, lnames[9106], ('fsl', 'ss', 'l', 'm', 20, 0, 20, 20, 0, 3, 0, 3, 0, 13), 'm', 0, NPC_REGULAR), + 9107: (9601, lnames[9107], ('fls', 'ld', 'l', 'f', 13, 0, 13, 13, 0, 5, 0, 5, 3, 2), 'f', 1, NPC_REGULAR), + 9108: (9602, lnames[9108], ('rll', 'ms', 'l', 'm', 6, 0, 6, 6, 1, 4, 1, 4, 0, 4), 'm', 1, NPC_REGULAR), + 9109: (9605, lnames[9109], ('rss', 'ls', 'l', 'f', 22, 0, 22, 22, 1, 6, 1, 6, 10, 27), 'f', 1, NPC_REGULAR), + 9110: (9608, lnames[9110], ('mss', 'ss', 'l', 'f', 13, 0, 13, 13, 1, 6, 1, 6, 25, 27), 'f', 1, NPC_REGULAR), + 9111: (9616, lnames[9111], 'r', 'f', 0, NPC_REGULAR), + 9112: (9617, lnames[9112], ('hsl', 'ms', 'm', 'm', 19, 0, 19, 19, 1, 5, 1, 5, 0, 12), 'm', 0, NPC_REGULAR), + 9113: (9622, lnames[9113], ('hss', 'ss', 'm', 'm', 13, 0, 13, 13, 1, 5, 1, 5, 0, 9), 'm', 0, NPC_REGULAR), + 9114: (9625, lnames[9114], ('cll', 'ld', 'm', 'f', 4, 0, 4, 4, 0, 8, 0, 8, 10, 27), 'f', 0, NPC_REGULAR), + 9115: (9626, lnames[9115], 'r', 'm', 0, NPC_REGULAR), + 9116: (9627, lnames[9116], ('cls', 'ss', 'm', 'm', 12, 0, 12, 12, 0, 7, 0, 7, 0, 17), 'm', 0, NPC_REGULAR), + 9117: (9628, lnames[9117], ('dsl', 'ld', 'm', 'f', 4, 0, 4, 4, 0, 11, 0, 11, 2, 9), 'f', 0, NPC_REGULAR), + 9118: (9629, lnames[9118], 'r', 'f', 0, NPC_REGULAR), + 9119: (9630, lnames[9119], ('fll', 'ms', 'm', 'm', 12, 0, 12, 12, 0, 8, 0, 8, 0, 6), 'm', 0, NPC_REGULAR), + 9120: (9631, lnames[9120], 'r', 'f', 0, NPC_REGULAR), + 9121: (9634, lnames[9121], ('fls', 'md', 'm', 'f', 19, 0, 19, 19, 1, 12, 1, 12, 16, 27), 'f', 0, NPC_REGULAR), + 9122: (9636, lnames[9122], ('rll', 'ms', 'm', 'm', 12, 0, 12, 12, 1, 8, 1, 8, 0, 16), 'm', 0, NPC_REGULAR), + 9123: (9639, lnames[9123], ('rss', 'ss', 'm', 'm', 4, 0, 4, 4, 1, 9, 1, 9, 0, 13), 'm', 0, NPC_REGULAR), + 9124: (9640, lnames[9124], ('rls', 'md', 'm', 'f', 19, 0, 19, 19, 1, 22, 1, 22, 8, 9), 'f', 0, NPC_REGULAR), + 9125: (9643, lnames[9125], ('mls', 'ms', 'l', 'm', 10, 0, 10, 10, 1, 9, 1, 9, 0, 4), 'm', 0, NPC_REGULAR), + 9126: (9644, lnames[9126], ('hsl', 'ms', 'l', 'f', 3, 0, 3, 3, 1, 23, 1, 23, 23, 27), 'f', 0, NPC_REGULAR), + 9127: (9645, lnames[9127], ('hss', 'ld', 'l', 'f', 19, 0, 19, 19, 0, 24, 0, 24, 10, 27), 'f', 0, NPC_REGULAR), + 9128: (9647, lnames[9128], ('cll', 'ms', 'l', 'm', 10, 0, 10, 10, 0, 11, 0, 11, 0, 15), 'm', 0, NPC_REGULAR), + 9129: (9649, lnames[9129], ('csl', 'ms', 'l', 'f', 3, 0, 3, 3, 0, 25, 0, 25, 25, 27), 'f', 0, NPC_REGULAR), + 9130: (9650, lnames[9130], ('cls', 'ss', 'l', 'm', 18, 0, 18, 18, 0, 12, 0, 12, 0, 9), 'm', 0, NPC_REGULAR), + 9131: (9651, lnames[9131], 'r', 'f', 0, NPC_REGULAR), + 9132: (9652, lnames[9132], ('dss', 'ls', 'l', 'f', 2, 0, 2, 2, 0, 27, 0, 27, 0, 0), 'f', 0, NPC_HQ), + 9133: (9652, lnames[9133], ('dls', 'ss', 'l', 'm', 17, 0, 17, 17, 1, 12, 1, 12, 0, 17), 'm', 0, NPC_HQ), + 9134: (9652, lnames[9134], ('fsl', 'ls', 'l', 'm', 10, 0, 10, 10, 1, 0, 1, 0, 0, 14), 'm', 0, NPC_HQ), + 9135: (9652, lnames[9135], ('fls', 'ms', 'l', 'm', 3, 0, 3, 3, 1, 0, 1, 0, 0, 11), 'm', 0, NPC_HQ), + 9136: (9153, lnames[9136], ('rll', 'ss', 'l', 'm', 17, 0, 17, 17, 1, 0, 1, 0, 1, 6), 'm', 0, NPC_FISHERMAN), + 9201: (9752, lnames[9201], ('psl', 'ss', 'm', 'm', 9, 0, 9, 9, 17, 11, 0, 11, 7, 20), 'm', 0, NPC_REGULAR), + 9202: (9703, lnames[9202], ('dss', 'ss', 's', 'm', 21, 0, 21, 21, 8, 3, 8, 3, 1, 17), 'm', 1, NPC_REGULAR), + 9203: (9741, lnames[9203], ('pls', 'ls', 's', 'm', 5, 0, 5, 5, 37, 27, 26, 27, 7, 4), 'm', 0, NPC_REGULAR), + 9204: (9704, lnames[9204], ('fsl', 'sd', 's', 'f', 19, 0, 19, 19, 21, 10, 0, 10, 8, 23), 'f', 1, NPC_REGULAR), + 9205: (9736, lnames[9205], ('dsl', 'ms', 'm', 'm', 15, 0, 15, 15, 45, 27, 34, 27, 2, 17), 'm', 0, NPC_REGULAR), + 9206: (9727, lnames[9206], ('rls', 'ld', 'l', 'f', 8, 0, 8, 8, 25, 27, 16, 27, 10, 27), 'f', 0, NPC_REGULAR), + 9207: (9709, lnames[9207], ('hss', 'ss', 's', 'f', 24, 0, 24, 24, 36, 27, 25, 27, 9, 27), 'f', 1, NPC_REGULAR), + 9208: (9705, lnames[9208], ('dsl', 'ms', 's', 'm', 20, 0, 20, 20, 46, 27, 35, 27, 6, 27), 'm', 1, NPC_REGULAR), + 9209: (9706, lnames[9209], ('pll', 'ss', 'm', 'm', 13, 0, 13, 13, 8, 12, 8, 12, 1, 12), 'm', 1, NPC_REGULAR), + 9210: (9740, lnames[9210], ('hsl', 'ls', 'l', 'm', 6, 0, 6, 6, 1, 0, 1, 0, 0, 0), 'm', 0, NPC_REGULAR), + 9211: (9707, lnames[9211], ('rll', 'ss', 's', 'f', 3, 0, 3, 3, 22, 22, 0, 22, 6, 22), 'f', 1, NPC_REGULAR), + 9212: (9753, lnames[9212], ('pss', 'md', 'm', 'f', 16, 0, 16, 16, 45, 27, 34, 27, 0, 3), 'f', 0, NPC_REGULAR), + 9213: (9711, lnames[9213], ('fsl', 'ss', 'm', 'm', 2, 0, 2, 2, 37, 27, 26, 27, 7, 18), 'm', 0, NPC_REGULAR), + 9214: (9710, lnames[9214], ('rll', 'ls', 'l', 'm', 18, 0, 18, 18, 10, 27, 0, 27, 0, 13), 'm', 0, NPC_REGULAR), + 9215: (9744, lnames[9215], ('csl', 'ls', 'l', 'm', 18, 0, 18, 18, 11, 4, 0, 4, 0, 4), 'm', 0, NPC_REGULAR), + 9216: (9725, lnames[9216], ('csl', 'sd', 'm', 'f', 14, 0, 14, 14, 1, 7, 1, 7, 3, 7), 'f', 0, NPC_REGULAR), + 9217: (9713, lnames[9217], ('mss', 'ms', 'm', 'f', 17, 0, 17, 17, 20, 26, 0, 26, 5, 12), 'f', 0, NPC_REGULAR), + 9218: (9737, lnames[9218], ('dss', 'md', 'l', 'f', 23, 0, 23, 23, 24, 27, 15, 27, 11, 27), 'f', 0, NPC_REGULAR), + 9219: (9712, lnames[9219], ('hll', 'sd', 'l', 'f', 10, 0, 10, 10, 9, 22, 9, 22, 12, 27), 'f', 0, NPC_REGULAR), + 9220: (9716, lnames[9220], ('mls', 'ms', 'l', 'm', 7, 0, 7, 7, 0, 27, 0, 27, 1, 10), 'm', 0, NPC_REGULAR), + 9221: (9738, lnames[9221], ('fss', 'md', 'l', 'f', 22, 0, 22, 22, 45, 27, 34, 27, 0, 6), 'f', 0, NPC_REGULAR), + 9222: (9754, lnames[9222], ('hsl', 'ls', 'l', 'm', 10, 0, 10, 10, 52, 27, 41, 27, 12, 27), 'm', 0, NPC_REGULAR), + 9223: (9714, lnames[9223], ('fsl', 'ms', 'm', 'm', 20, 0, 20, 20, 43, 27, 32, 27, 0, 0), 'm', 0, NPC_REGULAR), + 9224: (9718, lnames[9224], ('css', 'ms', 'm', 'f', 1, 0, 1, 1, 6, 8, 6, 8, 6, 8), 'f', 0, NPC_REGULAR), + 9225: (9717, lnames[9225], ('rss', 'md', 'm', 'f', 11, 0, 11, 11, 40, 27, 29, 27, 0, 27), 'f', 0, NPC_REGULAR), + 9226: (9715, lnames[9226], ('mls', 'ms', 's', 'm', 12, 0, 12, 12, 3, 10, 3, 10, 6, 10), 'm', 0, NPC_REGULAR), + 9227: (9721, lnames[9227], ('cls', 'ss', 's', 'm', 13, 0, 13, 13, 8, 5, 8, 5, 3, 18), 'm', 0, NPC_REGULAR), + 9228: (9720, lnames[9228], ('fss', 'sd', 's', 'f', 4, 0, 4, 4, 15, 5, 11, 5, 8, 5), 'f', 0, NPC_REGULAR), + 9229: (9708, lnames[9229], ('css', 'ld', 'm', 'f', 4, 0, 4, 4, 22, 21, 0, 21, 4, 21), 'f', 1, NPC_REGULAR), + 9230: (9719, lnames[9230], ('mss', 'ss', 's', 'm', 8, 0, 8, 8, 53, 27, 42, 27, 13, 27), 'm', 0, NPC_REGULAR), + 9231: (9722, lnames[9231], ('dll', 'ss', 's', 'm', 6, 0, 6, 6, 27, 27, 18, 27, 3, 8), 'm', 0, NPC_REGULAR), + 9232: (9759, lnames[9232], ('pss', 'ld', 'm', 'f', 21, 0, 21, 21, 0, 27, 0, 27, 13, 27), 'f', 0, NPC_REGULAR), + 9233: (9756, lnames[9233], ('csl', 'ls', 'l', 'f', 22, 0, 22, 22, 1, 7, 1, 7, 12, 27), 'f', 0, NPC_HQ), + 9234: (9756, lnames[9234], ('cls', 'ss', 'l', 'm', 14, 0, 14, 14, 1, 5, 1, 5, 0, 19), 'm', 0, NPC_HQ), + 9235: (9756, lnames[9235], ('dll', 'ls', 'l', 'm', 6, 0, 6, 6, 1, 6, 1, 6, 0, 16), 'm', 0, NPC_HQ), + 9236: (9756, lnames[9236], ('dss', 'ms', 'l', 'm', 20, 0, 20, 20, 0, 6, 0, 6, 0, 13), 'm', 0, NPC_HQ), + 9237: (9255, lnames[9237], ('dls', 'ss', 'l', 'm', 14, 0, 14, 14, 0, 7, 0, 7, 0, 10), 'm', 0, NPC_FISHERMAN), + 9301: (9329, lnames[9301], 'r', 'm', 0, NPC_FISHERMAN), + 9302: (9802, lnames[9302], ('dss', 'ld', 'l', 'f', 17, 0, 17, 17, 5, 21, 5, 21, 8, 26), 'f', 0, NPC_REGULAR), + 9303: (9826, lnames[9303], 'r', 'm', 0, NPC_REGULAR), + 9304: (9804, lnames[9304], ('dss', 'ls', 's', 'm', 16, 0, 16, 16, 14, 10, 10, 10, 3, 19), 'm', 0, NPC_REGULAR), + 9305: (9829, lnames[9305], 'r', 'm', 0, NPC_HQ), + 9306: (9829, lnames[9306], 'r', 'm', 0, NPC_HQ), + 9307: (9829, lnames[9307], 'r', 'f', 0, NPC_HQ), + 9308: (9829, lnames[9308], 'r', 'f', 0, NPC_HQ), + 9309: (9808, lnames[9309], ('css', 'ms', 'm', 'm', 26, 0, 26, 26, 8, 4, 8, 4, 7, 4), 'm', 0, NPC_REGULAR), + 9310: (9820, lnames[9310], 'r', 'm', 0, NPC_REGULAR), + 9311: (9809, lnames[9311], ('dls', 'ls', 'm', 'm', 24, 0, 18, 18, 11, 7, 0, 7, 1, 11), 'm', 0, NPC_REGULAR), + 9312: (9828, lnames[9312], 'r', 'f', 0, NPC_REGULAR), + 9313: (9827, lnames[9313], 'r', 'm', 0, NPC_REGULAR), + 9314: (9812, lnames[9314], 'r', 'm', 0, NPC_REGULAR), + 9315: (9813, lnames[9315], 'r', 'f', 0, NPC_REGULAR), + 9316: (9814, lnames[9316], 'r', 'f', 0, NPC_REGULAR), + 9317: (9815, lnames[9317], ('css', 'md', 's', 'f', 22, 0, 22, 22, 7, 4, 7, 4, 8, 11), 'f', 0, NPC_REGULAR), + 9318: (9816, lnames[9318], 'r', 'm', 0, NPC_REGULAR), + 9319: (9817, lnames[9319], ('css', 'ls', 'm', 'm', 26, 0, 26, 26, 5, 11, 5, 11, 5, 11), 'm', 0, NPC_REGULAR), + 9320: (9819, lnames[9320], 'r', 'm', 0, NPC_REGULAR), + 9321: (9824, lnames[9321], ('dss', 'ms', 'm', 'm', 2, 0, 2, 2, 4, 1, 4, 1, 2, 16), 'm', 0, NPC_REGULAR), + 9322: (9821, lnames[9322], ('dss', 'ms', 'm', 'm', 15, 0, 15, 15, 5, 6, 5, 6, 7, 9), 'f', 0, NPC_REGULAR), + 9323: (9822, lnames[9323], ('css', 'ms', 's', 'm', 31, 0, 31, 31, 8, 2, 8, 2, 5, 11), 'm', 0, NPC_REGULAR), + 9324: (9806, lnames[9324], ('fss', 'ls', 'l', 'm', 16, 0, 16, 16, 2, 9, 2, 9, 7, 20), 'm', 0, NPC_REGULAR), + 7001: (-1, lnames[7001], ('bss', 'md', 'm', 'f', 25, 0, 25, 25, 6, 12, 0, 0, 0, 2), 'f', 0, NPC_REGULAR), + 7002: (-1, lnames[7002], ('sss', 'ms', 'l', 'm', 7, 0, 7, 7, 18, 11, 0, 0, 4, 3), 'm', 0, NPC_REGULAR), + 7003: (-1, lnames[7003], ('sss', 'md', 'm', 'f', 21, 0, 21, 21, 45, 0, 0, 0, 7, 6), 'f', 0, NPC_REGULAR), + 7004: (-1, lnames[7004], ('pss', 'ls', 'l', 'm', 16, 0, 16, 16, 27, 0, 0, 0, 7, 16), 'm', 0, NPC_REGULAR), + 7005: (-1, lnames[7005], ('pls', 'ld', 's', 'f', 5, 0, 5, 5, 25, 0, 0, 0, 10, 0), 'f', 0, NPC_REGULAR), + 7006: (-1, lnames[7006], ('bll', 'ms', 's', 'm', 18, 0, 18, 18, 15, 4, 0, 0, 9, 3), 'm', 0, NPC_REGULAR), + 7007: (-1, lnames[7007], ('pls', 'ls', 's', 'm', 11, 0, 11, 11, 46, 0, 0, 0, 5, 16), 'm', 0, NPC_REGULAR), + 7008: (-1, lnames[7008], ('bls', 'ld', 's', 'f', 23, 0, 23, 23, 15, 6, 0, 0, 0, 18), 'f', 0, NPC_REGULAR), + 7009: (-1, lnames[7009], ('sll', 'ss', 's', 'm', 1, 0, 1, 1, 1, 6, 0, 0, 0, 6), 'm', 0, NPC_REGULAR), + 7010: (-1, lnames[7010], ('rll', 'ms', 'm', 'm', 2, 0, 2, 2, 19, 10, 13, 10, 7, 14, 0), 'm', 0, NPC_REGULAR), + 7011: (-1, lnames[7011], ('fll', 'ls', 'm', 'm', 0, 0, 9, 0, 10, 10, 0, 10, 5, 27), 'm', 0, NPC_REGULAR), + 7012: (-1, lnames[7012], ('pss', 'ms', 'l', 'm', 20, 0, 20, 20, 26, 0, 0, 0, 15), 'm', 0, NPC_REGULAR), + 7013: (-1, lnames[7013], ('bsl', 'ms', 'm', 'f', 20, 0, 20, 20, 3, 4, 0, 0, 5, 18), 'f', 0, NPC_REGULAR), + 7014: (-1, lnames[7014], ('bll', 'ss', 's', 'm', 11, 0, 11, 11, 3, 6, 0, 0, 1, 2), 'm', 0, NPC_REGULAR), + 7015: (-1, lnames[7015], ('ssl', 'sd', 'l', 'f', 13, 0, 13, 13, 1, 2, 0, 0, 0, 10), 'f', 0, NPC_REGULAR), + 7016: (-1, lnames[7016], ('hll', 'ls', 'l', 'm', 8, 0, 8, 8, 1, 3, 0, 0, 1, 16), 'm', 0, NPC_REGULAR), + 7017: (-1, lnames[7017], ('dsl', 'ms', 's', 'm', 5, 0, 5, 5, 1, 0, 0, 0, 0, 4), 'm', 0, NPC_REGULAR), + 7018: (-1, lnames[7018], ('pls', 'ls', 's', 'f', 14, 0, 14, 14, 0, 11, 0, 0, 5, 9), 'f', 0, NPC_REGULAR), + 7019: (-1, lnames[7019], ('bsl', 'ls', 'l', 'm', 12, 0, 12, 12, 1, 10, 0, 0, 1, 13), 'm', 0, NPC_REGULAR), + 7020: (-1, lnames[7020], ('sss', 'ms', 'l', 'm', 2, 0, 2, 2, 0, 4, 0, 0, 0, 6), 'm', 0, NPC_REGULAR), + 7021: (-1, lnames[7021], ('fsl', 'ls', 'm', 'm', 17, 0, 17, 17, 4, 4, 0, 0, 0, 10), 'm', 0, NPC_REGULAR), + 7022: (-1, lnames[7022], ('mss', 'sd', 's', 'f', 24, 0, 24, 24, 3, 1, 0, 0, 0, 13), 'f', 0, NPC_REGULAR), + 7023: (-1, lnames[7023], ('pss', 'sd', 'l', 'f', 9, 0, 9, 9, 0, 8, 0, 0, 11, 0), 'f', 0, NPC_REGULAR), + 10001: (10000, lnames[10001], 'r', 'f', 0, NPC_LAFF_RESTOCK), + 11001: (11000, lnames[11001], 'r', 'm', 0, NPC_LAFF_RESTOCK), + 12001: (12000, lnames[12001], 'r', 'm', 0, NPC_LAFF_RESTOCK), + 13001: (13000, lnames[13001], 'r', 'f', 0, NPC_LAFF_RESTOCK) +} if config.GetBool('want-new-toonhall', 1): - NPCToonDict[2001] = (2513, - lnames[2001], - ('dss', - 'ms', - 'm', - 'm', - 17, - 0, - 17, - 17, - 3, - 3, - 3, - 3, - 7, - 2), - 'm', - 1, - NPC_FLIPPYTOONHALL) + NPCToonDict[2001] = (2513, lnames[2001], ('dss', 'ms', 'm', 'm', 17, 0, 17, 17, 3, 3, 3, 3, 7, 2), 'm', 1, NPC_FLIPPYTOONHALL) else: - NPCToonDict[2001] = (2513, - lnames[2001], - ('dss', - 'ms', - 'm', - 'm', - 17, - 0, - 17, - 17, - 3, - 3, - 3, - 3, - 7, - 2), - 'm', - 1, - NPC_REGULAR) + NPCToonDict[2001] = (2513, lnames[2001], ('dss', 'ms', 'm', 'm', 17, 0, 17, 17, 3, 3, 3, 3, 7, 2), 'm', 1, NPC_REGULAR) + BlockerPositions = {TTLocalizer.Flippy: (Point3(207.4, 18.81, -0.475), 90.0)} LaffRestockPositions = {lnames[11001]: ((-27.0, -170.0, -19.6), 215.0), lnames[12001]: ((361.9, -394.4, -23.5), 120.0), @@ -11954,172 +909,56 @@ def getBuildingTitle(zoneId): return TTLocalizer.zone2TitleDict.get(zoneId, 'Toon Building')[0] -HQnpcFriends = {2001: (ToontownBattleGlobals.HEAL_TRACK, - 5, - ToontownGlobals.MaxHpLimit, - 5), - 2132: (ToontownBattleGlobals.HEAL_TRACK, - 5, - 70, - 4), - 2121: (ToontownBattleGlobals.HEAL_TRACK, - 5, - 45, - 3), - 2011: (ToontownBattleGlobals.TRAP_TRACK, - 4, - 180, - 5), - 3007: (ToontownBattleGlobals.TRAP_TRACK, - 4, - 70, - 4), - 1001: (ToontownBattleGlobals.TRAP_TRACK, - 4, - 50, - 3), - 3112: (ToontownBattleGlobals.LURE_TRACK, - 5, - 0, - 5), - 1323: (ToontownBattleGlobals.LURE_TRACK, - 5, - 0, - 3), - 2308: (ToontownBattleGlobals.LURE_TRACK, - 5, - 0, - 3), - 4119: (ToontownBattleGlobals.SOUND_TRACK, - 5, - 80, - 5), - 4219: (ToontownBattleGlobals.SOUND_TRACK, - 5, - 50, - 4), - 4115: (ToontownBattleGlobals.SOUND_TRACK, - 5, - 40, - 3), - 1116: (ToontownBattleGlobals.DROP_TRACK, - 5, - 170, - 5), - 2311: (ToontownBattleGlobals.DROP_TRACK, - 5, - 100, - 4), - 4140: (ToontownBattleGlobals.DROP_TRACK, - 5, - 60, - 3), - 3137: (ToontownBattleGlobals.NPC_COGS_MISS, - 0, - 0, - 4), - 4327: (ToontownBattleGlobals.NPC_COGS_MISS, - 0, - 0, - 4), - 4230: (ToontownBattleGlobals.NPC_COGS_MISS, - 0, - 0, - 4), - 3135: (ToontownBattleGlobals.NPC_TOONS_HIT, - 0, - 0, - 4), - 2208: (ToontownBattleGlobals.NPC_TOONS_HIT, - 0, - 0, - 4), - 5124: (ToontownBattleGlobals.NPC_TOONS_HIT, - 0, - 0, - 4), - 2003: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - -1, - 0, - 5), - 2126: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - ToontownBattleGlobals.HEAL_TRACK, - 0, - 3), - 4007: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - ToontownBattleGlobals.TRAP_TRACK, - 0, - 3), - 1315: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - ToontownBattleGlobals.LURE_TRACK, - 0, - 3), - 5207: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - ToontownBattleGlobals.SQUIRT_TRACK, - 0, - 3), - 3129: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - ToontownBattleGlobals.THROW_TRACK, - 0, - 3), - 4125: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - ToontownBattleGlobals.SOUND_TRACK, - 0, - 3), - 1329: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, - ToontownBattleGlobals.DROP_TRACK, - 0, - 3)} -FOnpcFriends = {7012: (ToontownBattleGlobals.HEAL_TRACK, - 3, - 10, - 0), - 7013: (ToontownBattleGlobals.HEAL_TRACK, - 3, - 20, - 1), - 7014: (ToontownBattleGlobals.HEAL_TRACK, - 3, - 30, - 2), - 7015: (ToontownBattleGlobals.DROP_TRACK, - 1, - 20, - 0), - 7016: (ToontownBattleGlobals.DROP_TRACK, - 2, - 35, - 1), - 7017: (ToontownBattleGlobals.DROP_TRACK, - 3, - 50, - 2), - 7018: (ToontownBattleGlobals.SOUND_TRACK, - 1, - 10, - 0), - 7019: (ToontownBattleGlobals.SOUND_TRACK, - 3, - 20, - 1), - 7020: (ToontownBattleGlobals.SOUND_TRACK, - 4, - 30, - 2), - 7021: (ToontownBattleGlobals.LURE_TRACK, - 1, - 0, - 0), - 7022: (ToontownBattleGlobals.LURE_TRACK, - 1, - 0, - 1), - 7023: (ToontownBattleGlobals.LURE_TRACK, - 3, - 0, - 2)} + +HQnpcFriends = { + 2001: (ToontownBattleGlobals.HEAL_TRACK, 5, ToontownGlobals.MaxHpLimit, 5), + 2132: (ToontownBattleGlobals.HEAL_TRACK, 5, 70, 4), + 2121: (ToontownBattleGlobals.HEAL_TRACK, 5, 45, 3), + 2011: (ToontownBattleGlobals.TRAP_TRACK, 4, 180, 5), + 3007: (ToontownBattleGlobals.TRAP_TRACK, 4, 70, 4), + 1001: (ToontownBattleGlobals.TRAP_TRACK, 4, 50, 3), + 3112: (ToontownBattleGlobals.LURE_TRACK, 5, 0, 5), + 1323: (ToontownBattleGlobals.LURE_TRACK, 5, 0, 3), + 2308: (ToontownBattleGlobals.LURE_TRACK, 5, 0, 3), + 4119: (ToontownBattleGlobals.SOUND_TRACK, 5, 80, 5), + 4219: (ToontownBattleGlobals.SOUND_TRACK, 5, 50, 4), + 4115: (ToontownBattleGlobals.SOUND_TRACK, 5, 40, 3), + 1116: (ToontownBattleGlobals.DROP_TRACK, 5, 170, 5), + 2311: (ToontownBattleGlobals.DROP_TRACK, 5, 100, 4), + 4140: (ToontownBattleGlobals.DROP_TRACK, 5, 60, 3), + 3137: (ToontownBattleGlobals.NPC_COGS_MISS, 0, 0, 4), + 4327: (ToontownBattleGlobals.NPC_COGS_MISS, 0, 0, 4), + 4230: (ToontownBattleGlobals.NPC_COGS_MISS, 0, 0, 4), + 3135: (ToontownBattleGlobals.NPC_TOONS_HIT, 0, 0, 4), + 2208: (ToontownBattleGlobals.NPC_TOONS_HIT, 0, 0, 4), + 5124: (ToontownBattleGlobals.NPC_TOONS_HIT, 0, 0, 4), + 2003: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, -1, 0, 5), + 2126: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, ToontownBattleGlobals.HEAL_TRACK, 0, 3), + 4007: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, ToontownBattleGlobals.TRAP_TRACK, 0, 3), + 1315: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, ToontownBattleGlobals.LURE_TRACK, 0, 3), + 5207: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, ToontownBattleGlobals.SQUIRT_TRACK, 0, 3), + 3129: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, ToontownBattleGlobals.THROW_TRACK, 0, 3), + 4125: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, ToontownBattleGlobals.SOUND_TRACK, 0, 3), + 1329: (ToontownBattleGlobals.NPC_RESTOCK_GAGS, ToontownBattleGlobals.DROP_TRACK, 0, 3) +} + +FOnpcFriends = { + 7012: (ToontownBattleGlobals.HEAL_TRACK, 3, 10, 0), + 7013: (ToontownBattleGlobals.HEAL_TRACK, 3, 20, 1), + 7014: (ToontownBattleGlobals.HEAL_TRACK, 3, 30, 2), + 7015: (ToontownBattleGlobals.DROP_TRACK, 1, 20, 0), + 7016: (ToontownBattleGlobals.DROP_TRACK, 2, 35, 1), + 7017: (ToontownBattleGlobals.DROP_TRACK, 3, 50, 2), + 7018: (ToontownBattleGlobals.SOUND_TRACK, 1, 10, 0), + 7019: (ToontownBattleGlobals.SOUND_TRACK, 3, 20, 1), + 7020: (ToontownBattleGlobals.SOUND_TRACK, 4, 30, 2), + 7021: (ToontownBattleGlobals.LURE_TRACK, 1, 0, 0), + 7022: (ToontownBattleGlobals.LURE_TRACK, 1, 0, 1), + 7023: (ToontownBattleGlobals.LURE_TRACK, 3, 0, 2) +} disabledSosCards = ConfigVariableList('disable-sos-card') + for npcId in disabledSosCards: npcId = int(npcId) if npcId in HQnpcFriends: @@ -12133,18 +972,13 @@ npcFriends.update(FOnpcFriends) def getNPCName(npcId): if npcId in NPCToonDict: return NPCToonDict[npcId][1] - return None - def npcFriendsMinMaxStars(minStars, maxStars): - return [ id for id in npcFriends.keys() if getNPCTrackLevelHpRarity(id)[3] >= minStars and getNPCTrackLevelHpRarity(id)[3] <= maxStars ] - + return [id for id in npcFriends.keys() if getNPCTrackLevelHpRarity(id)[3] >= minStars and getNPCTrackLevelHpRarity(id)[3] <= maxStars] def getNPCTrack(npcId): if npcId in npcFriends: return npcFriends[npcId][0] - return None - def getNPCTrackHp(npcId): if npcId in npcFriends: @@ -12152,14 +986,12 @@ def getNPCTrackHp(npcId): return (track, hp) return (None, None) - def getNPCTrackLevelHp(npcId): if npcId in npcFriends: track, level, hp, rarity = npcFriends[npcId] return (track, level, hp) return (None, None, None) - def getNPCTrackLevelHpRarity(npcId): if npcId in npcFriends: return npcFriends[npcId] From dc83a72cc4f5db8b322ce2725b9e5b72b2a1c37a Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 13:54:13 +0300 Subject: [PATCH 28/38] Widescreen whisper frame --- toontown/chat/ToontownChatManager.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/toontown/chat/ToontownChatManager.py b/toontown/chat/ToontownChatManager.py index 4c4675c3..8899697a 100755 --- a/toontown/chat/ToontownChatManager.py +++ b/toontown/chat/ToontownChatManager.py @@ -20,17 +20,17 @@ class ToontownChatManager(ChatManager.ChatManager): self.openScSfx.setVolume(0.6) self.scButton = DirectButton(image=(gui.find('**/ChtBx_ChtBtn_UP'), gui.find('**/ChtBx_ChtBtn_DN'), gui.find('**/ChtBx_ChtBtn_RLVR')), pos=TTLocalizer.TCMscButtonPos, parent=base.a2dTopLeft, scale=1.179, relief=None, image_color=Vec4(0.75, 1, 0.6, 1), text=('', OTPLocalizer.GlobalSpeedChatName, OTPLocalizer.GlobalSpeedChatName), text_scale=TTLocalizer.TCMscButton, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, sortOrder=DGG.FOREGROUND_SORT_INDEX, command=self.__scButtonPressed, clickSound=self.openScSfx) self.scButton.hide() - self.whisperFrame = DirectFrame(parent=base.a2dTopLeft, relief=None, image=DGG.getDefaultDialogGeom(), image_scale=(0.45, 0.45, 0.45), image_color=OTPGlobals.GlobalDialogColor, pos=(1.25, 0, -0.269), text=OTPLocalizer.ChatManagerWhisperTo, text_wordwrap=7.0, text_scale=TTLocalizer.TCMwhisperFrame, text_fg=Vec4(0, 0, 0, 1), text_pos=(0, 0.14), textMayChange=1, sortOrder=DGG.FOREGROUND_SORT_INDEX) + self.whisperFrame = DirectFrame(parent=base.a2dTopLeft, relief=None, image=DGG.getDefaultDialogGeom(), image_scale=(0.77, 0.70, 0.20), image_color=OTPGlobals.GlobalDialogColor, pos=(0.40, 0, -0.105), text=OTPLocalizer.ChatManagerWhisperTo, text_wordwrap=6.5, text_scale=TTLocalizer.TCMwhisperFrame, text_fg=Vec4(0, 0, 0, 1), text_pos=(0.18, 0.01), textMayChange=1, sortOrder=DGG.FOREGROUND_SORT_INDEX) self.whisperFrame.hide() - self.whisperButton = DirectButton(parent=self.whisperFrame, image=(gui.find('**/ChtBx_ChtBtn_UP'), gui.find('**/ChtBx_ChtBtn_DN'), gui.find('**/ChtBx_ChtBtn_RLVR')), pos=(-0.125, 0, -0.1), scale=1.179, relief=None, image_color=Vec4(1, 1, 1, 1), text=('', + self.whisperButton = DirectButton(parent=self.whisperFrame, image=(gui.find('**/ChtBx_ChtBtn_UP'), gui.find('**/ChtBx_ChtBtn_DN'), gui.find('**/ChtBx_ChtBtn_RLVR')), pos=(-0.33, 0, 0.033), scale=1.179, relief=None, image_color=Vec4(1, 1, 1, 1), text=('', OTPLocalizer.ChatManagerChat, OTPLocalizer.ChatManagerChat, ''), image3_color=Vec4(0.6, 0.6, 0.6, 0.6), text_scale=TTLocalizer.TCMwhisperButton, text_fg=(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.__whisperButtonPressed) - self.whisperScButton = DirectButton(parent=self.whisperFrame, image=(gui.find('**/ChtBx_ChtBtn_UP'), gui.find('**/ChtBx_ChtBtn_DN'), gui.find('**/ChtBx_ChtBtn_RLVR')), pos=(0.0, 0, -0.1), scale=1.179, relief=None, image_color=Vec4(0.75, 1, 0.6, 1), text=('', + self.whisperScButton = DirectButton(parent=self.whisperFrame, image=(gui.find('**/ChtBx_ChtBtn_UP'), gui.find('**/ChtBx_ChtBtn_DN'), gui.find('**/ChtBx_ChtBtn_RLVR')), pos=(-0.195, 0, 0.033), scale=1.179, relief=None, image_color=Vec4(0.75, 1, 0.6, 1), text=('', OTPLocalizer.GlobalSpeedChatName, OTPLocalizer.GlobalSpeedChatName, ''), image3_color=Vec4(0.6, 0.6, 0.6, 0.6), text_scale=TTLocalizer.TCMwhisperScButton, text_fg=(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.__whisperScButtonPressed) - self.whisperCancelButton = DirectButton(parent=self.whisperFrame, image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr')), pos=(0.125, 0, -0.1), scale=1.179, relief=None, text=('', OTPLocalizer.ChatManagerCancel, OTPLocalizer.ChatManagerCancel), text_scale=0.05, text_fg=(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.__whisperCancelPressed) + self.whisperCancelButton = DirectButton(parent=self.whisperFrame, image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr')), pos=(-0.06, 0, 0.033), scale=1.179, relief=None, text=('', OTPLocalizer.ChatManagerCancel, OTPLocalizer.ChatManagerCancel), text_scale=0.05, text_fg=(0, 0, 0, 1), text_pos=(0, -0.09), textMayChange=0, command=self.__whisperCancelPressed) gui.removeNode() ChatManager.ChatManager.__init__(self, cr, localAvatar) self.chatInputSpeedChat = TTChatInputSpeedChat(self) @@ -45,7 +45,6 @@ class ToontownChatManager(ChatManager.ChatManager): self.chatInputWhiteList.setPos(self.speedChatPlusPos) self.chatInputWhiteList.reparentTo(base.a2dTopLeft) self.chatInputWhiteList.desc = 'chatInputWhiteList' - return def delete(self): ChatManager.ChatManager.delete(self) @@ -147,7 +146,6 @@ class ToontownChatManager(ChatManager.ChatManager): self.fsm.request('mainMenu') return result = ChatManager.ChatManager.enterWhisperChat(self, avatarName, avatarId) - self.chatInputNormal.reparentTo(base.a2dTopCenter) self.chatInputNormal.setPos(self.whisperPos) if result == None: self.notify.warning('something went wrong in enterWhisperChat, falling back to main menu') From 0976a80befa070348f7ce6019eb0726553ffc371 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 13:58:38 +0300 Subject: [PATCH 29/38] Carry 3 TNTs and 7 trapdoors --- toontown/toonbase/ToontownBattleGlobals.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toontown/toonbase/ToontownBattleGlobals.py b/toontown/toonbase/ToontownBattleGlobals.py index c8552b78..74310f35 100755 --- a/toontown/toonbase/ToontownBattleGlobals.py +++ b/toontown/toonbase/ToontownBattleGlobals.py @@ -177,7 +177,7 @@ CarryLimits = (((10, (15, 15, 10, - 5, + 7, 3, 0, 0), @@ -185,15 +185,15 @@ CarryLimits = (((10, 15, 15, 10, - 5, - 2, + 7, + 3, 0), (20, 15, 15, 10, 5, - 2, + 3, 1)), ((10, 0, From 1d1e96d055fbe24ae732e4ec01c198adc23d1a26 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 14:03:08 +0300 Subject: [PATCH 30/38] Fix cast member crash --- toontown/toon/ToonAvatarPanel.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/toontown/toon/ToonAvatarPanel.py b/toontown/toon/ToonAvatarPanel.py index 50def5d4..19416132 100755 --- a/toontown/toon/ToonAvatarPanel.py +++ b/toontown/toon/ToonAvatarPanel.py @@ -526,8 +526,14 @@ class ToonAvatarPanel(AvatarPanelBase.AvatarPanelBase): def __handleCastDialog(self): self.cleanupDialog() base.cr.playGame.getPlace().setState('stopped') - self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.AvatarPanelCastInfo % self.avatar.getName(), text_wordwrap=20, command=self.cleanupDialogAndWalk) + self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.AvatarPanelCastInfo % self.avatar.getName(), text_wordwrap=20, command=self.__cleanupDialogAndWalk) self.dialog.show() + + def __cleanupDialogAndWalk(self, extra=None): + if self.dialog: + self.dialog.destroy() + self.dialog = None + base.cr.playGame.getPlace().fsm.request('walk') def __makeBoardingGui(self): self.confirmKickOutDialog = None From fc0a24904cfd59669deb3d03f37df568a20811e0 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 14:47:51 +0300 Subject: [PATCH 31/38] Tutorial chat bubble click fix + arrows fix --- toontown/quest/BlinkingArrows.py | 5 ++ toontown/quest/QuestParser.py | 3 ++ toontown/quest/QuestScripts.py | 91 +++++++++++++++++++++++--------- 3 files changed, 74 insertions(+), 25 deletions(-) diff --git a/toontown/quest/BlinkingArrows.py b/toontown/quest/BlinkingArrows.py index a0d225cd..3d6aa06b 100755 --- a/toontown/quest/BlinkingArrows.py +++ b/toontown/quest/BlinkingArrows.py @@ -38,6 +38,11 @@ class BlinkingArrows: self.stopArrowsFlashing() self.arrow1.reparentTo(hidden) self.arrow2.reparentTo(hidden) + + def reparentTo(self, parent): + self.parent = parent + self.arrow1.reparentTo(self.parent) + self.arrow2.reparentTo(self.parent) def startArrowsFlashing(self): onColor = Vec4(1, 1, 1, 1) diff --git a/toontown/quest/QuestParser.py b/toontown/quest/QuestParser.py index 6cb24c87..db41baba 100755 --- a/toontown/quest/QuestParser.py +++ b/toontown/quest/QuestParser.py @@ -21,6 +21,9 @@ def init(): 'camera': camera, 'hidden': hidden, 'aspect2d': aspect2d, + 'topLeft': base.a2dTopLeft, + 'bottomLeft': base.a2dBottomLeft, + 'bottomRight': base.a2dBottomRight, 'localToon': base.localAvatar, 'laffMeter': base.localAvatar.laffMeter, 'inventory': base.localAvatar.inventory, diff --git a/toontown/quest/QuestScripts.py b/toontown/quest/QuestScripts.py index 9a41a5a3..18d1b2da 100755 --- a/toontown/quest/QuestScripts.py +++ b/toontown/quest/QuestScripts.py @@ -11,9 +11,8 @@ POSHPRSCALE toonBuilding -1.05 7 0 0 0 0 1.875 1.875 1.875 POSHPRSCALE cogBuilding -1.05 7 0 0 0 0 1.875 1.875 1.875 POSHPRSCALE squirt1 -1.05 7 0 0 0 0 1.875 1.875 1.875 POSHPRSCALE squirt2 -1.05 7 0 0 0 0 1.875 1.875 1.875 -REPARENTTO camera npc -POS camera -2.2 5.2 3.3 -HPR camera 215 5 0 +WRTREPARENTTO camera npc +LERP_POSHPRSCALE camera 2.8 0.0 3.5 35 5 0 1 1 1 1.5 WRTREPARENTTO camera localToon PLAY_ANIM npc "right-hand-start" 1 WAIT 1 @@ -46,11 +45,13 @@ WAIT 0.5 REPARENTTO squirt2 hidden OBSCURE_LAFFMETER 0 SHOW laffMeter -POS laffMeter 0 0 0 -SCALE laffMeter 0.075 0.075 0.075 -LERP_POS laffMeter 1.7 0 0.87 1 +POS laffMeter 0.153 0.0 0.13 +SCALE laffMeter 0.0 0.0 0.0 +WRTREPARENTTO laffMeter aspect2d +LERP_POS laffMeter -0.25 0 -0.15 1 LERP_SCALE laffMeter 0.2 0.2 0.2 0.6 WAIT 1.0833 +LOOP_ANIM npc "right-hand" LOCAL_CHAT_CONFIRM npc QuestScript101_8 "CFReversed" LOCAL_CHAT_CONFIRM npc QuestScript101_9 "CFReversed" FUNCTION npc "sadEyes" @@ -90,9 +91,10 @@ LOCAL_CHAT_CONFIRM npc QuestScript101_10 "CFReversed" FUNCTION npc "normalEyes" FUNCTION npc "blinkEyes" LAFFMETER 15 15 +WRTREPARENTTO laffMeter bottomLeft WAIT 0.5 -LERP_POS laffMeter 0.15 0.15 0.15 1 -LERP_SCALE laffMeter 0.085 0.085 0.085 0.6 +LERP_POS laffMeter 0.153 0.0 0.13 0.6 +LERP_SCALE laffMeter 0.075 0.075 0.075 0.6 PLAY_ANIM npc "right-hand-start" -2 WAIT 1.0625 LOOP_ANIM npc "neutral" @@ -125,20 +127,30 @@ UPON_TIMEOUT FUNCTION squirt1 "removeNode" UPON_TIMEOUT FUNCTION squirt2 "removeNode" UPON_TIMEOUT LOOP_ANIM npc "neutral" UPON_TIMEOUT SHOW laffMeter -UPON_TIMEOUT POS laffMeter 0.15 0.15 0.15 -UPON_TIMEOUT SCALE laffMeter 0.085 0.085 0.085 +UPON_TIMEOUT REPARENTTO laffMeter bottomLeft +UPON_TIMEOUT POS laffMeter 0.15 0 0.13 +UPON_TIMEOUT SCALE laffMeter 0.075 0.075 0.075 POS localToon 0.776 14.6 0 HPR localToon 47.5 0 0 FINISH_QUEST_MOVIE ID quest_incomplete_110 -DEBUG "quest assign 110" LOCAL_CHAT_CONFIRM npc QuestScript110_1 OBSCURE_BOOK 0 +REPARENTTO bookOpenButton aspect2d SHOW bookOpenButton +POS bookOpenButton 0 0 0 +SCALE bookOpenButton 0.5 0.5 0.5 +LERP_COLOR_SCALE bookOpenButton 1 1 1 0 1 1 1 1 0.5 +WRTREPARENTTO bookOpenButton bottomRight +WAIT 1.5 +LERP_POS bookOpenButton -0.158 0 0.17 1 +LERP_SCALE bookOpenButton 0.305 0.305 0.305 1 +WAIT 1 LOCAL_CHAT_CONFIRM npc QuestScript110_2 -ARROWS_ON 1.364477 -0.89 0 1.664477 -0.64 90 +REPARENTTO arrows bottomRight +ARROWS_ON -0.41 0.11 0 -0.11 0.36 90 LOCAL_CHAT_PERSIST npc QuestScript110_3 WAIT_EVENT "enterStickerBook" ARROWS_OFF @@ -149,6 +161,7 @@ CLEAR_CHAT npc WAIT 0.5 TOON_HEAD npc -0.2 -0.45 1 LOCAL_CHAT_CONFIRM npc QuestScript110_4 +REPARENTTO arrows aspect2d ARROWS_ON 0.85 -0.75 -90 0.85 -0.75 -90 SHOW bookNextArrow LOCAL_CHAT_PERSIST npc QuestScript110_5 @@ -171,7 +184,8 @@ LOCAL_CHAT_CONFIRM npc QuestScript110_8 LOCAL_CHAT_CONFIRM npc QuestScript110_9 LOCAL_CHAT_PERSIST npc QuestScript110_10 ENABLE_CLOSE_BOOK -ARROWS_ON 1.364477 -0.89 0 1.664477 -0.64 90 +REPARENTTO arrows bottomRight +ARROWS_ON -0.41 0.11 0 -0.11 0.36 90 WAIT_EVENT "exitStickerBook" ARROWS_OFF TOON_HEAD npc 0 0 0 @@ -180,8 +194,11 @@ HIDE bookOpenButton LOCAL_CHAT_CONFIRM npc QuestScript110_11 1 UPON_TIMEOUT OBSCURE_BOOK 0 UPON_TIMEOUT ARROWS_OFF +UPON_TIMEOUT REPARENTTO arrows aspect2d UPON_TIMEOUT HIDE_BOOK UPON_TIMEOUT COLOR_SCALE bookOpenButton 1 1 1 1 +UPON_TIMEOUT POS bookOpenButton -0.158 0 0.17 +UPON_TIMEOUT SCALE bookOpenButton 0.305 0.305 0.305 UPON_TIMEOUT TOON_HEAD npc 0 0 0 UPON_TIMEOUT SHOW bookOpenButton FINISH_QUEST_MOVIE @@ -193,9 +210,9 @@ FUNCTION npc "stopLookAround" POS camera 0.0 6.0 4.0 HPR camera 180.0 0.0 0.0 LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_1 -WAIT 0.8 +WAIT 0.8 LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_2 -WAIT 0.8 +WAIT 0.8 POS camera -5.0 -9.0 6.0 HPR camera -25.0 -10.0 0.0 POS localToon 203.8 18.64 -0.475 @@ -203,9 +220,18 @@ HPR localToon -90.0 0.0 0.0 SHOW localToon LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_3 OBSCURE_CHAT 1 0 +REPARENTTO chatScButton aspect2d SHOW chatScButton -WAIT 0.6 -ARROWS_ON -1.3644 0.91 180 -1.5644 0.74 -90 +POS chatScButton -0.3 0 -0.1 +SCALE chatScButton 2.0 2.0 2.0 +LERP_COLOR_SCALE chatScButton 1 1 1 0 1 1 1 1 0.5 +WRTREPARENTTO chatScButton topLeft +WAIT 0.5 +LERP_POS chatScButton 0.204 0 -0.072 0.6 +LERP_SCALE chatScButton 1.179 1.179 1.179 0.6 +WAIT 0.6 +REPARENTTO arrows topLeft +ARROWS_ON 0.41 -0.09 180 0.21 -0.26 -90 LOCAL_CHAT_PERSIST npc QuestScriptTutorialBlocker_4 WAIT_EVENT "enterSpeedChat" ARROWS_OFF @@ -218,16 +244,24 @@ REPARENTTO camera localToon LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_5 "CFReversed" LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_6 "CFReversed" OBSCURE_CHAT 0 0 +REPARENTTO chatNormalButton aspect2d SHOW chatNormalButton -WAIT 0.6 +POS chatNormalButton -0.3 0 -0.1 +SCALE chatNormalButton 2.0 2.0 2.0 +LERP_COLOR_SCALE chatNormalButton 1 1 1 0 1 1 1 1 0.5 +WAIT 0.5 +WRTREPARENTTO chatNormalButton topLeft +LERP_POS chatNormalButton 0.068 0 -0.072 0.6 +LERP_SCALE chatNormalButton 1.179 1.179 1.179 0.6 +WAIT 0.6 LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_7 "CFReversed" LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_8 1 "CFReversed" LOOP_ANIM npc "walk" LERP_HPR npc 270 0 0 0.5 WAIT 0.5 LOOP_ANIM npc "run" -LERP_POS npc 217.4 18.81 -0.475 0.75 -LERP_HPR npc 240 0 0 0.75 +LERP_POS npc 217.4 18.81 -0.475 0.75 +LERP_HPR npc 240 0 0 0.75 WAIT 0.75 LERP_POS npc 222.4 15.0 -0.475 0.35 LERP_HPR npc 180 0 0 0.35 @@ -237,7 +271,12 @@ WAIT 0.75 REPARENTTO npc hidden FREE_LOCALTOON UPON_TIMEOUT ARROWS_OFF -UPON_TIMEOUT OBSCURE_CHAT 0 0 +UPON_TIMEOUT REPARENTTO arrows aspect2d +UPON_TIMEOUT POS chatScButton 0.204 0 -0.072 +UPON_TIMEOUT SCALE chatScButton 1.179 1.179 1.179 +UPON_TIMEOUT POS chatNormalButton 0.068 0 -0.072 +UPON_TIMEOUT SCALE chatNormalButton 1.179 1.179 1.179 +UPON_TIMEOUT OBSCURE_CHAT 0 0 UPON_TIMEOUT REPARENTTO camera localToon FINISH_QUEST_MOVIE @@ -250,13 +289,15 @@ WAIT 0.1 LOCAL_CHAT_CONFIRM npc QuestScriptGagShop_1 LERP_POS npcToonHead -0.64 0 -0.74 0.7 LERP_SCALE npcToonHead 0.82 0.82 0.82 0.7 -LERP_COLOR_SCALE purchaseBg 1 1 1 1 0.6 0.6 0.6 1 0.7 +LERP_COLOR_SCALE purchaseBg 1 1 1 1 0.6 0.6 0.6 1 0.7 WAIT 0.7 SHOW inventory LOCAL_CHAT_CONFIRM npc QuestScriptGagShop_1a +ARROWS_ON -0.19 0.04 180 -0.4 0.26 90 LOCAL_CHAT_PERSIST npc QuestScriptGagShop_3 SEND_EVENT "enableGagPanel" WAIT_EVENT "inventory-selection" +ARROWS_OFF CLEAR_CHAT npc WAIT 0.5 LOCAL_CHAT_CONFIRM npc QuestScriptGagShop_4 @@ -299,6 +340,7 @@ LERP_COLOR_SCALE purchaseBg 0.6 0.6 0.6 1 1 1 1 1 0.5 WAIT 0.5 SEND_EVENT "enableBackToPlayground" UPON_TIMEOUT TOON_HEAD npc 0 0 0 +UPON_TIMEOUT ARROWS_OFF UPON_TIMEOUT SHOW inventory UPON_TIMEOUT SEND_EVENT "enableGagPanel" UPON_TIMEOUT SEND_EVENT "enableBackToPlayground" @@ -320,10 +362,9 @@ CHAT_CONFIRM npc QuestScript145_2 1 UPON_TIMEOUT FUNCTION frame "removeNode" FINISH_QUEST_MOVIE - ID quest_incomplete_150 CHAT_CONFIRM npc QuestScript150_1 -ARROWS_ON 1.65 0.51 -120 1.65 0.51 -120 +ARROWS_ON 1.05 0.51 -120 1.05 0.51 -120 SHOW_FRIENDS_LIST CHAT_CONFIRM npc QuestScript150_2 ARROWS_OFF @@ -334,4 +375,4 @@ CHAT_CONFIRM npc QuestScript150_4 1 UPON_TIMEOUT HIDE_FRIENDS_LIST UPON_TIMEOUT ARROWS_OFF FINISH_QUEST_MOVIE -''' +''' \ No newline at end of file From a3822b50996f051159595c924e500ea9f9943aa1 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 15:41:18 +0300 Subject: [PATCH 32/38] Proper resistance toon DNAs + scarecrow fix in CFO battle --- toontown/suit/DistributedBossbotBoss.py | 15 ++------------- toontown/suit/DistributedCashbotBoss.py | 15 ++------------- toontown/toon/NPCToons.py | 2 ++ toontown/toonbase/TTLocalizerEnglish.py | 4 ++-- toontown/toonbase/ToontownBattleGlobals.py | 2 +- 5 files changed, 9 insertions(+), 29 deletions(-) diff --git a/toontown/suit/DistributedBossbotBoss.py b/toontown/suit/DistributedBossbotBoss.py index 132fed89..d9ca6b89 100755 --- a/toontown/suit/DistributedBossbotBoss.py +++ b/toontown/suit/DistributedBossbotBoss.py @@ -18,8 +18,7 @@ from toontown.effects import DustCloud from toontown.suit import DistributedBossCog from toontown.suit import Suit from toontown.suit import SuitDNA -from toontown.toon import Toon -from toontown.toon import ToonDNA +from toontown.toon import Toon, NPCToons from toontown.toonbase import TTLocalizer from toontown.toonbase import ToontownGlobals from toontown.toonbase import ToontownTimer @@ -197,17 +196,7 @@ class DistributedBossbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM): def __makeResistanceToon(self): if self.resistanceToon: return - npc = Toon.Toon() - npc.setName(TTLocalizer.BossbotResistanceToonName) - npc.setPickable(0) - npc.setPlayerType(NametagGroup.CCNonPlayer) - dna = ToonDNA.ToonDNA() - dna.newToonRandom(11237, 'm', 1) - dna.head = 'sls' - npc.setDNAString(dna.makeNetString()) - npc.animFSM.request('neutral') - npc.loop('neutral') - self.resistanceToon = npc + self.resistanceToon = NPCToons.createLocalNPC(10002) self.resistanceToon.setPosHpr(*ToontownGlobals.BossbotRTIntroStartPosHpr) state = random.getstate() random.seed(self.doId) diff --git a/toontown/suit/DistributedCashbotBoss.py b/toontown/suit/DistributedCashbotBoss.py index 986214c9..45aa8c19 100755 --- a/toontown/suit/DistributedCashbotBoss.py +++ b/toontown/suit/DistributedCashbotBoss.py @@ -19,8 +19,7 @@ from toontown.building import ElevatorUtils from toontown.chat import ResistanceChat from toontown.coghq import CogDisguiseGlobals from toontown.distributed import DelayDelete -from toontown.toon import Toon -from toontown.toon import ToonDNA +from toontown.toon import Toon, NPCToons from toontown.toonbase import TTLocalizer from toontown.toonbase import ToontownGlobals from otp.nametag import NametagGroup @@ -104,16 +103,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM): def __makeResistanceToon(self): if self.resistanceToon: return - npc = Toon.Toon() - npc.setName(TTLocalizer.ResistanceToonName) - npc.setPickable(0) - npc.setPlayerType(NametagGroup.CCNonPlayer) - dna = ToonDNA.ToonDNA() - dna.newToonRandom(11237, 'f', 1) - dna.head = 'pls' - npc.setDNAString(dna.makeNetString()) - npc.animFSM.request('neutral') - self.resistanceToon = npc + self.resistanceToon = NPCToons.createLocalNPC(12002) self.resistanceToon.setPosHpr(*ToontownGlobals.CashbotRTBattleOneStartPosHpr) state = random.getstate() random.seed(self.doId) @@ -700,7 +690,6 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM): self.endVault.unstash() self.evWalls.stash() self.midVault.unstash() - self.__showResistanceToon(True) base.playMusic(self.stingMusic, looping=1, volume=0.9) DistributedBossCog.DistributedBossCog.enterIntroduction(self) diff --git a/toontown/toon/NPCToons.py b/toontown/toon/NPCToons.py index 1074b855..db772e0d 100755 --- a/toontown/toon/NPCToons.py +++ b/toontown/toon/NPCToons.py @@ -860,8 +860,10 @@ NPCToonDict = { 7022: (-1, lnames[7022], ('mss', 'sd', 's', 'f', 24, 0, 24, 24, 3, 1, 0, 0, 0, 13), 'f', 0, NPC_REGULAR), 7023: (-1, lnames[7023], ('pss', 'sd', 'l', 'f', 9, 0, 9, 9, 0, 8, 0, 0, 11, 0), 'f', 0, NPC_REGULAR), 10001: (10000, lnames[10001], 'r', 'f', 0, NPC_LAFF_RESTOCK), + 10002: (-1, lnames[10002], ('sls', 'ss', 'm', 'm', 15, 0, 15, 15, 111, 27, 97, 27, 41, 27), 'm', 0, NPC_REGULAR), 11001: (11000, lnames[11001], 'r', 'm', 0, NPC_LAFF_RESTOCK), 12001: (12000, lnames[12001], 'r', 'm', 0, NPC_LAFF_RESTOCK), + 12002: (-1, lnames[12002], ('pls', 'ls', 'l', 'f', 3, 0, 3, 3, 111, 27, 97, 27, 45, 27), 'f', 0, NPC_REGULAR), 13001: (13000, lnames[13001], 'r', 'f', 0, NPC_LAFF_RESTOCK) } diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index 8bc24994..8e997196 100755 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -4741,7 +4741,6 @@ CagedToonBattleThreeMaxTouchCage = 21 CagedToonBattleThreeMaxAdvice = 106 CashbotBossHadEnough = "That's it. I've had enough of these pesky Toons!" CashbotBossOuttaHere = "I've got a train to catch!" -ResistanceToonName = 'Mata Hairy' ResistanceToonCongratulations = "You did it! Congratulations!\x07You're an asset to the Resistance!\x07Here's a special phrase you can use in a tight spot:\x07%s\x07When you say it, %s.\x07But you can only use it once, so choose that time well!" ResistanceToonToonupInstructions = 'all the Toons near you will gain %s Laff points' ResistanceToonToonupAllInstructions = 'all the Toons near you will gain full Laff points' @@ -6268,8 +6267,10 @@ NPCToonNames = {20000: 'Tutorial Tom', 7022: 'Dee Version', 7023: 'Bo Nanapeel', 10001: 'Healer Sara', + 10002: "Good ol' Gil Giggles", 11001: 'Healer Gabriel', 12001: 'Healer Bill', + 12002: 'Mata Hairy', 13001: 'Healer Clover'} zone2TitleDict = {2513: ('Toon Hall', ''), 2514: ('Toontown Bank', ''), @@ -8130,7 +8131,6 @@ BossbotBossPreTwo1 = "What's taking so long?" BossbotBossPreTwo2 = 'Get cracking and serve my banquet!' BossbotRTServeFood1 = 'Hehe, serve the food I place on these conveyor belts.' BossbotRTServeFood2 = 'If you serve a cog three times in a row it will explode.' -BossbotResistanceToonName = "Good ol' Gil Giggles" BossbotPhase3Speech1 = "What's happening here?!" BossbotPhase3Speech2 = 'These waiters are toons!' BossbotPhase3Speech3 = 'Get them!!!' diff --git a/toontown/toonbase/ToontownBattleGlobals.py b/toontown/toonbase/ToontownBattleGlobals.py index 74310f35..fcbea966 100755 --- a/toontown/toonbase/ToontownBattleGlobals.py +++ b/toontown/toonbase/ToontownBattleGlobals.py @@ -192,7 +192,7 @@ CarryLimits = (((10, 15, 15, 10, - 5, + 7, 3, 1)), ((10, From ae3a7e7dc52ca20a3ebcfa811e1e9b97839281dd Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 22:42:29 +0300 Subject: [PATCH 33/38] Nerf fish rarity properly --- toontown/fishing/FishGlobals.py | 122 ++++++++++++++++---------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/toontown/fishing/FishGlobals.py b/toontown/fishing/FishGlobals.py index 3cf288f1..bafe4492 100755 --- a/toontown/fishing/FishGlobals.py +++ b/toontown/fishing/FishGlobals.py @@ -33,7 +33,7 @@ Rod2JellybeanDict = {0: 10, HealAmount = 1 JellybeanFishingHolidayScoreMultiplier = 2 MAX_RARITY = 10 -GlobalRarityDialBase = 4.3 +GlobalRarityDialBase = 3.8 FishingAngleMax = 50.0 OVERALL_VALUE_SCALE = 15 RARITY_VALUE_SCALE = 0.2 @@ -334,19 +334,19 @@ __fishDict = {0: ((1, (Anywhere,)), (1, 1, - 3, + 4, (TTG.ToontownCentral, Anywhere)), (3, 5, - 4, + 5, (TTG.PunchlinePlace, TTG.TheBrrrgh)), (3, 5, - 2, + 3, (TTG.SillyStreet, TTG.DaisyGardens)), (1, 5, - 1, + 2, (TTG.LoopyLane, TTG.ToontownCentral))), 2: ((2, 6, @@ -354,27 +354,27 @@ __fishDict = {0: ((1, (TTG.DaisyGardens, Anywhere)), (2, 6, - 6, + 9, (TTG.ElmStreet, TTG.DaisyGardens)), (5, 11, - 3, - (TTG.LullabyLane,)), + 4, + (TTG.LullabyLane, TTG.BedtimeBoulevard)), (2, 6, - 2, + 3, (TTG.DaisyGardens, TTG.MyEstate, TTG.OutdoorZone)), (5, 11, - 1, - (TTG.DonaldsDreamland, TTG.MyEstate, TTG.OutdoorZone, TTG.BedtimeBoulevard))), + 2, + (TTG.DonaldsDreamland, TTG.MyEstate, TTG.OutdoorZone))), 4: ((2, 8, 1, (TTG.ToontownCentral, Anywhere)), (2, 8, - 3, + 4, (TTG.ToontownCentral, Anywhere)), (2, 8, @@ -382,7 +382,7 @@ __fishDict = {0: ((1, (TTG.ToontownCentral, Anywhere)), (2, 8, - 5, + 6, (TTG.ToontownCentral, TTG.MinniesMelodyland))), 6: ((8, 12, @@ -394,23 +394,23 @@ __fishDict = {0: ((1, (Anywhere,)), (2, 6, - 1, + 2, (TTG.MinniesMelodyland, Anywhere)), (5, 10, - 4, + 5, (TTG.MinniesMelodyland, Anywhere)), (1, 5, - 5, + 7, (TTG.MyEstate, TTG.OutdoorZone, Anywhere)), (1, 5, - 7, + 10, (TTG.MyEstate, TTG.OutdoorZone, Anywhere))), 10: ((6, 10, - 7, + 9, (TTG.MyEstate, TTG.OutdoorZone, Anywhere)),), 12: ((7, 15, @@ -418,15 +418,15 @@ __fishDict = {0: ((1, (TTG.DonaldsDock, Anywhere)), (18, 20, - 5, + 6, (TTG.DonaldsDock, TTG.MyEstate, TTG.OutdoorZone)), (1, 5, - 4, + 5, (TTG.DonaldsDock, TTG.MyEstate, TTG.OutdoorZone)), (3, 7, - 3, + 4, (TTG.DonaldsDock, TTG.MyEstate, TTG.OutdoorZone)), (1, 2, @@ -437,27 +437,27 @@ __fishDict = {0: ((1, 1, (TTG.DaisyGardens, TTG.MyEstate, TTG.OutdoorZone, Anywhere)), (2, 6, - 2, + 3, (TTG.DaisyGardens, TTG.MyEstate, TTG.OutdoorZone))), 16: ((4, 12, - 4, + 5, (TTG.MinniesMelodyland, Anywhere)), (4, 12, - 6, + 7, (TTG.BaritoneBoulevard, TTG.MinniesMelodyland)), (4, 12, - 6, + 8, (TTG.TenorTerrace, TTG.MinniesMelodyland))), 18: ((2, 4, - 2, + 3, (TTG.DonaldsDock, Anywhere)), (5, 8, - 6, + 7, (TTG.TheBrrrgh,)), (4, 6, - 6, + 8, (TTG.LighthouseLane,))), 20: ((4, 6, @@ -465,11 +465,11 @@ __fishDict = {0: ((1, (TTG.DonaldsDreamland,)), (14, 18, - 7, + 10, (TTG.DonaldsDreamland,)), (6, 10, - 7, + 8, (TTG.LullabyLane, TTG.BedtimeBoulevard)), (1, 1, @@ -477,11 +477,11 @@ __fishDict = {0: ((1, (TTG.DonaldsDreamland,)), (2, 6, - 5, + 6, (TTG.LullabyLane, TTG.BedtimeBoulevard)), (10, 14, - 3, + 4, (TTG.DonaldsDreamland, TTG.DaisyGardens))), 22: ((12, 16, @@ -489,40 +489,36 @@ __fishDict = {0: ((1, (TTG.MyEstate, TTG.OutdoorZone, TTG.DaisyGardens, Anywhere)), (14, 18, - 2, + 3, (TTG.MyEstate, TTG.OutdoorZone, TTG.DaisyGardens, Anywhere)), (14, 20, - 4, + 5, (TTG.MyEstate, TTG.OutdoorZone, TTG.DaisyGardens)), (14, 20, - 6, + 7, (TTG.MyEstate, TTG.OutdoorZone, TTG.DaisyGardens))), 24: ((9, 11, - 2, + 3, (Anywhere,)), - (8, - 12, - 4, - (TTG.DaisyGardens, TTG.DonaldsDock)), (8, 12, 5, (TTG.DaisyGardens, TTG.DonaldsDock)), (8, - 16, + 12, 6, + (TTG.DaisyGardens, TTG.DonaldsDock)), + (8, + 16, + 7, (TTG.DaisyGardens, TTG.DonaldsDock))), 26: ((10, 18, 2, (TTG.TheBrrrgh,)), - (10, - 18, - 2, - (TTG.TheBrrrgh,)), (10, 18, 3, @@ -531,51 +527,55 @@ __fishDict = {0: ((1, 18, 4, (TTG.TheBrrrgh,)), - (12, - 20, + (10, + 18, 5, (TTG.TheBrrrgh,)), - (14, + (12, 20, 6, (TTG.TheBrrrgh,)), (14, 20, - 6, + 7, + (TTG.TheBrrrgh,)), + (14, + 20, + 8, (TTG.SleetStreet, TTG.TheBrrrgh)), (16, 20, - 8, + 10, (TTG.WalrusWay, TTG.TheBrrrgh))), 28: ((2, 10, 2, (TTG.DonaldsDock, Anywhere)), (4, 10, - 5, + 6, (TTG.BarnacleBoulevard, TTG.DonaldsDock)), (4, 10, - 6, + 7, (TTG.SeaweedStreet, TTG.DonaldsDock))), 30: ((13, 17, - 4, + 5, (TTG.MinniesMelodyland, Anywhere)), (16, 20, - 8, + 10, (TTG.AltoAvenue, TTG.MinniesMelodyland)), (12, 18, - 7, + 9, (TTG.TenorTerrace, TTG.MinniesMelodyland)), (12, 18, - 5, + 6, (TTG.MinniesMelodyland,)), (12, 18, - 6, + 7, (TTG.MinniesMelodyland,))), 32: ((1, 5, @@ -587,19 +587,19 @@ __fishDict = {0: ((1, (TTG.TheBrrrgh, TTG.MyEstate, TTG.OutdoorZone, Anywhere)), (1, 5, - 3, + 4, (TTG.DaisyGardens, TTG.MyEstate, TTG.OutdoorZone)), (1, 5, - 4, + 5, (TTG.DonaldsDreamland, TTG.MyEstate, TTG.OutdoorZone)), (1, 5, - 7, + 10, (TTG.TheBrrrgh, TTG.DonaldsDreamland))), 34: ((1, 20, - 7, + 10, (TTG.DonaldsDreamland, Anywhere)),)} def getSpecies(genus): From ecc33e1c3d4a6e5c1971340547cefae1c9bb8234 Mon Sep 17 00:00:00 2001 From: Loudrob Date: Thu, 13 Aug 2015 16:00:50 -0400 Subject: [PATCH 34/38] some more mongo stuff (sorry that i pushed it here :() --- toontown/building/DistributedBuildingMgrAI.py | 99 +++++++++++++------ .../distributed/ToontownInternalRepository.py | 4 +- toontown/racing/LeaderboardMgrAI.py | 21 +++- 3 files changed, 92 insertions(+), 32 deletions(-) diff --git a/toontown/building/DistributedBuildingMgrAI.py b/toontown/building/DistributedBuildingMgrAI.py index 1c2c2d6c..240255d8 100755 --- a/toontown/building/DistributedBuildingMgrAI.py +++ b/toontown/building/DistributedBuildingMgrAI.py @@ -1,4 +1,6 @@ from direct.directnotify.DirectNotifyGlobal import * +import cPickle +from pymongo.errors import AutoReconnect from otp.ai.AIBaseGlobal import * from toontown.building import DistributedBuildingAI @@ -19,6 +21,7 @@ class DistributedBuildingMgrAI: self.dnaStore = dnaStore self.trophyMgr = trophyMgr self.__buildings = {} + self.tableName = 'buildings_%s' % self.branchId self.findAllLandmarkBuildings() def cleanup(self): @@ -105,10 +108,10 @@ class DistributedBuildingMgrAI: return (blocks, hqBlocks, gagshopBlocks, petshopBlocks, kartshopBlocks) def findAllLandmarkBuildings(self): - backups = simbase.backups.load('block-info', (self.air.districtId, self.branchId), default={}) + buildings = self.load() (blocks, hqBlocks, gagshopBlocks, petshopBlocks, kartshopBlocks) = self.getDNABlockLists() for blockNumber in blocks: - self.newBuilding(blockNumber, backup=backups.get(blockNumber, None)) + self.newBuilding(blockNumber, buildings.get(blockNumber, None)) for blockNumber in hqBlocks: self.newHQBuilding(blockNumber) for blockNumber in gagshopBlocks: @@ -118,25 +121,21 @@ class DistributedBuildingMgrAI: for block in kartshopBlocks: self.newKartShopBuilding(block) - def newBuilding(self, blockNumber, backup=None): - building = DistributedBuildingAI.DistributedBuildingAI( - self.air, blockNumber, self.branchId, self.trophyMgr) + def newBuilding(self, blockNumber, blockData = None): + building = DistributedBuildingAI.DistributedBuildingAI(self.air, blockNumber, self.branchId, self.trophyMgr) building.generateWithRequired(self.branchId) - if backup is not None: - state = backup.get('state', 'toon') - if ((state == 'suit') and simbase.air.wantCogbuildings) or ( - (state == 'cogdo') and simbase.air.wantCogdominiums): - building.track = backup.get('track', 'c') - building.difficulty = backup.get('difficulty', 1) - building.numFloors = backup.get('numFloors', 1) - building.updateSavedBy(backup.get('savedBy')) - building.becameSuitTime = backup.get('becameSuitTime', time.time()) - if (state == 'suit') and simbase.air.wantCogbuildings: - building.setState('suit') - elif (state == 'cogdo') and simbase.air.wantCogdominiums: + if blockData: + building.track = blockData.get('track', 'c') + building.realTrack = blockData.get('track', 'c') + building.difficulty = int(blockData.get('difficulty', 1)) + building.numFloors = int(blockData.get('numFloors', 1)) + building.numFloors = max(1, min(5, building.numFloors)) + building.becameSuitTime = blockData.get('becameSuitTime', time.time()) + if blockData['state'] == 'suit': + building.setState('suit') + elif blockData['state'] == 'cogdo': + if simbase.air.wantCogdominiums: building.setState('cogdo') - else: - building.setState('toon') else: building.setState('toon') else: @@ -181,17 +180,59 @@ class DistributedBuildingMgrAI: return building def save(self): + if self.air.dbConn: + buildings = [] + for i in self.__buildings.values(): + if isinstance(i, HQBuildingAI.HQBuildingAI): + continue + buildings.append(i.getPickleData()) + + street = {'ai': self.air.districtId, 'branch': self.branchId} + try: + self.air.dbGlobalCursor.streets.update(street, + {'$setOnInsert': street, + '$set': {'buildings': buildings}}, + upsert=True) + except AutoReconnect: # Something happened to our DB, but we can reconnect and retry. + taskMgr.doMethodLater(config.GetInt('mongodb-retry-time', 2), self.save, 'retrySave', extraArgs=[]) + + else: + self.saveDev() + + def saveDev(self): backups = {} for blockNumber in self.getSuitBlocks(): building = self.getBuilding(blockNumber) - backup = { - 'state': building.fsm.getCurrentState().getName(), - 'block': building.block, - 'track': building.track, - 'difficulty': building.difficulty, - 'numFloors': building.numFloors, - 'savedBy': building.savedBy, - 'becameSuitTime': building.becameSuitTime - } - backups[blockNumber] = backup + backups[blockNumber] = building.getPickleData() simbase.backups.save('block-info', (self.air.districtId, self.branchId), backups) + + def load(self): + if self.air.dbConn: + blocks = {} + + # Ensure that toontown.streets is indexed. Doing this at loading time + # is a fine way to make sure that we won't upset players with a + # lagspike while we wait for the backend to handle the index request. + self.air.dbGlobalCursor.streets.ensure_index([('ai', 1), + ('branch', 1)]) + + street = {'ai': self.air.districtId, 'branch': self.branchId} + try: + doc = self.air.dbGlobalCursor.streets.find_one(street) + except AutoReconnect: # We're failing over - normally we'd wait to retry, but this is on AI startup so we might want to retry (or refactor the bldgMgr so we can sanely retry). + return blocks + + if not doc: + return blocks + + for building in doc.get('buildings', []): + blocks[int(building['block'])] = building + + return blocks + + else: + blocks = simbase.backups.load('block-info', (self.air.districtId, self.branchId), default={}) + return blocks + + + diff --git a/toontown/distributed/ToontownInternalRepository.py b/toontown/distributed/ToontownInternalRepository.py index 8a083f4b..40a65d40 100755 --- a/toontown/distributed/ToontownInternalRepository.py +++ b/toontown/distributed/ToontownInternalRepository.py @@ -14,10 +14,12 @@ class ToontownInternalRepository(AstronInternalRepository): AstronInternalRepository.__init__( self, baseChannel, serverId=serverId, dcFileNames=dcFileNames, dcSuffix=dcSuffix, connectMethod=connectMethod, threadedNet=threadedNet) + + self.wantMongo = config.GetBool('want-mongo', False) def handleConnected(self): self.__messenger = ToontownNetMessengerAI(self) - if config.GetBool('want-mongo', False): + if self.wantMongo: import pymongo self.dbConn = pymongo.MongoClient(config.GetString('mongodb-url', 'localhost')) self.dbGlobalCursor = self.dbConn.toontownstride diff --git a/toontown/racing/LeaderboardMgrAI.py b/toontown/racing/LeaderboardMgrAI.py index 682dac40..dd122c24 100644 --- a/toontown/racing/LeaderboardMgrAI.py +++ b/toontown/racing/LeaderboardMgrAI.py @@ -6,13 +6,30 @@ class LeaderboardMgrAI: def __init__(self, air): self.air = air - self.database = simbase.backups.load('leaderboard', (self.air.districtId,), default=({})) + if self.air.dbConn: + self.air.dbGlobalCursor.leaderboards.ensure_index([('ai', 1)]) + shard = {'ai': self.air.districtId} + doc = self.air.dbGlobalCursor.leaderboards.find_one(shard) + if not doc: + self.database = ({}) + else: + self.database = doc.get('database', ({})) + + else: + self.database = simbase.backups.load('leaderboard', (self.air.districtId,), default=({})) def getDatabase(self): return self.database def saveDatabase(self): - simbase.backups.save('leaderboard', (self.air.districtId,), self.database) + if self.air.dbConn: + shard = {'ai': self.air.districtId} + self.air.dbGlobalCursor.leaderboards.update(shard, + {'$setOnInsert': shard, + '$set': {'database': self.database}}, + upsert = True) + else: + simbase.backups.save('leaderboard', (self.air.districtId,), self.database) messenger.send('goofyLeaderboardChange') def trimList(self, list): From 5f9592cdd795e48a68f799d08f976e7326eb510b Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 23:06:19 +0300 Subject: [PATCH 35/38] Magic word crash prevention --- otp/ai/MagicWordManager.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/otp/ai/MagicWordManager.py b/otp/ai/MagicWordManager.py index b7f3e84f..e9442937 100755 --- a/otp/ai/MagicWordManager.py +++ b/otp/ai/MagicWordManager.py @@ -1,12 +1,9 @@ from direct.directnotify import DirectNotifyGlobal from direct.distributed import DistributedObject - from otp.ai.MagicWordGlobal import * - lastClickedNametag = None - class MagicWordManager(DistributedObject.DistributedObject): notify = DirectNotifyGlobal.directNotify.newCategory('MagicWordManager') neverDisable = 1 @@ -20,6 +17,9 @@ class MagicWordManager(DistributedObject.DistributedObject): DistributedObject.DistributedObject.disable(self) def handleMagicWord(self, magicWord): + if not base.localAvatar.isAdmin(): + return + if magicWord.startswith('~~'): if lastClickedNametag == None: target = base.localAvatar @@ -32,6 +32,7 @@ class MagicWordManager(DistributedObject.DistributedObject): targetId = target.doId self.sendUpdate('sendMagicWord', [magicWord, targetId]) + if target == base.localAvatar: response = spellbook.process(base.localAvatar, target, magicWord) if response: From be54eb19dff6cae81f8c41e3420baf7eb2de55c5 Mon Sep 17 00:00:00 2001 From: John Date: Thu, 13 Aug 2015 23:39:09 +0300 Subject: [PATCH 36/38] 2X merit multiplier for factories --- toontown/ai/PromotionManagerAI.py | 4 ++-- toontown/building/DistributedBuildingMgrAI.py | 5 ++--- toontown/coghq/DistributedBattleFactoryAI.py | 2 +- toontown/coghq/DistributedCountryClubBattleAI.py | 2 +- toontown/coghq/DistributedMintBattleAI.py | 2 +- toontown/coghq/DistributedStageBattleAI.py | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/toontown/ai/PromotionManagerAI.py b/toontown/ai/PromotionManagerAI.py index a803d431..0c36b767 100755 --- a/toontown/ai/PromotionManagerAI.py +++ b/toontown/ai/PromotionManagerAI.py @@ -15,12 +15,12 @@ class PromotionManagerAI: def getPercentChance(self): return 100.0 - def recoverMerits(self, av, cogList, zoneId, multiplier = 1, extraMerits = None): + def recoverMerits(self, av, cogList, zoneId, multiplier = 1, extraMerits = None, addInvasion = True): avId = av.getDoId() meritsRecovered = [0, 0, 0, 0] if extraMerits is None: extraMerits = [0, 0, 0, 0] - if self.air.suitInvasionManager.getInvading(): + if addInvasion and self.air.suitInvasionManager.getInvading(): multiplier *= getInvasionMultiplier() for i in xrange(len(extraMerits)): if CogDisguiseGlobals.isSuitComplete(av.getCogParts(), i): diff --git a/toontown/building/DistributedBuildingMgrAI.py b/toontown/building/DistributedBuildingMgrAI.py index 240255d8..c4f4ff19 100755 --- a/toontown/building/DistributedBuildingMgrAI.py +++ b/toontown/building/DistributedBuildingMgrAI.py @@ -1,6 +1,5 @@ from direct.directnotify.DirectNotifyGlobal import * import cPickle -from pymongo.errors import AutoReconnect from otp.ai.AIBaseGlobal import * from toontown.building import DistributedBuildingAI @@ -193,7 +192,7 @@ class DistributedBuildingMgrAI: {'$setOnInsert': street, '$set': {'buildings': buildings}}, upsert=True) - except AutoReconnect: # Something happened to our DB, but we can reconnect and retry. + except: # Something happened to our DB, but we can reconnect and retry. taskMgr.doMethodLater(config.GetInt('mongodb-retry-time', 2), self.save, 'retrySave', extraArgs=[]) else: @@ -219,7 +218,7 @@ class DistributedBuildingMgrAI: street = {'ai': self.air.districtId, 'branch': self.branchId} try: doc = self.air.dbGlobalCursor.streets.find_one(street) - except AutoReconnect: # We're failing over - normally we'd wait to retry, but this is on AI startup so we might want to retry (or refactor the bldgMgr so we can sanely retry). + except: # We're failing over - normally we'd wait to retry, but this is on AI startup so we might want to retry (or refactor the bldgMgr so we can sanely retry). return blocks if not doc: diff --git a/toontown/coghq/DistributedBattleFactoryAI.py b/toontown/coghq/DistributedBattleFactoryAI.py index bd675395..7bbd6794 100755 --- a/toontown/coghq/DistributedBattleFactoryAI.py +++ b/toontown/coghq/DistributedBattleFactoryAI.py @@ -29,7 +29,7 @@ class DistributedBattleFactoryAI(DistributedLevelBattleAI.DistributedLevelBattle self.toonItems[toon.doId][1].extend(notRecovered) meritArray = self.air.promotionMgr.recoverMerits( toon, self.suitsKilled, self.getTaskZoneId(), - getFactoryMeritMultiplier(self.getTaskZoneId())) + getFactoryMeritMultiplier(self.getTaskZoneId()) * 2.0, addInvasion=False) if toon.doId in self.helpfulToons: self.toonMerits[toon.doId] = addListsByValue(self.toonMerits[toon.doId], meritArray) else: diff --git a/toontown/coghq/DistributedCountryClubBattleAI.py b/toontown/coghq/DistributedCountryClubBattleAI.py index 6950a9e7..1ca68d69 100755 --- a/toontown/coghq/DistributedCountryClubBattleAI.py +++ b/toontown/coghq/DistributedCountryClubBattleAI.py @@ -34,7 +34,7 @@ class DistributedCountryClubBattleAI(DistributedLevelBattleAI.DistributedLevelBa recovered, notRecovered = self.air.questManager.recoverItems(toon, self.suitsKilled, self.getTaskZoneId()) self.toonItems[toon.doId][0].extend(recovered) self.toonItems[toon.doId][1].extend(notRecovered) - meritArray = self.air.promotionMgr.recoverMerits(toon, self.suitsKilled, self.getTaskZoneId(), getCountryClubCreditMultiplier(self.getTaskZoneId()), extraMerits=extraMerits) + meritArray = self.air.promotionMgr.recoverMerits(toon, self.suitsKilled, self.getTaskZoneId(), getCountryClubCreditMultiplier(self.getTaskZoneId()) * 2.0, extraMerits=extraMerits, addInvasion=False) if toon.doId in self.helpfulToons: self.toonMerits[toon.doId] = addListsByValue(self.toonMerits[toon.doId], meritArray) else: diff --git a/toontown/coghq/DistributedMintBattleAI.py b/toontown/coghq/DistributedMintBattleAI.py index 47f5f99c..6d2ba1de 100755 --- a/toontown/coghq/DistributedMintBattleAI.py +++ b/toontown/coghq/DistributedMintBattleAI.py @@ -33,7 +33,7 @@ class DistributedMintBattleAI(DistributedLevelBattleAI.DistributedLevelBattleAI) recovered, notRecovered = self.air.questManager.recoverItems(toon, self.suitsKilled, self.getTaskZoneId()) self.toonItems[toon.doId][0].extend(recovered) self.toonItems[toon.doId][1].extend(notRecovered) - meritArray = self.air.promotionMgr.recoverMerits(toon, self.suitsKilled, self.getTaskZoneId(), getMintCreditMultiplier(self.getTaskZoneId()), extraMerits=extraMerits) + meritArray = self.air.promotionMgr.recoverMerits(toon, self.suitsKilled, self.getTaskZoneId(), getMintCreditMultiplier(self.getTaskZoneId()) * 2.0, extraMerits=extraMerits, addInvasion=False) if toon.doId in self.helpfulToons: self.toonMerits[toon.doId] = addListsByValue(self.toonMerits[toon.doId], meritArray) else: diff --git a/toontown/coghq/DistributedStageBattleAI.py b/toontown/coghq/DistributedStageBattleAI.py index 32e162ba..44f3e41c 100755 --- a/toontown/coghq/DistributedStageBattleAI.py +++ b/toontown/coghq/DistributedStageBattleAI.py @@ -41,7 +41,7 @@ class DistributedStageBattleAI(DistributedLevelBattleAI.DistributedLevelBattleAI recovered, notRecovered = self.air.questManager.recoverItems(toon, self.suitsKilled, self.getTaskZoneId()) self.toonItems[toon.doId][0].extend(recovered) self.toonItems[toon.doId][1].extend(notRecovered) - meritArray = self.air.promotionMgr.recoverMerits(toon, self.suitsKilled, self.getTaskZoneId(), getStageCreditMultiplier(self.level.getFloorNum()), extraMerits=extraMerits) + meritArray = self.air.promotionMgr.recoverMerits(toon, self.suitsKilled, self.getTaskZoneId(), getStageCreditMultiplier(self.level.getFloorNum()) * 2.0, extraMerits=extraMerits, addInvasion=False) if toon.doId in self.helpfulToons: self.toonMerits[toon.doId] = addListsByValue(self.toonMerits[toon.doId], meritArray) else: From b8ef66621fb5f4cab87e1a384dfd26c6cf164df5 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 14 Aug 2015 00:31:23 +0300 Subject: [PATCH 37/38] CHAT_SETTINGS Account dc field --- dependencies/astron/dclass/stride.dc | 3 +- dependencies/config/release/dev.prc | 3 +- otp/avatar/Avatar.py | 6 +-- otp/chat/WhiteList.py | 6 ++- otp/distributed/OTPClientRepository.py | 12 +++++ otp/nametag/NametagConstants.py | 2 +- toontown/chat/ToontownChatManager.py | 8 +-- toontown/friends/FriendHandle.py | 4 +- toontown/friends/ToontownFriendSecret.py | 2 +- toontown/shtiker/OptionsPage.py | 54 +++++---------------- toontown/toon/DistributedToon.py | 10 +++- toontown/toonbase/TTLocalizerEnglish.py | 4 -- toontown/toonbase/ToontownStart.py | 4 -- toontown/uberdog/ClientServicesManager.py | 3 +- toontown/uberdog/ClientServicesManagerUD.py | 5 +- 15 files changed, 56 insertions(+), 70 deletions(-) diff --git a/dependencies/astron/dclass/stride.dc b/dependencies/astron/dclass/stride.dc index c52391d7..bc053e3c 100644 --- a/dependencies/astron/dclass/stride.dc +++ b/dependencies/astron/dclass/stride.dc @@ -32,6 +32,7 @@ dclass Account { string ACCOUNT_ID db; uint16 ACCESS_LEVEL db; uint32 LAST_LOGIN_TS db; + uint8[] CHAT_SETTINGS db; }; struct BarrierData { @@ -3154,7 +3155,7 @@ dclass ClientServicesManager : DistributedObjectGlobal { acceptLogin(uint32 timestamp); requestAvatars() clsend; - setAvatars(PotentialToon[]); + setAvatars(uint8[], PotentialToon[]); createAvatar(blob dna, uint8 index) clsend; createAvatarResp(uint32 avId); diff --git a/dependencies/config/release/dev.prc b/dependencies/config/release/dev.prc index a3d97d2a..8aa75ff8 100644 --- a/dependencies/config/release/dev.prc +++ b/dependencies/config/release/dev.prc @@ -33,7 +33,8 @@ want-gifting #t want-top-toons #f # Chat: -want-whitelist #t +want-whitelist #f +want-sequence-list #f # Developer options: show-population #t diff --git a/otp/avatar/Avatar.py b/otp/avatar/Avatar.py index 2b708a8c..d9db1a27 100755 --- a/otp/avatar/Avatar.py +++ b/otp/avatar/Avatar.py @@ -116,16 +116,16 @@ class Avatar(Actor, ShadowCaster): elif self.playerType not in (NametagGroup.CCNormal, NametagGroup.CCSpeedChat): self.understandable = 1 self.setPlayerType(NametagGroup.CCNonPlayer) - elif settings['trueFriends'] and base.localAvatar.isTrueFriends(self.doId): + elif base.localAvatar.isTrueFriends(self.doId): self.understandable = 2 self.setPlayerType(NametagGroup.CCNormal) - elif settings['speedchatPlus']: + elif base.cr.wantSpeedchatPlus(): self.understandable = 1 self.setPlayerType(NametagGroup.CCSpeedChat) else: self.understandable = 0 self.setPlayerType(NametagGroup.CCSpeedChat) - if hasattr(self, 'adminAccess') and self.isAdmin(): + if base.cr.wantSpeedchatPlus() and hasattr(self, 'adminAccess') and self.isAdmin() and self != base.localAvatar: self.understandable = 2 if not hasattr(self, 'nametag'): self.notify.warning('no nametag attributed, but would have been used') diff --git a/otp/chat/WhiteList.py b/otp/chat/WhiteList.py index 6538ce77..4a513f89 100755 --- a/otp/chat/WhiteList.py +++ b/otp/chat/WhiteList.py @@ -29,7 +29,11 @@ class WhiteList: return i != self.numWords and self.words[i].startswith(text) def getReplacement(self, text, av=None, garbler=None): - return '\x01WLRed\x01%s\x02' % text if not garbler else garbler.garble(av, len(text.split(' '))) + if av and av == base.localAvatar: + return '\x01WLDisplay\x01%s\x02' % text + elif not garbler: + return '\x01WLRed\x01%s\x02' % text + return garbler.garble(av, len(text.split(' '))) def processText(self, text, av=None, garbler=None): if not self.words: diff --git a/otp/distributed/OTPClientRepository.py b/otp/distributed/OTPClientRepository.py index 1dd5c298..8bce5800 100755 --- a/otp/distributed/OTPClientRepository.py +++ b/otp/distributed/OTPClientRepository.py @@ -693,6 +693,18 @@ class OTPClientRepository(ClientRepositoryBase): def handleAvatarsList(self, avatars): self.avList = avatars self.loginFSM.request('chooseAvatar', [self.avList]) + + def handleChatSettings(self, chatSettings): + self.chatSettings = chatSettings + + def wantSpeedchatPlus(self): + return self.chatSettings[0] + + def wantTrueFriends(self): + return self.chatSettings[1] + + def wantTypedChat(self): + return self.wantSpeedchatPlus() or self.wantTrueFriends() @report(types=['args', 'deltaStamp'], dConfigParam='teleport') def enterChooseAvatar(self, avList): diff --git a/otp/nametag/NametagConstants.py b/otp/nametag/NametagConstants.py index 21585963..38307453 100644 --- a/otp/nametag/NametagConstants.py +++ b/otp/nametag/NametagConstants.py @@ -202,4 +202,4 @@ WHISPER_COLORS = { } def getFriendColor(handle): - return CCNormal if settings['trueFriends'] and base.localAvatar.isTrueFriends(handle.doId) else CCSpeedChat \ No newline at end of file + return CCNormal if base.localAvatar.isTrueFriends(handle.doId) else CCSpeedChat \ No newline at end of file diff --git a/toontown/chat/ToontownChatManager.py b/toontown/chat/ToontownChatManager.py index 8899697a..9140244c 100755 --- a/toontown/chat/ToontownChatManager.py +++ b/toontown/chat/ToontownChatManager.py @@ -110,7 +110,7 @@ class ToontownChatManager(ChatManager.ChatManager): if base.config.GetBool('want-qa-regression', 0): self.notify.info('QA-REGRESSION: CHAT: Speedchat Plus') messenger.send('wakeup') - if not settings['trueFriends'] and not settings['speedchatPlus']: + if not base.cr.wantTypedChat(): self.fsm.request('noSpeedchatPlus') return self.fsm.request('normalChat') @@ -124,7 +124,7 @@ class ToontownChatManager(ChatManager.ChatManager): def __whisperButtonPressed(self, avatarName, avatarId): messenger.send('wakeup') - if not settings['trueFriends'] and not settings['speedchatPlus']: + if not base.cr.wantTypedChat(): self.fsm.request('noSpeedchatPlus') return if avatarId: @@ -133,7 +133,7 @@ class ToontownChatManager(ChatManager.ChatManager): return def enterNormalChat(self): - if not settings['trueFriends'] and not settings['speedchatPlus']: + if not base.cr.wantTypedChat(): self.fsm.request('mainMenu') return result = ChatManager.ChatManager.enterNormalChat(self) @@ -142,7 +142,7 @@ class ToontownChatManager(ChatManager.ChatManager): self.fsm.request('mainMenu') def enterWhisperChat(self, avatarName, avatarId): - if not settings['trueFriends'] and not settings['speedchatPlus']: + if not base.cr.wantTypedChat(): self.fsm.request('mainMenu') return result = ChatManager.ChatManager.enterWhisperChat(self, avatarName, avatarId) diff --git a/toontown/friends/FriendHandle.py b/toontown/friends/FriendHandle.py index 18d6261f..69c2c760 100755 --- a/toontown/friends/FriendHandle.py +++ b/toontown/friends/FriendHandle.py @@ -66,8 +66,8 @@ class FriendHandle: base.cr.ttsFriendsManager.d_teleportGiveup(self.doId) def isUnderstandable(self): - if settings['speedchatPlus']: + if base.cr.wantTypedChat(): return 1 - elif settings['trueFriends'] and base.localAvatar.isTrueFriends(self.doId): + elif base.localAvatar.isTrueFriends(self.doId): return 1 return 0 diff --git a/toontown/friends/ToontownFriendSecret.py b/toontown/friends/ToontownFriendSecret.py index 1635a3c5..eb7abff1 100644 --- a/toontown/friends/ToontownFriendSecret.py +++ b/toontown/friends/ToontownFriendSecret.py @@ -8,7 +8,7 @@ globalFriendSecret = None def showFriendSecret(): global globalFriendSecret - if not settings['trueFriends']: + if not base.cr.wantTrueFriends(): chatMgr = base.localAvatar.chatMgr chatMgr.fsm.request('noTrueFriends') else: diff --git a/toontown/shtiker/OptionsPage.py b/toontown/shtiker/OptionsPage.py index 6da309cb..311767fb 100755 --- a/toontown/shtiker/OptionsPage.py +++ b/toontown/shtiker/OptionsPage.py @@ -729,31 +729,25 @@ class ExtraOptionsTabPage(DirectFrame): button_image = (guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')) self.speed_chat_scale = 0.055 self.fov_label = DirectLabel(parent=self, relief=None, text=TTLocalizer.FieldOfViewLabel, text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight)) - self.speedchatPlus_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - textRowHeight)) - self.trueFriends_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 2 * textRowHeight)) - self.cogInterface_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 3 * textRowHeight)) - self.tpTransition_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 4 * textRowHeight)) + self.cogInterface_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - textRowHeight)) + self.tpTransition_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 2 * textRowHeight)) self.fov_slider = DirectSlider(parent=self, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord), value=settings['fov'], pageSize=5, range=(ToontownGlobals.DefaultCameraFov, ToontownGlobals.MaxCameraFov), command=self.__doFov, thumb_geom=(circleModel.find('**/tt_t_gui_mat_namePanelCircle')), thumb_relief=None, thumb_geom_scale=2) self.fov_slider.setScale(0.25) - self.speedchatPlus_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - textRowHeight), command=self.__doToggleSpeedchatPlus) - self.trueFriends_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 2 * textRowHeight), command=self.__doToggleTrueFriends) - self.cogInterface_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 3 * textRowHeight), command=self.__doToggleCogInterface) - self.tpTransition_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 4 * textRowHeight), command=self.__doToggleTpTransition) + self.cogInterface_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - textRowHeight), command=self.__doToggleCogInterface) + self.tpTransition_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 2 * textRowHeight), command=self.__doToggleTpTransition) self.bugReportButton = DirectButton(parent=self, relief=None, text=TTLocalizer.BugReportButton, image=button_image, image_scale=button_image_scale, text_pos=(0, -0.01), text_fg=(0, 0, 0, 1), command=self.showReportNotice, pos=(0.0, 0.0, -0.6), text_scale=(0.045)) guiButton.removeNode() circleModel.removeNode() - self.optionChoosers['pole'] = OptionChooser.OptionChooser(self, TTLocalizer.FishingPoleLabel, 5, self.__updateFishingPole, [False], self.__applyFishingPole) - self.optionChoosers['nametag_style'] = OptionChooser.OptionChooser(self, TTLocalizer.NametagStyleLabel, 6, self.__updateNametagStyle, [False], self.__applyNametagStyle) + self.optionChoosers['pole'] = OptionChooser.OptionChooser(self, TTLocalizer.FishingPoleLabel, 3, self.__updateFishingPole, [False], self.__applyFishingPole) + self.optionChoosers['nametag_style'] = OptionChooser.OptionChooser(self, TTLocalizer.NametagStyleLabel, 4, self.__updateNametagStyle, [False], self.__applyNametagStyle) def enter(self): self.show() self.settingsChanged = 0 - self.__setSpeedchatPlusButton() - self.__setTrueFriendsButton() self.__setCogInterfaceButton() self.__setTpTransitionButton() self.__updateNametagStyle() @@ -774,18 +768,14 @@ class ExtraOptionsTabPage(DirectFrame): del self.fov_label self.fov_slider.destroy() del self.fov_slider - self.speedchatPlus_label.destroy() - del self.speedchatPlus_label - self.trueFriends_label.destroy() - del self.trueFriends_label self.cogInterface_label.destroy() del self.cogInterface_label - self.speedchatPlus_toggleButton.destroy() - del speedchatPlus_toggleButton - self.trueFriends_toggleButton.destroy() - del self.trueFriends_toggleButton self.cogInterface_toggleButton.destroy() - del self.cogInterface_toggleButton + del self.cogInterface_label + self.tpTransition_label.destroy() + del self.tpTransition_label + self.tpTransition_toggleButton.destroy() + del self.tpTransition_toggleButton self.bugReportButton.destroy() del self.bugReportButton self.destroyReportNotice() @@ -808,28 +798,6 @@ class ExtraOptionsTabPage(DirectFrame): self.cogInterface_label['text'] = TTLocalizer.CogInterfaceLabelOn if settings['cogInterface'] else TTLocalizer.CogInterfaceLabelOff self.cogInterface_toggleButton['text'] = TTLocalizer.OptionsPageToggleOff if settings['cogInterface'] else TTLocalizer.OptionsPageToggleOn - def __doToggleSpeedchatPlus(self): - messenger.send('wakeup') - settings['speedchatPlus'] = not settings['speedchatPlus'] - Toon.reconsiderAllToonsUnderstandable() - self.settingsChanged = 1 - self.__setSpeedchatPlusButton() - - def __setSpeedchatPlusButton(self): - self.speedchatPlus_label['text'] = TTLocalizer.SpeedchatPlusLabelOn if settings['speedchatPlus'] else TTLocalizer.SpeedchatPlusLabelOff - self.speedchatPlus_toggleButton['text'] = TTLocalizer.OptionsPageToggleOff if settings['speedchatPlus'] else TTLocalizer.OptionsPageToggleOn - - def __doToggleTrueFriends(self): - messenger.send('wakeup') - settings['trueFriends'] = not settings['trueFriends'] - Toon.reconsiderAllToonsUnderstandable() - self.settingsChanged = 1 - self.__setTrueFriendsButton() - - def __setTrueFriendsButton(self): - self.trueFriends_label['text'] = TTLocalizer.TrueFriendsLabelOn if settings['trueFriends'] else TTLocalizer.TrueFriendsLabelOff - self.trueFriends_toggleButton['text'] = TTLocalizer.OptionsPageToggleOff if settings['trueFriends'] else TTLocalizer.OptionsPageToggleOn - def __doToggleTpTransition(self): messenger.send('wakeup') settings['tpTransition'] = not settings['tpTransition'] diff --git a/toontown/toon/DistributedToon.py b/toontown/toon/DistributedToon.py index 560b8354..8769d196 100755 --- a/toontown/toon/DistributedToon.py +++ b/toontown/toon/DistributedToon.py @@ -2382,13 +2382,19 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute def addReport(self, doId): if not self.isReported(doId): self.reported.append(doId) + + def setFriendsList(self, friendsList): + DistributedPlayer.DistributedPlayer.setFriendsList(self, friendsList) + messenger.send('friendsListChanged') + Toon.reconsiderAllToonsUnderstandable() def setTrueFriends(self, trueFriends): - Toon.reconsiderAllToonsUnderstandable() self.trueFriends = trueFriends + Toon.reconsiderAllToonsUnderstandable() + messenger.send('friendsListChanged') def isTrueFriends(self, doId): - return doId in self.trueFriends + return base.cr.wantTrueFriends() and doId in self.trueFriends def applyBuffs(self): for id, timestamp in enumerate(self.buffs): diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index 8e997196..841a4d16 100755 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -8534,10 +8534,6 @@ BugReportNotice = 'Attention!\n\nThis button will open a browser which will send CodeRedemptionWarning = 'NOTICE: All codes can only be entered once!' CogInterfaceLabelOn = 'The cog battle interface is on.' CogInterfaceLabelOff = 'The cog battle interface is off.' -SpeedchatPlusLabelOn = 'Speedchat Plus is on.' -SpeedchatPlusLabelOff = 'Speedchat Plus is off.' -TrueFriendsLabelOn = 'True Friends is on.' -TrueFriendsLabelOff = 'True Friends is off.' TpTransitionLabelOn = 'The teleport transition is on.' TpTransitionLabelOff = 'The teleport transition is off.' FieldOfViewLabel = 'Field of View:' diff --git a/toontown/toonbase/ToontownStart.py b/toontown/toonbase/ToontownStart.py index ba86dacf..af820b4a 100644 --- a/toontown/toonbase/ToontownStart.py +++ b/toontown/toonbase/ToontownStart.py @@ -98,10 +98,6 @@ if 'language' not in settings: settings['language'] = 'English' if 'cogInterface' not in settings: settings['cogInterface'] = True -if 'speedchatPlus' not in settings: - settings['speedchatPlus'] = True -if 'trueFriends' not in settings: - settings['trueFriends'] = True if 'tpTransition' not in settings: settings['tpTransition'] = True if 'fov' not in settings: diff --git a/toontown/uberdog/ClientServicesManager.py b/toontown/uberdog/ClientServicesManager.py index eaec83bc..2e74d11e 100755 --- a/toontown/uberdog/ClientServicesManager.py +++ b/toontown/uberdog/ClientServicesManager.py @@ -35,7 +35,7 @@ class ClientServicesManager(DistributedObjectGlobal): def requestAvatars(self): self.sendUpdate('requestAvatars') - def setAvatars(self, avatars): + def setAvatars(self, chatSettings, avatars): avList = [] for avNum, avName, avDNA, avPosition, nameState in avatars: nameOpen = int(nameState == 1) @@ -48,6 +48,7 @@ class ClientServicesManager(DistributedObjectGlobal): names[3] = avName avList.append(PotentialAvatar(avNum, names, avDNA, avPosition, nameOpen)) + self.cr.handleChatSettings(chatSettings) self.cr.handleAvatarsList(avList) # --- AVATAR CREATION/DELETION --- diff --git a/toontown/uberdog/ClientServicesManagerUD.py b/toontown/uberdog/ClientServicesManagerUD.py index 462b59d2..a4702faf 100755 --- a/toontown/uberdog/ClientServicesManagerUD.py +++ b/toontown/uberdog/ClientServicesManagerUD.py @@ -333,7 +333,8 @@ class LoginAccountFSM(OperationFSM): 'LAST_LOGIN': time.ctime(), 'LAST_LOGIN_TS': time.time(), 'ACCOUNT_ID': str(self.userId), - 'ACCESS_LEVEL': self.accessLevel + 'ACCESS_LEVEL': self.accessLevel, + 'CHAT_SETTINGS': [1, 1] } self.csm.air.dbInterface.createObject( self.csm.air.dbId, @@ -645,7 +646,7 @@ class GetAvatarsFSM(AvatarOperationFSM): potentialAvs.append([avId, name, fields['setDNAString'][0], index, nameState]) - self.csm.sendUpdateToAccountId(self.target, 'setAvatars', [potentialAvs]) + self.csm.sendUpdateToAccountId(self.target, 'setAvatars', [self.account['CHAT_SETTINGS'], potentialAvs]) self.demand('Off') def enterQueryNameState(self): From 655d77a40131c7f4f11353db8951a291215fed11 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 14 Aug 2015 00:38:00 +0300 Subject: [PATCH 38/38] Add chat settings RPC command: untested --- toontown/rpc/ToontownRPCHandler.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/toontown/rpc/ToontownRPCHandler.py b/toontown/rpc/ToontownRPCHandler.py index c40c4850..d701d4a4 100755 --- a/toontown/rpc/ToontownRPCHandler.py +++ b/toontown/rpc/ToontownRPCHandler.py @@ -773,3 +773,22 @@ class ToontownRPCHandler(ToontownRPCHandlerBase): oldFields = {'setWishNameState': 'PENDING'} return self.rpc_updateObject( avId, 'DistributedToonUD', newFields, oldFields=oldFields) + + @rpcmethod(accessLevel=MODERATOR) + def rpc_setChatSettings(self, accId, chatSettings): + """ + Summary: + Sets the chat settings of the account associated with the provided + [accId]. + + Parameters: + [int accId] = The ID of the account whose chat settings + are to be changed. + [uint8[sp+, tf]] = The chat settings - SpeedChat Plus and + True Friends + + Example response: + On success: True + On failure: False + """ + return self.rpc_updateObject(accId, 'AccountUD', {'CHAT_SETTINGS': chatSettings})