Improved TV with "remote"

This commit is contained in:
John 2015-08-03 03:25:37 +03:00
parent 323d181e6f
commit ba586faa6f
8 changed files with 208 additions and 41 deletions

View file

@ -294,6 +294,7 @@ from toontown.estate import DistributedTrunk/AI
from toontown.estate import DistributedPhone/AI
from toontown.estate import DistributedRewardCrate/AI
from toontown.estate import DistributedChair/AI
from toontown.estate import DistributedTV/AI
from toontown.effects import DistributedFireworkShow/AI
from toontown.estate import DistributedFireworksCannon/AI
from toontown.coghq import LobbyManager/AI
@ -2091,6 +2092,12 @@ dclass DistributedChair : DistributedFurnitureItem {
setStatus(uint8) broadcast ram;
};
dclass DistributedTV : DistributedFurnitureItem {
setVideo(string(0-255), uint32) required broadcast ram;
requestVideo(string(0-255)) airecv clsend;
requestVideoResponse(uint8);
};
dclass DistributedFireworkShow : DistributedObject {
startShow(uint8, uint8, uint8, int16) broadcast ram;
requestFirework(int16/10, int16/10, int16/100, uint8, uint8, uint8) airecv clsend;

View file

@ -21,9 +21,10 @@ FLBillboard = 64
FLPhone = 128
FLCrate = 256
FLChair = 512
FLTrunk = 1024
FLBoysOnly = 2048
FLGirlsOnly = 4096
FLTV = 1024
FLTrunk = 2048
FLBoysOnly = 4096
FLGirlsOnly = 8192
furnitureColors = [
(0.792, 0.353, 0.29, 1.0),
(0.176, 0.592, 0.439, 1.0),
@ -752,15 +753,18 @@ FurnitureTypes = {
1530: ('phase_5.5/models/estate/bugRoomTV',
None,
None,
675),
675,
FLTV),
1531: ('phase_5.5/models/estate/bugRoomTV_50inch',
None,
None,
1250),
1250,
FLTV),
1532: ('phase_5.5/models/estate/bugRoomTV_100inch',
None,
None,
5000),
5000,
FLTV),
1600: ('phase_5.5/models/estate/vaseA_short',
None,
None,
@ -1107,38 +1111,7 @@ class CatalogFurnitureItem(CatalogAtticItem.CatalogAtticItem):
model.setScale(scale)
model.flattenLight()
if animate and self.furnitureType in TvToPosScale:
pos = TvToPosScale[self.furnitureType]
screen = NodePath(CardMaker('tv-screen').generate())
model.find('**/toonTownBugTV_screen').hide()
screen.reparentTo(model)
screen.setScale(*pos[1])
screen.setPos(*pos[0])
self.startVideo(screen)
return model
def startVideo(self, model, file=None):
files = glob.glob('user/videos/*.mp4')
if not files:
model.setTextureOff(TextureStage.getDefault())
model.setColor(0.3, 0.3, 0.3, 1.0)
return
if file is None:
file = random.randint(0, len(files) - 1)
elif file >= len(files):
file = 0
movie = loader.loadTexture(files[file])
sound = loader.loadSfx(files[file])
movie.synchronizeTo(sound)
model.setTexture(movie)
model.setTexScale(TextureStage.getDefault(), movie.getTexScale())
self.videoSequence = Sequence(SoundInterval(sound, volume=1.0), Func(self.startVideo, model, file + 1))
self.videoSequence.start()
def decodeDatagram(self, di, versionNumber, store):
CatalogAtticItem.CatalogAtticItem.decodeDatagram(self, di, versionNumber, store)

View file

@ -47,8 +47,6 @@ class DistributedFurnitureItem(DistributedHouseItem.DistributedHouseItem, Distri
def delete(self):
self.removeNode()
if hasattr(self.item, 'videoSequence') and self.item.videoSequence:
self.item.videoSequence.pause()
del self.item
DistributedHouseItem.DistributedHouseItem.delete(self)
DistributedSmoothNode.DistributedSmoothNode.delete(self)

View file

@ -1,7 +1,7 @@
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.catalog.CatalogItemList import CatalogItemList
from toontown.catalog import CatalogItem
from toontown.catalog.CatalogFurnitureItem import CatalogFurnitureItem, FLTrunk, FLCloset, FLBank, FLPhone, FLCrate, FLChair
from toontown.catalog.CatalogFurnitureItem import CatalogFurnitureItem, FLTrunk, FLCloset, FLBank, FLPhone, FLCrate, FLChair, FLTV
from toontown.catalog.CatalogWallpaperItem import CatalogWallpaperItem
from toontown.catalog.CatalogMouldingItem import CatalogMouldingItem
from toontown.catalog.CatalogFlooringItem import CatalogFlooringItem
@ -14,6 +14,7 @@ from DistributedTrunkAI import DistributedTrunkAI
from DistributedBankAI import DistributedBankAI
from DistributedRewardCrateAI import DistributedRewardCrateAI
from DistributedChairAI import DistributedChairAI
from DistributedTVAI import DistributedTVAI
from otp.ai.MagicWordGlobal import *
class FurnitureError(Exception):
@ -249,6 +250,8 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
do = DistributedRewardCrateAI(self.air, self, item)
elif item.getFlags() & FLChair:
do = DistributedChairAI(self.air, self, item)
elif item.getFlags() & FLTV:
do = DistributedTVAI(self.air, self, item)
else:
do = DistributedFurnitureItemAI(self.air, self, item)

View file

@ -0,0 +1,141 @@
from direct.gui.DirectGui import *
from otp.otpbase import OTPLocalizer
from toontown.catalog import CatalogFurnitureItem
from toontown.toonbase import ToontownGlobals, TTLocalizer
from toontown.toontowngui import TTDialog
from DistributedFurnitureItem import DistributedFurnitureItem
import glob, ntpath, os, time
class DistributedTV(DistributedFurnitureItem):
def __init__(self, cr):
DistributedFurnitureItem.__init__(self, cr)
self.dialog = None
self.screen = None
self.sound = None
def announceGenerate(self):
self.accept('exitingStoppedState', self.destroyGui)
DistributedFurnitureItem.announceGenerate(self)
def loadModel(self, animate=1):
model = DistributedFurnitureItem.loadModel(self)
if animate:
pos = CatalogFurnitureItem.TvToPosScale[self.item.furnitureType]
self.screen = NodePath(CardMaker('tv-screen').generate())
model.find('**/toonTownBugTV_screen').hide()
self.screen.reparentTo(model)
self.screen.setScale(*pos[1])
self.screen.setPos(*pos[0])
self.resetScreen()
cSphere = CollisionSphere(0.0, -1.5, 1.0, 1.575)
cSphere.setTangible(0)
colNode = CollisionNode('TV-%s' % self.doId)
colNode.addSolid(cSphere)
cSpherePath = model.attachNewNode(colNode)
cSpherePath.setCollideMask(ToontownGlobals.WallBitmask)
self.accept('enterTV-%s' % self.doId, self.__enterSphere)
return model
def disable(self):
self.ignoreAll()
self.destroyGui()
self.destroySound()
DistributedFurnitureItem.disable(self)
def setVideo(self, video, time):
if (not video) or (not time):
return
self.destroySound()
self.startVideo(os.path.join('user', os.path.join('videos', video)), time)
def getPack(self, name):
for pack in TTLocalizer.TVPacks:
if pack.lower() in name:
return pack
return None
def destroySound(self):
if self.sound:
self.sound.stop()
self.sound = None
def destroyGui(self, arg=None):
if self.dialog:
self.dialog.destroy()
self.dialog = None
def destroyGuiAndWalk(self, arg=None):
self.destroyGui()
base.cr.playGame.getPlace().setState('walk')
def cutOff(self, string):
return string if len(string) < 24 else '%s...' % string[:24]
def resetScreen(self):
self.screen.setTextureOff(TextureStage.getDefault())
self.screen.setColor(0.3, 0.3, 0.3, 1.0)
def startVideo(self, video, startTime):
if not os.path.exists(video):
pack = self.getPack(video)
base.localAvatar.setSystemMessage(0, TTLocalizer.TVUnknownVideoPack % pack if pack else TTLocalizer.TVUnknownVideo)
self.resetScreen()
return
movie = loader.loadTexture(video)
self.sound = loader.loadSfx(video)
movie.synchronizeTo(self.sound)
self.screen.setColor(1, 1, 1, 1)
self.screen.setTexture(movie)
self.screen.setTexScale(TextureStage.getDefault(), movie.getTexScale())
self.sound.setLoop(True)
self.sound.setTime(min(self.sound.length(), int(time.time() - startTime)))
self.sound.play()
def __enterSphere(self, collisionEntry):
if base.localAvatar.doId != self.furnitureMgr.ownerId:
return
videos = []
gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
buttonImage = (gui.find('**/FndsLst_ScrollUp'), gui.find('**/FndsLst_ScrollDN'), gui.find('**/FndsLst_ScrollUp_Rllvr'), gui.find('**/FndsLst_ScrollUp'))
base.cr.playGame.getPlace().setState('stopped')
self.dialog = DirectFrame(relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(1.33, 1, 1.4),
pos=(0, 0, 0), text=TTLocalizer.TVChooseVideo, text_scale=0.07, text_pos=(0, 0.575))
for file in sorted(glob.glob('user/videos/*.mp4')):
filename = ntpath.basename(file)
videos.append(DirectButton(relief=None, text=self.cutOff(filename[:-4]), text_pos=(0.0, -0.0225), text_scale=0.048, text_align=TextNode.ALeft, text_fg=(0, 0, 0, 1), text3_fg=(0.4, 0.8, 0.4, 1), text1_bg=(0.5, 0.9, 1, 1), text2_bg=(1, 1, 0, 1), command=self.chooseVideo, extraArgs=[filename]))
scrollList = DirectScrolledList(parent=self.dialog, relief=None, pos=(-0.05, 0, 0), incButton_image=buttonImage, incButton_relief=None, incButton_scale=(1.3, 1.3, -1.3),
incButton_pos=(0.045, 0, -0.4), incButton_image3_color=(1, 1, 1, 0.2), decButton_image=buttonImage, decButton_relief=None,
decButton_scale=1.3, decButton_pos=(0.045, 0, 0.5), decButton_image3_color=(1, 1, 1, 0.2), itemFrame_pos=(-0.247, 0, 0.365),
itemFrame_scale=1.0, itemFrame_relief=DGG.SUNKEN, itemFrame_frameSize=(-0.02, 0.6, -0.7, 0.08), itemFrame_frameColor=(0.85, 0.95, 1, 1),
itemFrame_borderWidth=(0.01, 0.01), numItemsVisible=10, forceHeight=0.065, items=videos)
cancelButton = DirectButton(parent=self.dialog, relief=None, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), pos=(0, 0, -0.55), text=OTPLocalizer.lCancel, text_scale=0.06, text_pos=(0, -0.1), command=self.destroyGuiAndWalk)
gui.removeNode()
buttons.removeNode()
def chooseVideo(self, video):
self.destroyGuiAndWalk()
self.sendUpdate('requestVideo', [video])
def showDialog(self, text):
base.cr.playGame.getPlace().setState('stopped')
self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=text, text_wordwrap=15, fadeScreen=1, command=self.destroyGuiAndWalk)
def requestVideoResponse(self, response):
if response == ToontownGlobals.TV_NOT_OWNER:
self.showDialog(TTLocalizer.TVNotOwner)
elif response == ToontownGlobals.TV_INVALID_VIDEO:
self.showDialog(TTLocalizer.TVInvalidVideo)
elif response == ToontownGlobals.TV_OK:
self.showDialog(TTLocalizer.TVOK)

View file

@ -0,0 +1,32 @@
from toontown.toonbase import ToontownGlobals
from DistributedFurnitureItemAI import DistributedFurnitureItemAI
import time
class DistributedTVAI(DistributedFurnitureItemAI):
def __init__(self, air, furnitureMgr, item):
DistributedFurnitureItemAI.__init__(self, air, furnitureMgr, item)
self.video = ['', 0]
def d_setVideo(self, video):
self.sendUpdate('setVideo', video)
def getVideo(self):
return self.video
def requestVideo(self, video):
avId = self.air.getAvatarIdFromSender()
av = self.air.doId2do.get(avId)
if not av:
return
elif self.furnitureMgr.ownerId != avId:
self.sendUpdateToAvatarId(avId, 'requestVideoResponse', [ToontownGlobals.TV_NOT_OWNER])
return
elif not video.endswith('.mp4'):
self.sendUpdateToAvatarId(avId, 'requestVideoResponse', [ToontownGlobals.TV_INVALID_VIDEO])
return
self.video = [video, int(time.time())]
self.d_setVideo(self.video)
self.sendUpdateToAvatarId(avId, 'requestVideoResponse', [ToontownGlobals.TV_OK])

View file

@ -8678,6 +8678,14 @@ GroupAskNoAccess = 'Sorry, but you have no teleport access %s %s.\n\nWould you s
GroupAskNoAccessSame = 'Sorry, but you have no teleport access %s %s.'
GroupAskAccess = 'Would you like to teleport %s %s in %s?'
TVNotOwner = 'Sorry, but this is not your TV.'
TVInvalidVideo = "Sorry, but we can't play that video. Make sure it is a MP4 video."
TVUnknownVideo = "Oops! Looks like the owner has picked a video to play which isn't currently on your computer!"
TVUnknownVideoPack = 'Oops! Looks like the owner has picked a video to play, but you need to download the %s TV Pack in the launcher.'
TVChooseVideo = 'Choose a video to play!'
TVOK = 'The video you selected is now playing!'
TVPacks = ['QuackityHQ']
Blacklist = [
"$1ut",
"$h1t",

View file

@ -1687,5 +1687,10 @@ TF_ALREADY_FRIENDS_NAME = 7
TF_SUCCESS = 8
GROUP_ZONES = [11000, 11100, 11200, 12000, 12100, 13000, 13100, 13200, 10000, 10100]
TOONUP_PULSE_ZONES = [ToontownCentral, DonaldsDock, DaisyGardens, MinniesMelodyland, TheBrrrgh, DonaldsDreamland]
TOONUP_FREQUENCY = 30
TOONUP_FREQUENCY = 30
TV_NOT_OWNER = 0
TV_INVALID_VIDEO = 1
TV_OK = 2