265 lines
11 KiB
Python
265 lines
11 KiB
Python
from direct.directnotify import DirectNotifyGlobal
|
|
|
|
from toontown.quest import Quests
|
|
|
|
|
|
class QuestManagerAI:
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('QuestManagerAI')
|
|
|
|
def __init__(self, air):
|
|
self.air = air
|
|
|
|
def toonPlayedMinigame(self, toon, toons):
|
|
# toons is never used. Sad!
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.TrolleyQuest):
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
def recoverItems(self, toon, suitsKilled, zoneId):
|
|
recovered, notRecovered = ([] for _ in xrange(2))
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.RecoverItemQuest):
|
|
isComplete = quest.getCompletionStatus(toon, toon.quests[index])
|
|
if isComplete == Quests.COMPLETE:
|
|
continue
|
|
|
|
if quest.isLocationMatch(zoneId):
|
|
if quest.getHolder() == Quests.Any or quest.getHolderType() in ['type', 'track', 'level']:
|
|
for suit in suitsKilled:
|
|
if quest.getCompletionStatus(toon, toon.quests[index]) == Quests.COMPLETE:
|
|
break
|
|
|
|
if (quest.getHolder() == Quests.Any) or (
|
|
quest.getHolderType() == 'type' and quest.getHolder() == suit['type']) or (
|
|
quest.getHolderType() == 'track' and quest.getHolder() == suit['track']) or (
|
|
quest.getHolderType() == 'level' and quest.getHolder() <= suit['level']):
|
|
# This seems to be how Disney did it.
|
|
progress = toon.quests[index][4] & pow(2, 16) - 1
|
|
completion = quest.testRecover(progress)
|
|
if completion[0]:
|
|
# Recovered!
|
|
recovered.append(quest.getItem())
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
else:
|
|
# Not recovered. Sad!
|
|
notRecovered.append(quest.getItem())
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
return recovered, notRecovered
|
|
|
|
def toonKilledCogs(self, toon, suitsKilled, zoneId, activeToons):
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.CogQuest):
|
|
for suit in suitsKilled:
|
|
for _ in xrange(quest.doesCogCount(toon.getDoId(), suit, zoneId, activeToons)):
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
def toonKilledCogdo(self, toon, difficulty, numFloors, zoneId, activeToons):
|
|
pass
|
|
|
|
def toonKilledBuilding(self, toon, track, difficulty, floors, zoneId, activeToons):
|
|
# Thank you difficulty, very cool!
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.BuildingQuest):
|
|
if quest.isLocationMatch(zoneId):
|
|
if quest.getBuildingTrack() == Quests.Any or quest.getBuildingTrack() == track:
|
|
if floors >= quest.getNumFloors():
|
|
for _ in xrange(quest.doesBuildingCount(toon.getDoId(), activeToons)):
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
def toonDefeatedFactory(self, toon, factoryId, activeToonVictors):
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.FactoryQuest):
|
|
for _ in xrange(quest.doesFactoryCount(toon.getDoId(), factoryId, activeToonVictors)):
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
def toonRecoveredCogSuitPart(self, toon, zoneId, toonList):
|
|
pass
|
|
|
|
def toonDefeatedMint(self, toon, mintId, activeToonVictors):
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.MintQuest):
|
|
for _ in xrange(quest.doesMintCount(toon.getDoId(), mintId, activeToonVictors)):
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
def toonDefeatedStage(self, toon, stageId, activeToonVictors):
|
|
pass
|
|
|
|
def hasTailorClothingTicket(self, toon, npc):
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
isComplete = quest.getCompletionStatus(toon, toon.quests[index], npc)
|
|
if isComplete == Quests.COMPLETE:
|
|
return True
|
|
|
|
return False
|
|
|
|
def requestInteract(self, avId, npc):
|
|
av = self.air.doId2do.get(avId)
|
|
if not av:
|
|
return
|
|
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(av.quests)):
|
|
questId, fromNpcId, toNpcId, rewardId, toonProgress = av.quests[index]
|
|
isComplete = quest.getCompletionStatus(av, av.quests[index], npc)
|
|
if isComplete != Quests.COMPLETE:
|
|
continue
|
|
|
|
if avId in self.air.tutorialManager.avId2fsm.keys():
|
|
self.air.tutorialManager.avId2fsm[avId].demand('Tunnel')
|
|
|
|
if isinstance(quest, Quests.DeliverGagQuest):
|
|
track, level = quest.getGagType()
|
|
av.inventory.setItem(track, level, av.inventory.numItem(track, level) - quest.getNumGags())
|
|
av.b_setInventory(av.inventory.makeNetString())
|
|
|
|
nextQuest = Quests.getNextQuest(questId, npc, av)
|
|
if nextQuest == (Quests.NA, Quests.NA):
|
|
if isinstance(quest, Quests.TrackChoiceQuest):
|
|
npc.presentTrackChoice(avId, questId, quest.getChoices())
|
|
return
|
|
|
|
rewardId = Quests.getAvatarRewardId(av, questId)
|
|
npc.completeQuest(avId, questId, rewardId)
|
|
self.completeQuest(av, questId)
|
|
self.giveReward(av, rewardId)
|
|
return
|
|
else:
|
|
self.completeQuest(av, questId)
|
|
nextQuestId = nextQuest[0]
|
|
nextRewardId = Quests.getFinalRewardId(questId, 1)
|
|
nextToNpcId = nextQuest[1]
|
|
self.npcGiveQuest(npc, av, nextQuestId, nextRewardId, nextToNpcId)
|
|
return
|
|
|
|
if len(self.__toonQuestsList2Quests(av.quests)) >= av.getQuestCarryLimit():
|
|
npc.rejectAvatar(avId)
|
|
return
|
|
|
|
if avId in self.air.tutorialManager.avId2fsm.keys():
|
|
if av.getRewardHistory()[0] == 0:
|
|
self.npcGiveQuest(npc, av, 101, Quests.findFinalRewardId(101)[0], Quests.getQuestToNpcId(101),
|
|
storeReward=True)
|
|
self.air.tutorialManager.avId2fsm[avId].demand('Battle')
|
|
return
|
|
|
|
tier = av.getRewardHistory()[0]
|
|
if Quests.avatarHasAllRequiredRewards(av, tier):
|
|
if not Quests.avatarWorkingOnRequiredRewards(av):
|
|
if tier != Quests.LOOPING_FINAL_TIER:
|
|
tier += 1
|
|
|
|
av.b_setRewardHistory(tier, [])
|
|
else:
|
|
npc.rejectAvatarTierNotDone(avId)
|
|
return
|
|
|
|
bestQuests = Quests.chooseBestQuests(tier, npc, av)
|
|
if not bestQuests:
|
|
npc.rejectAvatar(avId)
|
|
return
|
|
|
|
npc.presentQuestChoice(avId, bestQuests)
|
|
return
|
|
|
|
def __toonQuestsList2Quests(self, quests):
|
|
return [Quests.getQuest(x[0]) for x in quests]
|
|
|
|
def avatarCancelled(self, avId):
|
|
pass
|
|
|
|
def avatarChoseQuest(self, avId, npc, questId, rewardId, toNpcId):
|
|
av = self.air.doId2do.get(avId)
|
|
if not av:
|
|
return
|
|
|
|
self.npcGiveQuest(npc, av, questId, rewardId, toNpcId, storeReward=True)
|
|
|
|
def npcGiveQuest(self, npc, av, questId, rewardId, toNpcId, storeReward=False):
|
|
rewardId = Quests.transformReward(rewardId, av)
|
|
finalReward = rewardId if storeReward else 0
|
|
progress = 0
|
|
av.addQuest((questId, npc.getDoId(), toNpcId, rewardId, progress), finalReward)
|
|
npc.assignQuest(av.getDoId(), questId, rewardId, toNpcId)
|
|
|
|
def __incrementQuestProgress(self, quest):
|
|
quest[4] += 1
|
|
|
|
def completeQuest(self, toon, questId):
|
|
toon.toonUp(toon.getMaxHp())
|
|
toon.removeQuest(questId)
|
|
|
|
def toonRodeTrolleyFirstTime(self, toon):
|
|
# For this, we just call toonPlayedMinigame with the toon.
|
|
# And for toons, we just pass in an empty list. Not like
|
|
# it matters anyway, as that argument is never used.
|
|
self.toonPlayedMinigame(toon, [])
|
|
|
|
def removeClothingTicket(self, toon, npc):
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
questId, fromNpcId, toNpcId, rewardId, toonProgress = toon.quests[index]
|
|
isComplete = quest.getCompletionStatus(toon, toon.quests[index], npc)
|
|
if isComplete == Quests.COMPLETE:
|
|
toon.removeQuest(questId)
|
|
return True
|
|
|
|
return False
|
|
|
|
def giveReward(self, toon, rewardId):
|
|
reward = Quests.getReward(rewardId)
|
|
if reward:
|
|
reward.sendRewardAI(toon)
|
|
|
|
def toonMadeFriend(self, toon, otherToon):
|
|
# This is so sad, can we leave otherToon unused?
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.FriendQuest):
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
def toonFished(self, toon, zoneId):
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.RecoverItemQuest):
|
|
if quest.getCompletionStatus(toon, toon.quests[index]) == Quests.COMPLETE:
|
|
continue
|
|
|
|
if quest.isLocationMatch(zoneId):
|
|
if quest.getHolder() == Quests.AnyFish:
|
|
# This seems to be how Disney did it.
|
|
progress = toon.quests[index][4] & pow(2, 16) - 1
|
|
completion = quest.testRecover(progress)
|
|
if completion[0]:
|
|
# Recovered!
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|
|
|
|
return quest.getItem()
|
|
|
|
return 0
|
|
|
|
def toonCalledClarabelle(self, toon):
|
|
for index, quest in enumerate(self.__toonQuestsList2Quests(toon.quests)):
|
|
if isinstance(quest, Quests.PhoneQuest):
|
|
self.__incrementQuestProgress(toon.quests[index])
|
|
|
|
if toon.quests:
|
|
toon.d_setQuests(toon.getQuests())
|