Toon: Gender Removal is complete

Only things that cant be tested right now are estates
This commit is contained in:
DarthNihilus1 2023-11-13 23:01:17 -05:00
parent 3a83435282
commit 88f4b583f3
15 changed files with 1441 additions and 675 deletions

View File

@ -48,10 +48,10 @@ class BodyShop(StateData.StateData):
self.__swapHead(0)
self.__swapTorso(0)
self.__swapLegs(0)
choicePool = [ToonDNA.toonHeadTypes, torsoPool, ToonDNA.toonLegTypes]
self.__swapEyelashes(0)
choicePool = [ToonDNA.toonHeadTypes, torsoPool, ToonDNA.toonLegTypes, [0, 1]]
self.shuffleButton.setChoicePool(choicePool)
self.accept(self.shuffleFetchMsg, self.changeBody)
self.acceptOnce('last', self.__handleBackward)
self.accept('next', self.__handleForward)
self.acceptOnce('MAT-newToonCreated', self.shuffleButton.cleanHistory)
self.restrictHeadType(self.dna.head)
@ -131,6 +131,44 @@ class BodyShop(StateData.StateData):
shuffleArrowDown,
shuffleArrowRollover,
shuffleArrowDisabled), image_scale=halfButtonInvertScale, image1_scale=halfButtonInvertHoverScale, image2_scale=halfButtonInvertHoverScale, pos=(0.2, 0, 0), command=self.__swapLegs, extraArgs=[1])
# Creates the eyelashes frame
self.eyelashesFrame = DirectFrame(
parent=self.parentFrame,
image=shuffleFrame,
image_scale=halfButtonInvertScale,
relief=None,
pos=(0, 0, -0.9),
hpr=(0, 0, 3),
scale=0.9,
frameColor=(1, 1, 1, 1),
text=TTLocalizer.BodyShopEyelashes,
text_scale=0.0625,
text_pos=(-0.001, -0.015),
text_fg=(1, 1, 1, 1),
)
self.eyelashesLButton = DirectButton(
parent=self.eyelashesFrame,
relief=None,
image=(shuffleArrowUp, shuffleArrowDown, shuffleArrowRollover, shuffleArrowDisabled),
image_scale=halfButtonScale,
image1_scale=halfButtonHoverScale,
image2_scale=halfButtonHoverScale,
pos=(-0.2, 0, 0),
command=self.__swapEyelashes,
extraArgs=[-1],
)
self.eyelashesRButton = DirectButton(
parent=self.eyelashesFrame,
relief=None,
image=(shuffleArrowUp, shuffleArrowDown, shuffleArrowRollover, shuffleArrowDisabled),
image_scale=halfButtonInvertScale,
image1_scale=halfButtonInvertHoverScale,
image2_scale=halfButtonInvertHoverScale,
pos=(0.2, 0, 0),
command=self.__swapEyelashes,
extraArgs=[1],
)
self.memberButton = DirectButton(relief=None, image=(upsellTex,
upsellTex,
upsellTex,
@ -151,6 +189,7 @@ class BodyShop(StateData.StateData):
self.headFrame.destroy()
self.bodyFrame.destroy()
self.legsFrame.destroy()
self.eyelashesFrame.destroy()
self.speciesLButton.destroy()
self.speciesRButton.destroy()
self.headLButton.destroy()
@ -159,12 +198,15 @@ class BodyShop(StateData.StateData):
self.torsoRButton.destroy()
self.legLButton.destroy()
self.legRButton.destroy()
self.eyelashesLButton.destroy()
self.eyelashesRButton.destroy()
self.memberButton.destroy()
del self.parentFrame
del self.speciesFrame
del self.headFrame
del self.bodyFrame
del self.legsFrame
del self.eyelashesFrame
del self.speciesLButton
del self.speciesRButton
del self.headLButton
@ -173,6 +215,8 @@ class BodyShop(StateData.StateData):
del self.torsoRButton
del self.legLButton
del self.legRButton
del self.eyelashesLButton
del self.eyelashesRButton
del self.memberButton
self.shuffleButton.unload()
self.ignore('MAT-newToonCreated')
@ -258,20 +302,22 @@ class BodyShop(StateData.StateData):
self.toon.swapToonColor(self.dna)
self.restrictHeadType(newHead)
def __swapEyelashes(self, offset):
def __swapEyelashes(self, offset):
length = len([0,1])
self.eyelashesChoice = (self.eyelashesChoice + offset ) % length
self.__updateScrollButtons(self.eyelashesChoice, length, self.eyelashesStart,
self.eyelashesLButton, self.eyelashesRButton)
self.eyelashesLButton, self.eyelashesRButton)
self.eyelashes = [0, 1][self.eyelashesChoice]
self.__updateEyelashes()
def __updateEyelashes(self):
return
#WIP
#TODO figure out what toggles eyelashes and use the model head based on if they want eyelashes or not
self.__updateScrollButtons(self.eyelashesChoice, len([0, 1]), self.eyelashesStart,
self.eyelashesLButton, self.eyelashesRButton)
eyelashesIndex = self.eyelashesChoice
self.dna.eyelashes = eyelashesIndex
self.toon.setEyelashes(eyelashesIndex)
self.toon.setupEyelashes(self.dna)
self.toon.loop("neutral", 0)
def __updateScrollButtons(self, choice, length, start, lButton, rButton):
if choice == (start - 1) % length:
rButton['state'] = DGG.DISABLED
@ -301,9 +347,7 @@ class BodyShop(StateData.StateData):
self.doneStatus = 'next'
messenger.send(self.doneEvent)
def __handleBackward(self):
self.doneStatus = 'last'
messenger.send(self.doneEvent)
def restrictHeadType(self, head):
if not base.cr.isPaid():
@ -322,15 +366,18 @@ class BodyShop(StateData.StateData):
newHeadIndex = ToonDNA.toonHeadTypes.index(newHead) - ToonDNA.getHeadStartIndex(ToonDNA.getSpecies(newHead))
newTorsoIndex = ToonDNA.toonTorsoTypes.index(newChoice[1])
newLegsIndex = ToonDNA.toonLegTypes.index(newChoice[2])
newEyelashesIndex = random.randint(0,1)
oldHead = self.toon.style.head
oldSpeciesIndex = ToonDNA.toonSpeciesTypes.index(ToonDNA.getSpecies(oldHead))
oldHeadIndex = ToonDNA.toonHeadTypes.index(oldHead) - ToonDNA.getHeadStartIndex(ToonDNA.getSpecies(oldHead))
oldTorsoIndex = ToonDNA.toonTorsoTypes.index(self.toon.style.torso)
oldLegsIndex = ToonDNA.toonLegTypes.index(self.toon.style.legs)
oldEyelashesIndex = self.toon.style.eyelashes
self.__swapSpecies(newSpeciesIndex - oldSpeciesIndex)
self.__swapHead(newHeadIndex - oldHeadIndex)
self.__swapTorso(newTorsoIndex - oldTorsoIndex)
self.__swapLegs(newLegsIndex - oldLegsIndex)
self.__swapEyelashes(newEyelashesIndex - oldEyelashesIndex)
def getCurrToonSetting(self):
return [self.toon.style.head, self.toon.style.torso, self.toon.style.legs]

View File

@ -395,24 +395,56 @@ class MakeAToon(StateData.StateData):
def bodyShopOpening(self):
self.bs.showButtons()
self.guiNextButton.show()
self.guiLastButton.show()
self.rotateLeftButton.show()
self.rotateRightButton.show()
def enterBodyShop(self):
if hasattr(self, 'toon'):
if self.toon:
self.toon.show()
else:
self.dna = ToonDNA.ToonDNA()
# stage = 1 is MAKE_A_TOON
self.dna.newToonRandom(eyelashes=random.randint(0, 1), stage=1)
self.toon = Toon.Toon()
self.toon.setDNA(self.dna)
# make sure the avatar uses its highest LOD
self.toon.useLOD(1000)
# make sure his name doesn't show up
self.toon.setNameVisible(0)
self.toon.startBlink()
self.toon.startLookAround()
self.toon.reparentTo(render)
self.toon.setPos(self.toonPosition)
self.toon.setHpr(self.toonHpr)
self.toon.setScale(self.toonScale)
self.toon.loop("neutral")
self.setNextButtonState(DGG.NORMAL)
self.setToon(self.toon)
messenger.send("MAT-newToonCreated")
base.cr.centralLogger.writeClientEvent('MAT - enteringBodyShop')
self.toon.show()
if self.toon:
self.toon.show()
self.shop = BODYSHOP
self.guiTopBar['text'] = TTLocalizer.ShapeYourToonTitle
self.guiTopBar['text_fg'] = (0.0, 0.98, 0.5, 1)
self.guiTopBar['text_scale'] = TTLocalizer.MATenterBodyShop
self.accept('BodyShop-done', self.__handleBodyShopDone)
self.accept("BodyShop-done", self.__handleBodyShopDone)
self.dropRoom(self.bodyWalls, self.bodyProps)
# we need to do this first for setup...
self.bs.enter(self.toon, self.shopsVisited)
if BODYSHOP not in self.shopsVisited:
if (BODYSHOP not in self.shopsVisited):
self.shopsVisited.append(BODYSHOP)
self.bodyShopOpening()
def exitBodyShop(self):
self.squishRoom(self.bodyWalls)
self.squishProp(self.bodyProps)

View File

@ -9,6 +9,10 @@ class MakeClothesGUI(ClothesGUI.ClothesGUI):
def setupScrollInterface(self):
self.dna = self.toon.getStyle()
self.tops = ToonDNA.getRandomizedTops(tailorId = ToonDNA.MAKE_A_TOON)
self.bottoms = ToonDNA.getRandomizedBottoms(tailorId = ToonDNA.MAKE_A_TOON)
self.topChoice = 0
self.bottomChoice = 0
self.setupButtons()
def setupButtons(self):

View File

@ -1,16 +1,22 @@
from panda3d.core import *
from pandac.PandaModules import *
import random
import string
import copy
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
import os
from direct.showbase import AppRunnerGlobal
from direct.directnotify import DirectNotifyGlobal
class NameGenerator:
# A TextNode we will use to measure the lengths of names
text = TextNode('text')
text.setFont(ToontownGlobals.getInterfaceFont())
notify = DirectNotifyGlobal.directNotify.newCategory('NameGenerator')
notify = DirectNotifyGlobal.directNotify.newCategory("NameGenerator")
boyTitles = []
girlTitles = []
neutralTitles = []
@ -23,8 +29,13 @@ class NameGenerator:
def __init__(self):
self.generateLists()
return
def generateLists(self):
""" This method looks in a text file specified in the localizer and loads
in all the names into the 8 lists as well as populating self.nameDictionary
which has uniqueIDs mapped to a tuple of category and name
"""
self.boyTitles = []
self.girlTitles = []
self.neutralTitles = []
@ -35,91 +46,92 @@ class NameGenerator:
self.lastPrefixes = []
self.lastSuffixes = []
self.nameDictionary = {}
# Look for the name master file and read it in.
searchPath = DSearchPath()
if __debug__:
searchPath.appendDirectory(Filename('resources/phase_3/etc'))
if AppRunnerGlobal.appRunner:
# In the web-publish runtime, it will always be here:
searchPath.appendDirectory(Filename.expandFrom('$TT_3_ROOT/phase_3/etc'))
else:
# In other environments, including the dev environment, look here:
searchPath.appendDirectory(Filename('phase_3/etc'))
base = os.path.expandvars('$TOONTOWN') or './toontown'
searchPath.appendDirectory(Filename.fromOsSpecific(os.path.expandvars(base + '/src/configfiles')))
# RobotToonManager needs to look for file in current directory
searchPath.appendDirectory(Filename('.'))
filename = Filename(TTLocalizer.NameShopNameMaster)
found = vfs.resolveFilename(filename, searchPath)
if not found:
self.notify.error("NameGenerator: Error opening name list text file '%s.'" % TTLocalizer.NameShopNameMaster)
input = StreamReader(vfs.openReadFile(filename, 1), 1)
currentLine = input.readline()
while currentLine:
if currentLine.lstrip()[0:1] != b'#':
a1 = currentLine.find(b'*')
a2 = currentLine.find(b'*', a1 + 1)
self.nameDictionary[int(currentLine[0:a1])] = (int(currentLine[a1 + 1:a2]), currentLine[a2 + 1:].rstrip().decode('utf-8'))
self.nameDictionary[int(currentLine[0:a1])] = (int(currentLine[a1 + 1:a2]),
currentLine[a2 + 1:].rstrip().decode('utf-8'))
currentLine = input.readline()
masterList = [self.boyTitles,
self.girlTitles,
self.neutralTitles,
self.boyFirsts,
self.girlFirsts,
self.neutralFirsts,
self.capPrefixes,
self.lastPrefixes,
self.lastSuffixes]
masterList = [self.boyTitles, self.girlTitles, self.neutralTitles,
self.boyFirsts, self.girlFirsts, self.neutralFirsts,
self.capPrefixes, self.lastPrefixes, self.lastSuffixes]
for tu in list(self.nameDictionary.values()):
masterList[tu[0]].append(tu[1])
return 1
def _getNameParts(self, cat2part):
nameParts = [{},
{},
{},
{}]
# returns list of dict of string->index, one dict per name part
nameParts = [{}, {}, {}, {}]
# cat2part is mapping of NameMasterEnglish.txt category -> namePart index
for id, tpl in self.nameDictionary.items():
cat, str = tpl
if cat in cat2part:
nameParts[cat2part[cat]][str] = id
return nameParts
def getMaleNameParts(self):
return self._getNameParts({0: 0,
2: 0,
3: 1,
5: 1,
6: 2,
7: 2,
8: 3})
def getFemaleNameParts(self):
return self._getNameParts({1: 0,
2: 0,
4: 1,
5: 1,
6: 2,
7: 2,
8: 3})
def getAllNameParts(self):
return self._getNameParts({0: 0,
1: 0,
2: 0,
3: 1,
4: 1,
5: 1,
6: 2,
7: 2,
8: 3})
1: 0,
2: 0,
3: 1,
4: 1,
5: 1,
6: 2,
7: 2,
8: 3,
})
def getLastNamePrefixesCapped(self):
return self.capPrefixes
def returnUniqueID(self, name, listnumber):
""" This is a helper function which accepts a name string, and a listnumber of
type 0 = title, 1 = firstname, 2 = prefix, 3 = suffix
It then makes a list of search tuples newtu and searches nameDictionary.
If successful it returns the uniqueID, if not then -1
"""
newtu = [(), (), ()]
if listnumber == 0:
# Looking for a title
newtu[0] = (0, name)
newtu[1] = (1, name)
newtu[2] = (2, name)
elif listnumber == 1:
# Looking for a first name
newtu[0] = (3, name)
newtu[1] = (4, name)
newtu[2] = (5, name)
elif listnumber == 2:
# Looking for a prefix
newtu[0] = (6, name)
newtu[1] = (7, name)
else:
@ -128,60 +140,99 @@ class NameGenerator:
for g in newtu:
if tu[1] == g:
return tu[0]
return -1
def findWidestInList(self, text, nameList):
maxWidth = 0
maxName = ''
maxName = ""
for name in nameList:
width = text.calcWidth(name)
if width > maxWidth:
maxWidth = text.calcWidth(name)
maxName = name
print(maxName + ' ' + str(maxWidth))
print(maxName + " " + str(maxWidth))
return maxName
def findWidestName(self):
longestBoyTitle = self.findWidestInList(self.text, self.boyTitles + self.neutralTitles)
longestGirlTitle = self.findWidestInList(self.text, self.girlTitles + self.neutralTitles)
longestBoyFirst = self.findWidestInList(self.text, self.boyFirsts + self.neutralFirsts)
longestGirlFirst = self.findWidestInList(self.text, self.girlFirsts + self.neutralFirsts)
longestLastPrefix = self.findWidestInList(self.text, self.lastPrefixes)
longestLastSuffix = self.findWidestInList(self.text, self.lastSuffixes)
longestBoyFront = self.findWidestInList(self.text, [longestBoyTitle, longestBoyFirst])
longestGirlFront = self.findWidestInList(self.text, [longestGirlTitle, longestGirlFirst])
longestBoyName = longestBoyTitle + ' ' + longestBoyFirst + ' ' + longestLastPrefix + longestLastSuffix
longestGirlName = longestGirlTitle + ' ' + longestGirlFirst + ' ' + longestLastPrefix + longestLastSuffix
longestName = self.findWidestInList(self.text, [longestBoyName, longestGirlName])
longestBoyTitle = self.findWidestInList(self.text,
self.boyTitles +
self.neutralTitles)
longestGirlTitle = self.findWidestInList(self.text,
self.girlTitles +
self.neutralTitles)
longestBoyFirst = self.findWidestInList(self.text,
self.boyFirsts +
self.neutralFirsts)
longestGirlFirst = self.findWidestInList(self.text,
self.girlFirsts +
self.neutralFirsts)
longestLastPrefix = self.findWidestInList(self.text,
self.lastPrefixes)
longestLastSuffix = self.findWidestInList(self.text,
self.lastSuffixes)
longestBoyFront = self.findWidestInList(self.text,
[longestBoyTitle,
longestBoyFirst])
longestGirlFront = self.findWidestInList(self.text,
[longestGirlTitle,
longestGirlFirst])
longestBoyName = (longestBoyTitle + " " + longestBoyFirst + " " +
longestLastPrefix + longestLastSuffix)
longestGirlName = (longestGirlTitle + " " + longestGirlFirst + " " +
longestLastPrefix + longestLastSuffix)
longestName = self.findWidestInList(self.text,
[longestBoyName, longestGirlName])
return longestName
def findWidestTitleFirst(self):
longestBoyTitle = self.findWidestInList(self.text, self.boyTitles + self.neutralTitles)
longestGirlTitle = self.findWidestInList(self.text, self.girlTitles + self.neutralTitles)
longestBoyFirst = self.findWidestInList(self.text, self.boyFirsts + self.neutralFirsts)
longestGirlFirst = self.findWidestInList(self.text, self.girlFirsts + self.neutralFirsts)
longestBoyName = longestBoyTitle + ' ' + longestBoyFirst
longestGirlName = longestGirlTitle + ' ' + longestGirlFirst
longestName = self.findWidestInList(self.text, [longestBoyName, longestGirlName])
longestBoyTitle = self.findWidestInList(self.text,
self.boyTitles +
self.neutralTitles)
longestGirlTitle = self.findWidestInList(self.text,
self.girlTitles +
self.neutralTitles)
longestBoyFirst = self.findWidestInList(self.text,
self.boyFirsts +
self.neutralFirsts)
longestGirlFirst = self.findWidestInList(self.text,
self.girlFirsts +
self.neutralFirsts)
longestBoyName = (longestBoyTitle + " " + longestBoyFirst)
longestGirlName = (longestGirlTitle + " " + longestGirlFirst)
longestName = self.findWidestInList(self.text,
[longestBoyName, longestGirlName])
def findWidestTitle(self):
widestTitle = self.findWidestInList(self.text, self.neutralTitles + self.boyTitles + self.girlTitles)
widestTitle = self.findWidestInList(self.text,
self.neutralTitles +
self.boyTitles +
self.girlTitles)
return widestTitle
def findWidestFirstName(self):
widestFirst = self.findWidestInList(self.text, self.neutralFirsts + self.boyFirsts + self.girlFirsts)
widestFirst = self.findWidestInList(self.text,
self.neutralFirsts +
self.boyFirsts +
self.girlFirsts)
return widestFirst
def findWidestLastName(self):
longestLastPrefix = self.findWidestInList(self.text, self.lastPrefixes)
longestLastSuffix = self.findWidestInList(self.text, self.lastSuffixes)
longestLastPrefix = self.findWidestInList(self.text,
self.lastPrefixes)
longestLastSuffix = self.findWidestInList(self.text,
self.lastSuffixes)
longestLastName = longestLastPrefix + longestLastSuffix
return longestLastName
def findWidestNameWord(self):
widestWord = self.findWidestInList(self.text, [self.findWidestTitle(), self.findWidestFirstName(), self.findWidestLastName()])
widestWord = self.findWidestInList(self.text,
[self.findWidestTitle(),
self.findWidestFirstName(),
self.findWidestLastName()])
return widestWord
def findWidestNameWidth(self):
@ -192,125 +243,192 @@ class NameGenerator:
name = self.findWidestName()
width = self.text.calcWidth(name)
widthStr = str(width)
print('The widest name is: ' + name + ' (' + widthStr + ' units)')
print(("The widest name is: " + name + " (" +
widthStr + " units)"))
def printWidestLastName(self):
name = self.findWidestLastName()
width = self.text.calcWidth(name)
widthStr = str(width)
print('The widest last name is: ' + name + ' (' + widthStr + ' units)')
print(("The widest last name is: " + name + " (" +
widthStr + " units)"))
def randomName(self, boy = 0, girl = 0):
def randomName(self, boy=0, girl=0):
""" This method is outdated for current uses in Toontown, but good for
general debugging. You probably want to use randomNameMoreinfo
"""
if boy and girl:
self.error("A name can't be both boy and girl!")
if not boy and not girl:
if (not boy) and (not girl):
# Randomly pick the name sex
boy = random.choice([0, 1])
girl = not boy
uberFlag = random.choice(['title-first',
'title-last',
'first',
'last',
'first-last',
'title-first-last'])
# Five types of name combos
uberFlag = random.choice(["title-first", "title-last",
"first", "last", "first-last", "title-first-last"])
titleFlag = 0
if uberFlag == 'title-first' or uberFlag == 'title-last' or uberFlag == 'title-first-last':
if ((uberFlag == "title-first") or
(uberFlag == "title-last") or
(uberFlag == "title-first-last")):
titleFlag = 1
firstFlag = 0
if uberFlag == 'title-first' or uberFlag == 'first' or uberFlag == 'first-last' or uberFlag == 'title-first-last':
if ((uberFlag == "title-first") or
(uberFlag == "first") or
(uberFlag == "first-last") or
(uberFlag == "title-first-last")):
firstFlag = 1
lastFlag = 0
if uberFlag == 'title-last' or uberFlag == 'last' or uberFlag == 'first-last' or uberFlag == 'title-first-last':
if ((uberFlag == "title-last") or
(uberFlag == "last") or
(uberFlag == "first-last") or
(uberFlag == "title-first-last")
):
lastFlag = 1
retString = ''
retString = ""
if titleFlag:
# Shallow copy, since we will be altering the list
titleList = self.neutralTitles[:]
titleList += self.boyTitles
titleList += self.girlTitles
retString += random.choice(titleList) + ' '
if boy:
titleList += self.boyTitles
elif girl:
titleList += self.girlTitles
else:
self.error("Must be boy or girl.")
# Put a space because there will surely be another name.
retString += random.choice(titleList) + " "
if firstFlag:
# Shallow copy, since we will be altering the list
firstList = self.neutralFirsts[:]
firstList += self.boyFirsts
firstList += self.girlFirsts
if boy:
firstList += self.boyFirsts
elif girl:
firstList += self.girlFirsts
else:
self.error("Must be boy or girl.")
retString += random.choice(firstList)
# Put a space if there is going to be a last name.
if lastFlag:
retString += ' '
retString += " "
if lastFlag:
lastPrefix = random.choice(self.lastPrefixes)
lastSuffix = random.choice(self.lastSuffixes)
if lastPrefix in self.capPrefixes:
lastSuffix = lastSuffix.capitalize()
retString += lastPrefix + lastSuffix
return retString
def randomNameMoreinfo(self):
uberFlag = random.choice(['title-first',
'title-last',
'first',
'last',
'first-last',
'title-first-last'])
"""This is just like randomName only it returns a list where the first three
values are titleFlag, firstFlag, and lastFlag and the next four values are
the title, firstname, and lastname (if applicable, '' if not)
"""
# Five types of name combos
uberFlag = random.choice(["title-first", "title-last",
"first", "last", "first-last", "title-first-last"])
titleFlag = 0
if uberFlag == 'title-first' or uberFlag == 'title-last' or uberFlag == 'title-first-last':
if ((uberFlag == "title-first") or
(uberFlag == "title-last") or
(uberFlag == "title-first-last")):
titleFlag = 1
firstFlag = 0
if uberFlag == 'title-first' or uberFlag == 'first' or uberFlag == 'first-last' or uberFlag == 'title-first-last':
if ((uberFlag == "title-first") or
(uberFlag == "first") or
(uberFlag == "first-last") or
(uberFlag == "title-first-last")):
firstFlag = 1
lastFlag = 0
if uberFlag == 'title-last' or uberFlag == 'last' or uberFlag == 'first-last' or uberFlag == 'title-first-last':
if ((uberFlag == "title-last") or
(uberFlag == "last") or
(uberFlag == "first-last") or
(uberFlag == "title-first-last")):
lastFlag = 1
retString = ''
uberReturn = [0,
0,
0,
'',
'',
'',
'']
retString = ""
uberReturn = [0, 0, 0, '', '', '', '']
uberReturn[0] = titleFlag
uberReturn[1] = firstFlag
uberReturn[2] = lastFlag
# Choose random names in each slot even if we won't be using
# them. That way, if the user activates a previously deactive
# slot, s/he'll start at a random point in the list instead of
# always at the top.
# Shallow copy, since we will be altering the list
titleList = self.neutralTitles[:]
titleList += self.boyTitles
titleList += self.girlTitles
else:
self.error('Must be boy or girl.')
uberReturn[3] = random.choice(titleList)
# Shallow copy, since we will be altering the list
firstList = self.neutralFirsts[:]
firstList += self.boyFirsts
firstList += self.girlFirsts
uberReturn[4] = random.choice(firstList)
lastPrefix = random.choice(self.lastPrefixes)
lastSuffix = random.choice(self.lastSuffixes)
if lastPrefix in self.capPrefixes:
lastSuffix = lastSuffix.capitalize()
uberReturn[5] = lastPrefix
uberReturn[6] = lastSuffix
# Put a space because there will surely be another name.
if titleFlag:
retString += uberReturn[3] + ' '
retString += uberReturn[3] + " "
if firstFlag:
retString += uberReturn[4]
# Put a space if there is going to be a last name.
if lastFlag:
retString += ' '
retString += " "
if lastFlag:
retString += uberReturn[5] + uberReturn[6]
uberReturn.append(retString)
return uberReturn
def printRandomNames(self, boy = 0, girl = 0, total = 1):
def printRandomNames(self, boy=0, girl=0, total=1):
i = 0
origBoy = boy
origGirl = girl
while i < total:
if not origBoy and not origGirl:
if (not origBoy) and (not origGirl):
# Randomly pick the name sex
boy = random.choice([0, 1])
girl = not boy
name = self.randomName(boy, girl)
width = self.text.calcWidth(name)
widthStr = str(width)
print(name + ' (' + widthStr + ' units)')
if boy:
print("Boy: " + name + " (" + widthStr + " units)")
if girl:
print("Girl: " + name + " (" + widthStr + " units)")
i += 1
def percentOver(self, limit = 9.0, samples = 1000):
def percentOver(self, limit=9.0, samples=1000):
i = 0
over = 0
while i < samples:
@ -319,34 +437,60 @@ class NameGenerator:
if width > limit:
over += 1
i += 1
percent = float(over) / float(samples) * 100
print('Samples: ' + str(samples) + ' Over: ' + str(over) + ' Percent: ' + str(percent))
percent = (float(over) / float(samples)) * 100
print(("Samples: " + str(samples) + " Over: " +
str(over) + " Percent: " + str(percent)))
def totalNames(self):
firsts = len(self.boyFirsts) + len(self.girlFirsts) + len(self.neutralFirsts)
print('Total firsts: ' + str(firsts))
# Firsts only
firsts = (len(self.boyFirsts) + len(self.girlFirsts) +
len(self.neutralFirsts))
print("Total firsts: " + str(firsts))
# Lasts only
lasts = len(self.lastPrefixes) * len(self.lastSuffixes)
print('Total lasts: ' + str(lasts))
print("Total lasts: " + str(lasts))
# Title plus first
neutralTitleFirsts = len(self.neutralTitles) * len(self.neutralFirsts)
boyTitleFirsts = len(self.boyTitles) * (len(self.neutralFirsts) + len(self.boyFirsts)) + len(self.neutralTitles) * len(self.boyFirsts)
girlTitleFirsts = len(self.girlTitles) * (len(self.neutralFirsts) + len(self.girlFirsts)) + len(self.neutralTitles) * len(self.girlFirsts)
totalTitleFirsts = neutralTitleFirsts + boyTitleFirsts + girlTitleFirsts
print('Total title firsts: ' + str(totalTitleFirsts))
boyTitleFirsts = ((len(self.boyTitles) *
(len(self.neutralFirsts) + len(self.boyFirsts))) +
((len(self.neutralTitles) *
len(self.boyFirsts))))
girlTitleFirsts = ((len(self.girlTitles) *
(len(self.neutralFirsts) + len(self.girlFirsts))) +
((len(self.neutralTitles) *
len(self.girlFirsts))))
totalTitleFirsts = (neutralTitleFirsts + boyTitleFirsts +
girlTitleFirsts)
print("Total title firsts: " + str(totalTitleFirsts))
# Title plus last
neutralTitleLasts = len(self.neutralTitles) * lasts
boyTitleLasts = len(self.boyTitles) * lasts
girlTitleLasts = len(self.girlTitles) * lasts
totalTitleLasts = neutralTitleLasts + boyTitleFirsts + girlTitleLasts
print('Total title lasts: ' + str(totalTitleLasts))
boyTitleLasts = (len(self.boyTitles) *
lasts)
girlTitleLasts = (len(self.girlTitles) *
lasts)
totalTitleLasts = (neutralTitleLasts + boyTitleFirsts +
girlTitleLasts)
print("Total title lasts: " + str(totalTitleLasts))
# First plus last
neutralFirstLasts = len(self.neutralFirsts) * lasts
boyFirstLasts = len(self.boyFirsts) * lasts
girlFirstLasts = len(self.girlFirsts) * lasts
totalFirstLasts = neutralFirstLasts + boyFirstLasts + girlFirstLasts
print('Total first lasts: ' + str(totalFirstLasts))
totalFirstLasts = (neutralFirstLasts + boyFirstLasts +
girlFirstLasts)
print("Total first lasts: " + str(totalFirstLasts))
# Title plus first plus last
neutralTitleFirstLasts = neutralTitleFirsts * lasts
boyTitleFirstLasts = boyTitleFirsts * lasts
girlTitleFirstLasts = girlTitleFirsts * lasts
totalTitleFirstLasts = neutralTitleFirstLasts + boyTitleFirstLasts + girlTitleFirstLasts
print('Total title first lasts: ' + str(totalTitleFirstLasts))
totalNames = firsts + lasts + totalTitleFirsts + totalTitleLasts + totalFirstLasts + totalTitleFirstLasts
print('Total Names: ' + str(totalNames))
totalTitleFirstLasts = (neutralTitleFirstLasts + boyTitleFirstLasts + girlTitleFirstLasts)
print("Total title first lasts: " + str(totalTitleFirstLasts))
# Total
totalNames = (firsts + lasts + totalTitleFirsts +
totalTitleLasts + totalFirstLasts + totalTitleFirstLasts)
print("Total Names: " + str(totalNames))

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ class ShuffleButton:
shuffleArrowDisabled = gui.find('**/tt_t_gui_mat_shuffleArrowDisabled')
gui.removeNode()
del gui
self.parentFrame = DirectFrame(parent=self.parent.parentFrame, relief=DGG.RAISED, pos=(0, 0, -1), frameColor=(1, 0, 0, 0))
self.parentFrame = DirectFrame(parent=self.parent.parentFrame, relief=DGG.RAISED, pos=(0, 0, -1.1), frameColor=(1, 0, 0, 0))
self.shuffleFrame = DirectFrame(parent=self.parentFrame, image=shuffleFrame, image_scale=halfButtonInvertScale, relief=None, frameColor=(1, 1, 1, 1))
self.shuffleFrame.hide()
self.shuffleBtn = DirectButton(parent=self.parentFrame, relief=None, image=(shuffleUp, shuffleDown, shuffleUp), image_scale=halfButtonInvertScale, image1_scale=(-0.63, 0.6, 0.6), image2_scale=(-0.63, 0.6, 0.6), text=(TTLocalizer.ShuffleButton,

View File

@ -11,8 +11,6 @@ class TTPickANamePattern(PickANamePatternTwoPartLastName):
if TTPickANamePattern.NameParts is None:
TTPickANamePattern.NameParts = {}
ng = NameGenerator()
TTPickANamePattern.NameParts['m'] = ng.getMaleNameParts()
TTPickANamePattern.NameParts['f'] = ng.getFemaleNameParts()
TTPickANamePattern.NameParts['n'] = ng.getAllNameParts()
return TTPickANamePattern.NameParts['n']

View File

@ -486,9 +486,53 @@ class NPCMoviePlayer(DirectObject.DirectObject):
self.setVar(varName, dialogue)
return
def parseLoadCCDialogue(self, line):
token, varName, filenameTemplate = line
# TODO figure out the option for ppl who want minnie to show them around
classicChar = 'mickey'
filename = filenameTemplate % classicChar
if base.config.GetString('language', 'english') == 'japanese':
dialogue = base.loader.loadSfx(filename)
else:
dialogue = None
self.setVar(varName, dialogue)
return
def parseLoadChar(self, line):
token, name, charType = line
char = Char.Char()
dna = CharDNA.CharDNA()
dna.newChar(charType)
char.setDNA(dna)
if charType == 'mk' or charType == 'mn':
char.startEarTask()
char.nametag.manage(base.marginManager)
char.addActive()
char.hideName()
self.setVar(name, char)
def parseLoadClassicChar(self, line):
token, name = line
char = Char.Char()
dna = CharDNA.CharDNA()
charType = 'mk'
dna.newChar(charType)
char.setDNA(dna)
char.startEarTask()
char.nametag.manage(base.marginManager)
char.addActive()
char.hideName()
self.setVar(name, char)
self.chars.append(char)
def parseUnloadChar(self, line):
token, name = line
char = self.getVar(name)
track = Sequence()
track.append(Func(self.__unloadChar, char))
track.append(Func(self.delVar, name))
return track
def parseLoadSuit(self, line):

View File

@ -195,7 +195,7 @@ class DistributedBossbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
npc.setPickable(0)
npc.setPlayerType(NametagGroup.CCNonPlayer)
dna = ToonDNA.ToonDNA()
dna.newToonRandom(335933, 'm', 1)
dna.newToonRandom(335933, 1, 1)
dna.head = 'sls'
npc.setDNAString(dna.makeNetString())
npc.animFSM.request('neutral')

View File

@ -103,7 +103,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
npc.setPickable(0)
npc.setPlayerType(NametagGroup.CCNonPlayer)
dna = ToonDNA.ToonDNA()
dna.newToonRandom(146392, 'f', 1)
dna.newToonRandom(146392, 0, 1)
dna.head = 'pls'
npc.setDNAString(dna.makeNetString())
npc.animFSM.request('neutral')

View File

@ -209,10 +209,14 @@ class NPCFriendCard(DirectFrame):
NPCInfo = NPCToons.NPCToonDict[NPCID]
dnaList = NPCInfo[2]
eyelashes = NPCInfo[3]
if eyelashes == 'm':
eyelashes = 0
elif eyelashes == 'f':
eyelashes = 1
if dnaList == 'r':
dnaList = NPCToons.getRandomDNA(NPCID, eyelashes)
dna = ToonDNA.ToonDNA()
dna.newToonFromProperties(*dnaList)
dna.newToonFromProperties(*dnaList, isNPC=True)
head = ToonHead.ToonHead()
head.setupHead(dna, forGui=1)
self.fitGeometry(head, fFlip=1, dimension=dimension)

View File

@ -63,6 +63,7 @@ TAILOR_COUNTDOWN_TIME = 300
RTDNAFile = '/RTDNAFile.txt'
saveDNA = False
def getRandomDNA(seed, eyelashes):
randomDNA = ToonDNA.ToonDNA()
randomDNA.newToonRandom(seed, eyelashes, 1)
@ -139,7 +140,8 @@ def createNPC(air, npcId, desc, zoneId, posIndex = 0, questCallback = None):
rtDnaFile = open(RTDNAFile, 'w')
rtDnaFile.writelines(rtDNA)
rtDnaFile.close()
dna.newToonFromProperties(*dnaList)
dna.newToonFromProperties(*dnaList, isNPC=True)
npc.setDNAString(dna.makeNetString())
npc.setHp(15)
npc.setMaxHp(15)
@ -179,7 +181,7 @@ def createLocalNPC(npcId):
dnaList = getRandomDNA(npcId, eyelashes)
else:
dnaList = dnaType
dna.newToonFromProperties(*dnaList)
dna.newToonFromProperties(*dnaList, isNPC=True)
npc.setDNAString(dna.makeNetString())
npc.animFSM.request('neutral')
return npc

View File

@ -501,6 +501,7 @@ class Toon(Avatar.Avatar, ToonHead):
self.shoes = (0, 0, 0)
self.isStunned = 0
self.isDisguised = 0
self.eyelashes = 0
self.defaultColorScale = None
self.jar = None
self.setTag('pieCode', str(ToontownGlobals.PieCodeToon))
@ -3033,6 +3034,9 @@ class Toon(Avatar.Avatar, ToonHead):
def exitScientistPlay(self):
self.stop()
def setEyelashes(self, eyelashes):
self.eyelashes = eyelashes
loadModels()
compileGlobalAnimList()

View File

@ -643,21 +643,41 @@ GirlBottoms = [('phase_3/maps/desat_skirt_1.png', SKIRT),
Bottoms = GirlBottoms
# cycle through boyshorts if any any of them are not in girlbottoms add them to bottoms
for pair in BoyShorts:
if pair[0] not in Bottoms:
Bottoms.append((pair, SHORTS))
# add all shorts in BoyShorts to Bottoms
for short in BoyShorts:
Bottoms.append((short, SHORTS))
# a function to convert old male bottoms id to new bottoms id
def convertBoyShorts(oldId):
# go through boyshorts and bottoms
for pair in BoyShorts:
# if the old id is in boyshorts return the new id
if oldId == pair[0]:
return Bottoms.index(pair)
# remove any duplicates
for bottom in Bottoms:
if Bottoms.count(bottom) > 1:
Bottoms.remove(bottom)
# a function to convert old NPC bottom id to new bottoms id
def convertNPCSBottoms(oldId, kind):
if kind == 'm':
for index, short in enumerate(BoyShorts):
if index == oldId:
return Bottoms.index((short, SHORTS))
elif kind == 'f':
for index, bottom in enumerate(GirlBottoms):
if index == oldId:
if bottom[1] == SKIRT:
return Bottoms.index((bottom[0], SKIRT))
else:
return Bottoms.index((bottom[0], SHORTS))
return oldId
ClothesColors = [VBase4(0.933594, 0.265625, 0.28125, 1.0),
VBase4(0.863281, 0.40625, 0.417969, 1.0),
VBase4(0.710938, 0.234375, 0.4375, 1.0),
@ -2085,7 +2105,16 @@ class ToonDNA(AvatarDNA.AvatarDNA):
notify.error("tuple must be in format ('%s', '%s', '%s', '%s')")
return
def newToonFromProperties(self, head, torso, legs, eyelashes, armColor, gloveColor, legColor, headColor, topTexture, topTextureColor, sleeveTexture, sleeveTextureColor, bottomTexture, bottomTextureColor):
def newToonFromProperties(self, head, torso, legs, eyelashes, armColor, gloveColor, legColor, headColor, topTexture, topTextureColor, sleeveTexture, sleeveTextureColor, bottomTexture, bottomTextureColor, isNPC=0):
if eyelashes == 'm':
eyelashes = 1
kind = 'm'
elif eyelashes == 'f':
eyelashes = 0
kind = 'f'
if isNPC:
# convert the old bottom id to the new one
bottomTexture = convertNPCSBottoms(bottomTexture, kind)
self.type = 't'
self.head = head
self.torso = torso

View File

@ -5381,6 +5381,7 @@ GenderShopGirlButtonText = 'Girl'
BodyShopHead = 'Head'
BodyShopBody = 'Body'
BodyShopLegs = 'Legs'
BodyShopEyelashes = 'Eyelashes'
ColorShopToon = 'Toon Color'
ColorShopHead = 'Head'
ColorShopBody = 'Body'