historical/toontown-classic.git/toontown/tutorial/TutorialManagerAI.py
2024-01-16 11:20:27 -06:00

216 lines
7.9 KiB
Python

from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from direct.fsm.FSM import FSM
from toontown.building import DoorTypes
from toontown.building import FADoorCodes
from toontown.building.DistributedDoorAI import DistributedDoorAI
from toontown.building.DistributedTutorialInteriorAI import DistributedTutorialInteriorAI
from toontown.building.HQBuildingAI import HQBuildingAI
from toontown.quest import Quests
from toontown.suit.DistributedTutorialSuitAI import DistributedTutorialSuitAI
from toontown.toon import NPCToons
from toontown.toonbase import TTLocalizer
from toontown.toonbase import ToontownBattleGlobals
class TutorialZones:
BRANCH = 0
STREET = 0
SHOP = 0
HQ = 0
class TutorialBuildingAI:
notify = DirectNotifyGlobal.directNotify.newCategory('TutorialBuildingAI')
def __init__(self, air, street, interior, npcId):
self.air = air
self.interior = DistributedTutorialInteriorAI(self.air, interior, npcId)
self.interior.generateWithRequired(interior)
self.door0 = DistributedDoorAI(self.air, 2, DoorTypes.EXT_STANDARD, doorIndex=0)
self.insideDoor0 = DistributedDoorAI(self.air, 0, DoorTypes.INT_STANDARD, doorIndex=0)
self.door0.setOtherDoor(self.insideDoor0)
self.insideDoor0.setOtherDoor(self.door0)
self.door0.zoneId = street
self.insideDoor0.zoneId = interior
self.door0.generateWithRequired(street)
self.door0.sendUpdate('setDoorIndex', [self.door0.getDoorIndex()])
self.insideDoor0.generateWithRequired(interior)
self.insideDoor0.sendUpdate('setDoorIndex', [self.insideDoor0.getDoorIndex()])
def cleanup(self):
self.door0.requestDelete()
self.insideDoor0.requestDelete()
self.interior.requestDelete()
class TutorialFSM(FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('TutorialFSM')
def __init__(self, air, zones, avId):
FSM.__init__(self, 'TutorialFSM')
self.air = air
self.zones = zones
self.avId = avId
self.suit = None
self.flippy = None
tutorialTomDesc = NPCToons.NPCToonDict.get(20000)
self.tutorialTom = NPCToons.createNPC(self.air, 20000, tutorialTomDesc, self.zones.SHOP, 0)
self.tutorialTom.setTutorial(1)
hqHarryDesc = (
-1, TTLocalizer.TutorialHQOfficerName, ('dls', 'ms', 'm', 'm', 6, 0, 6, 6, 0, 10, 0, 10, 0, 9), 'm', 1,
NPCToons.NPC_HQ)
self.hqHarry = NPCToons.createNPC(self.air, 20002, hqHarryDesc, self.zones.HQ, 0)
self.hqHarry.setTutorial(1)
self.building = TutorialBuildingAI(self.air, zones.STREET, zones.SHOP, self.tutorialTom.getDoId())
self.hq = HQBuildingAI(self.air, zones.STREET, zones.HQ, 1)
self.forceTransition('Introduction')
def enterIntroduction(self):
self.building.insideDoor0.setDoorLock(FADoorCodes.TALK_TO_TOM)
def exitIntroduction(self):
self.building.insideDoor0.setDoorLock(FADoorCodes.UNLOCKED)
def enterBattle(self):
self.suit = DistributedTutorialSuitAI(self.air)
self.suit.generateWithRequired(self.zones.STREET)
self.building.door0.setDoorLock(FADoorCodes.DEFEAT_FLUNKY_TOM)
self.hq.door0.setDoorLock(FADoorCodes.DEFEAT_FLUNKY_HQ)
def exitBattle(self):
if self.suit:
self.suit.requestDelete()
def enterHQ(self):
self.building.door0.setDoorLock(FADoorCodes.TALK_TO_HQ_TOM)
self.hq.door0.setDoorLock(FADoorCodes.UNLOCKED)
self.hq.insideDoor0.setDoorLock(FADoorCodes.TALK_TO_HQ)
self.hq.insideDoor1.setDoorLock(FADoorCodes.TALK_TO_HQ)
def enterTunnel(self):
flippyDesc = NPCToons.NPCToonDict.get(20001)
self.flippy = NPCToons.createNPC(self.air, 20001, flippyDesc, self.zones.STREET, 0)
self.hq.insideDoor1.setDoorLock(FADoorCodes.UNLOCKED)
self.hq.door1.setDoorLock(FADoorCodes.GO_TO_PLAYGROUND)
self.hq.insideDoor0.setDoorLock(FADoorCodes.WRONG_DOOR_HQ)
def exitTunnel(self):
self.flippy.requestDelete()
def enterCleanup(self):
self.building.cleanup()
self.hq.cleanup()
self.tutorialTom.requestDelete()
self.hqHarry.requestDelete()
self.air.deallocateZone(self.zones.BRANCH)
self.air.deallocateZone(self.zones.STREET)
self.air.deallocateZone(self.zones.SHOP)
self.air.deallocateZone(self.zones.HQ)
del self.air.tutorialManager.avId2fsm[self.avId]
class TutorialManagerAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory('TutorialManagerAI')
def __init__(self, air):
DistributedObjectAI.__init__(self, air)
self.avId2fsm = {}
def requestTutorial(self):
avId = self.air.getAvatarIdFromSender()
if not avId:
return
zones = TutorialZones()
zones.BRANCH = self.air.allocateZone()
zones.STREET = self.air.allocateZone()
zones.SHOP = self.air.allocateZone()
zones.HQ = self.air.allocateZone()
self.avId2fsm[avId] = TutorialFSM(self.air, zones, avId)
event = self.air.getAvatarExitEvent(avId)
self.acceptOnce(event, self.__unexpectedExit, extraArgs=[avId])
self.d_enterTutorial(avId, zones.STREET, zones.STREET, zones.SHOP, zones.HQ)
def __unexpectedExit(self, avId):
fsm = self.avId2fsm.get(avId)
if fsm:
fsm.demand('Cleanup')
def rejectTutorial(self):
# This is never used by the client.
pass
def requestSkipTutorial(self):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
av.b_setTutorialAck(1)
av.b_setQuestHistory([101])
av.b_setRewardHistory(0, [100])
av.addQuest(
(110, Quests.getQuestFromNpcId(110), Quests.getQuestToNpcId(110), Quests.getQuestReward(110, av), 0), 0)
self.air.questManager.toonRodeTrolleyFirstTime(av)
self.d_skipTutorialResponse(avId, 1)
else:
self.d_skipTutorialResponse(avId, 0)
def d_skipTutorialResponse(self, avId, allOk):
self.sendUpdateToAvatarId(avId, 'skipTutorialResponse', [allOk])
def d_enterTutorial(self, avId, branchZone, streetZone, shopZone, hqZone):
self.sendUpdateToAvatarId(avId, 'enterTutorial', [branchZone, streetZone, shopZone, hqZone])
def toonArrived(self):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if not av:
return
if av.getTutorialAck():
self.avId2fsm[avId].demand('Cleanup')
self.air.writeServerEvent('suspicious', avId,
'Attempted to request tutorial when it would be impossible to do so')
return
# Reset Toon so that their stats are appropriate for the tutorial.
av.b_setQuests([])
av.b_setQuestHistory([])
av.b_setRewardHistory(0, [])
av.b_setHp(15)
av.b_setMaxHp(15)
av.inventory.zeroInv()
if av.inventory.numItem(ToontownBattleGlobals.THROW_TRACK, 0) == 0:
av.inventory.addItem(ToontownBattleGlobals.THROW_TRACK, 0)
if av.inventory.numItem(ToontownBattleGlobals.SQUIRT_TRACK, 0) == 0:
av.inventory.addItem(ToontownBattleGlobals.SQUIRT_TRACK, 0)
av.d_setInventory(av.inventory.makeNetString())
av.experience.zeroOutExp()
av.d_setExperience(av.experience.makeNetString())
def allDone(self):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if av:
av.b_setTutorialAck(1)
event = self.air.getAvatarExitEvent(avId)
self.ignore(event)
fsm = self.avId2fsm.get(avId)
if fsm:
fsm.demand('Cleanup')
else:
self.air.writeServerEvent('suspicious', avId, 'Attempted to exit a non-existent tutorial.')