175 lines
6.3 KiB
Python
175 lines
6.3 KiB
Python
from direct.directnotify.DirectNotifyGlobal import *
|
|
from direct.distributed.DistributedObjectAI import DistributedObjectAI
|
|
from direct.fsm.FSM import FSM
|
|
from toontown.building import FADoorCodes
|
|
from toontown.building.HQBuildingAI import HQBuildingAI
|
|
from toontown.building.TutorialBuildingAI import TutorialBuildingAI
|
|
from toontown.quest import Quests
|
|
from toontown.suit.DistributedTutorialSuitAI import DistributedTutorialSuitAI
|
|
from toontown.toon import NPCToons
|
|
from toontown.toonbase import ToontownBattleGlobals
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
|
|
class TutorialFSM(FSM):
|
|
def __init__(self, air, zones, avId):
|
|
FSM.__init__(self, 'TutorialFSM')
|
|
|
|
self.air = air
|
|
self.zones = zones
|
|
self.avId = avId
|
|
|
|
npcDesc = NPCToons.NPCToonDict.get(20000)
|
|
self.tutorialTom = NPCToons.createNPC(self.air, 20000, npcDesc, self.zones['building'])
|
|
self.tutorialTom.setTutorial(1)
|
|
|
|
npcDesc = NPCToons.NPCToonDict.get(20002)
|
|
self.hqHarry = NPCToons.createNPC(self.air, 20002, npcDesc, self.zones['hq'])
|
|
self.hqHarry.setTutorial(1)
|
|
self.hqHarry.setHq(1)
|
|
|
|
self.building = TutorialBuildingAI(
|
|
self.air, self.zones['street'], self.zones['building'], 2, self.tutorialTom.getDoId())
|
|
self.hq = HQBuildingAI(self.air, self.zones['street'], self.zones['hq'], 1)
|
|
|
|
self.forceTransition('Introduction')
|
|
|
|
def enterIntroduction(self):
|
|
self.building.insideDoor.setDoorLock(FADoorCodes.TALK_TO_TOM)
|
|
|
|
def exitIntroduction(self):
|
|
self.building.insideDoor.setDoorLock(FADoorCodes.UNLOCKED)
|
|
|
|
def enterBattle(self):
|
|
self.suit = DistributedTutorialSuitAI(self.air)
|
|
self.suit.generateWithRequired(self.zones['street'])
|
|
|
|
self.building.door.setDoorLock(FADoorCodes.DEFEAT_FLUNKY_TOM)
|
|
self.hq.door0.setDoorLock(FADoorCodes.DEFEAT_FLUNKY_HQ)
|
|
self.hq.door1.setDoorLock(FADoorCodes.DEFEAT_FLUNKY_HQ)
|
|
|
|
def exitBattle(self):
|
|
if self.suit:
|
|
self.suit.requestDelete()
|
|
|
|
def enterHQ(self):
|
|
self.building.door.setDoorLock(FADoorCodes.TALK_TO_HQ)
|
|
self.hq.door0.setDoorLock(FADoorCodes.UNLOCKED)
|
|
self.hq.door1.setDoorLock(FADoorCodes.UNLOCKED)
|
|
self.hq.insideDoor0.setDoorLock(FADoorCodes.TALK_TO_HQ)
|
|
self.hq.insideDoor1.setDoorLock(FADoorCodes.TALK_TO_HQ)
|
|
|
|
def enterTunnel(self):
|
|
npcDesc = NPCToons.NPCToonDict.get(20001)
|
|
self.flippy = NPCToons.createNPC(self.air, 20001, npcDesc, self.zones['street'], 0)
|
|
self.hq.insideDoor0.setDoorLock(FADoorCodes.WRONG_DOOR_HQ)
|
|
self.hq.insideDoor1.setDoorLock(FADoorCodes.UNLOCKED)
|
|
self.hq.door0.setDoorLock(FADoorCodes.GO_TO_PLAYGROUND)
|
|
self.hq.door1.setDoorLock(FADoorCodes.GO_TO_PLAYGROUND)
|
|
self.building.door.setDoorLock(FADoorCodes.GO_TO_PLAYGROUND)
|
|
|
|
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['street'])
|
|
self.air.deallocateZone(self.zones['building'])
|
|
self.air.deallocateZone(self.zones['hq'])
|
|
|
|
del self.air.tutorialManager.avId2fsm[self.avId]
|
|
|
|
|
|
class TutorialManagerAI(DistributedObjectAI):
|
|
notify = directNotify.newCategory('TutorialManagerAI')
|
|
|
|
def __init__(self, air):
|
|
DistributedObjectAI.__init__(self, air)
|
|
|
|
self.avId2fsm = {}
|
|
|
|
def requestTutorial(self):
|
|
avId = self.air.getAvatarIdFromSender()
|
|
|
|
zones = {}
|
|
zones['street'] = self.air.allocateZone()
|
|
zones['building'] = self.air.allocateZone()
|
|
zones['hq'] = self.air.allocateZone()
|
|
|
|
self.avId2fsm[avId] = TutorialFSM(self.air, zones, avId)
|
|
|
|
self.acceptOnce(self.air.getAvatarExitEvent(avId), self.__handleUnexpectedExit, extraArgs=[avId])
|
|
self.d_enterTutorial(avId, ToontownGlobals.Tutorial, zones['street'], zones['building'], zones['hq'])
|
|
|
|
def rejectTutorial(self):
|
|
pass
|
|
|
|
def requestSkipTutorial(self):
|
|
avId = self.air.getAvatarIdFromSender()
|
|
self.d_skipTutorialResponse(avId, 1)
|
|
|
|
|
|
def handleTutorialSkipped(av):
|
|
av.b_setTutorialAck(1)
|
|
av.b_setQuests([[110, 1, 1000, 100, 1]])
|
|
av.b_setQuestHistory([101])
|
|
av.b_setRewardHistory(1, [])
|
|
|
|
|
|
# We must wait for the avatar to be generated:
|
|
self.acceptOnce('generate-%d' % avId, handleTutorialSkipped)
|
|
|
|
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 allDone(self):
|
|
avId = self.air.getAvatarIdFromSender()
|
|
av = self.air.doId2do.get(avId)
|
|
if av is not None:
|
|
av.b_setTutorialAck(1)
|
|
self.ignore(self.air.getAvatarExitEvent(avId))
|
|
fsm = self.avId2fsm.get(avId)
|
|
if fsm is not None:
|
|
fsm.demand('Cleanup')
|
|
else:
|
|
self.air.writeServerEvent('suspicious', avId, issue='Attempted to exit a non-existent tutorial.')
|
|
|
|
def toonArrived(self):
|
|
avId = self.air.getAvatarIdFromSender()
|
|
av = self.air.doId2do.get(avId)
|
|
if av is None:
|
|
return
|
|
|
|
if av.getTutorialAck():
|
|
self.avId2fsm[avId].demand('Cleanup')
|
|
self.air.writeServerEvent('suspicious', avId, issue='Attempted to enter a tutorial when it should be impossible.')
|
|
return
|
|
|
|
# Prepare the player for the tutorial:
|
|
av.b_setQuests([])
|
|
av.b_setQuestHistory([])
|
|
av.b_setRewardHistory(0, [])
|
|
av.b_setHp(15)
|
|
av.b_setMaxHp(15)
|
|
av.inventory.zeroInv(killUber=True)
|
|
access = av.getTrackAccess()
|
|
|
|
for i in xrange(len(access)):
|
|
if access[i] == 1:
|
|
av.inventory.addItem(i, 0)
|
|
|
|
av.d_setInventory(av.inventory.makeNetString())
|
|
av.experience.zeroOutExp()
|
|
av.d_setExperience(av.experience.makeNetString())
|
|
|
|
def __handleUnexpectedExit(self, avId):
|
|
fsm = self.avId2fsm.get(avId)
|
|
if fsm is not None:
|
|
fsm.demand('Cleanup')
|