diff --git a/astron/dclass/toon.dc b/astron/dclass/toon.dc index d178bc92..36e68192 100644 --- a/astron/dclass/toon.dc +++ b/astron/dclass/toon.dc @@ -112,6 +112,7 @@ from toontown.toon import DistributedNPCFisherman/AI from toontown.toon import DistributedNPCPartyPerson/AI from toontown.toon import DistributedNPCPetclerk/AI from toontown.toon import DistributedNPCKartClerk/AI +from toontown.toon import DistributedNPCGlove/AI from toontown.building import DistributedKnockKnockDoor/AI from toontown.building import DistributedElevator/AI from toontown.building import DistributedElevatorFSM/AI @@ -1846,6 +1847,11 @@ dclass DistributedNPCKartClerk : DistributedNPCToonBase { transactionDone() airecv clsend; }; +dclass DistributedNPCGlove : DistributedNPCToonBase { + doTransformation(uint32 avId, uint32) broadcast; + requestTransformation(uint32) airecv clsend; +}; + dclass DistributedKnockKnockDoor : DistributedAnimatedProp { }; diff --git a/config/release/dev.prc b/config/release/dev.prc index e6e29ef2..bea2722d 100644 --- a/config/release/dev.prc +++ b/config/release/dev.prc @@ -33,6 +33,9 @@ want-resistance-toonup #t want-resistance-restock #t want-resistance-dance #t +# Optional: +want-glove-npc #t + # Developer options: show-population #t force-skip-tutorial #t diff --git a/otp/distributed/DCClassImports.py b/otp/distributed/DCClassImports.py index 257905a0..648d4791 100644 --- a/otp/distributed/DCClassImports.py +++ b/otp/distributed/DCClassImports.py @@ -2,7 +2,7 @@ from pandac.PandaModules import * -hashVal = 2077607028 +hashVal = 959103491 from toontown.coghq import DistributedCashbotBossSafe, DistributedCashbotBossCrane, DistributedBattleFactory, DistributedCashbotBossTreasure, DistributedCogHQDoor, DistributedSellbotHQDoor, DistributedFactoryElevatorExt, DistributedMintElevatorExt, DistributedLawOfficeElevatorExt, DistributedLawOfficeElevatorInt, LobbyManager, DistributedMegaCorp, DistributedFactory, DistributedLawOffice, DistributedLawOfficeFloor, DistributedLift, DistributedDoorEntity, DistributedSwitch, DistributedButton, DistributedTrigger, DistributedCrushableEntity, DistributedCrusherEntity, DistributedStomper, DistributedStomperPair, DistributedLaserField, DistributedGolfGreenGame, DistributedSecurityCamera, DistributedMover, DistributedElevatorMarker, DistributedBarrelBase, DistributedGagBarrel, DistributedBeanBarrel, DistributedHealBarrel, DistributedGrid, ActiveCell, DirectionalCell, CrusherCell, DistributedCrate, DistributedSinkingPlatform, BattleBlocker, DistributedMint, DistributedMintRoom, DistributedMintBattle, DistributedStage, DistributedStageRoom, DistributedStageBattle, DistributedLawbotBossGavel, DistributedLawbotCannon, DistributedLawbotChair, DistributedCogKart, DistributedCountryClub, DistributedCountryClubRoom, DistributedMoleField, DistributedCountryClubBattle, DistributedMaze, DistributedFoodBelt, DistributedBanquetTable, DistributedGolfSpot @@ -43,7 +43,7 @@ from toontown.friends import TTPlayerFriendsManager, TTUFriendsManager from toontown.cogdominium import DistributedCogdoInterior, DistributedCogdoBattleBldg, DistributedCogdoElevatorExt, DistributedCogdoElevatorInt, DistributedCogdoBarrel, DistCogdoGame, DistCogdoLevelGame, DistCogdoBoardroomGame, DistCogdoCraneGame, DistCogdoMazeGame, DistCogdoFlyingGame, DistCogdoCrane, DistCogdoCraneMoneyBag, DistCogdoCraneCog from otp.distributed import Account, ObjectServer, DistributedDistrict, DistributedDirectory, DistributedTestObject, CentralLogger from toontown.estate import DistributedCannon, DistributedTarget, EstateManager, DistributedEstate, DistributedHouse, DistributedHouseInterior, DistributedGarden, DistributedHouseDoor, DistributedBankMgr, DistributedMailbox, DistributedFurnitureManager, DistributedFurnitureItem, DistributedBank, DistributedCloset, DistributedTrunk, DistributedPhone, DistributedFireworksCannon, DistributedLawnDecor, DistributedGardenPlot, DistributedGardenBox, DistributedFlower, DistributedGagTree, DistributedStatuary, DistributedToonStatuary, DistributedChangingStatuary, DistributedAnimatedStatuary, DistributedPlantBase, DistributedLawnDecor -from toontown.toon import DistributedToon, DistributedNPCToonBase, DistributedNPCToon, DistributedSmartNPC, DistributedSmartNPC, DistributedNPCSpecialQuestGiver, DistributedNPCFlippyInToonHall, DistributedNPCScientist, DistributedNPCClerk, DistributedNPCTailor, DistributedNPCBlocker, DistributedNPCFisherman, DistributedNPCPartyPerson, DistributedNPCPetclerk, DistributedNPCKartClerk, DistributedNPCBanker +from toontown.toon import DistributedToon, DistributedNPCToonBase, DistributedNPCToon, DistributedSmartNPC, DistributedSmartNPC, DistributedNPCSpecialQuestGiver, DistributedNPCFlippyInToonHall, DistributedNPCScientist, DistributedNPCClerk, DistributedNPCTailor, DistributedNPCBlocker, DistributedNPCFisherman, DistributedNPCPartyPerson, DistributedNPCPetclerk, DistributedNPCKartClerk, DistributedNPCGlove, DistributedNPCBanker from toontown.tutorial import DistributedBattleTutorial, TutorialManager from toontown.coderedemption.TTCodeRedemptionMgr import TTCodeRedemptionMgr from toontown.distributed.NonRepeatableRandomSourceAI import NonRepeatableRandomSourceAI diff --git a/toontown/ai/ToontownAIRepository.py b/toontown/ai/ToontownAIRepository.py index 2fcf6a35..cce49004 100644 --- a/toontown/ai/ToontownAIRepository.py +++ b/toontown/ai/ToontownAIRepository.py @@ -87,6 +87,7 @@ class ToontownAIRepository(ToontownInternalRepository): self.doLiveUpdates = self.config.GetBool('want-live-updates', False) self.wantTrackClsends = self.config.GetBool('want-track-clsends', False) self.wantAchievements = self.config.GetBool('want-achievements', True) + self.wantGloveNpc = self.config.GetBool('want-glove-npc', True) self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0) self.wantHalloween = self.config.GetBool('want-halloween', False) self.wantChristmas = self.config.GetBool('want-christmas', False) diff --git a/toontown/hood/TTHoodAI.py b/toontown/hood/TTHoodAI.py index 72303abc..4da83fd3 100644 --- a/toontown/hood/TTHoodAI.py +++ b/toontown/hood/TTHoodAI.py @@ -31,7 +31,13 @@ class TTHoodAI(HoodAI.HoodAI): self.createClassicChar() if simbase.config.GetBool('want-butterflies', True): self.createButterflies() - + + if simbase.air.wantGloveNpc: + NPCToons.createNPC( + simbase.air, 2021, + (ToontownGlobals.ToontownCentral, TTLocalizer.NPCToonNames[2021], ('dss', 'ls', 's', 'm', 13, 41, 13, 13, 1, 6, 1, 6, 0, 18), 'm', 1, NPCToons.NPC_GLOVE), + ToontownGlobals.ToontownCentral, posIndex=0) + if simbase.air.wantHalloween: self.TrickOrTreatTargetManager = DistributedTrickOrTreatTargetAI.DistributedTrickOrTreatTargetAI(self.air) self.TrickOrTreatTargetManager.generateWithRequired(2649) diff --git a/toontown/toon/DistributedNPCGlove.py b/toontown/toon/DistributedNPCGlove.py new file mode 100644 index 00000000..ac24c7fc --- /dev/null +++ b/toontown/toon/DistributedNPCGlove.py @@ -0,0 +1,106 @@ +from direct.fsm import ClassicFSM, State +from direct.gui.DirectGui import * +from direct.task.Task import Task +from pandac.PandaModules import * +import time + +from DistributedNPCToonBase import * +from toontown.chat.ChatGlobals import * +from toontown.effects import DustCloud +from toontown.nametag.NametagGlobals import * +from toontown.toonbase import TTLocalizer + +def getDustCloud(toon): + dustCloud = DustCloud.DustCloud(fBillboard=0) + + dustCloud.setBillboardAxis(2.0) + dustCloud.setZ(3) + dustCloud.setScale(0.4) + dustCloud.createTrack() + return Sequence(Wait(0.5), Func(dustCloud.reparentTo, toon), dustCloud.track, Func(dustCloud.destroy)) + +class DistributedNPCGlove(DistributedNPCToonBase): + def __init__(self, cr): + DistributedNPCToonBase.__init__(self, cr) + self.nextCollision = 0 + + self.fsm = ClassicFSM.ClassicFSM( + 'NPCGlove', + [ + State.State('off', self.enterOff, self.exitOff, ['pickColor']), + State.State('pickColor', self.enterPickColor, self.exitPickColor, ['off']) + ], 'off', 'off') + self.fsm.enterInitialState() + + def disable(self): + self.ignoreAll() + self.nextCollision = 0 + DistributedNPCToonBase.disable(self) + + def initToonState(self): + self.setAnimState('neutral', 1.05, None, None) + self.setPosHpr(101, -14, 4, -305, 0, 0) + + def getCollSphereRadius(self): + return 1.0 + + def handleCollisionSphereEnter(self, collEntry): + self.currentTime = time.time() + if self.nextCollision <= self.currentTime: + self.fsm.request('pickColor') + self.nextCollision = self.currentTime + 2 + + def enterOff(self): + pass + + def exitOff(self): + pass + + def enterPickColor(self): + base.cr.playGame.getPlace().setState('stopped') + taskMgr.doMethodLater(15, self.reset, 'npcSleepTask-%s' % self.doId) + self.popupPickColorGUI() + + def exitPickColor(self, task=None): + taskMgr.remove('npcSleepTask-%s' % self.doId) + + if task is not None: + return task.done + + def popupPickColorGUI(self): + self.setChatAbsolute('', CFSpeech) + self.setChatAbsolute("Hi fucker", CFSpeech) + base.setCellsActive(base.bottomCells, 0) + self.d_requestTransformation(8) + + def getMessageById(self, response): + if response == 1: + return TTLocalizer.GloveSameColorMessage + elif response == 2: + return TTLocalizer.GloveNoMoneyMessage + else: + return TTLocalizer.GloveSuccessMessage + + def doTransformation(self, avId, response): + av = self.cr.doId2do.get(avId) + + if not av: + return + + if response == 3: + getDustCloud(av).start() + + self.setChatAbsolute('', CFSpeech) + self.setChatAbsolute(self.getMessageById(response), CFSpeech|CFTimeout) + + def d_requestTransformation(self, color): + self.sendUpdate('requestTransformation', [color]) + self.reset() + + def reset(self, task=None): + self.fsm.request('off') + base.cr.playGame.getPlace().setState('walk') + base.setCellsActive(base.bottomCells, 1) + + if task is not None: + return task.done \ No newline at end of file diff --git a/toontown/toon/DistributedNPCGloveAI.py b/toontown/toon/DistributedNPCGloveAI.py new file mode 100644 index 00000000..a82faa3f --- /dev/null +++ b/toontown/toon/DistributedNPCGloveAI.py @@ -0,0 +1,27 @@ +from DistributedNPCToonBaseAI import DistributedNPCToonBaseAI +from ToonDNA import ToonDNA +from toontown.toonbase import ToontownGlobals + +class DistributedNPCGloveAI(DistributedNPCToonBaseAI): + + def requestTransformation(self, color): + avId = self.air.getAvatarIdFromSender() + av = self.air.doId2do.get(avId) + + if av is None or not hasattr(av, 'dna'): + return + + if av.dna.gloveColor == color: + self.sendUpdate('doTransformation', [avId, 1]) + return + + if av.getMoney() < ToontownGlobals.GloveCost: + self.sendUpdate('doTransformation', [avId, 2]) + return + + av.takeMoney(ToontownGlobals.GloveCost) + newDNA = ToonDNA() + newDNA.makeFromNetString(av.getDNAString()) + newDNA.gloveColor = color + taskMgr.doMethodLater(1.0, lambda task: av.b_setDNAString(newDNA.makeNetString()), 'transform-%d' % avId) + self.sendUpdate('doTransformation', [avId, 3]) \ No newline at end of file diff --git a/toontown/toon/DistributedToonAI.py b/toontown/toon/DistributedToonAI.py index 50a68957..21f191ef 100644 --- a/toontown/toon/DistributedToonAI.py +++ b/toontown/toon/DistributedToonAI.py @@ -4999,6 +4999,8 @@ def dna(part, value): invoker.b_setDNAString(backup['dna'][value]) return 'Restored a DNA backup for %s under the name: %s' % (invoker.getName(), value) + if part == 'show': + return dna.asTuple() return 'Invalid part: ' + part @magicWord(category=CATEGORY_ADMINISTRATOR, types=[int]) diff --git a/toontown/toon/NPCToons.py b/toontown/toon/NPCToons.py index f0d76fa0..c5636427 100644 --- a/toontown/toon/NPCToons.py +++ b/toontown/toon/NPCToons.py @@ -70,6 +70,7 @@ NPC_FLIPPYTOONHALL = 10 NPC_SCIENTIST = 11 NPC_SMART = 13 NPC_BANKER = 14 +NPC_GLOVE = 15 CLERK_COUNTDOWN_TIME = 120 TAILOR_COUNTDOWN_TIME = 300 RTDNAFile = '/RTDNAFile.txt' @@ -95,6 +96,7 @@ def createNPC(air, npcId, desc, zoneId, posIndex = 0, questCallback = None): import DistributedNPCScientistAI import DistributedSmartNPCAI import DistributedNPCBankerAI + import DistributedNPCGloveAI canonicalZoneId, name, dnaType, gender, protected, type = desc if type == NPC_REGULAR: npc = DistributedNPCToonAI.DistributedNPCToonAI(air, npcId, questCallback=questCallback) @@ -124,6 +126,8 @@ def createNPC(air, npcId, desc, zoneId, posIndex = 0, questCallback = None): npc = DistributedSmartNPCAI.DistributedSmartNPCAI(air, npcId) elif type == NPC_BANKER: npc = DistributedNPCBankerAI.DistributedNPCBankerAI(air, npcId) + elif type == NPC_GLOVE and simbase.air.wantGloveNpc: + npc = DistributedNPCGloveAI.DistributedNPCGloveAI(air, npcId) else: print 'createNPC() error!!!' npc.setName(name) diff --git a/toontown/toonbase/TTLocalizerEnglish.py b/toontown/toonbase/TTLocalizerEnglish.py index 142864f8..9eb23fbe 100644 --- a/toontown/toonbase/TTLocalizerEnglish.py +++ b/toontown/toonbase/TTLocalizerEnglish.py @@ -7007,6 +7007,7 @@ NPCToonNames = {20000: 'Tutorial Tom', 2018: 'Doctor Surlee', 2019: 'Doctor Dimm', 2020: 'Professor Prepostera', + 2021: 'Painter Joey', 2101: 'Dentist Daniel', 2102: 'Sheriff Sherry', 2103: 'Sneezy Kitty', @@ -9785,6 +9786,9 @@ InteractivePropTrackBonusTerms = {0: 'Super Toon-Up!', 5: 'Super Squirt!', 6: ''} PlayingCardUnknown = 'Card Name is unknown' +GloveSameColorMessage = 'You already have that glove!' +GloveNoMoneyMessage = "You don't have enough jellybeans!" +GloveSuccessMessage = 'Have fun with your new glove!' # Buffs diff --git a/toontown/toonbase/ToontownGlobals.py b/toontown/toonbase/ToontownGlobals.py index 8c830637..c277dbec 100644 --- a/toontown/toonbase/ToontownGlobals.py +++ b/toontown/toonbase/ToontownGlobals.py @@ -1676,6 +1676,7 @@ AV_TOUCH_CHECK_DIST_Z = 5.0 AV_TOUCH_CHECK_TIMELIMIT_CL = 0.002 AV_TOUCH_COUNT_LIMIT = 5 AV_TOUCH_COUNT_TIME = 300 +GloveCost = 2000 # Buffs...