177 lines
6.0 KiB
Python
177 lines
6.0 KiB
Python
from toontown.toonbase import TTLocalizer
|
|
from direct.distributed.ClockDelta import *
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from . import DistributedNPCToonBaseAI
|
|
from direct.task import Task
|
|
import random
|
|
|
|
class NPCDialogue:
|
|
"""
|
|
The NPC dialogue for a given topic and set of participants
|
|
"""
|
|
|
|
notify = DirectNotifyGlobal.directNotify.newCategory("NPCDialogue")
|
|
|
|
def __init__(self, participant, dialogueTopic):
|
|
self.participants = {}
|
|
|
|
if dialogueTopic in TTLocalizer.toontownDialogues:
|
|
self.topic = dialogueTopic
|
|
else:
|
|
self.notify.warning("Dialogue does not exist: %s" %dialogueTopic)
|
|
self.topic = TTLocalizer.BoringTopic
|
|
|
|
self.conversation = TTLocalizer.toontownDialogues[self.topic]
|
|
|
|
if participant and isinstance(participant, DistributedNPCToonBaseAI.DistributedNPCToonBaseAI):
|
|
self.addParticipant(participant)
|
|
self.participantProgress = 0
|
|
self.currentParticipant = participant.npcId
|
|
else:
|
|
self.notify.warning("Participant does not exist: %s" %participant)
|
|
self.participantProgress = 0
|
|
self.currrentParticipant = None
|
|
|
|
def calcMaxNumMsgs(self):
|
|
"""
|
|
Find the participant that has the most number of things to say
|
|
"""
|
|
self.maxNumMsgs = 0
|
|
for participant, spiel in self.conversation.items():
|
|
if len(spiel)>self.maxNumMsgs and participant[1] in self.participants:
|
|
self.maxNumMsgs = len(spiel)
|
|
|
|
def getTopic(self):
|
|
"""
|
|
Accessor function for topic
|
|
"""
|
|
return self.topic
|
|
|
|
def addParticipant(self, participant):
|
|
"""
|
|
Add a new participant
|
|
"""
|
|
if self.getNumParticipants() > self.getMaxParticipants():
|
|
return False
|
|
if participant:
|
|
for partPos in self.conversation.keys():
|
|
if partPos[1] == participant.npcId:
|
|
if not (participant.npcId in self.participants):
|
|
self.participants[participant.npcId] = [participant]
|
|
else:
|
|
if participant not in self.participants[participant.npcId]:
|
|
self.participants[participant.npcId].append(participant)
|
|
else:
|
|
self.notify.warning("Participant: %s already in the conversation" %participant)
|
|
self.calcMaxNumMsgs()
|
|
return True
|
|
self.notify.warning("Participant: %s should not be in conversation" %participant)
|
|
return False
|
|
|
|
def removeParticipant(self, participant):
|
|
"""
|
|
Remove a participant
|
|
"""
|
|
if participant.npcId in self.participants:
|
|
if participant.npcId == self.currentParticipant:
|
|
self.getNextParticipant()
|
|
self.participants[participant.npcId].remove(participant)
|
|
if self.participants[participant.npcId] == []:
|
|
del self.participants[participant.npcId]
|
|
self.calcMaxNumMsgs()
|
|
return True
|
|
return False
|
|
|
|
def getNextParticipant(self):
|
|
while 1:
|
|
self.currentParticipant = self.calcNextParticipant()
|
|
if self.currentParticipant in self.participants:
|
|
break
|
|
|
|
def calcNextParticipant(self):
|
|
"""
|
|
Returns the next in line to talk
|
|
"""
|
|
nextParticipant = None
|
|
|
|
for partPos in self.conversation.keys():
|
|
if partPos[1] == self.currentParticipant:
|
|
nextPos = partPos[0]+1
|
|
break
|
|
if nextPos>len(self.conversation):
|
|
nextPos = 1
|
|
self.participantProgress = (self.participantProgress+1)%self.maxNumMsgs
|
|
for partPos in self.conversation.keys():
|
|
if partPos[0] == nextPos:
|
|
nextParticipant = partPos[1]
|
|
return nextParticipant
|
|
|
|
return self.currentParticipant
|
|
|
|
|
|
def getMaxParticipants(self):
|
|
"""
|
|
Number of conversation pieces provided in TTLocalizer
|
|
"""
|
|
return len(self.conversation)
|
|
|
|
def getNumParticipants(self):
|
|
"""
|
|
Returns the number of NPC's currently participating
|
|
"""
|
|
return len(self.participants)
|
|
|
|
def isRunning(self):
|
|
if taskMgr.hasTaskNamed("Dialogue"+self.topic):
|
|
return True
|
|
|
|
def start(self):
|
|
"""
|
|
Start up a dialogue amongst the participants
|
|
"""
|
|
self.nextChatTime = 0
|
|
|
|
taskMgr.add(self.__blather, "Dialogue"+self.topic)
|
|
|
|
return True
|
|
|
|
def stop(self):
|
|
"""
|
|
This conversation is over!
|
|
"""
|
|
taskMgr.remove("Dialogue"+self.topic)
|
|
|
|
def __blather(self, task):
|
|
"""
|
|
Speak in turn
|
|
"""
|
|
now = globalClock.getFrameTime()
|
|
if now < self.nextChatTime:
|
|
return Task.cont
|
|
|
|
if not self.currentParticipant:
|
|
return Task.done
|
|
|
|
# Increment the participantProgress
|
|
for partPos in self.conversation.keys():
|
|
if partPos[1] == self.currentParticipant:
|
|
convKey = partPos
|
|
break
|
|
if self.participantProgress >= len(self.conversation[convKey]):
|
|
self.getNextParticipant()
|
|
return Task.cont
|
|
|
|
# Select the current spiel
|
|
#msg = self.conversation[self.participants[self.currentParticipant]][self.participantProgress]
|
|
|
|
for participant in self.participants[self.currentParticipant]:
|
|
chatFlags = CFSpeech | CFTimeout
|
|
|
|
participant.sendUpdate("setChat", [self.topic, convKey[0], convKey[1], self.participantProgress, chatFlags])
|
|
|
|
self.getNextParticipant()
|
|
|
|
# Delay before next message
|
|
self.nextChatTime = now + 5.0
|
|
|
|
return Task.cont |