Merge branch 'feature/deployment'

This commit is contained in:
John 2015-08-31 00:03:21 +03:00
commit e2b8582261
120 changed files with 1469 additions and 977 deletions

4
.gitignore vendored
View file

@ -23,4 +23,6 @@ dependencies/config/local.prc
# PyMongo # PyMongo
bson bson
gridfs gridfs
pymongo pymongo
Toon Bot
DNS

11
.gitmodules vendored
View file

@ -1,3 +1,12 @@
[submodule "resources"] [submodule "resources"]
path = resources path = resources
url = git@Repo.Ez-webz.com:Stride/resources.git url = http://Repo.Ez-webz.com/Stride/resources.git
[submodule "build/nirai/src"]
path = build/nirai/src
url = https://github.com/nirai-compiler/src
[submodule "build/nirai/panda3d"]
path = build/nirai/panda3d
url = https://github.com/nirai-compiler/panda3d
[submodule "build/nirai/python"]
path = build/nirai/python
url = https://github.com/nirai-compiler/python

Binary file not shown.

View file

@ -1,14 +1,13 @@
from panda3d.core import * from panda3d.core import *
import __builtin__, os import __builtin__, os, sys
import rc4 import aes
import niraidata import niraidata
# Config # Config
prc = niraidata.CONFIG prc = niraidata.CONFIG
key, prc = prc[:32], prc[32:] iv, key, prc = prc[:16], prc[16:32], prc[32:]
rc4.rc4_setkey(key) prc = aes.decrypt(prc, key, iv)
prc = rc4.rc4(prc)
for line in prc.split('\n'): for line in prc.split('\n'):
line = line.strip() line = line.strip()
@ -16,43 +15,37 @@ for line in prc.split('\n'):
loadPrcFileData('nirai config', line) loadPrcFileData('nirai config', line)
del prc del prc
del iv
del key
# DC # DC
__builtin__.dcStream = StringStream() __builtin__.dcStream = StringStream()
dc = niraidata.DC dc = niraidata.DC
key, dc = dc[:32], dc[32:] iv, key, dc = dc[:16], dc[16:32], dc[32:]
rc4.rc4_setkey(key) dc = aes.decrypt(dc, key, iv)
dc = rc4.rc4(dc)
dcStream.setData(dc) dcStream.setData(dc)
del dc del dc
rc4.rc4_setkey('\0\0\0\0') del iv
del key
# The VirtualFileSystem, which has already initialized, doesn't see the mount
# directives in the config(s) yet. We have to force it to load those manually:
#from panda3d.core import VirtualFileSystem, ConfigVariableList, Filename
vfs = VirtualFileSystem.getGlobalPtr()
mounts = ConfigVariableList('vfs-mount')
for mount in mounts:
mountfile, mountpoint = (mount.split(' ', 2) + [None, None, None])[:2]
vfs.mount(Filename(mountfile), Filename(mountpoint), 0)
# Resources # Resources
# TO DO: Sign and verify the phases to prevent editing. # TO DO: Sign and verify the phases to prevent edition
vfs = VirtualFileSystem.getGlobalPtr()
mfs = (3, 3.5, 4, 5, 5.5, 6, 7, 8, 9, 10, 11, 12, 13)
abort = False abort = False
for mf in mfs:
filename = 'resources/default/phase_%s.mf' % mf
if not os.path.isfile(filename):
print 'Phase %s not found' % filename
abort = True
break
mf = Multifile()
mf.openRead(filename)
if not vfs.mount(mf, '../resources', 0):
print 'Unable to mount %s' % filename
abort = True
break
# Packs # Packs
pack = os.environ.get('TT_STRIDE_CONTENT_PACK') pack = os.environ.get('TT_STRIDE_CONTENT_PACK')
import glob
if pack and pack != 'default': if pack and pack != 'default':
print 'Loading content pack', pack print 'Loading content pack', pack
for file in glob.glob('resources/%s/*.mf' % pack): for file in glob.glob('resources/%s/*.mf' % pack):
@ -61,15 +54,9 @@ if pack and pack != 'default':
names = mf.getSubfileNames() names = mf.getSubfileNames()
for name in names: for name in names:
ext = os.path.splitext(name)[1] ext = os.path.splitext(name)[1]
if ext not in ('.jpg', '.jpeg', '.ogg', '.rgb'): if ext not in ['.jpg', '.jpeg', '.ogg', '.rgb']:
mf.removeSubfile(name) mf.removeSubfile(name)
vfs.mount(mf, Filename('/'), 0)
mf.flush()
if not vfs.mount(mf, '../resources', 0):
print 'Unable to mount %s' % filename
abort = True
break
if not abort: if not abort:
# Run # Run

View file

@ -1,126 +1,57 @@
from panda3d.core import * from panda3d.core import *
import argparse, marshal, struct import argparse, struct
import glob, sys, os import sys, glob
import rc4 import os
sys.path.append('nirai/src')
from niraitools import *
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--compile-cxx', '-c', action='store_true', parser.add_argument('--compile-cxx', '-c', action='store_true',
help='Compile the CXX codes and generate Nirai.exe into built.') help='Compile the CXX codes and generate stride.exe into built.')
parser.add_argument('--make-nri', '-n', action='store_true', parser.add_argument('--make-nri', '-n', action='store_true',
help='Generate stride NRI.') help='Generate stride NRI.')
parser.add_argument('--make-mfs', '-m', action='store_true',
help='Make multifiles')
args = parser.parse_args() args = parser.parse_args()
# BEGIN (STRIPPED AND MODIFIED) COPY FROM niraitools.py if not os.path.exists('built'):
class NiraiPackager: os.mkdir('built')
HEADER = 'NRI\n'
def __init__(self, outfile): def niraicall_obfuscate(code):
self.modules = {} # We'll obfuscate if len(code) % 4 == 0
self.outfile = outfile # This way we make sure both obfuscated and non-obfuscated code work.
if len(code) % 4:
return False, None
def __read_file(self, filename, mangler=None): # Reverse
with open(filename, 'rb') as f: code = code[::-1]
data = f.read()
base = filename.rsplit('.', 1)[0].replace('\\', '/').replace('/', '.') # XOR
pkg = base.endswith('.__init__') key = ['B', 'A', 'Q', 'J', 'R', 'P', 'Z', 'P', 'A', 'H', 'U', 'T']
moduleName = base.rsplit('.', 1)[0] if pkg else base output = []
name = moduleName for i in range(len(code)):
if mangler is not None: xor_num = ord(code[i]) ^ ord(key[i % len(key)])
name = mangler(name) output.append(chr(xor_num))
if not name: code = ''.join(output)
return '', ('', 0)
try: return True, code
data = self.compile_module(name, data)
except: niraimarshal.niraicall_obfuscate = niraicall_obfuscate
print 'WARNING: Failed to compile', filename
return '', ('', 0)
size = len(data) * (-1 if pkg else 1)
return name, (data, size)
def compile_module(self, name, data):
return marshal.dumps(compile(data, name, 'exec'))
def add_module(self, moduleName, data, size=None, compile=False):
if compile:
data = self.compile_module(moduleName, data)
if size is None:
size = len(data)
self.modules[moduleName] = (data, size)
def add_file(self, filename, mangler=None):
print 'Adding file', filename
moduleName, (data, size) = self.__read_file(filename, mangler)
if moduleName:
moduleName = os.path.basename(filename).rsplit('.', 1)[0]
self.add_module(moduleName, data, size)
def add_directory(self, dir, mangler=None):
print 'Adding directory', dir
def _recurse_dir(dir):
for f in os.listdir(dir):
f = os.path.join(dir, f)
if os.path.isdir(f):
_recurse_dir(f)
elif f.endswith('py'):
moduleName, (data, size) = self.__read_file(f, mangler)
if moduleName:
self.add_module(moduleName, data, size)
_recurse_dir(dir)
def get_mangle_base(self, *path):
return len(os.path.join(*path).rsplit('.', 1)[0].replace('\\', '/').replace('/', '.')) + 1
def write_out(self):
f = open(self.outfile, 'wb')
f.write(self.HEADER)
f.write(self.process_modules())
f.close()
def generate_key(self, size=256):
return os.urandom(size)
def dump_key(self, key):
for k in key:
print ord(k),
print
def process_modules(self):
# Pure virtual
raise NotImplementedError('process_datagram')
def get_file_contents(self, filename, keysize=0):
with open(filename, 'rb') as f:
data = f.read()
if keysize:
key = self.generate_key(keysize)
rc4.rc4_setkey(key)
data = key + rc4.rc4(data)
return data
# END COPY FROM niraitools.py
class StridePackager(NiraiPackager): class StridePackager(NiraiPackager):
HEADER = 'STRIDETT' HEADER = 'TTSTRIDE'
BASEDIR = '..' + os.sep BASEDIR = '..' + os.sep
def __init__(self, outfile): def __init__(self, outfile):
NiraiPackager.__init__(self, outfile) NiraiPackager.__init__(self, outfile)
self.__manglebase = self.get_mangle_base(self.BASEDIR) self.__manglebase = self.get_mangle_base(self.BASEDIR)
self.add_panda3d_dirs()
self.add_default_lib()
def add_source_dir(self, dir): def add_source_dir(self, dir):
self.add_directory(self.BASEDIR + dir, mangler=self.__mangler) self.add_directory(self.BASEDIR + dir, mangler=self.__mangler)
@ -131,7 +62,7 @@ class StridePackager(NiraiPackager):
def __mangler(self, name): def __mangler(self, name):
if name.endswith('AI') or name.endswith('UD') or name in ('ToontownAIRepository', 'ToontownUberRepository', if name.endswith('AI') or name.endswith('UD') or name in ('ToontownAIRepository', 'ToontownUberRepository',
'ToontownInternalRepository'): 'ToontownInternalRepository', 'ServiceStart'):
if not 'NonRepeatableRandomSource' in name: if not 'NonRepeatableRandomSource' in name:
return '' return ''
@ -139,26 +70,22 @@ class StridePackager(NiraiPackager):
def generate_niraidata(self): def generate_niraidata(self):
print 'Generating niraidata' print 'Generating niraidata'
# Config
config = self.get_file_contents('../deployment/public_client.prc')
config = self.get_file_contents('../dependencies/config/release/en.prc') config_iv = self.generate_key(16)
config += '\n\n' + self.get_file_contents('../dependencies/config/general.prc') config_key = self.generate_key(16)
key = self.generate_key(128) config = config_iv + config_key + aes.encrypt(config, config_key, config_iv)
rc4.rc4_setkey(key)
config = key + rc4.rc4(config)
niraidata = 'CONFIG = %r' % config niraidata = 'CONFIG = %r' % config
niraidata += '\nDC = %r' % self.get_file_contents('../dependencies/astron/dclass/stride.dc', 128)
# DC
niraidata += '\nDC = %r' % self.get_file_contents('../dependencies/astron/dclass/stride.dc', True)
self.add_module('niraidata', niraidata, compile=True) self.add_module('niraidata', niraidata, compile=True)
def process_modules(self): def process_modules(self):
with open('base.dg', 'rb') as f: # TODO: Compression
basesize, = struct.unpack('<I', f.read(4))
data = f.read()
dg = Datagram() dg = Datagram()
dg.addUint32(len(self.modules) + basesize) dg.addUint32(len(self.modules))
dg.appendData(data)
for moduleName in self.modules: for moduleName in self.modules:
data, size = self.modules[moduleName] data, size = self.modules[moduleName]
@ -167,19 +94,26 @@ class StridePackager(NiraiPackager):
dg.appendData(data) dg.appendData(data)
data = dg.getMessage() data = dg.getMessage()
compressed = compressString(data, 9) #compressed = compress_string(data, 9)
key = self.generate_key(100) iv = self.generate_key(16)
fixed = ''.join(chr((i ^ (5 * i + 7)) % ((i + 6) * 10)) for i in xrange(28)) key = self.generate_key(16)
rc4.rc4_setkey(key + fixed) fixed_key = ''.join(chr((i ^ (7 * i + 16)) % ((i + 5) * 3)) for i in xrange(16))
data = rc4.rc4(compressed) fixed_iv = ''.join(chr((i ^ (2 * i + 53)) % ((i + 9) * 6)) for i in xrange(16))
return key + data securekeyandiv = aes.encrypt(iv + key, fixed_key, fixed_iv)
return securekeyandiv + aes.encrypt(data, key, iv)
# 1. Make the NRI # Compile the engine
if args.compile_cxx:
compiler = NiraiCompiler('stride.exe', libs=set(glob.glob('c:/repos/libpandadna/libpandadna.dir/Release/*.obj')))
compiler.add_nirai_files()
compiler.add_source('src/stride.cxx')
compiler.run()
# Compile the game data
if args.make_nri: if args.make_nri:
if not os.path.exists('built'): pkg = StridePackager('built/TTSData.bin')
os.mkdir('built')
pkg = StridePackager('built/stride.dist')
pkg.add_source_dir('otp') pkg.add_source_dir('otp')
pkg.add_source_dir('toontown') pkg.add_source_dir('toontown')
@ -187,19 +121,18 @@ if args.make_nri:
pkg.add_data_file('NiraiStart') pkg.add_data_file('NiraiStart')
pkg.generate_niraidata() pkg.generate_niraidata()
pkg.write_out() pkg.write_out()
# 2. Compile CXX stuff if args.make_mfs:
if args.compile_cxx: os.chdir('../resources')
if not os.path.exists('built'): cmd = ''
os.mkdir('built') for phasenum in ['3', '3.5', '4', '5', '5.5', '6', '7', '8', '9', '10', '11', '12', '13']:
print 'phase_%s' % (phasenum)
cmd = 'multify -cf ../build/built/resources/default/phase_%s.mf phase_%s' % (phasenum, phasenum)
p = subprocess.Popen(cmd, stdout=sys.stdout, stderr=sys.stderr)
v = p.wait()
sys.path.append('../../../N2') if v != 0:
from niraitools import NiraiCompiler print 'The following command returned non-zero value (%d): %s' % (v, cmd[:100] + '...')
sys.exit(1)
compiler = NiraiCompiler('stride.exe', r'"C:\\Users\\Usuario\\workspace\\nirai-panda3d\\thirdparty\\win-libs-vc10"',
libs=set(glob.glob('libpandadna/libpandadna.dir/Release/*.obj')))
compiler.add_nirai_files()
compiler.add_source('src/stride.cxx')
compiler.run()

1
build/nirai/panda3d Submodule

@ -0,0 +1 @@
Subproject commit e4743737b0572feab80a08959f2b4d865ab3bc62

1
build/nirai/python Submodule

@ -0,0 +1 @@
Subproject commit d24aeac557165f986373fa6d59de128902b74112

1
build/nirai/src Submodule

@ -0,0 +1 @@
Subproject commit 3d29188a91b658f61cd2c3b3b8ada23050d4f230

Binary file not shown.

View file

@ -1,18 +1,17 @@
#include "nirai.h" #include "nirai.h"
#include <datagram.h> #include <datagram.h>
#include <datagramIterator.h> #include <datagramIterator.h>
#include <algorithm>
#include <string>
#include <compress_string.h> #include <compress_string.h>
string rc4(const char* data, const char* key, int ds, int ks);
extern "C" __declspec(dllexport) void initlibpandadna(); extern "C" __declspec(dllexport) void initlibpandadna();
void init_libpandadna(); void init_libpandadna();
const char* header = "STRIDETT"; const char* header = "TTSTRIDE";
const int header_size = 8; const int header_size = 8;
const int keysize = 100; const int key_and_iv_size = 16;
const int fixedsize = 28;
int niraicall_onPreStart(int argc, char* argv[]) int niraicall_onPreStart(int argc, char* argv[])
{ {
@ -24,7 +23,7 @@ int niraicall_onLoadGameData()
fstream gd; fstream gd;
// Open the file // Open the file
gd.open("stride.dist", ios_base::in | ios_base::binary); gd.open("TTSData.bin", ios_base::in | ios_base::binary);
if (!gd.is_open()) if (!gd.is_open())
{ {
std::cerr << "Unable to open game file!" << std::endl; std::cerr << "Unable to open game file!" << std::endl;
@ -43,31 +42,61 @@ int niraicall_onLoadGameData()
delete[] read_header; delete[] read_header;
// Extract the key // Decrypt
char* key = new char[keysize + fixedsize];
char* fixed = new char[keysize];
for (int i = 0; i < fixedsize; ++i)
fixed[i] = (i ^ (5 * i + 7)) % ((i + 6) * 10);
gd.read(key, keysize);
memcpy(&key[keysize], fixed, fixedsize);
std::stringstream ss; std::stringstream ss;
ss << gd.rdbuf(); ss << gd.rdbuf();
gd.close(); gd.close();
// Decrypt std::string brawdata = ss.str();
std::string rawdata = ss.str();
std::string decrypted_data = rc4(rawdata.c_str(), key, rawdata.size(), // Decrypted the encrypted key and iv
keysize + fixedsize); std::string enckeyandiv = brawdata.substr(0, (key_and_iv_size * 2) + key_and_iv_size);
unsigned char* deckeyandiv = new unsigned char[enckeyandiv.size()];
unsigned char* fixed_key = new unsigned char[key_and_iv_size];
unsigned char* fixed_iv = new unsigned char[key_and_iv_size];
// Create fixed key and iv
for (int i = 0; i < key_and_iv_size; ++i)
fixed_key[i] = (i ^ (7 * i + 16)) % ((i + 5) * 3);
for (int i = 0; i < key_and_iv_size; ++i)
fixed_iv[i] = (i ^ (2 * i + 53)) % ((i + 9) * 6);
int deckeyandivsize = AES_decrypt((unsigned char*)enckeyandiv.c_str(), enckeyandiv.size(), fixed_key, fixed_iv, deckeyandiv);
delete[] fixed_key;
delete[] fixed_iv;
unsigned char* key = new unsigned char[key_and_iv_size];
unsigned char* iv = new unsigned char[key_and_iv_size];
// Move the decrypted key and iv into their subsequent char
for (int i = 0; i < key_and_iv_size; ++i)
iv[i] = deckeyandiv[i];
for (int i = 0; i < key_and_iv_size; ++i)
key[i] = deckeyandiv[i + key_and_iv_size];
delete[] deckeyandiv;
// Decrypt the game data
std::string rawdata = brawdata.substr((key_and_iv_size * 2) + key_and_iv_size);
unsigned char* decrypted_data = new unsigned char[rawdata.size()];
int decsize = AES_decrypt((unsigned char*)rawdata.c_str(), rawdata.size(), key, iv, decrypted_data); // Assumes no error
delete[] key; delete[] key;
delete[] fixed; delete[] iv;
// Read
// Decompress and read // TODO: Compression
std::string decompressed = decompress_string(decrypted_data);
Datagram dg(decompressed); Datagram dg(decrypted_data, decsize);
DatagramIterator dgi(dg); DatagramIterator dgi(dg);
unsigned int num_modules = dgi.get_uint32(); unsigned int num_modules = dgi.get_uint32();
@ -102,12 +131,30 @@ int niraicall_onLoadGameData()
return 1; return 1;
} }
delete[] decrypted_data;
memset(&fzns[num_modules], 0, sizeof(_frozen)); memset(&fzns[num_modules], 0, sizeof(_frozen));
PyImport_FrozenModules = fzns; PyImport_FrozenModules = fzns;
delete[] &fzns;
// libpandadna // libpandadna
init_libpandadna(); init_libpandadna();
initlibpandadna(); initlibpandadna();
return 0; return 0;
} }
extern "C" PyObject* niraicall_deobfuscate(char* code, Py_ssize_t size)
{
std::string codestr(code, size);
const char key[12] = {'B', 'A', 'Q', 'J', 'R', 'P', 'Z', 'P', 'A', 'H', 'U', 'T'};
std::string output = codestr;
for (int i = 0; i < codestr.size(); i++)
output[i] = codestr[i] ^ key[i % (sizeof(key) / sizeof(char))];
std::reverse(output.begin(), output.end());
return PyString_FromStringAndSize(output.data(), size);
}

Binary file not shown.

Binary file not shown.

View file

@ -51,7 +51,7 @@ roles:
max: 399999999 max: 399999999
backend: backend:
type: yaml type: yaml
foldername: ../databases/astrondb directory: ../databases/astrondb
- type: dbss - type: dbss
database: 4003 database: 4003

View file

@ -133,7 +133,7 @@ dclass DistributedAvatar : DistributedSmoothNode {
friendsNotify(DoId avId, int8 status) ownrecv airecv; friendsNotify(DoId avId, int8 status) ownrecv airecv;
checkAvOnShard(DoId) clsend airecv; checkAvOnShard(DoId) clsend airecv;
confirmAvOnShard(DoId avId, int8 isOnShard); confirmAvOnShard(DoId avId, int8 isOnShard);
setTalk(string(0-400) chat) broadcast; setTalk(string(0-400) chat) broadcast ram;
setTalkWhisper(uint32 avId, string(0-400) chat) ownrecv clsend; setTalkWhisper(uint32 avId, string(0-400) chat) ownrecv clsend;
}; };
@ -590,8 +590,8 @@ dclass DistributedToon : DistributedPlayer {
setTrackAccess(uint16[] = [0,0,0,0,1,1,0]) required broadcast ownrecv db; setTrackAccess(uint16[] = [0,0,0,0,1,1,0]) required broadcast ownrecv db;
setTrackProgress(int8 = -1, uint32 = 0) required ownrecv db; setTrackProgress(int8 = -1, uint32 = 0) required ownrecv db;
setTrackBonusLevel(int8[] = [-1,-1,-1,-1,-1,-1,-1]) required broadcast ownrecv db; setTrackBonusLevel(int8[] = [-1,-1,-1,-1,-1,-1,-1]) required broadcast ownrecv db;
setInventory(blob = [0*7, 0*7, 0*7, 0*7, 0, 0*6, 0, 0*6, 0*7]) required ownrecv db; setInventory(blob = [0*7, 0*7, 0*7, 0*7, 0, 0*6, 0, 0*6, 0*7]) required broadcast ownrecv db;
setNPCFriendsDict(FriendEntry[] = []) required ownrecv db; setNPCFriendsDict(FriendEntry[] = []) required broadcast ownrecv db;
setDefaultShard(uint32 = 0) required ownrecv broadcast db; setDefaultShard(uint32 = 0) required ownrecv broadcast db;
setDefaultZone(uint32 = 0) required ownrecv broadcast db; setDefaultZone(uint32 = 0) required ownrecv broadcast db;
setHoodsVisited(uint32[] = [ 2000 ]) required ownrecv db; setHoodsVisited(uint32[] = [ 2000 ]) required ownrecv db;
@ -755,6 +755,7 @@ dclass DistributedToon : DistributedPlayer {
requestNametagStyle(uint8) airecv ownsend; requestNametagStyle(uint8) airecv ownsend;
requestFishingRod(uint8) airecv ownsend; requestFishingRod(uint8) airecv ownsend;
wipeStats() airecv ownsend; wipeStats() airecv ownsend;
takeMoney(int16) airecv ownsend;
}; };
dclass DistributedPartyGate : DistributedObject { dclass DistributedPartyGate : DistributedObject {
@ -2048,7 +2049,6 @@ dclass DistributedCloset : DistributedFurnitureItem {
setDNA(blob, int8, uint8) airecv clsend; setDNA(blob, int8, uint8) airecv clsend;
setState(uint8, uint32, uint32, string, uint8[], uint8[]) broadcast ram; setState(uint8, uint32, uint32, string, uint8[], uint8[]) broadcast ram;
setMovie(uint8, uint32, int16) broadcast ram; setMovie(uint8, uint32, int16) broadcast ram;
resetItemLists() broadcast ram;
setCustomerDNA(uint32, blob) broadcast ram; setCustomerDNA(uint32, blob) broadcast ram;
}; };
@ -3202,7 +3202,7 @@ dclass TTSFriendsManager : DistributedObjectGlobal {
goingOffline(uint32 avId); goingOffline(uint32 avId);
getAvatarDetails(uint32) clsend; getAvatarDetails(uint32) clsend;
friendDetails(uint32, blob, uint16[], int16, int16, uint32, uint32, blob, blob, int8[]); friendDetails(uint32, blob, uint16[], int16, int16, uint32, uint32, blob, blob, int8[], FriendEntry[]);
getPetDetails(uint32) clsend; getPetDetails(uint32) clsend;
petDetails(uint32, uint32, string, uint32, uint32, uint16/1000[], PetTrait[], int8[], uint32); petDetails(uint32, uint32, string, uint32, uint32, uint16/1000[], PetTrait[], int8[], uint32);

BIN
dependencies/astron/mongoclient.dll vendored Normal file

Binary file not shown.

View file

@ -25,6 +25,8 @@ accountdb-type developer
shard-low-pop 50 shard-low-pop 50
shard-mid-pop 100 shard-mid-pop 100
game-type developer
# RPC: # RPC:
want-rpc-server #f want-rpc-server #f
rpc-server-endpoint http://localhost:8080/ rpc-server-endpoint http://localhost:8080/

View file

@ -1,8 +1,8 @@
{ {
"__fyi__": "If you use anything other than the first 7 characters of the git hash, you just broke everything", "__fyi__": "If you use anything other than the first 7 characters of the git hash, you just broke everything",
"astron": "6b769e6", "astron": "696a6c4",
"panda3d": "b924139", "panda3d": "b924139",
"libpandadna": "a0047ce", "libpandadna": "a0047ce",
"version-prefix": "ttstride-alpha-", "version-prefix": "stride-beta-",
"server-resources": ["pdna", "txt", "dat", "bam", "ttf"] "server-resources": ["pdna", "txt", "dat", "bam", "ttf"]
} }

View file

@ -3,17 +3,25 @@
# Config.prc should be reproduced here. # Config.prc should be reproduced here.
# Client settings # Client settings
window-title Toontown Stride window-title Toontown Stride [Beta]
server-version SERVER_VERSION_HERE server-version SERVER_VERSION_HERE
audio-library-name p3openal_audio
video-library-name p3ffmpeg video-library-name p3ffmpeg
want-dev #f want-dev #f
preload-avatars #t preload-avatars #t
game-type remote
# Graphics:
aux-display pandagl
aux-display pandadx9
aux-display p3tinydisplay
# Textures: # Textures:
texture-anisotropic-degree 16 texture-anisotropic-degree 16
server-timezone EST/EDT/-5
# Resources settings # Resources settings
model-path / model-path /
@ -43,7 +51,6 @@ default-model-extension .bam
want-pets #t want-pets #t
want-parties #f want-parties #f
want-cogdominiums #t want-cogdominiums #t
want-lawbot-cogdo #t
want-anim-props #t want-anim-props #t
want-game-tables #t want-game-tables #t
want-find-four #t want-find-four #t
@ -51,9 +58,9 @@ want-chinese-checkers #t
want-checkers #t want-checkers #t
want-house-types #t want-house-types #t
want-gifting #t want-gifting #t
want-top-toons #f want-top-toons #t
want-language-selection #t want-language-selection #t
estate-day-night #t estate-day-night #f
want-mat-all-tailors #t want-mat-all-tailors #t
@ -67,14 +74,12 @@ want-dev #f
want-pstats 0 want-pstats 0
# Crates:
dont-destroy-crate #t
get-key-reward-always #t
get-crate-reward-always #t
# Chat: # Chat:
want-whitelist #t want-whitelist #f
want-sequence-list #f
want-emblems #f
cogdo-want-barrel-room #f
#<dev> #<dev>
@ -84,5 +89,20 @@ want-instant-delivery #t
cogdo-pop-factor 1.5 cogdo-pop-factor 1.5
cogdo-ratio 0.5 cogdo-ratio 0.5
default-directnotify-level info default-directnotify-level info
# Core features:
want-lawbot-cogdo #f
# Crates:
dont-destroy-crate #t
get-key-reward-always #t
get-crate-reward-always #t
#</dev> #</dev>
#<prod>
dont-destroy-crate #f
get-key-reward-always #f
get-crate-reward-always #f
want-lawbot-cogdo #f
#</prod>

View file

@ -12,7 +12,6 @@ cogsuit-hack-prevent #t
want-pets #t want-pets #t
want-parties #f want-parties #f
want-cogdominiums #t want-cogdominiums #t
want-lawbot-cogdo #t
want-anim-props #t want-anim-props #t
want-game-tables #t want-game-tables #t
want-find-four #t want-find-four #t
@ -20,13 +19,32 @@ want-chinese-checkers #t
want-checkers #t want-checkers #t
want-house-types #t want-house-types #t
want-gifting #t want-gifting #t
want-top-toons #f want-top-toons #t
want-language-selection #t want-language-selection #t
estate-day-night #t estate-day-night #f
want-mat-all-tailors #t want-mat-all-tailors #t
is-server #t is-server #t
# Developer options:
show-population #t
want-instant-parties #t
want-instant-delivery #t
cogdo-pop-factor 1.5
cogdo-ratio 0.5
default-directnotify-level info
# Crates:
dont-destroy-crate #t
get-key-reward-always #t
get-crate-reward-always #t
want-lawbot-cogdo #f
server-timezone EST/EDT/-5
want-emblems #f
cogdo-want-barrel-room #f
# Chat Settings # Chat Settings
want-whitelist #t want-whitelist #f
want-sequence-list #t want-sequence-list #f

View file

@ -51,11 +51,12 @@ if ':' in host:
port = int(port) port = int(port)
simbase.air.connect(host, port) simbase.air.connect(host, port)
gc.enable()
isServer = config.GetBool('is-server', False) isServer = config.GetBool('is-server', False)
try: try:
run() run()
gc.enable()
except SystemExit: except SystemExit:
raise raise
except Exception: except Exception:

View file

@ -50,6 +50,11 @@ if ':' in host:
port = int(port) port = int(port)
simbase.air.connect(host, port) simbase.air.connect(host, port)
isServer = config.GetBool('is-server', False)
if isServer:
import datetime
try: try:
run() run()
except SystemExit: except SystemExit:
@ -57,4 +62,9 @@ except SystemExit:
except Exception: except Exception:
info = describeException() info = describeException()
simbase.air.writeServerEvent('uberdog-exception', simbase.air.getAvatarIdFromSender(), simbase.air.getAccountIdFromSender(), info) simbase.air.writeServerEvent('uberdog-exception', simbase.air.getAvatarIdFromSender(), simbase.air.getAccountIdFromSender(), info)
raise
if isServer:
with open(config.GetString('ud-crash-log-name', '/opt/var/log/Uberdog-crash-%s.txt' % (datetime.datetime.now())), 'w+') as file:
file.write(info + "\n")
raise

View file

@ -8,6 +8,7 @@ echo #1 - Localhost
echo #2 - Dev Server echo #2 - Dev Server
echo #3 - Custom echo #3 - Custom
echo #4 - Local RemoteDB echo #4 - Local RemoteDB
echo #5 - Prod Server
echo. echo.
:selection :selection
@ -21,6 +22,8 @@ if %INPUT%==1 (
set TTS_GAMESERVER=167.114.220.172 set TTS_GAMESERVER=167.114.220.172
) else if %INPUT%==4 ( ) else if %INPUT%==4 (
set TTS_GAMESERVER=127.0.0.1 set TTS_GAMESERVER=127.0.0.1
) else if %INPUT%==5 (
SET TTS_GAMESERVER=lw2.ez-webz.com:7198
) else if %INPUT%==3 ( ) else if %INPUT%==3 (
echo. echo.
set /P TTS_GAMESERVER=Gameserver: set /P TTS_GAMESERVER=Gameserver:
@ -59,6 +62,7 @@ echo ===============================
cd ../../ cd ../../
:main
if %INPUT%==2 ( if %INPUT%==2 (
"C:\Panda3D-1.10.0\python\ppython.exe" -m toontown.toonbase.ToontownStartRemoteDB "C:\Panda3D-1.10.0\python\ppython.exe" -m toontown.toonbase.ToontownStartRemoteDB
) else if %INPUT%==4 ( ) else if %INPUT%==4 (
@ -66,5 +70,6 @@ if %INPUT%==2 (
) else ( ) else (
"C:\Panda3D-1.10.0\python\ppython.exe" -m toontown.toonbase.ToontownStart "C:\Panda3D-1.10.0\python\ppython.exe" -m toontown.toonbase.ToontownStart
) )
pause pause
goto main

View file

@ -115,9 +115,16 @@ class AIBase:
self.taskMgr.add(self.__resetPrevTransform, 'resetPrevTransform', priority=-51) self.taskMgr.add(self.__resetPrevTransform, 'resetPrevTransform', priority=-51)
self.taskMgr.add(self.__ivalLoop, 'ivalLoop', priority=20) self.taskMgr.add(self.__ivalLoop, 'ivalLoop', priority=20)
self.taskMgr.add(self.__igLoop, 'igLoop', priority=50) self.taskMgr.add(self.__igLoop, 'igLoop', priority=50)
if self.config.GetBool('garbage-collect-states', 1):
self.taskMgr.add(self.__garbageCollectStates, 'garbageCollectStates', priority=46)
if self.AISleep >= 0 and (not self.AIRunningNetYield or self.AIForceSleep): if self.AISleep >= 0 and (not self.AIRunningNetYield or self.AIForceSleep):
self.taskMgr.add(self.__sleepCycleTask, 'aiSleep', priority=55) self.taskMgr.add(self.__sleepCycleTask, 'aiSleep', priority=55)
self.eventMgr.restart() self.eventMgr.restart()
def __garbageCollectStates(self, state):
TransformState.garbageCollect()
RenderState.garbageCollect()
return Task.cont
def getRepository(self): def getRepository(self):
return self.air return self.air

View file

@ -29,4 +29,4 @@ vfs = VirtualFileSystem.getGlobalPtr()
mounts = ConfigVariableList('vfs-mount') mounts = ConfigVariableList('vfs-mount')
for mount in mounts: for mount in mounts:
mountfile, mountpoint = (mount.split(' ', 2) + [None, None, None])[:2] mountfile, mountpoint = (mount.split(' ', 2) + [None, None, None])[:2]
vfs.mount(Filename(mountfile), Filename(mountpoint), 0) vfs.mount(Filename(mountfile), Filename(mountpoint), 0)

View file

@ -10,7 +10,7 @@ from direct.showbase.DirectObject import DirectObject
class BanFSM(FSM): class BanFSM(FSM):
def __init__(self, air, avId, comment, duration): def __init__(self, air, avId, comment, duration, banner):
FSM.__init__(self, 'banFSM-%s' % avId) FSM.__init__(self, 'banFSM-%s' % avId)
self.air = air self.air = air
self.avId = avId self.avId = avId
@ -21,10 +21,11 @@ class BanFSM(FSM):
self.DISLid = None self.DISLid = None
self.accountId = None self.accountId = None
self.avName = None self.avName = None
self.banner = banner
def performBan(self, duration): def performBan(self, duration):
executeHttpRequest('ban', username=self.accountId, start=int(time.time()), executeHttpRequest('ban', username=self.accountId, start=int(time.time()),
duration=duration, reason=self.comment, bannedby='todo') duration=duration, reason=self.comment, bannedby=self.banner)
def ejectPlayer(self): def ejectPlayer(self):
av = self.air.doId2do.get(self.avId) av = self.air.doId2do.get(self.avId)
@ -41,7 +42,7 @@ class BanFSM(FSM):
simbase.air.send(datagram) simbase.air.send(datagram)
def dbCallback(self, dclass, fields): def dbCallback(self, dclass, fields):
if dclass != self.air.dclassesByName['AccountAI']: if dclass != simbase.air.dclassesByName['AccountAI']:
return return
self.accountId = fields.get('ACCOUNT_ID') self.accountId = fields.get('ACCOUNT_ID')
@ -99,8 +100,8 @@ class BanManagerAI(DirectObject):
self.air = air self.air = air
self.banFSMs = {} self.banFSMs = {}
def ban(self, avId, duration, comment): def ban(self, avId, duration, comment, banner):
self.banFSMs[avId] = BanFSM(self.air, avId, comment, duration) self.banFSMs[avId] = BanFSM(self.air, avId, comment, duration, banner)
self.banFSMs[avId].request('Start') self.banFSMs[avId].request('Start')
self.acceptOnce(self.air.getAvatarExitEvent(avId), self.banDone, [avId]) self.acceptOnce(self.air.getAvatarExitEvent(avId), self.banDone, [avId])
@ -136,5 +137,6 @@ def ban(reason, duration):
return "You can't ban yourself!" return "You can't ban yourself!"
if reason not in ('hacking', 'language', 'other'): if reason not in ('hacking', 'language', 'other'):
return "'%s' is not a valid reason." % reason return "'%s' is not a valid reason." % reason
simbase.air.banManager.ban(target.doId, duration, reason) banner = spellbook.getInvoker().DISLid
simbase.air.banManager.ban(target.doId, duration, reason, banner)
return "Banned %s from the game server!" % target.getName() return "Banned %s from the game server!" % target.getName()

View file

@ -67,6 +67,7 @@ class Avatar(Actor, ShadowCaster):
self.__chatSet = 0 self.__chatSet = 0
self.__chatLocal = 0 self.__chatLocal = 0
self.__currentDialogue = None self.__currentDialogue = None
self.wantAdminTag = True
def delete(self): def delete(self):
try: try:
@ -172,6 +173,12 @@ class Avatar(Actor, ShadowCaster):
def getType(self): def getType(self):
return self.avatarType return self.avatarType
def setWantAdminTag(self, bool):
self.wantAdminTag = bool
def getWantAdminTag(self):
return self.wantAdminTag
def setName(self, name): def setName(self, name):
if hasattr(self, 'isDisguised') and self.isDisguised: if hasattr(self, 'isDisguised') and self.isDisguised:
@ -194,7 +201,7 @@ class Avatar(Actor, ShadowCaster):
self.nametag.setName(name) self.nametag.setName(name)
if hasattr(self, 'adminAccess') and self.isAdmin(): if hasattr(self, 'adminAccess') and self.isAdmin() and self.getWantAdminTag():
access = self.getAdminAccess() access = self.getAdminAccess()
if access in OTPLocalizer.AccessToString: if access in OTPLocalizer.AccessToString:
@ -553,11 +560,9 @@ class Avatar(Actor, ShadowCaster):
return sequence return sequence
@magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[]) @magicWord(category=CATEGORY_COMMUNITY_MANAGER)
def target(): def target():
""" """
Returns the current Spellbook target. Returns the current Spellbook target.
""" """
target = spellbook.getTarget() return 'Your current target is: %s [avId: %s, access: %s]' % (spellbook.getTarget().getName(), spellbook.getTarget().doId, spellbook.getTarget().getAdminAccess())
return 'Target: %s-%d [%d]' % (target.getName(), int(target.doId), int(target.getAdminAccess()))

View file

@ -1125,9 +1125,6 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis
def d_setParent(self, parentToken): def d_setParent(self, parentToken):
DistributedSmoothNode.DistributedSmoothNode.d_setParent(self, parentToken) DistributedSmoothNode.DistributedSmoothNode.d_setParent(self, parentToken)
def canChat(self):
return 0
@magicWord(category=CATEGORY_COMMUNITY_MANAGER) @magicWord(category=CATEGORY_COMMUNITY_MANAGER)
def run(): def run():

View file

@ -1,5 +1,6 @@
from direct.distributed.DistributedObjectGlobal import DistributedObjectGlobal from direct.distributed.DistributedObjectGlobal import DistributedObjectGlobal
from otp.ai.MagicWordGlobal import * from otp.ai.MagicWordGlobal import *
from otp.avatar import Avatar
class ChatAgent(DistributedObjectGlobal): class ChatAgent(DistributedObjectGlobal):

View file

@ -11,7 +11,7 @@ OFFENSE_MSGS = ('-- DEV CHAT -- word blocked: %s', 'Watch your language! This is
class ChatAgentUD(DistributedObjectGlobalUD): class ChatAgentUD(DistributedObjectGlobalUD):
notify = DirectNotifyGlobal.directNotify.newCategory('ChatAgentUD') notify = DirectNotifyGlobal.directNotify.newCategory('ChatAgentUD')
WantWhitelist = config.GetBool('want-whitelist', True) wantWhitelist = config.GetBool('want-whitelist', True)
chatMode2channel = { chatMode2channel = {
1 : OtpDoGlobals.OTP_MOD_CHANNEL, 1 : OtpDoGlobals.OTP_MOD_CHANNEL,
@ -36,17 +36,12 @@ class ChatAgentUD(DistributedObjectGlobalUD):
'Account sent chat without an avatar', message) 'Account sent chat without an avatar', message)
return return
if chatMode == 0: if chatMode == 0 and self.wantWhitelist:
if self.detectBadWords(self.air.getMsgSender(), message): if self.detectBadWords(self.air.getMsgSender(), message):
return return
self.air.writeServerEvent('chat-said', sender, message) self.air.writeServerEvent('chat-said', sender, message)
self.air.send(self.air.dclassesByName['DistributedAvatarUD'].aiFormatUpdate('setTalk', sender, sender, self.air.ourChannel, [message]))
DistributedAvatar = self.air.dclassesByName['DistributedAvatarUD']
dg = DistributedAvatar.aiFormatUpdate('setTalk', sender, sender,
self.air.ourChannel,
[message])
self.air.send(dg)
def detectBadWords(self, sender, message): def detectBadWords(self, sender, message):
words = message.split() words = message.split()

View file

@ -123,7 +123,7 @@ class ChatManager(DirectObject.DirectObject):
def enterMainMenu(self): def enterMainMenu(self):
self.checkObscurred() self.checkObscurred()
if self.localAvatar.canChat(): if base.cr.wantTypedChat():
if self.wantBackgroundFocus: if self.wantBackgroundFocus:
self.chatInputNormal.chatEntry['backgroundFocus'] = 1 self.chatInputNormal.chatEntry['backgroundFocus'] = 1
self.acceptOnce('enterNormalChat', self.fsm.request, ['normalChat']) self.acceptOnce('enterNormalChat', self.fsm.request, ['normalChat'])

View file

@ -18,6 +18,7 @@ from otp.otpbase import OTPGlobals, OTPLocalizer
from otp.otpgui import OTPDialog from otp.otpgui import OTPDialog
from otp.nametag.NametagConstants import * from otp.nametag.NametagConstants import *
import sys, time, types, random import sys, time, types, random
import __builtin__
class OTPClientRepository(ClientRepositoryBase): class OTPClientRepository(ClientRepositoryBase):
notify = directNotify.newCategory('OTPClientRepository') notify = directNotify.newCategory('OTPClientRepository')
@ -222,7 +223,7 @@ class OTPClientRepository(ClientRepositoryBase):
if dcFileNames == None: if dcFileNames == None:
try: try:
# For Nirai # For Nirai
readResult = dcFile.read(dcStream, '__dc__') readResult = dcFile.read(dcStream)
del __builtin__.dcStream del __builtin__.dcStream
except NameError: except NameError:
@ -468,7 +469,7 @@ class OTPClientRepository(ClientRepositoryBase):
self.handler = self.handleMessageType self.handler = self.handleMessageType
messenger.send('connectionIssue') messenger.send('connectionIssue')
url = self.serverList[0] url = self.serverList[0]
self.notify.warning('Failed to connect to %s (%s %s). Notifying user.' % (url.cStr(), statusCode, statusString)) self.notify.warning('Failed to connect to %s (%s %s). Notifying user.' % (config.GetString('TTS_GAMESERVER'), statusCode, statusString))
dialogClass = OTPGlobals.getGlobalDialogClass() dialogClass = OTPGlobals.getGlobalDialogClass()
self.failedToConnectBox = dialogClass(message=OTPLocalizer.CRNoConnectTryAgain % (url.getServer(), url.getPort()), doneEvent='failedToConnectAck', text_wordwrap=18, style=OTPDialog.TwoChoice) self.failedToConnectBox = dialogClass(message=OTPLocalizer.CRNoConnectTryAgain % (url.getServer(), url.getPort()), doneEvent='failedToConnectAck', text_wordwrap=18, style=OTPDialog.TwoChoice)
self.failedToConnectBox.show() self.failedToConnectBox.show()
@ -624,7 +625,7 @@ class OTPClientRepository(ClientRepositoryBase):
else: else:
message = OTPLocalizer.CRLostConnection message = OTPLocalizer.CRLostConnection
reconnect = 1 reconnect = 1
if self.bootedIndex in (152, 127): if self.bootedIndex in (152, 127, 124, 101, 102, 103):
reconnect = 0 reconnect = 0
if self.bootedIndex == 152: if self.bootedIndex == 152:
message = message % {'name': self.bootedText} message = message % {'name': self.bootedText}

View file

@ -76,8 +76,8 @@ InterfaceFont = None
InterfaceFontPath = None InterfaceFontPath = None
SignFont = None SignFont = None
SignFontPath = None SignFontPath = None
FancyFont = None ChalkFont = None
FancyFontPath = None ChalkFontPath = None
NametagFonts = {} NametagFonts = {}
NametagFontPaths = {} NametagFontPaths = {}
DialogClass = None DialogClass = None
@ -115,20 +115,20 @@ def setSignFont(path):
global SignFontPath global SignFontPath
SignFontPath = path SignFontPath = path
def getFancyFont(): def getChalkFont():
global FancyFontPath global ChalkFontPath
global FancyFont global ChalkFont
if FancyFont == None: if ChalkFont == None:
if FancyFontPath == None: if ChalkFontPath == None:
InterfaceFont = TextNode.getDefaultFont() InterfaceFont = TextNode.getDefaultFont()
FancyFont = TextNode.getDefaultFont() ChalkFont = TextNode.getDefaultFont()
else: else:
FancyFont = loader.loadFont(FancyFontPath, lineHeight=1.0) ChalkFont = loader.loadFont(ChalkFontPath, lineHeight=1.0)
return FancyFont return ChalkFont
def setFancyFont(path): def setChalkFont(path):
global FancyFontPath global ChalkFontPath
FancyFontPath = path ChalkFontPath = path
def getNametagFont(index): def getNametagFont(index):
global NametagFontPaths global NametagFontPaths

View file

@ -132,6 +132,7 @@ CRBootedReasons = {100: 'You have been disconnected because someone else just lo
102: 'You are not authorized to use administrator privileges.', 102: 'You are not authorized to use administrator privileges.',
103: 'You were banned by a moderator.\n\nBehave next time!', 103: 'You were banned by a moderator.\n\nBehave next time!',
105: 'Toontown Stride is now temporarily closed for maintenance. Everyone who was playing has been disconnected from the game.\n\nFor more information, please visit the Toontown Stride website.', 105: 'Toontown Stride is now temporarily closed for maintenance. Everyone who was playing has been disconnected from the game.\n\nFor more information, please visit the Toontown Stride website.',
124: 'Your installed files are out of date! Use the official launcher to download the newest version, or contact Toontown Stride Support if the problem persists.',
153: 'The district you were playing on has been reset. Everyone who was playing on that district has been disconnected. However, you should be able to connect again and go right back into the game.', 153: 'The district you were playing on has been reset. Everyone who was playing on that district has been disconnected. However, you should be able to connect again and go right back into the game.',
166: 'You were disconnected to prevent a district reset.'} 166: 'You were disconnected to prevent a district reset.'}
CRBootedReasonUnknownCode = 'An unexpected problem has occurred (error code %s). Your connection has been lost, but you should be able to connect again and go right back into the game.' CRBootedReasonUnknownCode = 'An unexpected problem has occurred (error code %s). Your connection has been lost, but you should be able to connect again and go right back into the game.'
@ -291,7 +292,6 @@ EmoteList = ['Wave',
'Delighted', 'Delighted',
'Furious', 'Furious',
'Laugh', 'Laugh',
'Taunt',
'Rage'] 'Rage']
EmoteWhispers = ['%s waves.', EmoteWhispers = ['%s waves.',
'%s is happy.', '%s is happy.',
@ -318,7 +318,6 @@ EmoteWhispers = ['%s waves.',
'%s is delighted.', '%s is delighted.',
'%s is furious.', '%s is furious.',
'%s is laughing.', '%s is laughing.',
'%s taunts you.',
'%s is raging.'] '%s is raging.']
EmoteFuncDict = {'Wave': 0, EmoteFuncDict = {'Wave': 0,
'Happy': 1, 'Happy': 1,
@ -345,8 +344,7 @@ EmoteFuncDict = {'Wave': 0,
'Delighted': 22, 'Delighted': 22,
'Furious': 23, 'Furious': 23,
'Laugh': 24, 'Laugh': 24,
'Taunt': 25, 'Rage': 25}
'Rage': 26}
SuitBrushOffs = {'f': ["I'm late for a meeting."], SuitBrushOffs = {'f': ["I'm late for a meeting."],
'p': ['Push off.'], 'p': ['Push off.'],
'ym': ['Yes Man says NO.'], 'ym': ['Yes Man says NO.'],

@ -1 +1 @@
Subproject commit 769d26390634d17384aa28021cc7afd88306c4af Subproject commit af09e769b860512c03de6fff4a585e96d674e89b

View file

@ -3,6 +3,12 @@ from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.uberdog.ClientServicesManagerUD import executeHttpRequestAndLog from toontown.uberdog.ClientServicesManagerUD import executeHttpRequestAndLog
import ReportGlobals, threading, time import ReportGlobals, threading, time
# TODO: FIX
'''
THREADING.TIMER CAUSES CONTROL C NOT TO WORK, AND FOR THE AI NOT TO DIE
'''
class DistributedReportMgrAI(DistributedObjectAI): class DistributedReportMgrAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedReportMgrAI") notify = DirectNotifyGlobal.directNotify.newCategory("DistributedReportMgrAI")
@ -10,10 +16,10 @@ class DistributedReportMgrAI(DistributedObjectAI):
DistributedObjectAI.__init__(self, air) DistributedObjectAI.__init__(self, air)
self.reports = [] self.reports = []
self.interval = config.GetInt('report-interval', 600) self.interval = config.GetInt('report-interval', 600)
self.scheduleReport() #self.scheduleReport()
def scheduleReport(self): #def scheduleReport(self):
threading.Timer(self.interval, self.sendAllReports).start() # threading.Timer(self.interval, self.sendAllReports).start()
def sendReport(self, avId, category): def sendReport(self, avId, category):
if not ReportGlobals.isValidCategoryName(category) or not len(str(avId)) == 9: if not ReportGlobals.isValidCategoryName(category) or not len(str(avId)) == 9:
@ -28,7 +34,7 @@ class DistributedReportMgrAI(DistributedObjectAI):
self.reports.append('%s|%s|%s|%s' % (timestamp, reporter.doId, avId, category)) self.reports.append('%s|%s|%s|%s' % (timestamp, reporter.doId, avId, category))
def sendAllReports(self): def sendAllReports(self):
self.scheduleReport() #self.scheduleReport()
if not self.reports or config.GetString('accountdb-type', 'developer') != 'remote': if not self.reports or config.GetString('accountdb-type', 'developer') != 'remote':
return return

View file

@ -28,8 +28,10 @@ Holidays = {
'endMessage': TTLocalizer.SillySaturdayEnd 'endMessage': TTLocalizer.SillySaturdayEnd
}, },
ToontownGlobals.BLACK_CAT_DAY: { ToontownGlobals.BLACK_CAT_DAY: {
'startDay': 13, 'startMonth': 10,
'endDay': 13, 'startDay': 31,
'endMonth': 10,
'endDay': 31,
'startMessage': TTLocalizer.BlackCatHolidayStart, 'startMessage': TTLocalizer.BlackCatHolidayStart,
'ongoingMessage': TTLocalizer.BlackCatHolidayStart, 'ongoingMessage': TTLocalizer.BlackCatHolidayStart,
'endMessage': TTLocalizer.BlackCatHolidayEnd 'endMessage': TTLocalizer.BlackCatHolidayEnd

View file

@ -47,7 +47,7 @@ class NewsManagerAI(DistributedObjectAI):
return self.activeHolidays return self.activeHolidays
def __checkHolidays(self, task=None): def __checkHolidays(self, task=None):
date = datetime.datetime.utcnow().replace(tzinfo=HolidayGlobals.TIME_ZONE) date = datetime.datetime.now(HolidayGlobals.TIME_ZONE)
for id in HolidayGlobals.Holidays: for id in HolidayGlobals.Holidays:
holiday = HolidayGlobals.Holidays[id] holiday = HolidayGlobals.Holidays[id]

View file

@ -81,7 +81,7 @@ class QuestManagerAI:
# If it's a TrackChoiceQuest then present their track choices. # If it's a TrackChoiceQuest then present their track choices.
if isinstance(questClass, Quests.TrackChoiceQuest): if isinstance(questClass, Quests.TrackChoiceQuest):
npc.presentTrackChoice(avId, questId, questClass.getChoices(av)) npc.presentTrackChoice(avId, questId, questClass.getChoices())
break break
# If there is another part to this quest then give them that. # If there is another part to this quest then give them that.
if Quests.getNextQuest(questId, npc, av)[0] != Quests.NA: if Quests.getNextQuest(questId, npc, av)[0] != Quests.NA:

View file

@ -62,11 +62,10 @@ if ':' in host:
port = int(port) port = int(port)
simbase.air.connect(host, port) simbase.air.connect(host, port)
isServer = config.GetBool('is-server', False) gc.enable()
try: try:
run() run()
gc.enable()
except SystemExit: except SystemExit:
raise raise
except Exception: except Exception:
@ -74,9 +73,4 @@ except Exception:
simbase.air.writeServerEvent('ai-exception', avId=simbase.air.getAvatarIdFromSender(), accId=simbase.air.getAccountIdFromSender(), exception=info) simbase.air.writeServerEvent('ai-exception', avId=simbase.air.getAvatarIdFromSender(), accId=simbase.air.getAccountIdFromSender(), exception=info)
if isServer:
import datetime
with open(config.GetString('ai-crash-log-name', '/opt/var/log/%s-ai-crash-%s.txt' % (config.GetString('district-name', 'Devhaven'), datetime.datetime.now())), 'w+') as file:
file.write(info + "\n")
raise raise

View file

@ -52,6 +52,7 @@ from toontown.tutorial.TutorialManagerAI import TutorialManagerAI
from toontown.uberdog.DistributedPartyManagerAI import DistributedPartyManagerAI from toontown.uberdog.DistributedPartyManagerAI import DistributedPartyManagerAI
from toontown.uberdog.TopToonsManagerAI import TopToonsManagerAI from toontown.uberdog.TopToonsManagerAI import TopToonsManagerAI
#from toontown.uberdog.DistributedLobbyManagerAI import DistributedLobbyManagerAI #from toontown.uberdog.DistributedLobbyManagerAI import DistributedLobbyManagerAI
import threading
class ToontownAIRepository(ToontownInternalRepository): class ToontownAIRepository(ToontownInternalRepository):
def __init__(self, baseChannel, stateServerChannel, districtName): def __init__(self, baseChannel, stateServerChannel, districtName):
@ -180,6 +181,9 @@ class ToontownAIRepository(ToontownInternalRepository):
def handleConnected(self): def handleConnected(self):
ToontownInternalRepository.handleConnected(self) ToontownInternalRepository.handleConnected(self)
threading.Thread(target=self.startDistrict).start()
def startDistrict(self):
self.districtId = self.allocateChannel() self.districtId = self.allocateChannel()
self.notify.info('Creating ToontownDistrictAI(%d)...' % self.districtId) self.notify.info('Creating ToontownDistrictAI(%d)...' % self.districtId)
self.distributedDistrict = ToontownDistrictAI(self) self.distributedDistrict = ToontownDistrictAI(self)

View file

@ -229,8 +229,8 @@ class BattleBase:
posA] posA]
suitSpeed = 4.8 suitSpeed = 4.8
toonSpeed = 8.0 toonSpeed = 8.0
maxTimeToon = 10.0 maxTimeToon = 3.0
maxTimeSuit = 11.0 maxTimeSuit = 4.0
def __init__(self): def __init__(self):
self.pos = Point3(0, 0, 0) self.pos = Point3(0, 0, 0)

View file

@ -993,6 +993,7 @@ class DistributedBattleBaseAI(DistributedObjectAI.DistributedObjectAI, BattleBas
self.notify.warning('requestAttack() - no toon: %d' % toonId) self.notify.warning('requestAttack() - no toon: %d' % toonId)
return return
validResponse = 1 validResponse = 1
self.npcAttacks = {k:v for k, v in self.npcAttacks.iteritems() if v != toonId}
if track == SOS: if track == SOS:
self.notify.debug('toon: %d calls for help' % toonId) self.notify.debug('toon: %d calls for help' % toonId)
self.air.writeServerEvent('friendSOS', toonId, '%s' % av) self.air.writeServerEvent('friendSOS', toonId, '%s' % av)
@ -1007,7 +1008,7 @@ class DistributedBattleBaseAI(DistributedObjectAI.DistributedObjectAI, BattleBas
npcCollision = 0 npcCollision = 0
if av in self.npcAttacks: if av in self.npcAttacks:
callingToon = self.npcAttacks[av] callingToon = self.npcAttacks[av]
if self.activeToons.count(callingToon) == 1: if callingToon != toonId and self.activeToons.count(callingToon) == 1:
self.toonAttacks[toonId] = getToonAttack(toonId, track=PASS) self.toonAttacks[toonId] = getToonAttack(toonId, track=PASS)
npcCollision = 1 npcCollision = 1
if npcCollision == 0: if npcCollision == 0:

View file

@ -255,17 +255,13 @@ def createSuitReviveTrack(suit, toon, battle, npcs = []):
if hasattr(suit, 'battleTrapProp') and suit.battleTrapProp and suit.battleTrapProp.getName() == 'traintrack' and not suit.battleTrapProp.isHidden(): if hasattr(suit, 'battleTrapProp') and suit.battleTrapProp and suit.battleTrapProp.getName() == 'traintrack' and not suit.battleTrapProp.isHidden():
suitTrack.append(createTrainTrackAppearTrack(suit, toon, battle, npcs)) suitTrack.append(createTrainTrackAppearTrack(suit, toon, battle, npcs))
deathSuit = suit.getLoseActor() deathSuit = suit.getLoseActor()
suitTrack.append(Func(notify.debug, 'before insertDeathSuit'))
suitTrack.append(Func(insertReviveSuit, suit, deathSuit, battle, suitPos, suitHpr)) suitTrack.append(Func(insertReviveSuit, suit, deathSuit, battle, suitPos, suitHpr))
suitTrack.append(Func(notify.debug, 'before actorInterval lose'))
suitTrack.append(ActorInterval(deathSuit, 'lose', duration=SUIT_LOSE_REVIVE_DURATION)) suitTrack.append(ActorInterval(deathSuit, 'lose', duration=SUIT_LOSE_REVIVE_DURATION))
suitTrack.append(Func(notify.debug, 'before removeDeathSuit'))
suitTrack.append(Func(removeReviveSuit, suit, deathSuit, name='remove-death-suit')) suitTrack.append(Func(removeReviveSuit, suit, deathSuit, name='remove-death-suit'))
suitTrack.append(Func(notify.debug, 'after removeDeathSuit'))
suitTrack.append(ActorInterval(suit, 'slip-forward', startTime=2.48, duration=0.1)) suitTrack.append(ActorInterval(suit, 'slip-forward', startTime=2.48, duration=0.1))
suitTrack.append(ActorInterval(suit, 'slip-forward', startTime=2.58)) suitTrack.append(ActorInterval(suit, 'slip-forward', startTime=2.58))
suitTrack.append(Func(suit.loop, 'neutral')) suitTrack.append(Func(suit.loop, 'neutral'))
suitTrack.append(Func(messenger.send, suit.uniqueName('hpChange'))) suitTrack.append(Func(suit.setHP, suit.getMaxHP()))
spinningSound = base.loadSfx('phase_3.5/audio/sfx/Cog_Death.ogg') spinningSound = base.loadSfx('phase_3.5/audio/sfx/Cog_Death.ogg')
deathSound = base.loadSfx('phase_3.5/audio/sfx/ENC_cogfall_apart_%s.ogg' % random.randint(1, 6)) deathSound = base.loadSfx('phase_3.5/audio/sfx/ENC_cogfall_apart_%s.ogg' % random.randint(1, 6))
deathSoundTrack = Sequence(Wait(0.8), SoundInterval(spinningSound, duration=1.2, startTime=1.5, volume=0.2), SoundInterval(spinningSound, duration=3.0, startTime=0.6, volume=0.8), SoundInterval(deathSound, volume=0.32)) deathSoundTrack = Sequence(Wait(0.8), SoundInterval(spinningSound, duration=1.2, startTime=1.5, volume=0.2), SoundInterval(spinningSound, duration=3.0, startTime=0.6, volume=0.8), SoundInterval(deathSound, volume=0.32))

View file

@ -434,10 +434,10 @@ class RewardPanel(DirectFrame):
def getTrackIntervalList(self, toon, track, origSkill, earnedSkill, hasUber): def getTrackIntervalList(self, toon, track, origSkill, earnedSkill, hasUber):
if hasUber < 0: if hasUber < 0:
print (toon.doId, 'Reward Panel received an invalid hasUber from an uberList') print (toon.doId, 'Reward Panel received an invalid hasUber from an uberList')
tickDelay = 1.0 / 60 tickDelay = 0.1
intervalList = [] intervalList = []
intervalList.append(Func(self.showTrackIncLabel, track, earnedSkill)) intervalList.append(Func(self.showTrackIncLabel, track, earnedSkill))
barTime = 0.5 barTime = math.log(earnedSkill + 0.5)
numTicks = int(math.ceil(barTime / tickDelay)) numTicks = int(math.ceil(barTime / tickDelay))
for i in xrange(numTicks): for i in xrange(numTicks):
t = (i + 1) / float(numTicks) t = (i + 1) / float(numTicks)
@ -463,9 +463,9 @@ class RewardPanel(DirectFrame):
uberSkill = ToontownBattleGlobals.UberSkill + ToontownBattleGlobals.Levels[track][ToontownBattleGlobals.LAST_REGULAR_GAG_LEVEL + 1] uberSkill = ToontownBattleGlobals.UberSkill + ToontownBattleGlobals.Levels[track][ToontownBattleGlobals.LAST_REGULAR_GAG_LEVEL + 1]
if currentSkill >= uberSkill and not hasUber > 0: if currentSkill >= uberSkill and not hasUber > 0:
intervalList += self.getUberGagIntervalList(toon, track, ToontownBattleGlobals.LAST_REGULAR_GAG_LEVEL + 1) intervalList += self.getUberGagIntervalList(toon, track, ToontownBattleGlobals.LAST_REGULAR_GAG_LEVEL + 1)
intervalList.append(Wait(0.1)) intervalList.append(Wait(0.3))
skillDiff = currentSkill - ToontownBattleGlobals.Levels[track][ToontownBattleGlobals.LAST_REGULAR_GAG_LEVEL + 1] skillDiff = currentSkill - ToontownBattleGlobals.Levels[track][ToontownBattleGlobals.LAST_REGULAR_GAG_LEVEL + 1]
barTime = math.log(skillDiff + 1) barTime = math.log(skillDiff + 0.5)
numTicks = int(math.ceil(barTime / tickDelay)) numTicks = int(math.ceil(barTime / tickDelay))
displayedSkillDiff = skillDiff displayedSkillDiff = skillDiff
if displayedSkillDiff > ToontownBattleGlobals.UberSkill: if displayedSkillDiff > ToontownBattleGlobals.UberSkill:
@ -477,18 +477,18 @@ class RewardPanel(DirectFrame):
intervalList.append(Func(self.incrementExp, track, newValue, toon)) intervalList.append(Func(self.incrementExp, track, newValue, toon))
intervalList.append(Wait(tickDelay * 0.5)) intervalList.append(Wait(tickDelay * 0.5))
intervalList.append(Wait(0.1)) intervalList.append(Wait(0.3))
return intervalList return intervalList
def getMeritIntervalList(self, toon, dept, origMerits, earnedMerits): def getMeritIntervalList(self, toon, dept, origMerits, earnedMerits):
tickDelay = 1.0 / 60 tickDelay = 0.08
intervalList = [] intervalList = []
totalMerits = CogDisguiseGlobals.getTotalMerits(toon, dept) totalMerits = CogDisguiseGlobals.getTotalMerits(toon, dept)
neededMerits = 0 neededMerits = 0
if totalMerits and origMerits != totalMerits: if totalMerits and origMerits != totalMerits:
neededMerits = totalMerits - origMerits neededMerits = totalMerits - origMerits
intervalList.append(Func(self.showMeritIncLabel, dept, min(neededMerits, earnedMerits))) intervalList.append(Func(self.showMeritIncLabel, dept, min(neededMerits, earnedMerits)))
barTime = 0.5 barTime = math.log(earnedMerits + 1)
numTicks = int(math.ceil(barTime / tickDelay)) numTicks = int(math.ceil(barTime / tickDelay))
for i in xrange(numTicks): for i in xrange(numTicks):
t = (i + 1) / float(numTicks) t = (i + 1) / float(numTicks)
@ -497,10 +497,10 @@ class RewardPanel(DirectFrame):
intervalList.append(Wait(tickDelay)) intervalList.append(Wait(tickDelay))
intervalList.append(Func(self.resetMeritBarColor, dept)) intervalList.append(Func(self.resetMeritBarColor, dept))
intervalList.append(Wait(0.1)) intervalList.append(Wait(0.3))
if toon.cogLevels[dept] < ToontownGlobals.MaxCogSuitLevel: if toon.cogLevels[dept] < ToontownGlobals.MaxCogSuitLevel:
if neededMerits and toon.readyForPromotion(dept): if neededMerits and toon.readyForPromotion(dept):
intervalList.append(Wait(0.4)) intervalList.append(Wait(0.3))
intervalList += self.getPromotionIntervalList(toon, dept) intervalList += self.getPromotionIntervalList(toon, dept)
return intervalList return intervalList
@ -621,7 +621,7 @@ class RewardPanel(DirectFrame):
if earned > 0: if earned > 0:
earned = min(earned, quest.getNumQuestItems() - questDesc[4]) earned = min(earned, quest.getNumQuestItems() - questDesc[4])
if earned > 0 or base.localAvatar.tutorialAck == 0 and num == 1: if earned > 0 or base.localAvatar.tutorialAck == 0 and num == 1:
barTime = 0.5 barTime = math.log(earned + 1)
numTicks = int(math.ceil(barTime / tickDelay)) numTicks = int(math.ceil(barTime / tickDelay))
for i in xrange(numTicks): for i in xrange(numTicks):
t = (i + 1) / float(numTicks) t = (i + 1) / float(numTicks)
@ -683,19 +683,19 @@ class RewardPanel(DirectFrame):
if meritList[dept]: if meritList[dept]:
track += self.getMeritIntervalList(toon, dept, origMeritList[dept], meritList[dept]) track += self.getMeritIntervalList(toon, dept, origMeritList[dept], meritList[dept])
track.append(Wait(0.75)) track.append(Wait(1.0))
itemInterval = self.getItemIntervalList(toon, itemList) itemInterval = self.getItemIntervalList(toon, itemList)
if itemInterval: if itemInterval:
track.append(Func(self.initItemFrame, toon)) track.append(Func(self.initItemFrame, toon))
track.append(Wait(0.25)) track.append(Wait(1.0))
track += itemInterval track += itemInterval
track.append(Wait(0.5)) track.append(Wait(1.0))
missedItemInterval = self.getMissedItemIntervalList(toon, missedItemList) missedItemInterval = self.getMissedItemIntervalList(toon, missedItemList)
if missedItemInterval: if missedItemInterval:
track.append(Func(self.initMissedItemFrame, toon)) track.append(Func(self.initMissedItemFrame, toon))
track.append(Wait(0.25)) track.append(Wait(1.0))
track += missedItemInterval track += missedItemInterval
track.append(Wait(0.5)) track.append(Wait(1.0))
self.notify.debug('partList = %s' % partList) self.notify.debug('partList = %s' % partList)
newPart = 0 newPart = 0
for part in partList: for part in partList:
@ -707,9 +707,9 @@ class RewardPanel(DirectFrame):
partList = self.getCogPartIntervalList(toon, partList) partList = self.getCogPartIntervalList(toon, partList)
if partList: if partList:
track.append(Func(self.initCogPartFrame, toon)) track.append(Func(self.initCogPartFrame, toon))
track.append(Wait(0.25)) track.append(Wait(1.0))
track += partList track += partList
track.append(Wait(0.5)) track.append(Wait(1.0))
questList = self.getQuestIntervalList(toon, deathList, toonList, origQuestsList, itemList, helpfulToonsList) questList = self.getQuestIntervalList(toon, deathList, toonList, origQuestsList, itemList, helpfulToonsList)
if questList: if questList:
avQuests = [] avQuests = []
@ -717,9 +717,9 @@ class RewardPanel(DirectFrame):
avQuests.append(origQuestsList[i:i + 5]) avQuests.append(origQuestsList[i:i + 5])
track.append(Func(self.initQuestFrame, toon, copy.deepcopy(avQuests))) track.append(Func(self.initQuestFrame, toon, copy.deepcopy(avQuests)))
track.append(Wait(0.25)) track.append(Wait(1.0))
track += questList track += questList
track.append(Wait(0.5)) track.append(Wait(2.0))
track.append(Wait(0.25)) track.append(Wait(0.25))
if trackEnded: if trackEnded:
track.append(Func(self.vanishFrames)) track.append(Func(self.vanishFrames))

View file

@ -3170,3 +3170,18 @@ def getAttackTaunt(attackName, index = None):
SuitAttackTaunts = TTLocalizer.SuitAttackTaunts SuitAttackTaunts = TTLocalizer.SuitAttackTaunts
DisabledAttacks = ('Gavel', 'SongAndDance', 'SandTrap', 'FloodTheMarket', 'FiveOClockShadow')
def getAttacksByType(attributes):
groupAttacks = []
singleAttacks = []
for attack in sorted(attributes['attacks'], key=lambda x: x[0]):
if attack[0] in DisabledAttacks:
continue
if SuitAttacks[attack[0]][1] == ATK_TGT_GROUP:
groupAttacks.append(attack)
else:
singleAttacks.append(attack)
return groupAttacks, singleAttacks

View file

@ -465,7 +465,6 @@ class DistributedElevator(DistributedObject.DistributedObject):
del self.elevatorFSM del self.elevatorFSM
elevator.signalDone(doneStatus) elevator.signalDone(doneStatus)
base.camLens.setMinFov(ToontownGlobals.CBElevatorFov/(4./3.)) base.camLens.setMinFov(ToontownGlobals.CBElevatorFov/(4./3.))
return
def getElevatorModel(self): def getElevatorModel(self):
self.notify.error('getElevatorModel: pure virtual -- inheritors must override') self.notify.error('getElevatorModel: pure virtual -- inheritors must override')
@ -530,10 +529,7 @@ class DistributedElevator(DistributedObject.DistributedObject):
return self.offsetNP.getPos(render) return self.offsetNP.getPos(render)
def canHideBoardingQuitBtn(self, avId): def canHideBoardingQuitBtn(self, avId):
if avId == localAvatar.doId and hasattr(localAvatar, 'boardingParty') and localAvatar.boardingParty and localAvatar.boardingParty.groupPanel: return avId == localAvatar.doId and hasattr(localAvatar, 'boardingParty') and localAvatar.boardingParty and localAvatar.boardingParty.groupPanel
return True
else:
return False
def getBoardingTrack(self, toon, seatIndex, wantToonRotation): def getBoardingTrack(self, toon, seatIndex, wantToonRotation):
self.boardingGroupShow = BoardingGroupShow.BoardingGroupShow(toon) self.boardingGroupShow = BoardingGroupShow.BoardingGroupShow(toon)

View file

@ -53,11 +53,7 @@ class DistributedKnockKnockDoor(DistributedAnimatedProp.DistributedAnimatedProp)
def avatarExit(self, avatarId): def avatarExit(self, avatarId):
if avatarId == self.avatarId: if avatarId == self.avatarId:
for track in self.avatarTracks: self.stopTracks()
track.finish()
DelayDelete.cleanupDelayDeletes(track)
self.avatarTracks = []
def knockKnockTrack(self, avatar, duration): def knockKnockTrack(self, avatar, duration):
if avatar is None: if avatar is None:
@ -96,7 +92,7 @@ class DistributedKnockKnockDoor(DistributedAnimatedProp.DistributedAnimatedProp)
return track return track
def cleanupTrack(self): def cleanupTrack(self):
avatar = self.cr.doId2do.get(self.avatarId, None) avatar = self.cr.doId2do.get(self.avatarId)
if avatar: if avatar:
avatar.clearChat() avatar.clearChat()
if self.nametag: if self.nametag:
@ -105,7 +101,6 @@ class DistributedKnockKnockDoor(DistributedAnimatedProp.DistributedAnimatedProp)
self.nametag.destroy() self.nametag.destroy()
self.nametag = None self.nametag = None
self.nametagNP = None self.nametagNP = None
return
def enterOff(self): def enterOff(self):
DistributedAnimatedProp.DistributedAnimatedProp.enterOff(self) DistributedAnimatedProp.DistributedAnimatedProp.enterOff(self)
@ -132,9 +127,13 @@ class DistributedKnockKnockDoor(DistributedAnimatedProp.DistributedAnimatedProp)
def exitPlaying(self): def exitPlaying(self):
DistributedAnimatedProp.DistributedAnimatedProp.exitPlaying(self) DistributedAnimatedProp.DistributedAnimatedProp.exitPlaying(self)
self.stopTracks()
def stopTracks(self):
for track in self.avatarTracks: for track in self.avatarTracks:
track.finish() track.pause()
DelayDelete.cleanupDelayDeletes(track) DelayDelete.cleanupDelayDeletes(track)
self.cleanupTrack()
self.avatarTracks = [] self.avatarTracks = []
self.avatarId = 0 self.avatarId = 0

View file

@ -10,6 +10,9 @@ class DistributedKnockKnockDoorAI(DistributedAnimatedPropAI.DistributedAnimatedP
self.fsm.setName('DistributedKnockKnockDoor') self.fsm.setName('DistributedKnockKnockDoor')
self.propId = propId self.propId = propId
self.doLaterTask = None self.doLaterTask = None
def delete(self):
DistributedAnimatedPropAI.DistributedAnimatedPropAI.delete(self)
def enterOff(self): def enterOff(self):
DistributedAnimatedPropAI.DistributedAnimatedPropAI.enterOff(self) DistributedAnimatedPropAI.DistributedAnimatedPropAI.enterOff(self)

View file

@ -365,6 +365,7 @@ class DistributedSuitInterior(DistributedObject.DistributedObject):
def enterResting(self, ts = 0): def enterResting(self, ts = 0):
base.playMusic(self.waitMusic, looping=1, volume=0.7) base.playMusic(self.waitMusic, looping=1, volume=0.7)
base.localAvatar.questMap.stop()
self.__closeInElevator() self.__closeInElevator()
def exitResting(self): def exitResting(self):

View file

@ -176,16 +176,17 @@ class ToonInterior(Place.Place):
def enterTeleportIn(self, requestStatus): def enterTeleportIn(self, requestStatus):
modelType = DistributedToonInterior.DistributedToonInterior(base.cr).getModelType(self.getZoneId()) modelType = DistributedToonInterior.DistributedToonInterior(base.cr).getModelType(self.getZoneId())
if ZoneUtil.isHQ(self.zoneId): if self.zoneId == ToontownGlobals.ToonHall:
base.localAvatar.setPosHpr(-63.5, 30.5, ToontownGlobals.FloorOffset, 90.0, 0.0, 0.0)
elif ZoneUtil.isHQ(self.zoneId):
base.localAvatar.setPosHpr(-5.5, -1.5, ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0) base.localAvatar.setPosHpr(-5.5, -1.5, ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0)
elif ZoneUtil.isPetshop(self.zoneId): elif ZoneUtil.isPetshop(self.zoneId):
base.localAvatar.setPosHpr(0, 0, ToontownGlobals.FloorOffset, 45.0, 0.0, 0.0) base.localAvatar.setPosHpr(0, 0, ToontownGlobals.FloorOffset, 45.0, 0.0, 0.0)
elif modelType in InteriorTypes:
area = InteriorTypes[modelType]
base.localAvatar.setPosHpr(area[0], area[1], ToontownGlobals.FloorOffset, area[2], 0.0, 0.0)
else: else:
if modelType in InteriorTypes: base.localAvatar.setPosHpr(2.5, 11.5, ToontownGlobals.FloorOffset, 45.0, 0.0, 0.0)
area = InteriorTypes[modelType]
base.localAvatar.setPosHpr(area[0], area[1], ToontownGlobals.FloorOffset, area[2], 0.0, 0.0)
else:
base.localAvatar.setPosHpr(2.5, 11.5, ToontownGlobals.FloorOffset, 45.0, 0.0, 0.0)
Place.Place.enterTeleportIn(self, requestStatus) Place.Place.enterTeleportIn(self, requestStatus)
def enterTeleportOut(self, requestStatus): def enterTeleportOut(self, requestStatus):

View file

@ -1059,7 +1059,7 @@ class CatalogFurnitureItem(CatalogAtticItem.CatalogAtticItem):
return 24 * 60 return 24 * 60
def getPicture(self, avatar): def getPicture(self, avatar):
model = self.loadModel(animate=0) model = self.loadModel()
spin = 1 spin = 1
flags = self.getFlags() flags = self.getFlags()
if flags & FLRug: if flags & FLRug:
@ -1095,7 +1095,7 @@ class CatalogFurnitureItem(CatalogAtticItem.CatalogAtticItem):
def getBasePrice(self): def getBasePrice(self):
return FurnitureTypes[self.furnitureType][FTBasePrice] return FurnitureTypes[self.furnitureType][FTBasePrice]
def loadModel(self, animate=1): def loadModel(self):
type = FurnitureTypes[self.furnitureType] type = FurnitureTypes[self.furnitureType]
model = loader.loadModel(type[FTModelName]) model = loader.loadModel(type[FTModelName])
self.applyColor(model, type[FTColor]) self.applyColor(model, type[FTColor])

View file

@ -535,13 +535,12 @@ MonthlySchedule = ((7,
CatalogClothingItem(1606, 0, True), CatalogClothingItem(1606, 0, True),
CatalogClothingItem(1603, 0, True), CatalogClothingItem(1603, 0, True),
CatalogClothingItem(1600, 0, True), CatalogClothingItem(1600, 0, True),
CatalogEmoteItem(25, True),
CatalogEmoteItem(26, True),
CatalogEmoteItem(20, True), CatalogEmoteItem(20, True),
CatalogEmoteItem(21, True), CatalogEmoteItem(21, True),
CatalogEmoteItem(22, True), CatalogEmoteItem(22, True),
CatalogEmoteItem(23, True), CatalogEmoteItem(23, True),
CatalogEmoteItem(24, True), CatalogEmoteItem(24, True),
CatalogEmoteItem(25, True),
CatalogClothingItem(1821, 0, True))), CatalogClothingItem(1821, 0, True))),
(5, (5,
26, 26,

View file

@ -130,15 +130,9 @@ class ToontownChatManager(ChatManager.ChatManager):
if avatarId: if avatarId:
self.enterWhisperChat(avatarName, avatarId) self.enterWhisperChat(avatarName, avatarId)
self.whisperFrame.hide() self.whisperFrame.hide()
return
def enterNormalChat(self): def enterNormalChat(self):
if not base.cr.wantTypedChat(): if not base.cr.wantTypedChat() or not base.localAvatar.getTutorialAck() or not ChatManager.ChatManager.enterNormalChat(self):
self.fsm.request('mainMenu')
return
result = ChatManager.ChatManager.enterNormalChat(self)
if result == None:
self.notify.warning('something went wrong in enterNormalChat, falling back to main menu')
self.fsm.request('mainMenu') self.fsm.request('mainMenu')
def enterWhisperChat(self, avatarName, avatarId): def enterWhisperChat(self, avatarName, avatarId):

View file

@ -23,7 +23,6 @@ class CogdoBarrelRoom:
self.fog = None self.fog = None
self.defaultFar = None self.defaultFar = None
self.stomperSfx = None self.stomperSfx = None
return
def destroy(self): def destroy(self):
self.unload() self.unload()
@ -71,7 +70,6 @@ class CogdoBarrelRoom:
taskMgr.remove(self.rewardUiTaskName) taskMgr.remove(self.rewardUiTaskName)
taskMgr.remove(self.rewardCameraTaskName) taskMgr.remove(self.rewardCameraTaskName)
self._isLoaded = False self._isLoaded = False
return
def isLoaded(self): def isLoaded(self):
return self._isLoaded return self._isLoaded

View file

@ -113,7 +113,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self._movie = None self._movie = None
self.SOSToonName = None self.SOSToonName = None
self.FOType = None self.FOType = None
return
def setShopOwnerNpcId(self, npcId): def setShopOwnerNpcId(self, npcId):
self.shopOwnerNpcId = npcId self.shopOwnerNpcId = npcId
@ -202,13 +201,11 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self.shopOwnerNpc.removeActive() self.shopOwnerNpc.removeActive()
self.shopOwnerNpc.delete() self.shopOwnerNpc.delete()
self.shopOwnerNpc = None self.shopOwnerNpc = None
return
def __cleanupPenthouseIntro(self): def __cleanupPenthouseIntro(self):
if hasattr(self, '_movie') and self._movie: if hasattr(self, '_movie') and self._movie:
self._movie.unload() self._movie.unload()
self._movie = None self._movie = None
return
def delete(self): def delete(self):
self._stashEntranceElevatorFC.destroy() self._stashEntranceElevatorFC.destroy()
@ -223,13 +220,9 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
del self.fsm del self.fsm
base.localAvatar.inventory.setBattleCreditMultiplier(1) base.localAvatar.inventory.setBattleCreditMultiplier(1)
DistributedObject.DistributedObject.delete(self) DistributedObject.DistributedObject.delete(self)
return
def isBossFloor(self, floorNum): def isBossFloor(self, floorNum):
if not self.layout.hasBossBattle(): return self.layout.hasBossBattle() and (self.layout.getBossBattleFloor() + 0) == floorNum
return False
return (self.layout.getBossBattleFloor() + 0) == floorNum
def __cleanup(self): def __cleanup(self):
self.toons = [] self.toons = []
@ -251,7 +244,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self.rightDoorIn = None self.rightDoorIn = None
self.leftDoorOut = None self.leftDoorOut = None
self.rightDoorOut = None self.rightDoorOut = None
return
def __addToon(self, toon): def __addToon(self, toon):
self.accept(toon.uniqueName('disable'), self.__handleUnexpectedExit, extraArgs=[toon]) self.accept(toon.uniqueName('disable'), self.__handleUnexpectedExit, extraArgs=[toon])
@ -404,7 +396,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
def enterWaitForAllToonsInside(self, ts = 0): def enterWaitForAllToonsInside(self, ts = 0):
base.transitions.fadeOut(0) base.transitions.fadeOut(0)
return None
def exitWaitForAllToonsInside(self): def exitWaitForAllToonsInside(self):
return None return None
@ -568,7 +559,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self._movie.end() self._movie.end()
self.__cleanupPenthouseIntro() self.__cleanupPenthouseIntro()
self.__finishInterval(self.elevatorName) self.__finishInterval(self.elevatorName)
return None
def __setupBarrelRoom(self): def __setupBarrelRoom(self):
self.currentFloor += 1 self.currentFloor += 1
@ -607,7 +597,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self.barrelRoomIntroTrack.finish() self.barrelRoomIntroTrack.finish()
DelayDelete.cleanupDelayDeletes(self.barrelRoomIntroTrack) DelayDelete.cleanupDelayDeletes(self.barrelRoomIntroTrack)
self.barrelRoomIntroTrack = None self.barrelRoomIntroTrack = None
return
def __handleLocalToonLeftBarrelRoom(self): def __handleLocalToonLeftBarrelRoom(self):
self.notify.info('Local toon teleported out of barrel room.') self.notify.info('Local toon teleported out of barrel room.')
@ -620,6 +609,7 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self.acceptOnce('localToonLeft', self.__handleLocalToonLeftBarrelRoom) self.acceptOnce('localToonLeft', self.__handleLocalToonLeftBarrelRoom)
self.barrelRoom.activate() self.barrelRoom.activate()
base.playMusic(self.waitMusic, looping=1, volume=0.7) base.playMusic(self.waitMusic, looping=1, volume=0.7)
base.localAvatar.questMap.stop()
def exitCollectBarrels(self): def exitCollectBarrels(self):
if self._wantBarrelRoom and not self.isBossFloor(self.currentFloor): if self._wantBarrelRoom and not self.isBossFloor(self.currentFloor):
@ -675,13 +665,11 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self.__playCloseElevatorOut(self.uniqueName('close-out-elevator')) self.__playCloseElevatorOut(self.uniqueName('close-out-elevator'))
camera.setPos(0, -15, 6) camera.setPos(0, -15, 6)
camera.headsUp(self.elevatorModelOut) camera.headsUp(self.elevatorModelOut)
return None
def exitBattle(self): def exitBattle(self):
if self.elevatorOutOpen == 1: if self.elevatorOutOpen == 1:
self.__finishInterval(self.uniqueName('close-out-elevator')) self.__finishInterval(self.uniqueName('close-out-elevator'))
self.elevatorOutOpen = 0 self.elevatorOutOpen = 0
return None
def __playReservesJoining(self, ts, name, callback): def __playReservesJoining(self, ts, name, callback):
index = 0 index = 0
@ -698,7 +686,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
def enterReservesJoining(self, ts = 0): def enterReservesJoining(self, ts = 0):
self.__playReservesJoining(ts, self.uniqueName('reserves-joining'), self.__handleReserveJoinDone) self.__playReservesJoining(ts, self.uniqueName('reserves-joining'), self.__handleReserveJoinDone)
return None
def __handleReserveJoinDone(self): def __handleReserveJoinDone(self):
self.joiningReserves = [] self.joiningReserves = []
@ -707,7 +694,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
def exitReservesJoining(self): def exitReservesJoining(self):
self.__finishInterval(self.uniqueName('reserves-joining')) self.__finishInterval(self.uniqueName('reserves-joining'))
return None
def enterResting(self, ts = 0): def enterResting(self, ts = 0):
self._showExitElevator() self._showExitElevator()
@ -734,7 +720,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self.penthouseOutroTrack.start(ts) self.penthouseOutroTrack.start(ts)
else: else:
self.exitCogdoBuilding() self.exitCogdoBuilding()
return None
def exitReward(self): def exitReward(self):
self.notify.debug('exitReward') self.notify.debug('exitReward')
@ -747,16 +732,13 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
self.__outroPenthouseChatDone() self.__outroPenthouseChatDone()
self.penthouseOutroChatDoneTrack.finish() self.penthouseOutroChatDoneTrack.finish()
self.penthouseOutroChatDoneTrack = None self.penthouseOutroChatDoneTrack = None
return
def enterFailed(self, ts = 0): def enterFailed(self, ts = 0):
self.exitCogdoBuilding() self.exitCogdoBuilding()
return None
def exitFailed(self): def exitFailed(self):
self.notify.debug('exitFailed()') self.notify.debug('exitFailed()')
self.exitCogdoBuilding() self.exitCogdoBuilding()
return None
def exitCogdoBuilding(self): def exitCogdoBuilding(self):
if base.localAvatar.hp < 0: if base.localAvatar.hp < 0:
@ -771,7 +753,6 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
'avId': -1, 'avId': -1,
'bldgDoId': self.distBldgDoId} 'bldgDoId': self.distBldgDoId}
messenger.send('DSIDoneEvent', [request]) messenger.send('DSIDoneEvent', [request])
return
def displayBadges(self): def displayBadges(self):
numFloors = self.layout.getNumGameFloors() numFloors = self.layout.getNumGameFloors()
@ -796,9 +777,8 @@ class DistributedCogdoInterior(DistributedObject.DistributedObject):
track = Parallel(name=trackName) track = Parallel(name=trackName)
base.cr.playGame.getPlace().fsm.request('stopped') base.cr.playGame.getPlace().fsm.request('stopped')
if self.FOType == "l": if self.FOType == 'l':
speech = TTLocalizer.CogdoExecutiveSuiteToonThankYouLawbot speech = TTLocalizer.CogdoExecutiveSuiteToonThankYouLawbot
else: else:
speech = TTLocalizer.CogdoExecutiveSuiteToonThankYou % self.SOSToonName speech = TTLocalizer.CogdoExecutiveSuiteToonThankYou % self.SOSToonName

View file

@ -99,7 +99,7 @@ class CogHQExterior(BattlePlace.BattlePlace):
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
def enterTunnelOut(self, requestStatus): def enterTunnelOut(self, requestStatus):
fromZoneId = self.zoneId - self.zoneId % 100 fromZoneId = self.zoneId - self.zoneId % 100

View file

@ -63,7 +63,7 @@ class ToontownClientRepository(OTPClientRepository.OTPClientRepository):
self._playerAvDclass = self.dclassesByName['DistributedToon'] self._playerAvDclass = self.dclassesByName['DistributedToon']
setInterfaceFont(TTLocalizer.InterfaceFont) setInterfaceFont(TTLocalizer.InterfaceFont)
setSignFont(TTLocalizer.SignFont) setSignFont(TTLocalizer.SignFont)
setFancyFont(TTLocalizer.FancyFont) setChalkFont(TTLocalizer.ChalkFont)
for i in xrange(len(TTLocalizer.NametagFonts)): for i in xrange(len(TTLocalizer.NametagFonts)):
setNametagFont(i, TTLocalizer.NametagFonts[i]) setNametagFont(i, TTLocalizer.NametagFonts[i])

View file

@ -4,6 +4,7 @@ from toontown.distributed.ToontownNetMessengerAI import ToontownNetMessengerAI
from direct.distributed.PyDatagram import PyDatagram from direct.distributed.PyDatagram import PyDatagram
import traceback import traceback
import sys import sys
import urlparse
class ToontownInternalRepository(AstronInternalRepository): class ToontownInternalRepository(AstronInternalRepository):
GameGlobalsId = OTP_DO_ID_TOONTOWN GameGlobalsId = OTP_DO_ID_TOONTOWN
@ -21,13 +22,19 @@ class ToontownInternalRepository(AstronInternalRepository):
self.__messenger = ToontownNetMessengerAI(self) self.__messenger = ToontownNetMessengerAI(self)
if self.wantMongo: if self.wantMongo:
import pymongo import pymongo
self.dbConn = pymongo.MongoClient(config.GetString('mongodb-url', 'localhost')) mongourl = config.GetString('mongodb-url', 'mongodb://localhost')
self.dbGlobalCursor = self.dbConn.toontownstride replicaset = config.GetString('mongodb-replicaset', '')
self.dbCursor = self.dbGlobalCursor['air-%d' % self.ourChannel] db = (urlparse.urlparse(mongourl).path or '/Astron_Dev')[1:]
if replicaset:
self.dbConn = pymongo.MongoClient(mongourl, replicaset=replicaset)
else:
self.dbConn = pymongo.MongoClient(mongourl)
self.database = self.dbConn[db]
self.dbGlobalCursor = self.database.toontownstride
else: else:
self.dbConn = None self.dbConn = None
self.database = None
self.dbGlobalCursor = None self.dbGlobalCursor = None
self.dbCursor = None
def sendNetEvent(self, message, sentArgs=[]): def sendNetEvent(self, message, sentArgs=[]):
self.__messenger.send(message, sentArgs) self.__messenger.send(message, sentArgs)

View file

@ -16,21 +16,21 @@ class DNABulkLoader:
def loadDNABulk(dnaStorage, file): def loadDNABulk(dnaStorage, file):
dnaLoader = DNALoader() dnaLoader = DNALoader()
fileu = 'resources/' + file file = '/' + file
dnaLoader.loadDNAFile(dnaStorage, fileu) dnaLoader.loadDNAFile(dnaStorage, file)
def loadDNAFile(dnaStorage, file): def loadDNAFile(dnaStorage, file):
print 'Reading DNA file...', file print 'Reading DNA file...', file
dnaLoader = DNALoader() dnaLoader = DNALoader()
fileu = 'resources/' + file file = '/' + file
node = dnaLoader.loadDNAFile(dnaStorage, fileu) node = dnaLoader.loadDNAFile(dnaStorage, file)
if node.node().getNumChildren() > 0: if node.node().getNumChildren() > 0:
return node.node() return node.node()
def loadDNAFileAI(dnaStorage, file): def loadDNAFileAI(dnaStorage, file):
dnaLoader = DNALoader() dnaLoader = DNALoader()
fileu = 'resources/' + file file = '/' + file
data = dnaLoader.loadDNAFileAI(dnaStorage, fileu) data = dnaLoader.loadDNAFileAI(dnaStorage, file)
return data return data
def setupDoor(a, b, c, d, e, f): def setupDoor(a, b, c, d, e, f):

View file

@ -11,7 +11,7 @@ from toontown.toonbase import TTLocalizer
class ClosetGUI(ClothesGUI.ClothesGUI): class ClosetGUI(ClothesGUI.ClothesGUI):
notify = directNotify.newCategory('ClosetGUI') notify = directNotify.newCategory('ClosetGUI')
def __init__(self, isOwner, doneEvent, cancelEvent, swapEvent, deleteEvent, topList = None, botList = None): def __init__(self, isOwner, doneEvent, cancelEvent, swapEvent, deleteEvent, topList = None, botList = None, maxClothes = 0):
ClothesGUI.ClothesGUI.__init__(self, ClothesGUI.CLOTHES_CLOSET, doneEvent, swapEvent) ClothesGUI.ClothesGUI.__init__(self, ClothesGUI.CLOTHES_CLOSET, doneEvent, swapEvent)
self.toon = None self.toon = None
self.topsList = topList self.topsList = topList
@ -20,29 +20,31 @@ class ClosetGUI(ClothesGUI.ClothesGUI):
self.deleteEvent = deleteEvent self.deleteEvent = deleteEvent
self.cancelEvent = cancelEvent self.cancelEvent = cancelEvent
self.genderChange = 0 self.genderChange = 0
self.maxClothes = maxClothes
self.verify = None self.verify = None
return
def load(self): def load(self):
ClothesGUI.ClothesGUI.load(self) ClothesGUI.ClothesGUI.load(self)
self.gui = loader.loadModel('phase_3/models/gui/create_a_toon_gui') self.gui = loader.loadModel('phase_3/models/gui/create_a_toon_gui')
self.cancelButton = DirectButton(relief=None, image=(self.gui.find('**/CrtAtoon_Btn2_UP'), self.gui.find('**/CrtAtoon_Btn2_DOWN'), self.gui.find('**/CrtAtoon_Btn2_RLLVR')), pos=(0.15, 0, -0.85), command=self.__handleCancel, text=('', TTLocalizer.MakeAToonCancel, TTLocalizer.MakeAToonCancel), text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08, text_pos=(0, -0.03), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1)) self.cancelButton = DirectButton(relief=None, image=(self.gui.find('**/CrtAtoon_Btn2_UP'), self.gui.find('**/CrtAtoon_Btn2_DOWN'), self.gui.find('**/CrtAtoon_Btn2_RLLVR')), pos=(0.15, 0, -0.85), command=self.__handleCancel, text=('', TTLocalizer.MakeAToonCancel, TTLocalizer.MakeAToonCancel), text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08, text_pos=(0, -0.03), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1))
self.cancelButton.hide() self.cancelButton.hide()
self.countFrame = DirectFrame(parent=self.parentFrame, image=self.shuffleFrame, image_scale=(-0.6, 0.6, 0.6), relief=None, pos=(0, 0, -0.125), scale=1.2, frameColor=(1, 1, 1, 1), text=TTLocalizer.ClothesGUICount % (0, 0), text_scale=0.0575, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1))
if self.isOwner: if self.isOwner:
trashcanGui = loader.loadModel('phase_3/models/gui/trashcan_gui.bam') trashcanGui = loader.loadModel('phase_3/models/gui/trashcan_gui')
trashImage = (trashcanGui.find('**/TrashCan_CLSD'), trashcanGui.find('**/TrashCan_OPEN'), trashcanGui.find('**/TrashCan_RLVR')) trashImage = (trashcanGui.find('**/TrashCan_CLSD'), trashcanGui.find('**/TrashCan_OPEN'), trashcanGui.find('**/TrashCan_RLVR'))
self.trashPanel = DirectFrame(parent=aspect2d, image=DGG.getDefaultDialogGeom(), image_color=(1, 1, 0.75, 0.8), image_scale=(0.36, 0, 0.75), pos=(-.86, 0, -.05), relief=None) self.trashPanel = DirectFrame(parent=aspect2d, image=DGG.getDefaultDialogGeom(), image_color=(1, 1, 0.75, 0.8), image_scale=(0.36, 0, 0.75), pos=(-.86, 0, -.05), relief=None)
self.topTrashButton = DirectButton(parent=self.trashPanel, image=trashImage, relief=None, pos=(-0.09, 0, 0.2), command=self.__handleDelete, extraArgs=[ClosetGlobals.SHIRT], scale=(0.5, 0.5, 0.5), text=TTLocalizer.ClosetDeleteShirt, text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.12, text_pos=(0.3, 0), text_fg=(0.8, 0.2, 0.2, 1), text_shadow=(0, 0, 0, 1), textMayChange=0) self.topTrashButton = DirectButton(parent=self.trashPanel, image=trashImage, relief=None, pos=(-0.09, 0, 0.2), command=self.__handleDelete, extraArgs=[ClosetGlobals.SHIRT], scale=(0.5, 0.5, 0.5), text=TTLocalizer.ClosetDeleteShirt, text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.12, text_pos=(0.3, 0), text_fg=(0.8, 0.2, 0.2, 1), text_shadow=(0, 0, 0, 1), textMayChange=0)
self.bottomTrashButton = DirectButton(parent=self.trashPanel, image=trashImage, relief=None, textMayChange=1, pos=(-0.09, 0, -0.2), command=self.__handleDelete, extraArgs=[ClosetGlobals.SHORTS], scale=(0.5, 0.5, 0.5), text=TTLocalizer.ClosetDeleteShorts, text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.12, text_pos=(0.3, 0), text_fg=(0.8, 0.2, 0.2, 1), text_shadow=(0, 0, 0, 1)) self.bottomTrashButton = DirectButton(parent=self.trashPanel, image=trashImage, relief=None, textMayChange=1, pos=(-0.09, 0, -0.2), command=self.__handleDelete, extraArgs=[ClosetGlobals.SHORTS], scale=(0.5, 0.5, 0.5), text=TTLocalizer.ClosetDeleteShorts, text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.12, text_pos=(0.3, 0), text_fg=(0.8, 0.2, 0.2, 1), text_shadow=(0, 0, 0, 1))
self.button = DirectButton(relief=None, image=(self.gui.find('**/CrtAtoon_Btn1_UP'), self.gui.find('**/CrtAtoon_Btn1_DOWN'), self.gui.find('**/CrtAtoon_Btn1_RLLVR')), pos=(-0.15, 0, -0.85), command=self.__handleButton, text=('', TTLocalizer.MakeAToonDone, TTLocalizer.MakeAToonDone), text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08, text_pos=(0, -0.03), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1)) self.button = DirectButton(relief=None, image=(self.gui.find('**/CrtAtoon_Btn1_UP'), self.gui.find('**/CrtAtoon_Btn1_DOWN'), self.gui.find('**/CrtAtoon_Btn1_RLLVR')), pos=(-0.15, 0, -0.85), command=self.__handleButton, text=('', TTLocalizer.MakeAToonDone, TTLocalizer.MakeAToonDone), text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08, text_pos=(0, -0.03), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1))
trashcanGui.removeNode() trashcanGui.removeNode()
return
def unload(self): def unload(self):
self.ignore('verifyDone') self.ignore('verifyDone')
ClothesGUI.ClothesGUI.unload(self) ClothesGUI.ClothesGUI.unload(self)
self.cancelButton.destroy() self.cancelButton.destroy()
del self.cancelButton del self.cancelButton
self.countFrame.destroy()
del self.countFrame
if self.isOwner: if self.isOwner:
self.topTrashButton.destroy() self.topTrashButton.destroy()
self.bottomTrashButton.destroy() self.bottomTrashButton.destroy()
@ -108,7 +110,10 @@ class ClosetGUI(ClothesGUI.ClothesGUI):
if self.isOwner: if self.isOwner:
self.updateTrashButtons() self.updateTrashButtons()
self.setupButtons() self.setupButtons()
return self.updateCount()
def updateCount(self, clothes, maxClothes):
self.countFrame['text'] = TTLocalizer.ClothesGUICount % (clothes, maxClothes)
def updateTrashButtons(self): def updateTrashButtons(self):
if len(self.tops) < 2: if len(self.tops) < 2:
@ -124,6 +129,11 @@ class ClosetGUI(ClothesGUI.ClothesGUI):
self.bottomTrashButton['text'] = TTLocalizer.ClosetDeleteSkirt self.bottomTrashButton['text'] = TTLocalizer.ClosetDeleteSkirt
else: else:
self.bottomTrashButton['text'] = TTLocalizer.ClosetDeleteShorts self.bottomTrashButton['text'] = TTLocalizer.ClosetDeleteShorts
self.updateCount()
def updateCount(self):
clothes = (len(self.tops) + len(self.bottoms)) - 2
self.countFrame['text'] = TTLocalizer.ClothesGUICount % (clothes, self.maxClothes)
def setGender(self, gender): def setGender(self, gender):
self.ownerGender = gender self.ownerGender = gender

View file

@ -864,7 +864,6 @@ class DistributedCannon(DistributedObject.DistributedObject):
def removeAvFromCannon(self): def removeAvFromCannon(self):
place = base.cr.playGame.getPlace() place = base.cr.playGame.getPlace()
print 'removeAvFromCannon'
self.notify.debug('self.inWater = %s' % self.inWater) self.notify.debug('self.inWater = %s' % self.inWater)
if place: if place:
if not hasattr(place, 'fsm'): if not hasattr(place, 'fsm'):

View file

@ -13,6 +13,7 @@ from direct.task.Task import Task
import ClosetGlobals import ClosetGlobals
import DistributedFurnitureItem import DistributedFurnitureItem
from toontown.toonbase import TTLocalizer from toontown.toonbase import TTLocalizer
from toontown.catalog import CatalogFurnitureItem
class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem): class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem):
notify = directNotify.newCategory('DistributedCloset') notify = directNotify.newCategory('DistributedCloset')
@ -235,7 +236,8 @@ class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem):
if self.isOwner: if self.isOwner:
self.accept(self.deleteEvent, self.__handleDelete) self.accept(self.deleteEvent, self.__handleDelete)
if not self.closetGUI: if not self.closetGUI:
self.closetGUI = ClosetGUI.ClosetGUI(self.isOwner, self.purchaseDoneEvent, self.cancelEvent, self.swapEvent, self.deleteEvent, self.topList, self.botList) maxClothes = CatalogFurnitureItem.ClosetToClothes.get(self.item.furnitureType)
self.closetGUI = ClosetGUI.ClosetGUI(self.isOwner, self.purchaseDoneEvent, self.cancelEvent, self.swapEvent, self.deleteEvent, self.topList, self.botList, maxClothes)
self.closetGUI.load() self.closetGUI.load()
if self.gender != self.ownerGender: if self.gender != self.ownerGender:
self.closetGUI.setGender(self.ownerGender) self.closetGUI.setGender(self.ownerGender)
@ -320,14 +322,6 @@ class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem):
else: else:
self.notify.warning("cant delete this item(type = %s), since we don't have a replacement" % t_or_b) self.notify.warning("cant delete this item(type = %s), since we don't have a replacement" % t_or_b)
def resetItemLists(self):
self.topList = self.oldTopList[0:]
self.botList = self.oldBotList[0:]
self.closetGUI.tops = self.topList
self.closetGUI.bottoms = self.botList
self.topDeleted = 0
self.bottomDeleted = 0
def __proceedToCheckout(self): def __proceedToCheckout(self):
if self.topDeleted or self.bottomDeleted: if self.topDeleted or self.bottomDeleted:
self.__popupAreYouSurePanel() self.__popupAreYouSurePanel()
@ -360,7 +354,6 @@ class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem):
self.av.swapToonTorso(self.av.style.torso, genClothes=0) self.av.swapToonTorso(self.av.style.torso, genClothes=0)
self.av.loop('neutral', 0) self.av.loop('neutral', 0)
self.av.generateToonClothes() self.av.generateToonClothes()
return
def printInfo(self): def printInfo(self):
print 'avid: %s, gender: %s' % (self.av.doId, self.av.style.gender) print 'avid: %s, gender: %s' % (self.av.doId, self.av.style.gender)
@ -425,7 +418,6 @@ class DistributedCloset(DistributedFurnitureItem.DistributedFurnitureItem):
DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.0, 0.0, -0.16), command=self.__handleTimeoutMessageOK) DirectButton(self.popupInfo, image=okButtonImage, relief=None, text=TTLocalizer.ClosetPopupOK, text_scale=0.05, text_pos=(0.0, -0.1), textMayChange=0, pos=(0.0, 0.0, -0.16), command=self.__handleTimeoutMessageOK)
buttons.removeNode() buttons.removeNode()
self.popupInfo.reparentTo(aspect2d) self.popupInfo.reparentTo(aspect2d)
return
def __handleTimeoutMessageOK(self): def __handleTimeoutMessageOK(self):
self.popupInfo.reparentTo(hidden) self.popupInfo.reparentTo(hidden)

View file

@ -206,8 +206,5 @@ class DistributedClosetAI(DistributedFurnitureItemAI):
def setMovie(self, todo0, todo1, todo2): def setMovie(self, todo0, todo1, todo2):
pass pass
def resetItemLists(self):
pass
def setCustomerDNA(self, todo0, todo1): def setCustomerDNA(self, todo0, todo1):
pass pass

View file

@ -317,7 +317,7 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Invalid wallpaper at index %s' % index) self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Invalid wallpaper at index %s' % index)
return ToontownGlobals.FM_InvalidIndex return ToontownGlobals.FM_InvalidIndex
if room > 1: if room > 3:
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to apply a wallpaper in an invalid room %d!' % room) self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), issue='Tried to apply a wallpaper in an invalid room %d!' % room)
return ToontownGlobals.FM_InvalidItem return ToontownGlobals.FM_InvalidItem
interiorIndex = room*4 interiorIndex = room*4
@ -354,7 +354,7 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
def moveWindowFromAttic(self, index, slot): def moveWindowFromAttic(self, index, slot):
retcode = ToontownGlobals.FM_MovedItem retcode = ToontownGlobals.FM_MovedItem
window = self.getAtticFurniture(self.atticWindows, index) window = self.getAtticFurniture(self.atticWindows, index)
if slot > 5: if slot > 7:
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(),
issue='Tried to move window to invalid slot %d!' % slot) issue='Tried to move window to invalid slot %d!' % slot)
return ToontownGlobals.FM_HouseFull return ToontownGlobals.FM_HouseFull
@ -373,7 +373,7 @@ class DistributedFurnitureManagerAI(DistributedObjectAI):
window = self.getWindow(fromSlot) window = self.getWindow(fromSlot)
if window is None: if window is None:
return ToontownGlobals.FM_InvalidIndex return ToontownGlobals.FM_InvalidIndex
if toSlot > 5: if toSlot > 7:
self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(), self.air.writeServerEvent('suspicious', avId=self.air.getAvatarIdFromSender(),
issue='DistributedfTried to move window to invalid slot %d!' % toSlot) issue='DistributedfTried to move window to invalid slot %d!' % toSlot)
return ToontownGlobals.FM_HouseFull return ToontownGlobals.FM_HouseFull

View file

@ -14,8 +14,8 @@ from toontown.catalog import CatalogFlooringItem
from toontown.catalog import CatalogMouldingItem from toontown.catalog import CatalogMouldingItem
from toontown.catalog import CatalogWainscotingItem from toontown.catalog import CatalogWainscotingItem
from toontown.dna.DNAParser import * from toontown.dna.DNAParser import *
WindowPlugNames = ('**/windowcut_a*', '**/windowcut_b*', '**/windowcut_c*', '**/windowcut_d*', '**/windowcut_e*', '**/windowcut_f*') WindowPlugNames = ['**/windowcut_%s*' % x for x in ('b', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i')]
RoomNames = ('**/group2', '**/group1') RoomNames = ['**/group%s' % x for x in ( 4, 3, 2, 1)]
WallNames = ('ceiling*', 'wall_side_middle*', 'wall_front_middle*', 'windowcut_*') WallNames = ('ceiling*', 'wall_side_middle*', 'wall_front_middle*', 'windowcut_*')
MouldingNames = ('wall_side_top*', 'wall_front_top*') MouldingNames = ('wall_side_top*', 'wall_front_top*')
FloorNames = ('floor*',) FloorNames = ('floor*',)
@ -35,7 +35,6 @@ class DistributedHouseInterior(DistributedObject.DistributedObject):
self.houseIndex = 0 self.houseIndex = 0
self.interior = None self.interior = None
self.exteriorWindowsHidden = 0 self.exteriorWindowsHidden = 0
return
def generate(self): def generate(self):
DistributedObject.DistributedObject.generate(self) DistributedObject.DistributedObject.generate(self)
@ -83,8 +82,9 @@ class DistributedHouseInterior(DistributedObject.DistributedObject):
plug.flattenLight() plug.flattenLight()
self.windowSlots.append((plug, viewBase)) self.windowSlots.append((plug, viewBase))
self.windowSlots[2][1].setPosHpr(16.0, -12.0, 5.51, -90, 0, 0) self.windowSlots[2][1].setPosHpr(-21.28, -37.15, 16.25, -90.4, 0, 0)
self.windowSlots[4][1].setPosHpr(-12.0, 26.0, 5.51, 0, 0, 0) self.windowSlots[6][1].setPosHpr(-12.0, 26.0, 5.51, 0, 0, 0)
self.windowSlots[4][1].setPosHpr(16.0, -12.0, 5.51, -90, 0, 0)
self.__colorWalls() self.__colorWalls()
self.__setupWindows() self.__setupWindows()
messenger.send('houseInteriorLoaded-%d' % self.zoneId) messenger.send('houseInteriorLoaded-%d' % self.zoneId)
@ -185,19 +185,3 @@ class DistributedHouseInterior(DistributedObject.DistributedObject):
self.windows = CatalogItemList.CatalogItemList(items, store=CatalogItem.Customization | CatalogItem.WindowPlacement) self.windows = CatalogItemList.CatalogItemList(items, store=CatalogItem.Customization | CatalogItem.WindowPlacement)
if self.interior: if self.interior:
self.__setupWindows() self.__setupWindows()
def testWallpaperCombo(self, wallpaperType, wallpaperColorIndex, borderIndex, borderColorIndex, mouldingType, mouldingColorIndex, flooringType, flooringColorIndex, wainscotingType, wainscotingColorIndex):
wallpaperItem = CatalogWallpaperItem.CatalogWallpaperItem(wallpaperType, wallpaperColorIndex, borderIndex, borderColorIndex)
mouldingItem = CatalogMouldingItem.CatalogMouldingItem(mouldingType, mouldingColorIndex)
flooringItem = CatalogFlooringItem.CatalogFlooringItem(flooringType, flooringColorIndex)
wainscotingItem = CatalogWainscotingItem.CatalogWainscotingItem(wainscotingType, wainscotingColorIndex)
self.wallpaper = CatalogItemList.CatalogItemList([wallpaperItem,
mouldingItem,
flooringItem,
wainscotingItem,
wallpaperItem,
mouldingItem,
flooringItem,
wainscotingItem], store=CatalogItem.Customization)
if self.interior:
self.__colorWalls()

View file

@ -22,7 +22,7 @@ houseInteriors = [
] ]
defaultWindows = [ defaultWindows = [
CatalogWindowItem(20, placement=2), CatalogWindowItem(20, placement=4) CatalogWindowItem(20, placement=2), CatalogWindowItem(20, placement=4), CatalogWindowItem(20, placement=6)
] ]
defaultWallpaper = [ defaultWallpaper = [
@ -34,6 +34,14 @@ defaultWallpaper = [
CatalogMouldingItem(1000, 2), CatalogMouldingItem(1000, 2),
CatalogFlooringItem(1000, 4), CatalogFlooringItem(1000, 4),
CatalogWainscotingItem(1010, 4), CatalogWainscotingItem(1010, 4),
CatalogWallpaperItem(1110, 0, 1010, 0),
CatalogMouldingItem(1000, 2),
CatalogFlooringItem(1000, 4),
CatalogWainscotingItem(1010, 4),
CatalogWallpaperItem(1110, 0, 1010, 0),
CatalogMouldingItem(1000, 2),
CatalogFlooringItem(1000, 4),
CatalogWainscotingItem(1010, 4),
] ]

View file

@ -177,6 +177,7 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
self.notify.debug('Entering Phone Sphere....') self.notify.debug('Entering Phone Sphere....')
taskMgr.remove(self.uniqueName('ringDoLater')) taskMgr.remove(self.uniqueName('ringDoLater'))
base.localAvatar.obscureMoveFurnitureButton(1)
self.cr.playGame.getPlace().detectedPhoneCollision() self.cr.playGame.getPlace().detectedPhoneCollision()
self.hasLocalAvatar = 1 self.hasLocalAvatar = 1
self.sendUpdate('avatarEnter', []) self.sendUpdate('avatarEnter', [])
@ -184,6 +185,7 @@ class DistributedPhone(DistributedFurnitureItem.DistributedFurnitureItem):
def __handlePhoneDone(self): def __handlePhoneDone(self):
self.sendUpdate('avatarExit', []) self.sendUpdate('avatarExit', [])
self.ignore(self.phoneGuiDoneEvent) self.ignore(self.phoneGuiDoneEvent)
base.localAvatar.obscureMoveFurnitureButton(0)
self.setPos(self.getPos()) self.setPos(self.getPos())
self.phoneGui = None self.phoneGui = None

View file

@ -231,20 +231,6 @@ class DistributedTrunk(DistributedCloset.DistributedCloset):
else: else:
self.notify.warning("cant delete this item(type = %s), since we don't have a replacement" % which) self.notify.warning("cant delete this item(type = %s), since we don't have a replacement" % which)
def resetItemLists(self):
self.hatList = self.oldHatList[0:]
self.glassesList = self.oldGlassesList[0:]
self.backpackList = self.oldBackpackList[0:]
self.shoesList = self.oldShoesList[0:]
self.closetGUI.hat = self.hatList
self.closetGUI.glasses = self.glassesList
self.closetGUI.backpack = self.backpackList
self.closetGUI.shoes = self.shoesList
self.hatDeleted = 0
self.glassesDeleted = 0
self.backpackDeleted = 0
self.shoesDeleted = 0
def __proceedToCheckout(self): def __proceedToCheckout(self):
if self.hatDeleted or self.glassesDeleted or self.backpackDeleted or self.shoesDeleted: if self.hatDeleted or self.glassesDeleted or self.backpackDeleted or self.shoesDeleted:
self.__popupAreYouSurePanel() self.__popupAreYouSurePanel()

View file

@ -164,7 +164,7 @@ class House(Place.Place):
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
base.localAvatar.stopSleepWatch() base.localAvatar.stopSleepWatch()
def enterBanking(self): def enterBanking(self):

View file

@ -31,25 +31,24 @@ class TrunkGUI(StateData.StateData):
self.cancelEvent = cancelEvent self.cancelEvent = cancelEvent
self.genderChange = 0 self.genderChange = 0
self.verify = None self.verify = None
return
def load(self): def load(self):
self.gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui') self.matGui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui')
guiRArrowUp = self.gui.find('**/tt_t_gui_mat_arrowUp') guiRArrowUp = self.matGui.find('**/tt_t_gui_mat_arrowUp')
guiRArrowRollover = self.gui.find('**/tt_t_gui_mat_arrowUp') guiRArrowRollover = self.matGui.find('**/tt_t_gui_mat_arrowUp')
guiRArrowDown = self.gui.find('**/tt_t_gui_mat_arrowDown') guiRArrowDown = self.matGui.find('**/tt_t_gui_mat_arrowDown')
guiRArrowDisabled = self.gui.find('**/tt_t_gui_mat_arrowDisabled') guiRArrowDisabled = self.matGui.find('**/tt_t_gui_mat_arrowDisabled')
guiArrowRotateUp = self.gui.find('**/tt_t_gui_mat_arrowRotateUp') guiArrowRotateUp = self.matGui.find('**/tt_t_gui_mat_arrowRotateUp')
guiArrowRotateDown = self.gui.find('**/tt_t_gui_mat_arrowRotateDown') guiArrowRotateDown = self.matGui.find('**/tt_t_gui_mat_arrowRotateDown')
shuffleFrame = self.gui.find('**/tt_t_gui_mat_shuffleFrame') self.shuffleFrame = self.matGui.find('**/tt_t_gui_mat_shuffleFrame')
shuffleArrowUp = self.gui.find('**/tt_t_gui_mat_shuffleArrowUp') shuffleArrowUp = self.matGui.find('**/tt_t_gui_mat_shuffleArrowUp')
shuffleArrowDown = self.gui.find('**/tt_t_gui_mat_shuffleArrowDown') shuffleArrowDown = self.matGui.find('**/tt_t_gui_mat_shuffleArrowDown')
shuffleArrowRollover = self.gui.find('**/tt_t_gui_mat_shuffleArrowUp') shuffleArrowRollover = self.matGui.find('**/tt_t_gui_mat_shuffleArrowUp')
shuffleArrowDisabled = self.gui.find('**/tt_t_gui_mat_shuffleArrowDisabled') shuffleArrowDisabled = self.matGui.find('**/tt_t_gui_mat_shuffleArrowDisabled')
self.parentFrame = DirectFrame(relief=DGG.RAISED, pos=(0.98, 0, 0.416), frameColor=(1, 0, 0, 0)) self.parentFrame = DirectFrame(relief=DGG.RAISED, pos=(0.98, 0, 0.216), frameColor=(1, 0, 0, 0))
def addFrame(posZ, text): def addFrame(posZ, text):
return DirectFrame(parent=self.parentFrame, image=shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(0, 0, posZ), hpr=(0, 0, 3), scale=1.2, frameColor=(1, 1, 1, 1), text=text, text_scale=0.0575, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1)) return DirectFrame(parent=self.parentFrame, image=self.shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(0, 0, posZ), hpr=(0, 0, 3), scale=1.2, frameColor=(1, 1, 1, 1), text=text, text_scale=0.0575, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1))
def addButton(parent, scale, hoverScale, posX, command, extraArg): def addButton(parent, scale, hoverScale, posX, command, extraArg):
return DirectButton(parent=parent, relief=None, image=(shuffleArrowUp, return DirectButton(parent=parent, relief=None, image=(shuffleArrowUp,
@ -57,6 +56,7 @@ class TrunkGUI(StateData.StateData):
shuffleArrowRollover, shuffleArrowRollover,
shuffleArrowDisabled), image_scale=scale, image1_scale=hoverScale, image2_scale=hoverScale, pos=(posX, 0, 0), command=command, extraArgs=[extraArg]) shuffleArrowDisabled), image_scale=scale, image1_scale=hoverScale, image2_scale=hoverScale, pos=(posX, 0, 0), command=command, extraArgs=[extraArg])
self.countFrame = addFrame(0.37, TTLocalizer.ClothesGUICount % (0, 0))
self.hatFrame = addFrame(0.1, TTLocalizer.TrunkHatGUI) self.hatFrame = addFrame(0.1, TTLocalizer.TrunkHatGUI)
self.hatLButton = addButton(self.hatFrame, halfButtonScale, halfButtonHoverScale, -0.2, self.swapHat, -1) self.hatLButton = addButton(self.hatFrame, halfButtonScale, halfButtonHoverScale, -0.2, self.swapHat, -1)
self.hatRButton = addButton(self.hatFrame, halfButtonInvertScale, halfButtonInvertHoverScale, 0.2, self.swapHat, 1) self.hatRButton = addButton(self.hatFrame, halfButtonInvertScale, halfButtonInvertHoverScale, 0.2, self.swapHat, 1)
@ -103,7 +103,6 @@ class TrunkGUI(StateData.StateData):
self.shoesTrashButton = addTrashButton(-0.4, TTLocalizer.TrunkDeleteShoes, ToonDNA.SHOES) self.shoesTrashButton = addTrashButton(-0.4, TTLocalizer.TrunkDeleteShoes, ToonDNA.SHOES)
self.button = DirectButton(relief=None, image=(self.gui.find('**/CrtAtoon_Btn1_UP'), self.gui.find('**/CrtAtoon_Btn1_DOWN'), self.gui.find('**/CrtAtoon_Btn1_RLLVR')), pos=(-0.15, 0, -0.85), command=self.__handleButton, text=('', TTLocalizer.MakeAToonDone, TTLocalizer.MakeAToonDone), text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08, text_pos=(0, -0.03), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1)) self.button = DirectButton(relief=None, image=(self.gui.find('**/CrtAtoon_Btn1_UP'), self.gui.find('**/CrtAtoon_Btn1_DOWN'), self.gui.find('**/CrtAtoon_Btn1_RLLVR')), pos=(-0.15, 0, -0.85), command=self.__handleButton, text=('', TTLocalizer.MakeAToonDone, TTLocalizer.MakeAToonDone), text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08, text_pos=(0, -0.03), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1))
trashcanGui.removeNode() trashcanGui.removeNode()
return
def unload(self): def unload(self):
taskMgr.remove(self.taskName('rotateL')) taskMgr.remove(self.taskName('rotateL'))
@ -111,7 +110,11 @@ class TrunkGUI(StateData.StateData):
self.ignore('verifyDone') self.ignore('verifyDone')
self.gui.removeNode() self.gui.removeNode()
del self.gui del self.gui
self.matGui.removeNode()
del self.matGui
del self.shuffleFrame
self.parentFrame.destroy() self.parentFrame.destroy()
self.countFrame.destroy()
self.hatFrame.destroy() self.hatFrame.destroy()
self.glassesFrame.destroy() self.glassesFrame.destroy()
self.backpackFrame.destroy() self.backpackFrame.destroy()
@ -124,6 +127,7 @@ class TrunkGUI(StateData.StateData):
self.backpackRButton.destroy() self.backpackRButton.destroy()
self.shoesLButton.destroy() self.shoesLButton.destroy()
self.shoesRButton.destroy() self.shoesRButton.destroy()
del self.countFrame
del self.parentFrame del self.parentFrame
del self.hatFrame del self.hatFrame
del self.glassesFrame del self.glassesFrame
@ -286,7 +290,7 @@ class TrunkGUI(StateData.StateData):
self.swapShoes(0) self.swapShoes(0)
self.updateTrashButtons() self.updateTrashButtons()
self.setupButtons() self.setupButtons()
return self.updateCountFrame()
def updateTrashButtons(self): def updateTrashButtons(self):
if not self.isOwner: if not self.isOwner:
@ -307,6 +311,11 @@ class TrunkGUI(StateData.StateData):
self.shoesTrashButton['state'] = DGG.DISABLED self.shoesTrashButton['state'] = DGG.DISABLED
else: else:
self.shoesTrashButton['state'] = DGG.NORMAL self.shoesTrashButton['state'] = DGG.NORMAL
self.updateCountFrame()
def updateCountFrame(self):
accessories = (len(self.hats) + len(self.glasses) + len(self.backpacks) + len(self.shoes)) - 4
self.countFrame['text'] = TTLocalizer.ClothesGUICount % (accessories, ToontownGlobals.MaxAccessories)
def rotateToonL(self, task): def rotateToonL(self, task):
self.toon.setH(self.toon.getH() - 4) self.toon.setH(self.toon.getH() - 4)

View file

@ -1328,12 +1328,20 @@ class ObjectManager(NodePath, DirectObject):
if self.deleteMode: if self.deleteMode:
self.requestDelete(item, itemIndex, self.deleteWallpaperFromAttic) self.requestDelete(item, itemIndex, self.deleteWallpaperFromAttic)
return return
if base.localAvatar.getY() < 2.3: room = self.getRoom()
room = 0
else:
room = 1
self.furnitureManager.moveWallpaperFromAttic(itemIndex, room, self.__bringWallpaperFromAtticCallback) self.furnitureManager.moveWallpaperFromAttic(itemIndex, room, self.__bringWallpaperFromAtticCallback)
def getRoom(self):
x, y, z = base.localAvatar.getPos()
if (x <= -13.5 and y <= -7.6 and y >= 0.0) or (z >= 4.5 and z <= 10):
return 0
elif base.localAvatar.getZ() > 5.0:
return 1
elif base.localAvatar.getY() < 2.3:
return 2
return 3
def __bringWallpaperFromAtticCallback(self, retcode, itemIndex, room): def __bringWallpaperFromAtticCallback(self, retcode, itemIndex, room):
self.__enableItemButtons(1) self.__enableItemButtons(1)
if retcode < 0: if retcode < 0:
@ -1367,10 +1375,10 @@ class ObjectManager(NodePath, DirectObject):
if self.deleteMode: if self.deleteMode:
self.requestDelete(item, itemIndex, self.deleteWindowFromAttic) self.requestDelete(item, itemIndex, self.deleteWindowFromAttic)
return return
if base.localAvatar.getY() < 2.3: room = self.getRoom()
slot = 2 if room == 0:
else: room = 1
slot = 4 slot = room * 2
self.furnitureManager.moveWindowFromAttic(itemIndex, slot, self.__bringWindowFromAtticCallback) self.furnitureManager.moveWindowFromAttic(itemIndex, slot, self.__bringWindowFromAtticCallback)
def __bringWindowFromAtticCallback(self, retcode, itemIndex, slot): def __bringWindowFromAtticCallback(self, retcode, itemIndex, slot):

View file

@ -90,7 +90,7 @@ class DistributedFishingPond(DistributedObject.DistributedObject):
return self.pondBingoMgr return self.pondBingoMgr
def hasPondBingoManager(self): def hasPondBingoManager(self):
return (self.pondBingoMgr and [1] or [0])[0] return self.pondBingoMgr is not None
def handleBingoCatch(self, catch): def handleBingoCatch(self, catch):
if self.pondBingoMgr: if self.pondBingoMgr:

View file

@ -27,7 +27,7 @@ class TTSFriendsManager(DistributedObjectGlobal):
def d_getAvatarDetails(self, avId): def d_getAvatarDetails(self, avId):
self.sendUpdate('getAvatarDetails', [avId]) self.sendUpdate('getAvatarDetails', [avId])
def friendDetails(self, avId, inventory, trackAccess, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel): def friendDetails(self, avId, inventory, trackAccess, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel, npcFriends):
fields = [ fields = [
['setExperience' , experience], ['setExperience' , experience],
['setTrackAccess' , trackAccess], ['setTrackAccess' , trackAccess],
@ -38,6 +38,7 @@ class TTSFriendsManager(DistributedObjectGlobal):
['setDefaultShard' , defaultShard], ['setDefaultShard' , defaultShard],
['setLastHood' , lastHood], ['setLastHood' , lastHood],
['setDNAString' , dnaString], ['setDNAString' , dnaString],
['setNPCFriendsDict', npcFriends]
] ]
base.cr.n_handleGetAvatarDetailsResp(avId, fields=fields) base.cr.n_handleGetAvatarDetailsResp(avId, fields=fields)
@ -71,6 +72,12 @@ class TTSFriendsManager(DistributedObjectGlobal):
if not hasattr(base.localAvatar, 'getTeleportAvailable') or not hasattr(base.localAvatar, 'ghostMode'): if not hasattr(base.localAvatar, 'getTeleportAvailable') or not hasattr(base.localAvatar, 'ghostMode'):
self.sendUpdate('teleportResponse', [ fromId, 0, 0, 0, 0 ]) self.sendUpdate('teleportResponse', [ fromId, 0, 0, 0, 0 ])
return return
if not base.localAvatar.acceptingTeleport:
self.sendUpdate('teleportResponse', [ fromId, 3, 0, 0, 0 ])
return
if base.localAvatar.isIgnored(fromId):
self.sendUpdate('teleportResponse', [ fromId, 2, 0, 0, 0 ])
return
friend = base.cr.identifyFriend(fromId) friend = base.cr.identifyFriend(fromId)

View file

@ -198,8 +198,9 @@ class TTSFriendsManagerUD(DistributedObjectGlobalUD):
dnaString = fields['setDNAString'][0] dnaString = fields['setDNAString'][0]
experience = fields['setExperience'][0] experience = fields['setExperience'][0]
trackBonusLevel = fields['setTrackBonusLevel'][0] trackBonusLevel = fields['setTrackBonusLevel'][0]
npcFriends = fields['setNPCFriendsDict'][0]
self.sendUpdateToAvatarId(senderId, 'friendDetails', [avId, inventory, trackAccess, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel]) self.sendUpdateToAvatarId(senderId, 'friendDetails', [avId, inventory, trackAccess, hp, maxHp, defaultShard, lastHood, dnaString, experience, trackBonusLevel, npcFriends])
self.air.dbInterface.queryObject(self.air.dbId, avId, handleToon) self.air.dbInterface.queryObject(self.air.dbId, avId, handleToon)
def getPetDetails(self, avId): def getPetDetails(self, avId):

View file

@ -187,7 +187,6 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
base.localAvatar.invPage.hideInventoryOnscreen() base.localAvatar.invPage.hideInventoryOnscreen()
base.localAvatar.questMap.hide() base.localAvatar.questMap.hide()
base.localAvatar.questMap.ignoreOnscreenHooks() base.localAvatar.questMap.ignoreOnscreenHooks()
return
def handleWalkDone(self, doneStatus): def handleWalkDone(self, doneStatus):
mode = doneStatus['mode'] mode = doneStatus['mode']
@ -293,7 +292,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
self.ignore('bookDone') self.ignore('bookDone')
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
target = base.cr.doFind('DistributedTarget') target = base.cr.doFind('DistributedTarget')
if target: if target:
target.showGui() target.showGui()
@ -445,13 +444,13 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
def exitDoorIn(self): def exitDoorIn(self):
NametagGlobals.setMasterArrowsOn(1) NametagGlobals.setMasterArrowsOn(1)
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
def enterDoorOut(self): def enterDoorOut(self):
base.localAvatar.obscureMoveFurnitureButton(1) base.localAvatar.obscureMoveFurnitureButton(1)
def exitDoorOut(self): def exitDoorOut(self):
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
base.localAvatar.stopQuestMap() base.localAvatar.stopQuestMap()
def handleDoorDoneEvent(self, requestStatus): def handleDoorDoneEvent(self, requestStatus):
@ -495,7 +494,6 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
self.accept('tunnelOutMovieDone', self.__tunnelOutMovieDone) self.accept('tunnelOutMovieDone', self.__tunnelOutMovieDone)
base.localAvatar.tunnelOut(tunnelOrigin) base.localAvatar.tunnelOut(tunnelOrigin)
base.localAvatar.stopQuestMap() base.localAvatar.stopQuestMap()
return
def __tunnelOutMovieDone(self): def __tunnelOutMovieDone(self):
self.ignore('tunnelOutMovieDone') self.ignore('tunnelOutMovieDone')
@ -512,7 +510,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
def exitTeleportOut(self): def exitTeleportOut(self):
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.stopQuestMap() base.localAvatar.stopQuestMap()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
def enterDied(self, requestStatus, callback = None): def enterDied(self, requestStatus, callback = None):
if callback == None: if callback == None:
@ -529,7 +527,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
def exitDied(self): def exitDied(self):
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
def getEstateZoneAndGoHome(self, requestStatus): def getEstateZoneAndGoHome(self, requestStatus):
self.doneStatus = requestStatus self.doneStatus = requestStatus
@ -647,7 +645,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
self._tiToken = None self._tiToken = None
NametagGlobals.setMasterArrowsOn(1) NametagGlobals.setMasterArrowsOn(1)
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
base.localAvatar.stopUpdateSmartCamera() base.localAvatar.stopUpdateSmartCamera()
base.localAvatar.detachCamera() base.localAvatar.detachCamera()
base.localAvatar.stopPosHprBroadcast() base.localAvatar.stopPosHprBroadcast()
@ -692,7 +690,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
def enterPurchase(self): def enterPurchase(self):
base.localAvatar.b_setAnimState('neutral', 1) base.localAvatar.b_setAnimState('neutral', 1)
@ -705,7 +703,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
def enterFishing(self): def enterFishing(self):
base.localAvatar.b_setAnimState('neutral', 1) base.localAvatar.b_setAnimState('neutral', 1)
@ -736,7 +734,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
base.localAvatar.stopSleepWatch() base.localAvatar.stopSleepWatch()
def enterPhone(self): def enterPhone(self):
@ -757,7 +755,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
base.localAvatar.stopSleepWatch() base.localAvatar.stopSleepWatch()
def enterStopped(self): def enterStopped(self):
@ -783,7 +781,7 @@ class Place(StateData.StateData, FriendsListManager.FriendsListManager):
base.localAvatar.setTeleportAvailable(0) base.localAvatar.setTeleportAvailable(0)
self.ignore('teleportQuery') self.ignore('teleportQuery')
base.localAvatar.laffMeter.stop() base.localAvatar.laffMeter.stop()
base.localAvatar.obscureMoveFurnitureButton(-1) base.localAvatar.obscureMoveFurnitureButton(0)
base.localAvatar.stopSleepWatch() base.localAvatar.stopSleepWatch()
messenger.send('exitingStoppedState') messenger.send('exitingStoppedState')

View file

@ -46,7 +46,20 @@ class TTSLauncher:
return self.getValue('TTS_PLAYCOOKIE') return self.getValue('TTS_PLAYCOOKIE')
def getGameServer(self): def getGameServer(self):
return self.getValue('TTS_GAMESERVER') if config.GetString('game-type', 'developer') != 'remote':
return self.getValue('TTS_GAMESERVER')
return self.getServer(self.getValue('TTS_GAMESERVER'))
def getServer(self, gameserver):
import DNS
DNS.DiscoverNameServers()
srv_req = DNS.Request(qtype = 'srv')
srv_result = srv_req.req('_toontown._tcp.'+ gameserver)
for result in srv_result.answers:
if result['typename'] == 'SRV':
data = result['data']
return data[3] + ":" + str(data[2])
def getValue(self, key, default = None): def getValue(self, key, default = None):
return os.environ.get(key, default) return os.environ.get(key, default)

View file

@ -25,20 +25,20 @@ class ClothesGUI(StateData.StateData):
return return
def load(self): def load(self):
self.gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui') self.matGui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui')
guiRArrowUp = self.gui.find('**/tt_t_gui_mat_arrowUp') guiRArrowUp = self.matGui.find('**/tt_t_gui_mat_arrowUp')
guiRArrowRollover = self.gui.find('**/tt_t_gui_mat_arrowUp') guiRArrowRollover = self.matGui.find('**/tt_t_gui_mat_arrowUp')
guiRArrowDown = self.gui.find('**/tt_t_gui_mat_arrowDown') guiRArrowDown = self.matGui.find('**/tt_t_gui_mat_arrowDown')
guiRArrowDisabled = self.gui.find('**/tt_t_gui_mat_arrowDisabled') guiRArrowDisabled = self.matGui.find('**/tt_t_gui_mat_arrowDisabled')
shuffleFrame = self.gui.find('**/tt_t_gui_mat_shuffleFrame') self.shuffleFrame = self.matGui.find('**/tt_t_gui_mat_shuffleFrame')
shuffleArrowUp = self.gui.find('**/tt_t_gui_mat_shuffleArrowUp') shuffleArrowUp = self.matGui.find('**/tt_t_gui_mat_shuffleArrowUp')
shuffleArrowDown = self.gui.find('**/tt_t_gui_mat_shuffleArrowDown') shuffleArrowDown = self.matGui.find('**/tt_t_gui_mat_shuffleArrowDown')
shuffleArrowRollover = self.gui.find('**/tt_t_gui_mat_shuffleArrowUp') shuffleArrowRollover = self.matGui.find('**/tt_t_gui_mat_shuffleArrowUp')
shuffleArrowDisabled = self.gui.find('**/tt_t_gui_mat_shuffleArrowDisabled') shuffleArrowDisabled = self.matGui.find('**/tt_t_gui_mat_shuffleArrowDisabled')
self.parentFrame = DirectFrame(relief=DGG.RAISED, pos=(0.98, 0, 0.416), frameColor=(1, 0, 0, 0)) self.parentFrame = DirectFrame(relief=DGG.RAISED, pos=(0.98, 0, 0.416), frameColor=(1, 0, 0, 0))
self.parentFrame.setPos(-0.36, 0, -0.5) self.parentFrame.setPos(-0.36, 0, -0.5)
self.parentFrame.reparentTo(base.a2dTopRight) self.parentFrame.reparentTo(base.a2dTopRight)
self.shirtFrame = DirectFrame(parent=self.parentFrame, image=shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(0, 0, -0.4), hpr=(0, 0, 3), scale=1.2, frameColor=(1, 1, 1, 1), text=TTLocalizer.ClothesShopShirt, text_scale=0.0575, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1)) self.shirtFrame = DirectFrame(parent=self.parentFrame, image=self.shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(0, 0, -0.4), hpr=(0, 0, 3), scale=1.2, frameColor=(1, 1, 1, 1), text=TTLocalizer.ClothesShopShirt, text_scale=0.0575, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1))
self.topLButton = DirectButton(parent=self.shirtFrame, relief=None, image=(shuffleArrowUp, self.topLButton = DirectButton(parent=self.shirtFrame, relief=None, image=(shuffleArrowUp,
shuffleArrowDown, shuffleArrowDown,
shuffleArrowRollover, shuffleArrowRollover,
@ -47,7 +47,7 @@ class ClothesGUI(StateData.StateData):
shuffleArrowDown, shuffleArrowDown,
shuffleArrowRollover, shuffleArrowRollover,
shuffleArrowDisabled), image_scale=halfButtonInvertScale, image1_scale=halfButtonInvertHoverScale, image2_scale=halfButtonInvertHoverScale, pos=(0.2, 0, 0), command=self.swapTop, extraArgs=[1]) shuffleArrowDisabled), image_scale=halfButtonInvertScale, image1_scale=halfButtonInvertHoverScale, image2_scale=halfButtonInvertHoverScale, pos=(0.2, 0, 0), command=self.swapTop, extraArgs=[1])
self.bottomFrame = DirectFrame(parent=self.parentFrame, image=shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(0, 0, -0.65), hpr=(0, 0, -2), scale=1.2, frameColor=(1, 1, 1, 1), text=TTLocalizer.ColorShopToon, text_scale=0.0575, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1)) self.bottomFrame = DirectFrame(parent=self.parentFrame, image=self.shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(0, 0, -0.65), hpr=(0, 0, -2), scale=1.2, frameColor=(1, 1, 1, 1), text=TTLocalizer.ColorShopToon, text_scale=0.0575, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1))
self.bottomLButton = DirectButton(parent=self.bottomFrame, relief=None, image=(shuffleArrowUp, self.bottomLButton = DirectButton(parent=self.bottomFrame, relief=None, image=(shuffleArrowUp,
shuffleArrowDown, shuffleArrowDown,
shuffleArrowRollover, shuffleArrowRollover,
@ -59,11 +59,10 @@ class ClothesGUI(StateData.StateData):
self.parentFrame.hide() self.parentFrame.hide()
self.shuffleFetchMsg = 'ClothesShopShuffle' self.shuffleFetchMsg = 'ClothesShopShuffle'
self.shuffleButton = ShuffleButton.ShuffleButton(self, self.shuffleFetchMsg) self.shuffleButton = ShuffleButton.ShuffleButton(self, self.shuffleFetchMsg)
return
def unload(self): def unload(self):
self.gui.removeNode() self.matGui.removeNode()
del self.gui del self.matGui
self.parentFrame.destroy() self.parentFrame.destroy()
self.shirtFrame.destroy() self.shirtFrame.destroy()
self.bottomFrame.destroy() self.bottomFrame.destroy()
@ -71,6 +70,7 @@ class ClothesGUI(StateData.StateData):
self.topRButton.destroy() self.topRButton.destroy()
self.bottomLButton.destroy() self.bottomLButton.destroy()
self.bottomRButton.destroy() self.bottomRButton.destroy()
del self.shuffleFrame
del self.parentFrame del self.parentFrame
del self.shirtFrame del self.shirtFrame
del self.bottomFrame del self.bottomFrame

View file

@ -91,7 +91,7 @@ class ColorShop(StateData.StateData):
self.pickContainer.setTransparency(True) self.pickContainer.setTransparency(True)
self.pickImage = PNMImage(int((ToontownGlobals.COLOR_SATURATION_MAX - ToontownGlobals.COLOR_SATURATION_MIN) * 100), int((ToontownGlobals.COLOR_VALUE_MAX - ToontownGlobals.COLOR_VALUE_MIN) * 100)) self.pickImage = PNMImage(int((ToontownGlobals.COLOR_SATURATION_MAX - ToontownGlobals.COLOR_SATURATION_MIN) * 100), int((ToontownGlobals.COLOR_VALUE_MAX - ToontownGlobals.COLOR_VALUE_MIN) * 100))
self.hueSlider = DirectSlider(parent=self.advancedFrame, relief=None, image='phase_3/maps/color_picker_hue.jpg', scale=0.3, pos=(-0.05, 0, -0.43), image_scale=(0.1, 1.0, 1.0), pageSize=5, orientation=DGG.VERTICAL, command=self.__chooseHue) self.hueSlider = DirectSlider(parent=self.advancedFrame, relief=None, image='phase_3/maps/color_picker_hue.jpg', scale=0.3, pos=(-0.05, 0, -0.43), image_scale=(0.1, 1.0, 1.0), pageSize=5, orientation=DGG.VERTICAL, command=self.__chooseHue)
self.pickButton = DirectButton(parent=self.advancedFrame, relief=None, image='phase_3/maps/color_picker_empty.png', scale=0.3, pos=(-0.45, 0, -0.43), frameColor=(1, 1, 1, 0.1), pressEffect=0) self.pickButton = DirectButton(parent=self.advancedFrame, relief=None, image='phase_3/maps/invisible.png', scale=0.3, pos=(-0.45, 0, -0.43), frameColor=(1, 1, 1, 0.1), pressEffect=0)
self.pickButton.bind(DGG.B1PRESS, self.__startPickColor) self.pickButton.bind(DGG.B1PRESS, self.__startPickColor)
self.pickButton.bind(DGG.B1RELEASE, self.__stopPickColor) self.pickButton.bind(DGG.B1RELEASE, self.__stopPickColor)
self.partsFrame = DirectFrame(parent=self.advancedFrame, image=shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(-0.395, 0, -0.85), hpr=(0, 0, -2), scale=0.9, frameColor=(1, 1, 1, 1), text=TTLocalizer.ColorAll, text_scale=0.0625, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1)) self.partsFrame = DirectFrame(parent=self.advancedFrame, image=shuffleFrame, image_scale=halfButtonInvertScale, relief=None, pos=(-0.395, 0, -0.85), hpr=(0, 0, -2), scale=0.9, frameColor=(1, 1, 1, 1), text=TTLocalizer.ColorAll, text_scale=0.0625, text_pos=(-0.001, -0.015), text_fg=(1, 1, 1, 1))

View file

@ -30,9 +30,6 @@ class QuestMap(DirectFrame):
self.cogInfoFrame.setPos(0, 0, 0.6) self.cogInfoFrame.setPos(0, 0, 0.6)
self.buildingMarkers = [] self.buildingMarkers = []
self.av = av self.av = av
self.wantToggle = False
if base.config.GetBool('want-toggle-quest-map', True):
self.wantToggle = True
self.updateMarker = True self.updateMarker = True
self.cornerPosInfo = None self.cornerPosInfo = None
self.hqPosInfo = None self.hqPosInfo = None
@ -47,8 +44,6 @@ class QuestMap(DirectFrame):
tracks = currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_TRACK] tracks = currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_TRACK]
self.suitPercentage[currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_ZONE]] = tracks self.suitPercentage[currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_ZONE]] = tracks
return
def load(self): def load(self):
gui = loader.loadModel('phase_4/models/questmap/questmap_gui') gui = loader.loadModel('phase_4/models/questmap/questmap_gui')
icon = gui.find('**/tt_t_gui_qst_arrow') icon = gui.find('**/tt_t_gui_qst_arrow')
@ -279,7 +274,6 @@ class QuestMap(DirectFrame):
self.obscureButton() self.obscureButton()
self.ignore('questPageUpdated') self.ignore('questPageUpdated')
taskMgr.remove('questMapUpdate') taskMgr.remove('questMapUpdate')
return
def handleMarker(self): def handleMarker(self):
if hasattr(base.cr.playGame.getPlace(), 'isInterior') and base.cr.playGame.getPlace().isInterior: if hasattr(base.cr.playGame.getPlace(), 'isInterior') and base.cr.playGame.getPlace().isInterior:
@ -288,15 +282,9 @@ class QuestMap(DirectFrame):
self.updateMarker = True self.updateMarker = True
def acceptOnscreenHooks(self): def acceptOnscreenHooks(self):
if self.wantToggle: self.accept(ToontownGlobals.MapHotkey, self.toggle)
self.accept(ToontownGlobals.MapHotkey, self.toggle)
else:
self.accept(ToontownGlobals.MapHotkeyOn, self.show)
self.accept(ToontownGlobals.MapHotkeyOff, self.hide)
self.updateMap() self.updateMap()
def ignoreOnscreenHooks(self): def ignoreOnscreenHooks(self):
self.ignore(ToontownGlobals.MapHotkey) self.ignore(ToontownGlobals.MapHotkey)
self.ignore(ToontownGlobals.MapHotkeyOn)
self.ignore(ToontownGlobals.MapHotkeyOff)
self.obscureButton() self.obscureButton()

View file

@ -406,8 +406,11 @@ class NPCMoviePlayer(DirectObject.DirectObject):
self.closePreviousChapter(iList) self.closePreviousChapter(iList)
chapterList = [] chapterList = []
self.currentEvent = nextEvent self.currentEvent = nextEvent
elif command == 'TUTORIAL_ACK_DONE':
iList.append(Func(base.localAvatar.setTutorialAck, True))
else: else:
notify.warning('Unknown command token: %s for scriptId: %s on line: %s' % (command, self.scriptId, lineNum)) notify.warning('Unknown command token: %s for scriptId: %s on line: %s' % (command, self.scriptId, lineNum))
self.closePreviousChapter(chapterList) self.closePreviousChapter(chapterList)
if timeoutList: if timeoutList:

View file

@ -73,11 +73,18 @@ class QuestPoster(DirectFrame):
self.teleportButton = DirectButton(parent=self.questFrame, relief=None, image=circleModel, text=TTLocalizer.TeleportButton, text_scale=0.035, text_pos=(-0.0025, -0.015), pos=(0.175, 0, 0.125), scale=0.75) #, text_bg=(0, 0.75, 1, 1) self.teleportButton = DirectButton(parent=self.questFrame, relief=None, image=circleModel, text=TTLocalizer.TeleportButton, text_scale=0.035, text_pos=(-0.0025, -0.015), pos=(0.175, 0, 0.125), scale=0.75) #, text_bg=(0, 0.75, 1, 1)
self.teleportButton.hide() self.teleportButton.hide()
self.laffMeter = None self.laffMeter = None
return self.dialog = None
def destroy(self): def destroy(self):
self._deleteGeoms() self._deleteGeoms()
self.destroyDialog()
DirectFrame.destroy(self) DirectFrame.destroy(self)
def destroyDialog(self, extra=None):
if self.dialog:
self.dialog.destroy()
self.dialog = None
base.cr.playGame.getPlace().setState('walk')
def _deleteGeoms(self): def _deleteGeoms(self):
for icon in (self.lQuestIcon, self.rQuestIcon): for icon in (self.lQuestIcon, self.rQuestIcon):
@ -153,11 +160,7 @@ class QuestPoster(DirectFrame):
def loadElevator(self, building, numFloors): def loadElevator(self, building, numFloors):
elevatorNodePath = hidden.attachNewNode('elevatorNodePath') elevatorNodePath = hidden.attachNewNode('elevatorNodePath')
elevatorModel = loader.loadModel('phase_4/models/modules/elevator') elevatorModel = loader.loadModel('phase_4/models/modules/elevator')
floorIndicator = [None, floorIndicator = [None] * 5
None,
None,
None,
None]
npc = elevatorModel.findAllMatches('**/floor_light_?;+s') npc = elevatorModel.findAllMatches('**/floor_light_?;+s')
for i in xrange(npc.getNumPaths()): for i in xrange(npc.getNumPaths()):
np = npc.getPath(i) np = npc.getPath(i)
@ -174,6 +177,9 @@ class QuestPoster(DirectFrame):
elevatorNodePath.setPosHpr(0, 0, 0, 0, 0, 0) elevatorNodePath.setPosHpr(0, 0, 0, 0, 0, 0)
def teleportToShop(self, npcId): def teleportToShop(self, npcId):
if base.cr.playGame.getPlace().getState() != 'walk':
return
npcZone = NPCToons.getNPCZone(npcId) npcZone = NPCToons.getNPCZone(npcId)
npcHood = ZoneUtil.getCanonicalHoodId(npcZone) npcHood = ZoneUtil.getCanonicalHoodId(npcZone)
hqZone = {2000:2520, 1000:1507, 3000:3508, 4000:4504, 5000:5502, 7000:7503, 9000:9505} hqZone = {2000:2520, 1000:1507, 3000:3508, 4000:4504, 5000:5502, 7000:7503, 9000:9505}
@ -184,15 +190,32 @@ class QuestPoster(DirectFrame):
zoneId = 2000 zoneId = 2000
npcHood = ZoneUtil.getCanonicalHoodId(zoneId) npcHood = ZoneUtil.getCanonicalHoodId(zoneId)
npcZone = hqZone.get(npcHood, 2520) npcZone = hqZone.get(npcHood, 2520)
cost = ToontownGlobals.getTeleportButtonCost(npcHood)
self.destroyDialog()
base.cr.playGame.getPlace().setState('stopped')
if base.localAvatar.getTotalMoney() < cost:
self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.TeleportButtonNoMoney % cost, command=self.destroyDialog)
else:
self.dialog = TTDialog.TTDialog(style=TTDialog.YesNo, text=TTLocalizer.TeleportButtonConfirm % cost, command=lambda value: self.teleportToShopConfirm(npcZone, npcHood, cost, value))
base.cr.buildingQueryMgr.d_isSuit(npcZone, lambda isSuit: self.teleportToShopCallback(npcZone, npcHood, isSuit)) self.dialog.show()
def teleportToShopCallback(self, npcZone, npcHood, flag): def teleportToShopConfirm(self, npcZone, npcHood, cost, value):
self.destroyDialog()
if value > 0:
base.cr.buildingQueryMgr.d_isSuit(npcZone, lambda isSuit: self.teleportToShopCallback(npcZone, npcHood, cost, isSuit))
def teleportToShopCallback(self, npcZone, npcHood, cost, flag):
if flag: if flag:
self.teleportButton.setColorScale(0.3, 0.3, 0.3, 1.0) base.cr.playGame.getPlace().setState('stopped')
self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.TeleportButtonTakenOver, command=self.destroyDialog)
self.dialog.show()
return return
self.teleportButton.setColorScale(1.0, 1.0, 1.0, 1.0) base.localAvatar.takeMoney(cost)
base.cr.playGame.getPlace().requestTeleport(npcHood, npcZone, base.localAvatar.defaultShard, -1) base.cr.playGame.getPlace().requestTeleport(npcHood, npcZone, base.localAvatar.defaultShard, -1)
def fitGeometry(self, geom, fFlip = 0, dimension = 0.8): def fitGeometry(self, geom, fFlip = 0, dimension = 0.8):
@ -228,6 +251,7 @@ class QuestPoster(DirectFrame):
self.rPictureFrame.hide() self.rPictureFrame.hide()
self.questProgress.hide() self.questProgress.hide()
self.teleportButton.hide() self.teleportButton.hide()
self.destroyDialog()
if hasattr(self, 'chooseButton'): if hasattr(self, 'chooseButton'):
self.chooseButton.destroy() self.chooseButton.destroy()
del self.chooseButton del self.chooseButton
@ -419,8 +443,8 @@ class QuestPoster(DirectFrame):
elif quest.getType() == Quests.TrackChoiceQuest: elif quest.getType() == Quests.TrackChoiceQuest:
frameBgColor = 'green' frameBgColor = 'green'
invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons') invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons')
track1, track2 = quest.getChoices(base.localAvatar)
track1, track2 = quest.getChoices()
lIconGeom = invModel.find('**/' + AvPropsNew[track1][1]) lIconGeom = invModel.find('**/' + AvPropsNew[track1][1])
if not fComplete: if not fComplete:

View file

@ -253,7 +253,8 @@ WAIT 0.5
WRTREPARENTTO chatNormalButton topLeft WRTREPARENTTO chatNormalButton topLeft
LERP_POS chatNormalButton 0.068 0 -0.072 0.6 LERP_POS chatNormalButton 0.068 0 -0.072 0.6
LERP_SCALE chatNormalButton 1.179 1.179 1.179 0.6 LERP_SCALE chatNormalButton 1.179 1.179 1.179 0.6
WAIT 0.6 WAIT 0.6
TUTORIAL_ACK_DONE
LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_7 "CFReversed" LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_7 "CFReversed"
LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_8 1 "CFReversed" LOCAL_CHAT_CONFIRM npc QuestScriptTutorialBlocker_8 1 "CFReversed"
LOOP_ANIM npc "walk" LOOP_ANIM npc "walk"

View file

@ -289,6 +289,9 @@ class Quest:
elif holderType == 'track': elif holderType == 'track':
self.check(holder in self._cogTracks, 'invalid recovery item holder: %s for holderType: %s' % (holder, holderType)) self.check(holder in self._cogTracks, 'invalid recovery item holder: %s for holderType: %s' % (holder, holderType))
def checkTrackChoice(self, option):
self.check(option >= ToontownBattleGlobals.MIN_TRACK_INDEX and option <= ToontownBattleGlobals.MAX_TRACK_INDEX, 'invalid track option: %s' % option)
def checkNumFriends(self, num): def checkNumFriends(self, num):
self.check(1, 'invalid number of friends: %s' % num) self.check(1, 'invalid number of friends: %s' % num)
@ -1499,24 +1502,11 @@ class RecoverItemQuest(LocationBasedQuest):
class TrackChoiceQuest(Quest): class TrackChoiceQuest(Quest):
def __init__(self, id, quest): def __init__(self, id, quest):
Quest.__init__(self, id, quest) Quest.__init__(self, id, quest)
self.checkTrackChoice(self.quest[0])
self.checkTrackChoice(self.quest[1])
def getChoices(self, av): def getChoices(self):
trackAccess = av.getTrackAccess() return (self.quest[0], self.quest[1])
first = None
second = None
for i in xrange(len(trackAccess)):
if trackAccess[i] == 0:
if first is None:
first = i
elif second is None:
second = i
break
if first is None or second is None:
return (0, 1)
return (first, second)
def getCompletionStatus(self, av, questDesc, npc = None): def getCompletionStatus(self, av, questDesc, npc = None):
questId, fromNpcId, toNpcId, rewardId, toonProgress = questDesc questId, fromNpcId, toNpcId, rewardId, toonProgress = questDesc
@ -1532,7 +1522,7 @@ class TrackChoiceQuest(Quest):
return NotChosenString return NotChosenString
def getObjectiveStrings(self): def getObjectiveStrings(self):
trackA, trackB = self.getChoices(base.localAvatar) trackA, trackB = self.getChoices()
trackAName = ToontownBattleGlobals.Tracks[trackA].capitalize() trackAName = ToontownBattleGlobals.Tracks[trackA].capitalize()
trackBName = ToontownBattleGlobals.Tracks[trackB].capitalize() trackBName = ToontownBattleGlobals.Tracks[trackB].capitalize()
return [trackAName, trackBName] return [trackAName, trackBName]
@ -1542,7 +1532,7 @@ class TrackChoiceQuest(Quest):
'trackB': self.getObjectiveStrings()[1]} 'trackB': self.getObjectiveStrings()[1]}
def getSCStrings(self, toNpcId, progress): def getSCStrings(self, toNpcId, progress):
trackA, trackB = self.getChoices(base.localAvatar) trackA, trackB = self.getChoices()
trackAName = ToontownBattleGlobals.Tracks[trackA].capitalize() trackAName = ToontownBattleGlobals.Tracks[trackA].capitalize()
trackBName = ToontownBattleGlobals.Tracks[trackB].capitalize() trackBName = ToontownBattleGlobals.Tracks[trackB].capitalize()
return [TTLocalizer.QuestsTrackChoiceQuestSCString % {'trackA': trackAName, return [TTLocalizer.QuestsTrackChoiceQuestSCString % {'trackA': trackAName,
@ -1740,7 +1730,7 @@ QuestDict = {
170: (TT_TIER + 1, Cont, (VisitQuest,), Same, 2005, NA, 400, TTLocalizer.QuestDialogDict[170]), 170: (TT_TIER + 1, Cont, (VisitQuest,), Same, 2005, NA, 400, TTLocalizer.QuestDialogDict[170]),
171: (TT_TIER + 1, Cont, (VisitQuest,), Same, 2311, NA, 400, TTLocalizer.QuestDialogDict[171]), 171: (TT_TIER + 1, Cont, (VisitQuest,), Same, 2311, NA, 400, TTLocalizer.QuestDialogDict[171]),
172: (TT_TIER + 1, Cont, (VisitQuest,), Same, 2119, NA, 400, TTLocalizer.QuestDialogDict[172]), 172: (TT_TIER + 1, Cont, (VisitQuest,), Same, 2119, NA, 400, TTLocalizer.QuestDialogDict[172]),
400: (TT_TIER + 1, Cont, (TrackChoiceQuest,), Same, Same, 400, NA, TTLocalizer.QuestDialogDict[400]), 400: (TT_TIER + 1, Cont, (TrackChoiceQuest, ToontownBattleGlobals.SOUND_TRACK, ToontownBattleGlobals.HEAL_TRACK), Same, Same, 400, NA, TTLocalizer.QuestDialogDict[400]),
1001: (TT_TIER + 2, Start, (CogQuest, ToontownGlobals.ToontownCentral, 3, Any), Any, ToonHQ, Any, NA, DefaultDialog), 1001: (TT_TIER + 2, Start, (CogQuest, ToontownGlobals.ToontownCentral, 3, Any), Any, ToonHQ, Any, NA, DefaultDialog),
1002: (TT_TIER + 2, Start, (CogQuest, ToontownGlobals.ToontownCentral, 4, Any), Any, ToonHQ, Any, NA, DefaultDialog), 1002: (TT_TIER + 2, Start, (CogQuest, ToontownGlobals.ToontownCentral, 4, Any), Any, ToonHQ, Any, NA, DefaultDialog),
1003: (TT_TIER + 2, Start, (CogQuest, ToontownGlobals.ToontownCentral, 5, Any), Any, ToonHQ, Any, NA, DefaultDialog), 1003: (TT_TIER + 2, Start, (CogQuest, ToontownGlobals.ToontownCentral, 5, Any), Any, ToonHQ, Any, NA, DefaultDialog),
@ -1846,7 +1836,7 @@ QuestDict = {
1210: (TT_TIER + 3, Start, (CogQuest, Anywhere, 4, 'pp'), Any, ToonHQ, Any, NA, DefaultDialog), 1210: (TT_TIER + 3, Start, (CogQuest, Anywhere, 4, 'pp'), Any, ToonHQ, Any, NA, DefaultDialog),
1211: (TT_TIER + 3, Start, (CogQuest, Anywhere, 4, 'cc'), Any, ToonHQ, Any, NA, DefaultDialog), 1211: (TT_TIER + 3, Start, (CogQuest, Anywhere, 4, 'cc'), Any, ToonHQ, Any, NA, DefaultDialog),
1212: (TT_TIER + 3, Start, (CogQuest, Anywhere, 4, 'tm'), Any, ToonHQ, Any, NA, DefaultDialog), 1212: (TT_TIER + 3, Start, (CogQuest, Anywhere, 4, 'tm'), Any, ToonHQ, Any, NA, DefaultDialog),
401: (DD_TIER, Start, (TrackChoiceQuest,), Any, ToonHQ, 400, NA, TTLocalizer.QuestDialogDict[401]), 401: (DD_TIER, Start, (TrackChoiceQuest, ToontownBattleGlobals.DROP_TRACK, ToontownBattleGlobals.LURE_TRACK), Any, ToonHQ, 400, NA, TTLocalizer.QuestDialogDict[401]),
2001: (DD_TIER, Start, (CogQuest, Anywhere, 3, Any), Any, ToonHQ, Any, NA, DefaultDialog), 2001: (DD_TIER, Start, (CogQuest, Anywhere, 3, Any), Any, ToonHQ, Any, NA, DefaultDialog),
2002: (DD_TIER, Start, (CogQuest, Anywhere, 4, Any), Any, ToonHQ, Any, NA, DefaultDialog), 2002: (DD_TIER, Start, (CogQuest, Anywhere, 4, Any), Any, ToonHQ, Any, NA, DefaultDialog),
2003: (DD_TIER, Start, (CogQuest, Anywhere, 5, Any), Any, ToonHQ, Any, NA, DefaultDialog), 2003: (DD_TIER, Start, (CogQuest, Anywhere, 5, Any), Any, ToonHQ, Any, NA, DefaultDialog),
@ -2106,7 +2096,8 @@ QuestDict = {
3501: (DG_TIER, Cont, (DeliverItemQuest, 1000), Any, 5007, 1000, NA, DefaultDialog), 3501: (DG_TIER, Cont, (DeliverItemQuest, 1000), Any, 5007, 1000, NA, DefaultDialog),
3502: (DG_TIER, Start, (RescueQuest, InVP, 1), Any, ToonHQ, Any, NA, DefaultDialog), 3502: (DG_TIER, Start, (RescueQuest, InVP, 1), Any, ToonHQ, Any, NA, DefaultDialog),
3503: (DG_TIER, Start, (RescueQuest, InFO, 2), Any, ToonHQ, Any, NA, DefaultDialog), 3503: (DG_TIER, Start, (RescueQuest, InFO, 2), Any, ToonHQ, Any, NA, DefaultDialog),
4001: (MM_TIER, Start, (TrackChoiceQuest,), Any, ToonHQ, 400, NA, TTLocalizer.QuestDialogDict[4001]), 4001: (MM_TIER, Start, (TrackChoiceQuest, ToontownBattleGlobals.TRAP_TRACK, ToontownBattleGlobals.HEAL_TRACK), Any, ToonHQ, 400, NA, TTLocalizer.QuestDialogDict[4001]),
4002: (MM_TIER, Start, (TrackChoiceQuest, ToontownBattleGlobals.TRAP_TRACK, ToontownBattleGlobals.SOUND_TRACK), Any, ToonHQ, 400, NA, TTLocalizer.QuestDialogDict[4002]),
4010: (MM_TIER, Start, (CogQuest, Anywhere, 16, Any), Any, ToonHQ, Any, NA, DefaultDialog), 4010: (MM_TIER, Start, (CogQuest, Anywhere, 16, Any), Any, ToonHQ, Any, NA, DefaultDialog),
4011: (MM_TIER, Start, (CogQuest, Anywhere, 18, Any), Any, ToonHQ, Any, NA, DefaultDialog), 4011: (MM_TIER, Start, (CogQuest, Anywhere, 18, Any), Any, ToonHQ, Any, NA, DefaultDialog),
4012: (MM_TIER, Start, (CogQuest, Anywhere, 20, Any), Any, ToonHQ, Any, NA, DefaultDialog), 4012: (MM_TIER, Start, (CogQuest, Anywhere, 20, Any), Any, ToonHQ, Any, NA, DefaultDialog),
@ -2280,10 +2271,18 @@ QuestDict = {
5247: (BR_TIER, Start, (VisitQuest,), Any, 3112, NA, 5248, TTLocalizer.QuestDialogDict[5247]), 5247: (BR_TIER, Start, (VisitQuest,), Any, 3112, NA, 5248, TTLocalizer.QuestDialogDict[5247]),
5248: (BR_TIER, Start, (CogLevelQuest, Anywhere, 10, 8), 3112, Same, NA, 5249, TTLocalizer.QuestDialogDict[5248]), 5248: (BR_TIER, Start, (CogLevelQuest, Anywhere, 10, 8), 3112, Same, NA, 5249, TTLocalizer.QuestDialogDict[5248]),
5249: (BR_TIER, Cont, (RecoverItemQuest, Anywhere, 3, 3018, VeryHard, AnyFish), Same, Same, NA, (5250, 5258, 5259, 5260), TTLocalizer.QuestDialogDict[5249]), 5249: (BR_TIER, Cont, (RecoverItemQuest, Anywhere, 3, 3018, VeryHard, AnyFish), Same, Same, NA, (5250, 5258, 5259, 5260), TTLocalizer.QuestDialogDict[5249]),
5250: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 'l', 4, 0), Same, Same, 408, NA, TTLocalizer.QuestDialogDict[5250]), 5250: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 'l', 4, 0), Same, Same, NA, (5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008), TTLocalizer.QuestDialogDict[5250]),
5258: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 'c', 4, 0), Same, Same, 408, NA, TTLocalizer.QuestDialogDict[5258]), 5258: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 'c', 4, 0), Same, Same, NA, (5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008), TTLocalizer.QuestDialogDict[5258]),
5259: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 'm', 4, 0), Same, Same, 408, NA, TTLocalizer.QuestDialogDict[5259]), 5259: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 'm', 4, 0), Same, Same, NA, (5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008), TTLocalizer.QuestDialogDict[5259]),
5260: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 's', 4, 0), Same, Same, 408, NA, TTLocalizer.QuestDialogDict[5260]), 5260: (BR_TIER, Cont, (BuildingQuest, Anywhere, 2, 's', 4, 0), Same, Same, NA, (5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008), TTLocalizer.QuestDialogDict[5260]),
5001: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.SOUND_TRACK, ToontownBattleGlobals.DROP_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5002: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.SOUND_TRACK, ToontownBattleGlobals.LURE_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5003: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.HEAL_TRACK, ToontownBattleGlobals.DROP_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5004: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.HEAL_TRACK, ToontownBattleGlobals.LURE_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5005: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.TRAP_TRACK, ToontownBattleGlobals.SOUND_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5006: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.TRAP_TRACK, ToontownBattleGlobals.HEAL_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5007: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.TRAP_TRACK, ToontownBattleGlobals.DROP_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5008: (BR_TIER, Cont, (TrackChoiceQuest, ToontownBattleGlobals.TRAP_TRACK, ToontownBattleGlobals.LURE_TRACK), Same, Same, 400, NA, TTLocalizer.TheBrrrghTrackQuestDict),
5020: (BR_TIER, Start, (CogQuest, Anywhere, 36, Any), Any, ToonHQ, Any, NA, DefaultDialog), 5020: (BR_TIER, Start, (CogQuest, Anywhere, 36, Any), Any, ToonHQ, Any, NA, DefaultDialog),
5021: (BR_TIER, Start, (CogQuest, Anywhere, 38, Any), Any, ToonHQ, Any, NA, DefaultDialog), 5021: (BR_TIER, Start, (CogQuest, Anywhere, 38, Any), Any, ToonHQ, Any, NA, DefaultDialog),
5022: (BR_TIER, Start, (CogQuest, Anywhere, 40, Any), Any, ToonHQ, Any, NA, DefaultDialog), 5022: (BR_TIER, Start, (CogQuest, Anywhere, 40, Any), Any, ToonHQ, Any, NA, DefaultDialog),
@ -3317,12 +3316,55 @@ def filterQuests(entireQuestPool, currentNpc, av):
def chooseTrackChoiceQuest(tier, av, fixed = 0): def chooseTrackChoiceQuest(tier, av, fixed = 0):
def fixAndCallAgain():
if not fixed and av.fixTrackAccess():
notify.info('av %s trackAccess fixed: %s' % (av.getDoId(), trackAccess))
return chooseTrackChoiceQuest(tier, av, fixed=1)
else:
return None
return None
bestQuest = None
trackAccess = av.getTrackAccess()
if tier == MM_TIER: if tier == MM_TIER:
return 4001 if trackAccess[ToontownBattleGlobals.HEAL_TRACK] == 1:
bestQuest = 4002
elif trackAccess[ToontownBattleGlobals.SOUND_TRACK] == 1:
bestQuest = 4001
else:
notify.warning('av %s has bogus trackAccess: %s' % (av.getDoId(), trackAccess))
return fixAndCallAgain()
elif tier == BR_TIER: elif tier == BR_TIER:
return 5247 if trackAccess[ToontownBattleGlobals.SOUND_TRACK] + trackAccess[ToontownBattleGlobals.DROP_TRACK] == 0:
bestQuest = 5001
elif trackAccess[ToontownBattleGlobals.SOUND_TRACK] + trackAccess[ToontownBattleGlobals.LURE_TRACK] == 0:
bestQuest = 5002
elif trackAccess[ToontownBattleGlobals.HEAL_TRACK] + trackAccess[ToontownBattleGlobals.DROP_TRACK] == 0:
bestQuest = 5003
elif trackAccess[ToontownBattleGlobals.HEAL_TRACK] + trackAccess[ToontownBattleGlobals.LURE_TRACK] == 0:
bestQuest = 5004
elif trackAccess[ToontownBattleGlobals.TRAP_TRACK] + trackAccess[ToontownBattleGlobals.SOUND_TRACK] == 0:
bestQuest = 5005
elif trackAccess[ToontownBattleGlobals.TRAP_TRACK] + trackAccess[ToontownBattleGlobals.HEAL_TRACK] == 0:
bestQuest = 5006
elif trackAccess[ToontownBattleGlobals.TRAP_TRACK] + trackAccess[ToontownBattleGlobals.DROP_TRACK] == 0:
bestQuest = 5007
elif trackAccess[ToontownBattleGlobals.TRAP_TRACK] + trackAccess[ToontownBattleGlobals.LURE_TRACK] == 0:
bestQuest = 5008
else:
notify.warning('av %s has bogus trackAccess: %s' % (av.getDoId(), trackAccess))
return fixAndCallAgain()
else: else:
return seededRandomChoice(Tier2Reward2QuestsDict[tier][400]) if notify.getDebug():
notify.debug('questPool for reward 400 had no dynamic choice, tier: %s' % tier)
bestQuest = seededRandomChoice(Tier2Reward2QuestsDict[tier][400])
if notify.getDebug():
notify.debug('chooseTrackChoiceQuest: avId: %s trackAccess: %s tier: %s bestQuest: %s' % (av.getDoId(),
trackAccess,
tier,
bestQuest))
return bestQuest
def chooseMatchingQuest(tier, validQuestPool, rewardId, npc, av): def chooseMatchingQuest(tier, validQuestPool, rewardId, npc, av):
@ -3790,26 +3832,21 @@ class TrackTrainingReward(Reward):
def __init__(self, id, reward): def __init__(self, id, reward):
Reward.__init__(self, id, reward) Reward.__init__(self, id, reward)
def getTrack(self, av): def getTrack(self):
track = self.reward[0] track = self.reward[0]
if track == None: if track == None:
track = 0 track = 0
trackAccess = av.getTrackAccess()
for i in xrange(len(trackAccess)):
if trackAccess[i] == 0:
return i
return track return track
def sendRewardAI(self, av): def sendRewardAI(self, av):
av.b_setTrackProgress(self.getTrack(av), 0) av.b_setTrackProgress(self.getTrack(), 0)
def countReward(self, qrc): def countReward(self, qrc):
qrc.trackProgressId = self.getTrack(base.localAvatar) qrc.trackProgressId = self.getTrack()
qrc.trackProgress = 0 qrc.trackProgress = 0
def getString(self): def getString(self):
trackName = ToontownBattleGlobals.Tracks[self.getTrack(base.localAvatar)].capitalize() trackName = ToontownBattleGlobals.Tracks[self.getTrack()].capitalize()
return TTLocalizer.QuestsTrackTrainingReward % trackName return TTLocalizer.QuestsTrackTrainingReward % trackName
def getPosterString(self): def getPosterString(self):
@ -4160,7 +4197,6 @@ RewardDict = {
405: (TrackTrainingReward, ToontownBattleGlobals.THROW_TRACK), 405: (TrackTrainingReward, ToontownBattleGlobals.THROW_TRACK),
406: (TrackTrainingReward, ToontownBattleGlobals.SQUIRT_TRACK), 406: (TrackTrainingReward, ToontownBattleGlobals.SQUIRT_TRACK),
407: (TrackTrainingReward, ToontownBattleGlobals.DROP_TRACK), 407: (TrackTrainingReward, ToontownBattleGlobals.DROP_TRACK),
408: (TrackTrainingReward, None),
500: (MaxQuestCarryReward, 2), 500: (MaxQuestCarryReward, 2),
501: (MaxQuestCarryReward, 3), 501: (MaxQuestCarryReward, 3),
502: (MaxQuestCarryReward, 4), 502: (MaxQuestCarryReward, 4),

View file

@ -551,14 +551,14 @@ class DistributedRace(DistributedObject.DistributedObject):
newLapT = (newT - self.startT) / self.curve.getMaxT() % 1.0 newLapT = (newT - self.startT) / self.curve.getMaxT() % 1.0
if newLapT - self.currLapT < -0.5: if newLapT - self.currLapT < -0.5:
self.laps += 1 self.laps += 1
self.changeMusicTempo(1 + self.laps * 0.33) self.changeMusicTempo(1 + self.laps * 0.5)
self.notify.debug('crossed the start line: %s, %s, %s, %s' % (self.laps, self.notify.debug('crossed the start line: %s, %s, %s, %s' % (self.laps,
self.startT, self.startT,
self.currT, self.currT,
newT)) newT))
elif newLapT - self.currLapT > 0.5: elif newLapT - self.currLapT > 0.5:
self.laps -= 1 self.laps -= 1
self.changeMusicTempo(1 + self.laps * 0.33) self.changeMusicTempo(1 + self.laps * 0.5)
self.notify.debug('crossed the start line - wrong way: %s, %s, %s, %s' % (self.laps, self.notify.debug('crossed the start line - wrong way: %s, %s, %s, %s' % (self.laps,
self.startT, self.startT,
self.currT, self.currT,

View file

@ -33,6 +33,7 @@ class DistributedRaceAI(DistributedObjectAI, FSM):
self.livingGags = [] self.livingGags = []
self.currentlyAffectedByAnvil = {} self.currentlyAffectedByAnvil = {}
self.avatarProgress = {} self.avatarProgress = {}
self.startTime = globalClockDelta.networkToLocalTime(globalClockDelta.getRealNetworkTime()) + 3
def generate(self): def generate(self):
for avatar in self.avatars: for avatar in self.avatars:

View file

@ -2,7 +2,7 @@ import datetime
from direct.distributed.MsgTypes import CLIENTAGENT_EJECT from direct.distributed.MsgTypes import CLIENTAGENT_EJECT
from direct.distributed.PyDatagram import PyDatagram from direct.distributed.PyDatagram import PyDatagram
from direct.stdpy import threading2 from direct.stdpy import threading2
import re import re, json
from otp.distributed import OtpDoGlobals from otp.distributed import OtpDoGlobals
from toontown.distributed.ShardStatusReceiver import ShardStatusReceiver from toontown.distributed.ShardStatusReceiver import ShardStatusReceiver
@ -437,8 +437,14 @@ class ToontownRPCHandler(ToontownRPCHandlerBase):
On success: 100000000 On success: 100000000
On failure: None On failure: None
""" """
if str(userId) in self.air.csm.accountDB.dbm: response = executeHttpRequest('accountid', username=str(userId))
return int(self.air.csm.accountDB.dbm[str(userId)]) if response is not None:
response = json.loads(response)
if response['success'] is True:
return int(response['accountId'])
else:
print response['error']
return False
@rpcmethod(accessLevel=MODERATOR) @rpcmethod(accessLevel=MODERATOR)
def rpc_getUserAvatars(self, userId): def rpc_getUserAvatars(self, userId):
@ -642,8 +648,9 @@ class ToontownRPCHandler(ToontownRPCHandlerBase):
dna.makeFromNetString(fields['setDNAString'][0]) dna.makeFromNetString(fields['setDNAString'][0])
result['species'] = ToonDNA.getSpeciesName(dna.head) result['species'] = ToonDNA.getSpeciesName(dna.head)
result['head-color'] = dna.headColor result['head_color'] = dna.headColor
result['max-hp'] = fields['setMaxHp'][0] result['max_hp'] = fields['setMaxHp'][0]
result['hp'] = fields['setHp'][0]
result['online'] = (avId in self.air.friendsManager.onlineToons) result['online'] = (avId in self.air.friendsManager.onlineToons)
return result return result
@ -661,13 +668,13 @@ class ToontownRPCHandler(ToontownRPCHandlerBase):
Example response: [100000001, ...] Example response: [100000001, ...]
""" """
if not config.GetBool('want-mongo-client', False): if not config.GetBool('want-mongo', False):
return [] return []
if not needle: if not needle:
return [] return []
self.air.mongodb.astron.objects.ensure_index('fields.setName') self.air.database.astron.objects.ensure_index('fields.setName')
exp = re.compile('.*%s.*' % needle, re.IGNORECASE) exp = re.compile('.*%s.*' % needle, re.IGNORECASE)
result = self.air.mongodb.astron.objects.find({'fields.setName._0': exp}) result = self.air.database.astron.objects.find({'fields.setName._0': exp})
return [avatar['_id'] for avatar in result] return [avatar['_id'] for avatar in result]
# --- SHARDS --- # --- SHARDS ---

View file

@ -568,6 +568,7 @@ class DistributedFishingSpot(DistributedObject.DistributedObject):
self.sellFishConfirmDialog.hide() self.sellFishConfirmDialog.hide()
self.brokeDialog.hide() self.brokeDialog.hide()
self.howToDialog.hide() self.howToDialog.hide()
self.exitButton.hide()
self.castButton.unbind(DGG.B1PRESS) self.castButton.unbind(DGG.B1PRESS)
self.castButton.unbind(DGG.B3PRESS) self.castButton.unbind(DGG.B3PRESS)
self.castButton.unbind(DGG.B1RELEASE) self.castButton.unbind(DGG.B1RELEASE)
@ -592,7 +593,7 @@ class DistributedFishingSpot(DistributedObject.DistributedObject):
self.castGui.setPos(0, 1, 0) self.castGui.setPos(0, 1, 0)
for nodeName in ('bucket', 'jar', 'display_bucket', 'display_jar'): for nodeName in ('bucket', 'jar', 'display_bucket', 'display_jar'):
self.castGui.find('**/' + nodeName).reparentTo(self.castGui) self.castGui.find('**/' + nodeName).reparentTo(self.castGui)
self.exitButton = DirectButton(parent=self.castGui, relief=None, text=('', TTLocalizer.FishingExit, TTLocalizer.FishingExit), text_align=TextNode.ACenter, text_scale=0.1, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0.0, -0.12), pos=(1.75*(4./3.), 0, -1.33), textMayChange=0, image=(self.castGui.find('**/exit_buttonUp'), self.castGui.find('**/exit_buttonDown'), self.castGui.find('**/exit_buttonRollover')), command=self.__userExit) self.exitButton = DirectButton(parent=base.a2dBottomRight, relief=None, text=('', TTLocalizer.FishingExit, TTLocalizer.FishingExit), text_align=TextNode.ACenter, text_scale=0.1, text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0.0, -0.12), pos=(-0.218, 0, 0.11), scale=0.8, textMayChange=0, image=(self.castGui.find('**/exit_buttonUp'), self.castGui.find('**/exit_buttonDown'), self.castGui.find('**/exit_buttonRollover')), command=self.__userExit)
self.castGui.find('**/exitButton').removeNode() self.castGui.find('**/exitButton').removeNode()
self.castButton = DirectButton(parent=self.castGui, relief=None, text=TTLocalizer.FishingCast, text_align=TextNode.ACenter, text_scale=(3, 3 * 0.75, 3 * 0.75), text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -4), image=self.castGui.find('**/castButton'), image0_color=(1, 0, 0, 1), image1_color=(0, 1, 0, 1), image2_color=(1, 1, 0, 1), image3_color=(0.8, 0.5, 0.5, 1), pos=(0, -0.05, -0.666), scale=(0.036, 1, 0.048)) self.castButton = DirectButton(parent=self.castGui, relief=None, text=TTLocalizer.FishingCast, text_align=TextNode.ACenter, text_scale=(3, 3 * 0.75, 3 * 0.75), text_fg=Vec4(1, 1, 1, 1), text_shadow=Vec4(0, 0, 0, 1), text_pos=(0, -4), image=self.castGui.find('**/castButton'), image0_color=(1, 0, 0, 1), image1_color=(0, 1, 0, 1), image2_color=(1, 1, 0, 1), image3_color=(0.8, 0.5, 0.5, 1), pos=(0, -0.05, -0.666), scale=(0.036, 1, 0.048))
self.castGui.find('**/castButton').removeNode() self.castGui.find('**/castButton').removeNode()
@ -1050,9 +1051,4 @@ class DistributedFishingSpot(DistributedObject.DistributedObject):
self.fsm.request('waiting', [False]) self.fsm.request('waiting', [False])
def __allowSellFish(self): def __allowSellFish(self):
if base.wantBingo: return base.wantBingo and self.pond.hasPondBingoManager()
if self.pond.hasPondBingoManager():
hoodId = base.cr.playGame.getPlaceId()
if hoodId == ToontownGlobals.MyEstate:
return True
return False

View file

@ -16,8 +16,11 @@ class TTSafeZoneLoader(SafeZoneLoader.SafeZoneLoader):
'phase_4/audio/sfx/SZ_TC_bird2.ogg', 'phase_4/audio/sfx/SZ_TC_bird2.ogg',
'phase_4/audio/sfx/SZ_TC_bird3.ogg']) 'phase_4/audio/sfx/SZ_TC_bird3.ogg'])
bank = self.geom.find('**/*toon_landmark_TT_bank_DNARoot') bank = self.geom.find('**/*toon_landmark_TT_bank_DNARoot')
library = self.geom.find('**/library/square_drop_shadow')
doorTrigger = bank.find('**/door_trigger*') doorTrigger = bank.find('**/door_trigger*')
doorTrigger.setY(doorTrigger.getY() - 1.5) doorTrigger.setY(doorTrigger.getY() - 1.5)
library.find('**/building_front').setY(0.3)
library.find('**/front_entrance_flag').setY(0.1)
def unload(self): def unload(self):
SafeZoneLoader.SafeZoneLoader.unload(self) SafeZoneLoader.SafeZoneLoader.unload(self)

View file

@ -731,25 +731,31 @@ class ExtraOptionsTabPage(DirectFrame):
self.fov_label = DirectLabel(parent=self, relief=None, text=TTLocalizer.FieldOfViewLabel, text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight)) self.fov_label = DirectLabel(parent=self, relief=None, text=TTLocalizer.FieldOfViewLabel, text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight))
self.cogInterface_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - textRowHeight)) self.cogInterface_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - textRowHeight))
self.tpTransition_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 2 * textRowHeight)) self.tpTransition_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 2 * textRowHeight))
self.fpsMeter_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 3 * textRowHeight))
self.teleport_label = DirectLabel(parent=self, relief=None, text='', text_align=TextNode.ALeft, text_scale=options_text_scale, text_wordwrap=16, pos=(leftMargin, 0, textStartHeight - 4 * textRowHeight))
self.fov_slider = DirectSlider(parent=self, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord), self.fov_slider = DirectSlider(parent=self, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord),
value=settings['fov'], pageSize=5, range=(ToontownGlobals.DefaultCameraFov, ToontownGlobals.MaxCameraFov), command=self.__doFov, value=settings['fov'], pageSize=5, range=(ToontownGlobals.DefaultCameraFov, ToontownGlobals.MaxCameraFov), command=self.__doFov,
thumb_geom=(circleModel.find('**/tt_t_gui_mat_namePanelCircle')), thumb_relief=None, thumb_geom_scale=2) thumb_geom=(circleModel.find('**/tt_t_gui_mat_namePanelCircle')), thumb_relief=None, thumb_geom_scale=2)
self.fov_slider.setScale(0.25) self.fov_slider.setScale(0.25)
self.cogInterface_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - textRowHeight), command=self.__doToggleCogInterface) self.cogInterface_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - textRowHeight), command=self.__doToggleCogInterface)
self.tpTransition_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 2 * textRowHeight), command=self.__doToggleTpTransition) self.tpTransition_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 2 * textRowHeight), command=self.__doToggleTpTransition)
self.fpsMeter_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 3 * textRowHeight), command=self.__doToggleFpsMeter)
self.teleport_toggleButton = DirectButton(parent=self, relief=None, image=button_image, image_scale=button_image_scale, text='', text_scale=options_text_scale, text_pos=button_textpos, pos=(buttonbase_xcoord, 0.0, buttonbase_ycoord - 4 * textRowHeight), command=self.__doToggleTeleport)
self.bugReportButton = DirectButton(parent=self, relief=None, text=TTLocalizer.BugReportButton, image=button_image, image_scale=button_image_scale, text_pos=(0, -0.01), text_fg=(0, 0, 0, 1), self.bugReportButton = DirectButton(parent=self, relief=None, text=TTLocalizer.BugReportButton, image=button_image, image_scale=button_image_scale, text_pos=(0, -0.01), text_fg=(0, 0, 0, 1),
command=self.showReportNotice, pos=(0.0, 0.0, -0.6), text_scale=(0.045)) command=self.showReportNotice, pos=(0.0, 0.0, -0.6), text_scale=(0.045))
guiButton.removeNode() guiButton.removeNode()
circleModel.removeNode() circleModel.removeNode()
self.optionChoosers['pole'] = OptionChooser.OptionChooser(self, TTLocalizer.FishingPoleLabel, 3, self.__updateFishingPole, [False], self.__applyFishingPole) self.optionChoosers['pole'] = OptionChooser.OptionChooser(self, TTLocalizer.FishingPoleLabel, 5, self.__updateFishingPole, [False], self.__applyFishingPole)
self.optionChoosers['nametag_style'] = OptionChooser.OptionChooser(self, TTLocalizer.NametagStyleLabel, 4, self.__updateNametagStyle, [False], self.__applyNametagStyle) self.optionChoosers['nametag_style'] = OptionChooser.OptionChooser(self, TTLocalizer.NametagStyleLabel, 6, self.__updateNametagStyle, [False], self.__applyNametagStyle)
def enter(self): def enter(self):
self.show() self.show()
self.settingsChanged = 0 self.settingsChanged = 0
self.__setCogInterfaceButton() self.__setCogInterfaceButton()
self.__setTpTransitionButton() self.__setTpTransitionButton()
self.__setFpsMeterButton()
self.__setTeleportButton()
self.__updateNametagStyle() self.__updateNametagStyle()
self.__updateFishingPole() self.__updateFishingPole()
self.accept('refreshNametagStyle', self.__updateNametagStyle) self.accept('refreshNametagStyle', self.__updateNametagStyle)
@ -776,6 +782,14 @@ class ExtraOptionsTabPage(DirectFrame):
del self.tpTransition_label del self.tpTransition_label
self.tpTransition_toggleButton.destroy() self.tpTransition_toggleButton.destroy()
del self.tpTransition_toggleButton del self.tpTransition_toggleButton
self.fpsMeter_label.destroy()
del self.fpsMeter_label
self.fpsMeter_toggleButton.destroy()
del self.fpsMeter_toggleButton
self.teleport_label.destroy()
del self.teleport_label
self.teleport_toggleButton.destroy()
del self.teleport_toggleButton
self.bugReportButton.destroy() self.bugReportButton.destroy()
del self.bugReportButton del self.bugReportButton
self.destroyReportNotice() self.destroyReportNotice()
@ -807,6 +821,34 @@ class ExtraOptionsTabPage(DirectFrame):
def __setTpTransitionButton(self): def __setTpTransitionButton(self):
self.tpTransition_label['text'] = TTLocalizer.TpTransitionLabelOn if settings['tpTransition'] else TTLocalizer.TpTransitionLabelOff self.tpTransition_label['text'] = TTLocalizer.TpTransitionLabelOn if settings['tpTransition'] else TTLocalizer.TpTransitionLabelOff
self.tpTransition_toggleButton['text'] = TTLocalizer.OptionsPageToggleOff if settings['tpTransition'] else TTLocalizer.OptionsPageToggleOn self.tpTransition_toggleButton['text'] = TTLocalizer.OptionsPageToggleOff if settings['tpTransition'] else TTLocalizer.OptionsPageToggleOn
def __doToggleFpsMeter(self):
messenger.send('wakeup')
settings['fpsMeter'] = not settings['fpsMeter']
base.setFrameRateMeter(settings['fpsMeter'])
self.settingsChanged = 1
self.__setFpsMeterButton()
def __setFpsMeterButton(self):
self.fpsMeter_label['text'] = TTLocalizer.FpsMeterLabelOn if settings['fpsMeter'] else TTLocalizer.FpsMeterLabelOff
self.fpsMeter_toggleButton['text'] = TTLocalizer.OptionsPageToggleOff if settings['fpsMeter'] else TTLocalizer.OptionsPageToggleOn
def __doToggleTeleport(self):
messenger.send('wakeup')
acceptingTeleport = settings.get('acceptingTeleport', {})
if base.localAvatar.acceptingTeleport:
base.localAvatar.acceptingTeleport = 0
acceptingTeleport[str(base.localAvatar.doId)] = False
else:
base.localAvatar.acceptingTeleport = 1
acceptingTeleport[str(base.localAvatar.doId)] = True
settings['acceptingTeleport'] = acceptingTeleport
self.settingsChanged = 1
self.__setTeleportButton()
def __setTeleportButton(self):
self.teleport_label['text'] = TTLocalizer.TeleportLabelOn if base.localAvatar.acceptingTeleport else TTLocalizer.TeleportLabelOff
self.teleport_toggleButton['text'] = TTLocalizer.OptionsPageToggleOff if base.localAvatar.acceptingTeleport else TTLocalizer.OptionsPageToggleOn
def __updateNametagStyle(self, resetIndex=True): def __updateNametagStyle(self, resetIndex=True):
chooser = self.optionChoosers['nametag_style'] chooser = self.optionChoosers['nametag_style']

View file

@ -21,8 +21,7 @@ class ShtikerBook(DirectFrame, StateData.StateData):
self.pages = [] self.pages = []
self.pageTabs = [] self.pageTabs = []
self.currPageTabIndex = None self.currPageTabIndex = None
self.pageTabFrame = DirectFrame(parent=self, relief=None, pos=(0.93, 1, 0.575), scale=1.25) self.pageTabFrames = [self.createPageTabFrame(x) for x in (-0.93, 0.93)]
self.pageTabFrame.hide()
self.currPageIndex = None self.currPageIndex = None
self.entered = 0 self.entered = 0
self.safeMode = 0 self.safeMode = 0
@ -47,6 +46,11 @@ class ShtikerBook(DirectFrame, StateData.StateData):
TTLocalizer.PhotoPageTitle, TTLocalizer.PhotoPageTitle,
TTLocalizer.EventsPageName, TTLocalizer.EventsPageName,
TTLocalizer.StatPageTitle] TTLocalizer.StatPageTitle]
def createPageTabFrame(self, x):
frame = DirectFrame(parent=self, relief=None, pos=(x, 0, 0.66), scale=1.25)
frame.hide()
return frame
def setSafeMode(self, setting): def setSafeMode(self, setting):
self.safeMode = setting self.safeMode = setting
@ -76,7 +80,8 @@ class ShtikerBook(DirectFrame, StateData.StateData):
self.accept('shtiker-page-done', self.__pageDone) self.accept('shtiker-page-done', self.__pageDone)
self.accept(ToontownGlobals.StickerBookHotkey, self.__close) self.accept(ToontownGlobals.StickerBookHotkey, self.__close)
self.accept(ToontownGlobals.OptionsPageHotkey, self.__close) self.accept(ToontownGlobals.OptionsPageHotkey, self.__close)
self.pageTabFrame.show() for tab in self.pageTabFrames:
tab.show()
self.pages[self.currPageIndex].enter() self.pages[self.currPageIndex].enter()
def exit(self): def exit(self):
@ -106,7 +111,8 @@ class ShtikerBook(DirectFrame, StateData.StateData):
self.hide() self.hide()
self.hideButton() self.hideButton()
cleanupDialog('globalDialog') cleanupDialog('globalDialog')
self.pageTabFrame.hide() for tab in self.pageTabFrames:
tab.hide()
self.ignore('shtiker-page-done') self.ignore('shtiker-page-done')
self.ignore(ToontownGlobals.StickerBookHotkey) self.ignore(ToontownGlobals.StickerBookHotkey)
self.ignore(ToontownGlobals.OptionsPageHotkey) self.ignore(ToontownGlobals.OptionsPageHotkey)
@ -178,7 +184,7 @@ class ShtikerBook(DirectFrame, StateData.StateData):
if base.config.GetBool('want-qa-regression', 0): if base.config.GetBool('want-qa-regression', 0):
self.notify.info('QA-REGRESSION: SHTICKERBOOK: Browse tabs %s' % page.pageName) self.notify.info('QA-REGRESSION: SHTICKERBOOK: Browse tabs %s' % page.pageName)
yOffset = 0.07 * pageIndex yOffset = 0.07 * (pageIndex % 16)
iconGeom = None iconGeom = None
iconImage = None iconImage = None
iconScale = 1 iconScale = 1
@ -257,13 +263,14 @@ class ShtikerBook(DirectFrame, StateData.StateData):
iconModels.detachNode() iconModels.detachNode()
if pageName == TTLocalizer.OptionsPageTitle: if pageName == TTLocalizer.OptionsPageTitle:
pageName = TTLocalizer.OptionsTabTitle pageName = TTLocalizer.OptionsTabTitle
pageTab = DirectButton(parent=self.pageTabFrame, relief=DGG.RAISED, frameSize=(-0.575, rightSide = pageIndex < 16
pageTab = DirectButton(parent=self.pageTabFrames[rightSide], relief=DGG.RAISED, frameSize=(-0.575,
0.575, 0.575,
-0.575, -0.575,
0.575), borderWidth=(0.05, 0.05), text=('', 0.575), borderWidth=(0.05, 0.05), text=('',
'', '',
pageName, pageName,
''), text_align=TextNode.ALeft, text_pos=(1, -0.2), text_scale=TTLocalizer.SBpageTab, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), image=iconImage, image_scale=iconScale, geom=iconGeom, geom_scale=iconScale, geom_color=iconColor, pos=(0, 0, -yOffset), scale=0.06, command=buttonPressedCommand, extraArgs=extraArgs) ''), text_align=TextNode.ALeft, text_pos=(1 if rightSide else -4, -0.2), text_scale=TTLocalizer.SBpageTab, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), image=iconImage, image_scale=iconScale, geom=iconGeom, geom_scale=iconScale, geom_color=iconColor, pos=(0, 0, -yOffset), scale=0.06, command=buttonPressedCommand, extraArgs=extraArgs)
self.pageTabs.insert(pageIndex, pageTab) self.pageTabs.insert(pageIndex, pageTab)
return return

View file

@ -1,24 +1,21 @@
from direct.gui.DirectGui import * from direct.gui.DirectGui import *
from toontown.toonbase import TTLocalizer from toontown.toonbase import TTLocalizer, ToontownGlobals
from toontown.toontowngui import TTDialog from toontown.toontowngui import TTDialog
import ShtikerPage import ShtikerPage
STATS = ['cog', 'v2', 'skele', 'beanSpent', 'beanEarnt', 'task', 'vp', 'cfo', 'cj', 'ceo', 'sad', 'bldg', 'cogdo', 'item', 'fish', 'flower', 'race', 'golf', 'sos', 'unite', 'slip', 'gag']
class StatPage(ShtikerPage.ShtikerPage): class StatPage(ShtikerPage.ShtikerPage):
def __init__(self): def __init__(self):
ShtikerPage.ShtikerPage.__init__(self) ShtikerPage.ShtikerPage.__init__(self)
self.dialog = None self.dialog = None
self.chunkCount = 11
def load(self): def load(self):
guiButton = loader.loadModel('phase_3/models/gui/quit_button') guiButton = loader.loadModel('phase_3/models/gui/quit_button')
self.rows = [None] * 2 self.rows = [self.createRow(pos) for pos in ((-0.8, 0, 0.435), (0.08, 0, 0.435))]
self.title = DirectLabel(parent=self, relief=None, text=TTLocalizer.StatPageTitle, text_scale=0.12, textMayChange=0, pos=(0, 0, 0.6)) self.title = DirectLabel(parent=self, relief=None, text=TTLocalizer.StatPageTitle, text_scale=0.12, textMayChange=0, pos=(-0.625, 0, 0.625))
self.rows[0] = DirectLabel(parent=self, relief=None, text_align=TextNode.ALeft, text='', text_scale=0.06, text_wordwrap=16, pos=(-0.8, 0, 0.515)) self.resetButton = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=(1.1, 1, 1), text=TTLocalizer.StatPageClear, text_scale=0.055, text_pos=(0, -0.02), pos=(0.605, 0, 0.66), command=self.__showDialog)
self.rows[1] = DirectLabel(parent=self, relief=None, text_align=TextNode.ALeft, text='', text_scale=0.06, text_wordwrap=16, pos=(0.05, 0, 0.515))
self.resetButton = empty = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=(1.1, 1, 1), text='Reset stats', text_scale=0.055, text_pos=(0, -0.02), pos=(-0.55, 0.0, 0.65), command=self.__showDialog)
guiButton.removeNode() guiButton.removeNode()
def enter(self): def enter(self):
@ -47,25 +44,26 @@ class StatPage(ShtikerPage.ShtikerPage):
if self.dialog: if self.dialog:
self.dialog.destroy() self.dialog.destroy()
self.dialog = None self.dialog = None
def createRow(self, pos):
row = DirectLabel(parent=self, relief=None, text_align=TextNode.ALeft, text='', text_scale=0.045, text_wordwrap=16, text_font=ToontownGlobals.getChalkFont(), text_fg=(1, 1, 1, 1), image='phase_3/maps/stat_board.png', image_scale=(0.42, 0, 0.6), image_pos=(0.35, 0, -0.45))
row.setPos(pos)
return row
def cutToChunks(self, list, size): def cutToChunks(self, list, size):
for i in xrange(0, len(list), size): for i in xrange(0, len(list), size):
yield list[i:i+size] yield list[i:i+size]
def updateStats(self): def updateStats(self):
dict = {}
stats = base.localAvatar.stats stats = base.localAvatar.stats
allStats = [TTLocalizer.Stats[i] % '{:,}'.format(stats[i]) for i in xrange(len(stats))]
for i, string in enumerate(STATS): textChunks = list(self.cutToChunks(allStats, self.chunkCount))
dict[string] = "{:,}".format(stats[i])
textChunks = list(self.cutToChunks(TTLocalizer.Stats, 11))
for i, chunk in enumerate(textChunks): for i, chunk in enumerate(textChunks):
self.rows[i]['text'] = '\n\n'.join(chunk) % dict self.rows[i]['text'] = '\n\n'.join(chunk)
def __showDialog(self): def __showDialog(self):
self.dialog = TTDialog.TTDialog(style=TTDialog.TwoChoice, text=TTLocalizer.StatResetAsk, text_wordwrap=15, command=self.__handleDialogResponse) self.dialog = TTDialog.TTDialog(style=TTDialog.TwoChoice, text=TTLocalizer.StatPageClearAsk, text_wordwrap=15, command=self.__handleDialogResponse)
self.dialog.show() self.dialog.show()
def __handleDialogResponse(self, response): def __handleDialogResponse(self, response):
@ -75,5 +73,5 @@ class StatPage(ShtikerPage.ShtikerPage):
return return
base.localAvatar.wipeStats() base.localAvatar.wipeStats()
self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.StatResetDone, text_wordwrap=15, command=self.unloadDialog) self.dialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=TTLocalizer.StatPageClearDone, text_wordwrap=15, command=self.unloadDialog)
self.dialog.show() self.dialog.show()

View file

@ -75,8 +75,8 @@ SHADOW_SCALE_POS = ((1.225,
0, 0,
10, 10,
-0.01), -0.01),
(0.9, (1.05,
0.005, 0,
10, 10,
-0.01), -0.01),
(0.95, (0.95,
@ -230,6 +230,7 @@ class SuitPage(ShtikerPage.ShtikerPage):
self.legalRadarButton.destroy() self.legalRadarButton.destroy()
self.moneyRadarButton.destroy() self.moneyRadarButton.destroy()
self.salesRadarButton.destroy() self.salesRadarButton.destroy()
self.rolloverFrame.destroy()
for panel in self.panels: for panel in self.panels:
panel.destroy() panel.destroy()
del self.panels del self.panels
@ -335,6 +336,12 @@ class SuitPage(ShtikerPage.ShtikerPage):
yStart = -0.18 yStart = -0.18
xOffset = 0.199 xOffset = 0.199
yOffset = 0.284 yOffset = 0.284
gui = loader.loadModel('phase_3.5/models/gui/suit_detail_panel')
gui.find('**/avatar_panel/shadow').setColor(1, 1, 1, 0.5)
self.rolloverFrame = DirectFrame(parent=self.panelNode, relief=None, geom=gui.find('**/avatar_panel'), geom_color=(0.5, 0.5, 0.5, 1), geom_scale=(0.59, 0, 0.21), text_scale=0.06, text_pos=(0, 0.35), text='', text_fg=(1, 1, 1, 1), text_font=ToontownGlobals.getSuitFont(), pos=(0.8, 0, 0))
self.rolloverFrame.setBin('gui-popup', 0)
self.rolloverFrame.hide()
gui.removeNode()
for dept in xrange(0, len(SuitDNA.suitDepts)): for dept in xrange(0, len(SuitDNA.suitDepts)):
row = [] row = []
color = PANEL_COLORS[dept] color = PANEL_COLORS[dept]
@ -347,10 +354,20 @@ class SuitPage(ShtikerPage.ShtikerPage):
panel.shadow = None panel.shadow = None
panel.count = 0 panel.count = 0
panel.summonButton = None panel.summonButton = None
panel.hoverButton = DirectButton(parent=panel, relief=None, image_scale=(0.15, 0, 0.225), image='phase_3/maps/invisible.png', pressEffect=0)
panel.hoverButton.setTransparency(True)
panel.hoverButton.panel = panel
self.addCogRadarLabel(panel) self.addCogRadarLabel(panel)
self.panels.append(panel) self.panels.append(panel)
base.panels.append(panel) base.panels.append(panel)
return
def showInfo(self, panel, text, extra):
self.rolloverFrame.reparentTo(panel)
self.rolloverFrame.show()
self.rolloverFrame['text'] = text
def hideInfo(self, extra):
self.rolloverFrame.hide()
def addQuotaLabel(self, panel): def addQuotaLabel(self, panel):
index = self.panels.index(panel) index = self.panels.index(panel)
@ -405,7 +422,6 @@ class SuitPage(ShtikerPage.ShtikerPage):
index = self.panels.index(panel) index = self.panels.index(panel)
if not base.localAvatar.hasCogSummons(index): if not base.localAvatar.hasCogSummons(index):
panel.summonButton.hide() panel.summonButton.hide()
return
def addBuildingRadarLabel(self, button): def addBuildingRadarLabel(self, button):
gui = loader.loadModel('phase_3.5/models/gui/suit_detail_panel') gui = loader.loadModel('phase_3.5/models/gui/suit_detail_panel')
@ -413,7 +429,6 @@ class SuitPage(ShtikerPage.ShtikerPage):
buildingRadarLabel = DirectLabel(parent=button, relief=None, pos=(0.225, 0.0, zPos), state=DGG.DISABLED, image=gui.find('**/avatar_panel'), image_hpr=(0, 0, 90), image_scale=(0.05, 1, 0.1), image_pos=(0, 0, 0.015), text=TTLocalizer.SuitPageBuildingRadarP % '0', text_scale=0.05, text_fg=(1, 0, 0, 1), text_font=ToontownGlobals.getSuitFont()) buildingRadarLabel = DirectLabel(parent=button, relief=None, pos=(0.225, 0.0, zPos), state=DGG.DISABLED, image=gui.find('**/avatar_panel'), image_hpr=(0, 0, 90), image_scale=(0.05, 1, 0.1), image_pos=(0, 0, 0.015), text=TTLocalizer.SuitPageBuildingRadarP % '0', text_scale=0.05, text_fg=(1, 0, 0, 1), text_font=ToontownGlobals.getSuitFont())
gui.removeNode() gui.removeNode()
button.buildingRadarLabel = buildingRadarLabel button.buildingRadarLabel = buildingRadarLabel
return
def resetPanel(self, dept, type): def resetPanel(self, dept, type):
panel = self.panels[dept * SuitDNA.suitsPerDept + type] panel = self.panels[dept * SuitDNA.suitsPerDept + type]
@ -428,6 +443,9 @@ class SuitPage(ShtikerPage.ShtikerPage):
panel.shadow.hide() panel.shadow.hide()
if panel.summonButton: if panel.summonButton:
panel.summonButton.hide() panel.summonButton.hide()
self.rolloverFrame.hide()
panel.hoverButton.unbind(DGG.ENTER)
panel.hoverButton.unbind(DGG.EXIT)
color = PANEL_COLORS[dept] color = PANEL_COLORS[dept]
panel['image_color'] = color panel['image_color'] = color
for button in self.radarButtons: for button in self.radarButtons:
@ -467,6 +485,19 @@ class SuitPage(ShtikerPage.ShtikerPage):
panel['image_color'] = PANEL_COLORS_COMPLETE1[index / SuitDNA.suitsPerDept] panel['image_color'] = PANEL_COLORS_COMPLETE1[index / SuitDNA.suitsPerDept]
elif status == COG_COMPLETE2: elif status == COG_COMPLETE2:
panel['image_color'] = PANEL_COLORS_COMPLETE2[index / SuitDNA.suitsPerDept] panel['image_color'] = PANEL_COLORS_COMPLETE2[index / SuitDNA.suitsPerDept]
if status in (COG_DEFEATED, COG_COMPLETE1, COG_COMPLETE2):
name = SuitDNA.suitHeadTypes[index]
attributes = SuitBattleGlobals.SuitAttributes[name]
level = attributes['level']
groupAttacks, singleAttacks = SuitBattleGlobals.getAttacksByType(attributes)
info = TTLocalizer.SuitPageAttackFormat % (level + 1, level + 5, self.getAttackStrings(groupAttacks), self.getAttackStrings(singleAttacks))
panel.hoverButton.bind(DGG.ENTER, self.showInfo, extraArgs=[panel, info])
panel.hoverButton.bind(DGG.EXIT, self.hideInfo)
def getAttackStrings(self, attacks):
string = '\n'.join(['%s %s' % (TTLocalizer.SuitAttackNames[attack[0]], '-'.join(str(x) for x in attack[1])) for attack in attacks])
return string if string else TTLocalizer.SuitPageNoAttacks
def updateAllCogs(self, status): def updateAllCogs(self, status):
for index in xrange(0, len(base.localAvatar.cogs)): for index in xrange(0, len(base.localAvatar.cogs)):
@ -572,4 +603,3 @@ class SuitPage(ShtikerPage.ShtikerPage):
taskMgr.doMethodLater(RADAR_DELAY * SuitDNA.suitsPerDept, showLabel, 'showBuildingRadarLater', extraArgs=(button,)) taskMgr.doMethodLater(RADAR_DELAY * SuitDNA.suitsPerDept, showLabel, 'showBuildingRadarLater', extraArgs=(button,))
else: else:
button.buildingRadarLabel.hide() button.buildingRadarLabel.hide()
return

View file

@ -461,7 +461,8 @@ class BossCog(Avatar.Avatar):
self.doAnimate(None, raised=1, happy=1, queueNeutral=1) self.doAnimate(None, raised=1, happy=1, queueNeutral=1)
ival = Sequence() ival = Sequence()
if self.dna.dept == 'm': if self.dna.dept == 'm':
ival.append(Parallel(SoundInterval(self.warningSfx, node=self), Wait(5.0))) ival.append(Func(self.loop, 'Ff_neutral'))
ival.append(Parallel(SoundInterval(self.warningSfx, node=self, volume=2.0), Wait(3.0)))
ival.append(Parallel(ActorInterval(self, 'Fb_jump'), Sequence(Func(self.setChatAbsolute, random.choice(TTLocalizer.JumpBossTaunts[self.dna.dept]), CFSpeech | CFTimeout), SoundInterval(self.swishSfx, duration=1.1, node=self), SoundInterval(self.boomSfx, duration=1.9)), Sequence(Wait(1.21), Func(self.announceAreaAttack)))) ival.append(Parallel(ActorInterval(self, 'Fb_jump'), Sequence(Func(self.setChatAbsolute, random.choice(TTLocalizer.JumpBossTaunts[self.dna.dept]), CFSpeech | CFTimeout), SoundInterval(self.swishSfx, duration=1.1, node=self), SoundInterval(self.boomSfx, duration=1.9)), Sequence(Wait(1.21), Func(self.announceAreaAttack))))
if self.twoFaced: if self.twoFaced:
self.happy = 0 self.happy = 0

View file

@ -561,7 +561,7 @@ class DistributedBossCogAI(DistributedAvatarAI.DistributedAvatarAI):
damage *= self.getDamageMultiplier() damage *= self.getDamageMultiplier()
self.damageToon(toon, damage) self.damageToon(toon, damage)
currState = self.getCurrentOrNextState() currState = self.getCurrentOrNextState()
if attackCode == ToontownGlobals.BossCogElectricFence and (currState == 'RollToBattleTwo' or currState == 'BattleThree'): if attackCode == ToontownGlobals.BossCogElectricFence and (currState == 'RollToBattleTwo' or currState == 'BattleThree') and self.attackCode not in (ToontownGlobals.BossCogDizzy, ToontownGlobals.BossCogDizzyNow):
if bpy < 0 and abs(bpx / bpy) > 0.5: if bpy < 0 and abs(bpx / bpy) > 0.5:
if bpx < 0: if bpx < 0:
self.b_setAttackCode(ToontownGlobals.BossCogSwatRight) self.b_setAttackCode(ToontownGlobals.BossCogSwatRight)
@ -600,7 +600,6 @@ class DistributedBossCogAI(DistributedAvatarAI.DistributedAvatarAI):
if self.dept == 'm' and attackCode == ToontownGlobals.BossCogAreaAttack: if self.dept == 'm' and attackCode == ToontownGlobals.BossCogAreaAttack:
delayTime += 5.0 delayTime += 5.0
self.waitForNextAttack(delayTime) self.waitForNextAttack(delayTime)
return
def d_setAttackCode(self, attackCode, avId = 0): def d_setAttackCode(self, attackCode, avId = 0):
self.sendUpdate('setAttackCode', [attackCode, avId]) self.sendUpdate('setAttackCode', [attackCode, avId])

View file

@ -145,7 +145,7 @@ class DistributedCashbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FS
def doNextAttack(self, task): def doNextAttack(self, task):
if random.random() <= 0.2: if random.random() <= 0.2:
self.b_setAttackCode(ToontownGlobals.BossCogAreaAttack) self.b_setAttackCode(ToontownGlobals.BossCogAreaAttack)
taskMgr.doMethodLater(9.36, self.__reviveGoons, self.uniqueName('reviveGoons')) taskMgr.doMethodLater(7.36, self.__reviveGoons, self.uniqueName('reviveGoons'))
else: else:
self.__doDirectedAttack() self.__doDirectedAttack()
if self.heldObject == None and not self.waitingForHelmet: if self.heldObject == None and not self.waitingForHelmet:

View file

@ -23,10 +23,9 @@ from toontown.building import ElevatorConstants
from toontown.building import ElevatorUtils from toontown.building import ElevatorUtils
from toontown.coghq import CogDisguiseGlobals from toontown.coghq import CogDisguiseGlobals
from toontown.distributed import DelayDelete from toontown.distributed import DelayDelete
from otp.nametag import NametagGroup
from otp.nametag.NametagConstants import * from otp.nametag.NametagConstants import *
from otp.nametag import NametagGlobals from otp.nametag import NametagGlobals
from toontown.toon import Toon from toontown.toon import NPCToons
from toontown.toonbase import TTLocalizer from toontown.toonbase import TTLocalizer
from toontown.toonbase import ToontownBattleGlobals from toontown.toonbase import ToontownBattleGlobals
from toontown.toonbase import ToontownGlobals from toontown.toonbase import ToontownGlobals
@ -1567,15 +1566,11 @@ class DistributedLawbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
return bossTrack return bossTrack
def __makeWitnessToon(self): def __makeWitnessToon(self):
dnaNetString = 't\x1b\x00\x01\x01\x00\x03\x00\x03\x01\x10\x13\x00\x13\x13' if self.witnessToon:
npc = Toon.Toon() return
npc.setDNAString(dnaNetString) self.witnessToon = NPCToons.createLocalNPC(13002)
npc.setName(TTLocalizer.WitnessToonName)
npc.setPickable(0)
npc.setPlayerType(NametagGroup.CCNonPlayer)
npc.animFSM.request('Sit')
self.witnessToon = npc
self.witnessToon.setPosHpr(*ToontownGlobals.LawbotBossWitnessStandPosHpr) self.witnessToon.setPosHpr(*ToontownGlobals.LawbotBossWitnessStandPosHpr)
self.witnessToon.animFSM.request('Sit')
def __cleanupWitnessToon(self): def __cleanupWitnessToon(self):
self.__hideWitnessToon() self.__hideWitnessToon()
@ -1583,7 +1578,6 @@ class DistributedLawbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
self.witnessToon.removeActive() self.witnessToon.removeActive()
self.witnessToon.delete() self.witnessToon.delete()
self.witnessToon = None self.witnessToon = None
return
def __showWitnessToon(self): def __showWitnessToon(self):
if not self.witnessToonOnstage: if not self.witnessToonOnstage:

View file

@ -30,7 +30,6 @@ class DistributedSellbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FS
self.bossMaxDamage = ToontownGlobals.SellbotBossMaxDamage self.bossMaxDamage = ToontownGlobals.SellbotBossMaxDamage
self.recoverRate = 0 self.recoverRate = 0
self.recoverStartTime = 0 self.recoverStartTime = 0
self.punishedToons = []
def delete(self): def delete(self):
return DistributedBossCogAI.DistributedBossCogAI.delete(self) return DistributedBossCogAI.DistributedBossCogAI.delete(self)
@ -197,13 +196,6 @@ class DistributedSellbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FS
return self.invokeSuitPlanner(10, 1) return self.invokeSuitPlanner(10, 1)
def removeToon(self, avId): def removeToon(self, avId):
av = self.air.doId2do.get(avId)
if not av is None:
if av.getHp() <= 0:
if avId not in self.punishedToons:
self.air.cogSuitMgr.removeParts(av, self.deptIndex)
self.punishedToons.append(avId)
toon = simbase.air.doId2do.get(avId) toon = simbase.air.doId2do.get(avId)
if toon: if toon:
toon.b_setNumPies(0) toon.b_setNumPies(0)

View file

@ -235,12 +235,12 @@ def loadDialog(level):
SuitDialogFiles = ['COG_VO_grunt', SuitDialogFiles = ['COG_VO_grunt',
'COG_VO_murmur', 'COG_VO_murmur',
'COG_VO_statement', 'COG_VO_statement',
'COG_VO_question'] 'COG_VO_question',
'COG_VO_exclaim']
for file in SuitDialogFiles: for file in SuitDialogFiles:
SuitDialogArray.append(base.loadSfx(loadPath + file + '.ogg')) SuitDialogArray.append(base.loadSfx(loadPath + file + '.ogg'))
SuitDialogArray.append(SuitDialogArray[2]) SuitDialogArray.append(SuitDialogArray[2])
SuitDialogArray.append(SuitDialogArray[2])
def loadSkelDialog(): def loadSkelDialog():
@ -252,11 +252,12 @@ def loadSkelDialog():
murmur = loader.loadSfx('phase_5/audio/sfx/Skel_COG_VO_murmur.ogg') murmur = loader.loadSfx('phase_5/audio/sfx/Skel_COG_VO_murmur.ogg')
statement = loader.loadSfx('phase_5/audio/sfx/Skel_COG_VO_statement.ogg') statement = loader.loadSfx('phase_5/audio/sfx/Skel_COG_VO_statement.ogg')
question = loader.loadSfx('phase_5/audio/sfx/Skel_COG_VO_question.ogg') question = loader.loadSfx('phase_5/audio/sfx/Skel_COG_VO_question.ogg')
exclaim = loader.loadSfx('phase_5/audio/sfx/Skel_COG_VO_exclaim.ogg')
SkelSuitDialogArray = [grunt, SkelSuitDialogArray = [grunt,
murmur, murmur,
statement, statement,
question, question,
statement, exclaim,
statement] statement]

View file

@ -19,7 +19,7 @@ suitProperties = {'f': (4.0 / cSize, SuitDNA.corpPolyColor, ['flunky', 'glasses'
'p': (3.35 / bSize, SuitDNA.corpPolyColor, ['pencilpusher'], '', 5.0), 'p': (3.35 / bSize, SuitDNA.corpPolyColor, ['pencilpusher'], '', 5.0),
'ym': (4.125 / aSize, SuitDNA.corpPolyColor, ['yesman'], '', 5.28), 'ym': (4.125 / aSize, SuitDNA.corpPolyColor, ['yesman'], '', 5.28),
'mm': (2.5 / cSize, SuitDNA.corpPolyColor, ['micromanager'], '', 3.25), 'mm': (2.5 / cSize, SuitDNA.corpPolyColor, ['micromanager'], '', 3.25),
'ds': (4.5 / bSize, SuitDNA.corpPolyColor, ['beancounter'], '', 6.08), 'ds': (4.5 / bSize, VBase4(0.8, 0.7, 0.7, 1.0), ['downsizer', 'hatjp187187'], '', 6.08),
'hh': (6.5 / aSize, SuitDNA.corpPolyColor, ['headhunter'], '', 7.45), 'hh': (6.5 / aSize, SuitDNA.corpPolyColor, ['headhunter'], '', 7.45),
'cr': (6.75 / cSize, VBase4(0.85, 0.55, 0.55, 1.0), ['flunky'], 'corporate-raider.jpg', 8.23), 'cr': (6.75 / cSize, VBase4(0.85, 0.55, 0.55, 1.0), ['flunky'], 'corporate-raider.jpg', 8.23),
'tbc': (7.0 / aSize, VBase4(0.75, 0.95, 0.75, 1.0), ['bigcheese'], '', 9.34), 'tbc': (7.0 / aSize, VBase4(0.75, 0.95, 0.75, 1.0), ['bigcheese'], '', 9.34),
@ -29,7 +29,7 @@ suitProperties = {'f': (4.0 / cSize, SuitDNA.corpPolyColor, ['flunky', 'glasses'
'dt': (4.25 / aSize, SuitDNA.legalPolyColor, ['twoface'], 'double-talker.jpg', 5.63), 'dt': (4.25 / aSize, SuitDNA.legalPolyColor, ['twoface'], 'double-talker.jpg', 5.63),
'ac': (4.35 / bSize, SuitDNA.legalPolyColor, ['ambulancechaser'], '', 6.39), 'ac': (4.35 / bSize, SuitDNA.legalPolyColor, ['ambulancechaser'], '', 6.39),
'bs': (4.5 / aSize, SuitDNA.legalPolyColor, ['backstabber'], '', 6.71), 'bs': (4.5 / aSize, SuitDNA.legalPolyColor, ['backstabber'], '', 6.71),
'sd': (5.65 / bSize, VBase4(0.5, 0.8, 0.75, 1.0), ['telemarketer'], 'spin-doctor.jpg', 7.9), 'sd': (5.65 / bSize, VBase4(0.8, 0.9, 0.7, 1.0), ['spindoctor', 'scopejp187187', 'bandjp187187'], '', 7.9),
'le': (7.125 / aSize, VBase4(0.25, 0.25, 0.5, 1.0), ['legaleagle'], '', 8.27), 'le': (7.125 / aSize, VBase4(0.25, 0.25, 0.5, 1.0), ['legaleagle'], '', 8.27),
'bw': (7.0 / aSize, SuitDNA.legalPolyColor, ['bigwig'], '', 8.69), 'bw': (7.0 / aSize, SuitDNA.legalPolyColor, ['bigwig'], '', 8.69),
# Cashbots # Cashbots

View file

@ -490,6 +490,9 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
def getNPCFriendsDict(self): def getNPCFriendsDict(self):
return self.NPCFriendsDict return self.NPCFriendsDict
def getNPCFriendCount(self, npcId):
return self.NPCFriendsDict.get(npcId, 0)
def setNPCFriendsDict(self, NPCFriendsList): def setNPCFriendsDict(self, NPCFriendsList):
NPCFriendsDict = {} NPCFriendsDict = {}
@ -589,6 +592,9 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
def setTutorialAck(self, tutorialAck): def setTutorialAck(self, tutorialAck):
self.tutorialAck = tutorialAck self.tutorialAck = tutorialAck
def getTutorialAck(self):
return self.tutorialAck
def setEarnedExperience(self, earnedExp): def setEarnedExperience(self, earnedExp):
self.earnedExperience = earnedExp self.earnedExperience = earnedExp
@ -1176,6 +1182,8 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
DistributedSmoothNode.DistributedSmoothNode.d_setParent(self, parentToken) DistributedSmoothNode.DistributedSmoothNode.d_setParent(self, parentToken)
def setEmoteAccess(self, bits): def setEmoteAccess(self, bits):
if bits[26]:
bits.remove(bits[26])
self.emoteAccess = bits self.emoteAccess = bits
if self == base.localAvatar: if self == base.localAvatar:
messenger.send('emotesChanged') messenger.send('emotesChanged')
@ -1250,6 +1258,9 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
def getTotalMoney(self): def getTotalMoney(self):
return self.getBankMoney() + self.getMoney() return self.getBankMoney() + self.getMoney()
def takeMoney(self, money):
self.sendUpdate('takeMoney', [money])
def setEmblems(self, emblems): def setEmblems(self, emblems):
if self.emblems != emblems: if self.emblems != emblems:
@ -2448,6 +2459,18 @@ def blackCat():
""" """
base.cr.blackCatMgr.requestBlackCatTransformation() base.cr.blackCatMgr.requestBlackCatTransformation()
@magicWord(category=CATEGORY_COMMUNITY_MANAGER)
def toggleGM():
invoker = spellbook.getInvoker()
if invoker.gmIcon:
invoker.setWantAdminTag(False)
invoker.removeGMIcon()
invoker.setNametagName()#setName(invoker.getName())
else:
invoker.setWantAdminTag(True)
invoker.setGMIcon(invoker.getAdminAccess())
invoker.setNametagName()#setName(invoker.getName())
@magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[str]) @magicWord(category=CATEGORY_COMMUNITY_MANAGER, types=[str])
def showParticle(name): def showParticle(name):
""" """

Some files were not shown because too many files have changed in this diff Show more