207 lines
6.9 KiB
Python
207 lines
6.9 KiB
Python
import math
|
|
import time
|
|
import datetime
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from direct.interval.LerpInterval import LerpFunc
|
|
from pandac.PandaModules import Vec3
|
|
from toontown.toonbase import TTLocalizer
|
|
from toontown.toonbase.ToontownTimer import ToontownTimer
|
|
from toontown.parties import PartyGlobals
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('PartyUtils')
|
|
|
|
def getNewToontownTimer():
|
|
timer = ToontownTimer()
|
|
timer.hide()
|
|
timer.posInTopRightCorner()
|
|
timer.setColor(1, 1, 1, 0.75)
|
|
return timer
|
|
|
|
|
|
def getPartyActivityIcon(activityIconsModel, activityName):
|
|
activityIconsDict = {'PartyValentineDance': 'tt_t_ara_pty_iconDanceFloorValentine',
|
|
'PartyValentineDance20': 'tt_t_ara_pty_iconDanceFloorValentine',
|
|
'PartyValentineJukebox': 'tt_t_ara_pty_iconJukeboxValentine',
|
|
'PartyValentineJukebox40': 'tt_t_ara_pty_iconJukeboxValentine',
|
|
'PartyValentineTrampoline': 'tt_t_ara_pty_iconTrampolineValentine'}
|
|
iconName = activityIconsDict.get(activityName)
|
|
if iconName:
|
|
icon = activityIconsModel.find('**/%s' % iconName)
|
|
else:
|
|
icon = activityIconsModel.find('**/%sIcon' % activityName)
|
|
if icon.isEmpty():
|
|
icon = activityIconsModel.find('**/PartyClockIcon')
|
|
notify.warning("Couldn't find %sIcon in %s, using PartyClockIcon" % (activityName, activityIconsModel.getName()))
|
|
return icon
|
|
|
|
|
|
def arcPosInterval(duration, object, pos, arcHeight, other):
|
|
startPos = object.getPos()
|
|
endPos = object.getParent().getRelativePoint(other, pos)
|
|
startX = startPos.getX()
|
|
startY = startPos.getY()
|
|
startZ = startPos.getZ()
|
|
dx = endPos.getX() - startPos.getX()
|
|
dy = endPos.getY() - startPos.getY()
|
|
dz = endPos.getZ() - startPos.getZ()
|
|
|
|
def setArcPos(t):
|
|
newX = startX + dx * t
|
|
newY = startY + dy * t
|
|
newZ = startZ + dz * t + arcHeight * (-(2.0 * t - 1.0) ** 2 + 1.0)
|
|
object.setPos(newX, newY, newZ)
|
|
|
|
return LerpFunc(setArcPos, duration=duration)
|
|
|
|
|
|
def formatDate(year, month, day):
|
|
monthString = TTLocalizer.DateOfBirthEntryMonths[month - 1]
|
|
return TTLocalizer.PartyDateFormat % {'mm': monthString,
|
|
'dd': day,
|
|
'yyyy': year}
|
|
|
|
|
|
def truncateTextOfLabelBasedOnWidth(directGuiObject, textToTruncate, maxWidth):
|
|
text0 = directGuiObject.component('text0')
|
|
tempNode = text0.textNode
|
|
currentText = textToTruncate[:]
|
|
scale = text0.getScale()[0]
|
|
width = tempNode.calcWidth(currentText) * scale
|
|
while width > maxWidth:
|
|
currentText = currentText[:-1]
|
|
width = tempNode.calcWidth(currentText) * scale
|
|
|
|
directGuiObject['text'] = currentText
|
|
if directGuiObject['text'] != textToTruncate:
|
|
directGuiObject['text'] = '%s...' % directGuiObject['text']
|
|
|
|
|
|
def truncateTextOfLabelBasedOnMaxLetters(directGuiObject, textToTruncate, maxLetters):
|
|
curStr = directGuiObject['text']
|
|
if maxLetters < len(curStr):
|
|
curStr = curStr[:maxLetters]
|
|
curStr += '...'
|
|
directGuiObject['text'] = curStr
|
|
|
|
|
|
def scaleTextOfGuiObjectBasedOnWidth(directGuiObject, textToScale, maxWidth):
|
|
width = directGuiObject.getWidth()
|
|
scale = 0.01
|
|
while width > maxWidth:
|
|
directGuiObject['text_scale'] = scale
|
|
directGuiObject.resetFrameSize()
|
|
width = directGuiObject.getWidth()
|
|
scale += 0.005
|
|
|
|
|
|
def formatTime(hour, minute):
|
|
meridiemString = TTLocalizer.PartyTimeFormatMeridiemAM
|
|
if hour == 0:
|
|
hour = 12
|
|
elif hour > 11:
|
|
meridiemString = TTLocalizer.PartyTimeFormatMeridiemPM
|
|
if hour > 12:
|
|
hour -= 12
|
|
return TTLocalizer.PartyTimeFormat % (hour, minute, meridiemString)
|
|
|
|
|
|
SecondsInOneDay = 60 * 60 * 24
|
|
|
|
def getTimeDeltaInSeconds(td):
|
|
result = td.days * SecondsInOneDay + td.seconds + td.microseconds / 1000000.0
|
|
return result
|
|
|
|
|
|
def formatDateTime(dateTimeToShow, inLocalTime = False):
|
|
if inLocalTime:
|
|
curServerTime = base.cr.toontownTimeManager.getCurServerDateTime()
|
|
ltime = time.localtime()
|
|
localTime = datetime.datetime(year=ltime.tm_year, month=ltime.tm_mon, day=ltime.tm_mday, hour=ltime.tm_hour, minute=ltime.tm_min, second=ltime.tm_sec)
|
|
naiveServerTime = curServerTime.replace(tzinfo=None)
|
|
newTimeDelta = localTime - naiveServerTime
|
|
localDifference = getTimeDeltaInSeconds(newTimeDelta)
|
|
dateTimeToShow = dateTimeToShow + datetime.timedelta(seconds=localDifference)
|
|
return '%s %s' % (formatDate(dateTimeToShow.year, dateTimeToShow.month, dateTimeToShow.day), formatTime(dateTimeToShow.hour, dateTimeToShow.minute))
|
|
else:
|
|
return '%s %s' % (formatDate(dateTimeToShow.year, dateTimeToShow.month, dateTimeToShow.day), formatTime(dateTimeToShow.hour, dateTimeToShow.minute))
|
|
return
|
|
|
|
|
|
def convertDistanceToPartyGrid(d, index):
|
|
return int((d - PartyGlobals.PartyGridToPandaOffset[index]) / PartyGlobals.PartyGridUnitLength[index])
|
|
|
|
|
|
def convertDistanceFromPartyGrid(d, index):
|
|
return d * PartyGlobals.PartyGridUnitLength[index] + PartyGlobals.PartyGridToPandaOffset[index] + PartyGlobals.PartyGridUnitLength[index] / 2.0
|
|
|
|
|
|
def convertDegreesToPartyGrid(h):
|
|
while h < 0.0:
|
|
h = h + 360.0
|
|
|
|
h = h % 360.0
|
|
return int(h / PartyGlobals.PartyGridHeadingConverter)
|
|
|
|
|
|
def convertDegreesFromPartyGrid(h):
|
|
return h * PartyGlobals.PartyGridHeadingConverter
|
|
|
|
|
|
def getCenterPosFromGridSize(x, y, gridsize):
|
|
if gridsize[0] % 2 == 0:
|
|
xMod = PartyGlobals.PartyGridUnitLength[0] / 2.0
|
|
else:
|
|
xMod = 0
|
|
if gridsize[1] % 2 == 0:
|
|
yMod = PartyGlobals.PartyGridUnitLength[1] / 2.0
|
|
else:
|
|
yMod = 0
|
|
return (x + xMod, y + yMod)
|
|
|
|
|
|
def toRadians(angle):
|
|
return angle * math.pi / 180.0
|
|
|
|
|
|
def toDegrees(angle):
|
|
return angle * 180.0 / math.pi
|
|
|
|
|
|
def calcVelocity(rotation, angle, initialVelocity = 1.0):
|
|
horizVel = initialVelocity * math.cos(angle)
|
|
xVel = horizVel * -math.sin(rotation)
|
|
yVel = horizVel * math.cos(rotation)
|
|
zVel = initialVelocity * math.sin(angle)
|
|
return Vec3(xVel, yVel, zVel)
|
|
|
|
|
|
class LineSegment:
|
|
|
|
def __init__(self, pt1, pt2):
|
|
self.pt1 = pt1
|
|
self.pt2 = pt2
|
|
|
|
def isIntersecting(self, line, compare = None):
|
|
x1 = self.pt1.getX()
|
|
x2 = self.pt2.getX()
|
|
x3 = line.pt1.getX()
|
|
x4 = line.pt2.getX()
|
|
y1 = self.pt1.getY()
|
|
y2 = self.pt2.getY()
|
|
y3 = line.pt1.getY()
|
|
y4 = line.pt2.getY()
|
|
top1 = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)
|
|
top2 = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)
|
|
bot = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
|
|
if bot == 0.0:
|
|
return False
|
|
u1 = top1 / bot
|
|
u2 = top2 / bot
|
|
if compare is None:
|
|
return 0 <= u1 and u1 <= 1 and 0 <= u2 and u2 <= 1
|
|
elif compare == 'segment-ray':
|
|
return 0 <= u1 and u1 <= 1 and 0 <= u2
|
|
elif compare == 'ray-ray':
|
|
return 0 <= u1 and 0 <= u2
|
|
elif compare == 'ray-segment':
|
|
return 0 <= u1 and 0 <= u2 and u2 <= 1
|
|
return
|