mirror of
https://github.com/izzy2lost/Diddy-Kong-Racing.git
synced 2026-06-19 01:16:26 -07:00
Updated score script with game status.
This commit is contained in:
+25
-30
@@ -1,6 +1,8 @@
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
from file_util import FileUtil
|
||||
from score_display import ScoreDisplay
|
||||
|
||||
ASM_FOLDERS = [
|
||||
'./asm/unknown_0251F0',
|
||||
@@ -13,7 +15,7 @@ ASM_FOLDERS = [
|
||||
]
|
||||
|
||||
# These will automatically be added to the adventure one percentage.
|
||||
ASM_FUNCTIONS = [ 'entrypoint' ]
|
||||
ASM_LABELS = [ 'entrypoint' ]
|
||||
for folder in ASM_FOLDERS:
|
||||
GLABEL_REGEX = r'glabel ([0-9A-Za-z_]+)'
|
||||
filenames = FileUtil.get_filenames_from_directory(folder, extensions=('.s',))
|
||||
@@ -22,12 +24,12 @@ for folder in ASM_FOLDERS:
|
||||
text = asmFile.read()
|
||||
matches = re.finditer(GLABEL_REGEX, text, re.MULTILINE)
|
||||
for matchNum, match in enumerate(matches, start=1):
|
||||
ASM_FUNCTIONS.append(match.groups()[0])
|
||||
ASM_LABELS.append(match.groups()[0])
|
||||
|
||||
BUILD_DIRECTORY = './build/us_1.0'
|
||||
SRC_DIRECTORY = './src'
|
||||
LIB_SRC_DIRECTORY = './lib/src'
|
||||
FUNCTION_REGEX = r'([/][*][*]([^*]|([*][^/]))*[*][/][\n]\s*)?(void|s64|s32|s16|s8|u64|u32|u16|u8|f32|f64)(\s|[*])*([0-9A-Za-z_]+)\s*[(][^)]*[)]\s*{'
|
||||
FUNCTION_REGEX = r'((?:[\/][*][*]+[\n])(?:[^\n]*\n)*?(?:.*[*][\/]))?(void|s64|s32|s16|s8|u64|u32|u16|u8|f32|f64)(?:\s|[*])*([0-9A-Za-z_]+)\s*[(][^)]*[)]\s*{'
|
||||
GLOBAL_ASM_REGEX = r'GLOBAL_ASM[(]".*(?=\/)\/([^.]+).s"[)]'
|
||||
WIP_REGEX = r'#if(.|\n)*?(GLOBAL_ASM[(]([^)]*)[)])(.|\n)*?#else(.|\n)*?#endif'
|
||||
|
||||
@@ -87,7 +89,7 @@ class ScoreFile:
|
||||
matches = re.finditer(FUNCTION_REGEX, self.text, re.MULTILINE)
|
||||
for matchNum, match in enumerate(matches, start=1):
|
||||
groups = match.groups()
|
||||
self.functions.append(ScoreFileMatch(groups[0], groups[5]))
|
||||
self.functions.append(ScoreFileMatch(groups[0], groups[2]))
|
||||
|
||||
matches = re.finditer(GLOBAL_ASM_REGEX, self.text, re.MULTILINE)
|
||||
for matchNum, match in enumerate(matches, start=1):
|
||||
@@ -120,17 +122,16 @@ class ScoreFile:
|
||||
|
||||
def main():
|
||||
showTopFiles = 0
|
||||
|
||||
numArgs = len(sys.argv)
|
||||
for i in range(1, numArgs):
|
||||
arg = sys.argv[i].lower()
|
||||
print('Argument:', sys.argv[i])
|
||||
if arg.startswith("--top"):
|
||||
num = arg[5:]
|
||||
if num == "":
|
||||
showTopFiles = 10 # 10 is the default
|
||||
else:
|
||||
showTopFiles = int(num)
|
||||
|
||||
parser = argparse.ArgumentParser(description="")
|
||||
parser.add_argument("-t", "--top", help="(Optional) Shows the top N files remaining.")
|
||||
parser.add_argument("-a", "--adventure", help="(Optional) Only shows adventure 1 or 2 based on passed in value.", choices=['1', '2'])
|
||||
args = parser.parse_args()
|
||||
adventureSelect = 3 # Show both adventures by default
|
||||
if args.adventure != None:
|
||||
adventureSelect = int(args.adventure)
|
||||
if args.top != None:
|
||||
showTopFiles = int(args.top)
|
||||
|
||||
scoreFiles = []
|
||||
totalNumberOfDecompiledFunctions = 0
|
||||
@@ -158,25 +159,17 @@ def main():
|
||||
totalSizeOfDocumentedFunctions += scoreFile.get_size_of_documented_functions()
|
||||
scoreFiles.append(scoreFile)
|
||||
|
||||
totalNumberOfFunctions = MAP_FILE.numFunctions
|
||||
|
||||
for asm_function in ASM_FUNCTIONS:
|
||||
totalSizeOfDecompiledFunctions += MAP_FILE.functionSizes[asm_function]
|
||||
totalNumberOfFunctions = MAP_FILE.numFunctions
|
||||
for asm_function in ASM_LABELS:
|
||||
if asm_function in MAP_FILE.functionSizes:
|
||||
totalSizeOfDecompiledFunctions += MAP_FILE.functionSizes[asm_function]
|
||||
|
||||
adventureOnePercentage = (totalSizeOfDecompiledFunctions / CODE_SIZE) * 100
|
||||
adventureTwoPercentage = (totalSizeOfDocumentedFunctions / CODE_SIZE) * 100
|
||||
|
||||
print('=========================================')
|
||||
print(' ADVENTURE ONE (ASM -> C Decompilation)')
|
||||
print(' ----------- {:5.2f}% Complete -----------'.format(adventureOnePercentage))
|
||||
print(' # Decompiled functions: ' + str(totalNumberOfDecompiledFunctions))
|
||||
print(' # GLOBAL_ASM remaining: ' + str(totalNumberOfGlobalAsms))
|
||||
print('=========================================')
|
||||
print(' ADVENTURE TWO (Cleanup & Documentation)')
|
||||
print(' ----------- {:5.2f}% Complete -----------'.format(adventureTwoPercentage))
|
||||
print(' # Documented functions: ' + str(totalNumberOfDocumentedFunctions))
|
||||
print(' # Undocumented remaining: ' + str(totalNumberOfFunctions - totalNumberOfDocumentedFunctions))
|
||||
print('=========================================')
|
||||
scoreDisplay = ScoreDisplay()
|
||||
print(scoreDisplay.getDisplay(adventureOnePercentage, adventureTwoPercentage, adventureSelect, totalNumberOfDecompiledFunctions, totalNumberOfGlobalAsms, totalNumberOfDocumentedFunctions, totalNumberOfFunctions - totalNumberOfDocumentedFunctions))
|
||||
|
||||
if showTopFiles > 0:
|
||||
if showTopFiles > len(scoreFiles):
|
||||
@@ -189,7 +182,9 @@ def main():
|
||||
for i in range(0, showTopFiles):
|
||||
percentageRemaining = (files[i][1] / CODE_SIZE) * 100
|
||||
percentageDone = (files[i][2] / CODE_SIZE) * 100
|
||||
funcName = files[i][0][12:]
|
||||
funcName = files[i][0]
|
||||
if '/' in funcName:
|
||||
funcName = funcName[funcName.rindex('/') + 1:]
|
||||
print("", funcName, (" " * (24 - len(funcName))), "| {:5.2f}% | {:5.2f}% |".format(percentageRemaining, percentageDone))
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
import json
|
||||
import argparse
|
||||
|
||||
def readScoreDisplayJson(filename='./tools/python/score_progress.json'):
|
||||
with open(filename, 'r') as inFile:
|
||||
return json.loads(inFile.read())
|
||||
|
||||
TOTAL_NUMBER_OF_BALLOONS = 47
|
||||
TOTAL_NUMBER_OF_KEYS = 4
|
||||
TOTAL_NUMBER_OF_TT_AMULETS = 4
|
||||
TOTAL_NUMBER_OF_WIZPIG_AMULETS = 4
|
||||
TOTAL_NUMBER_OF_TROPHIES = 5
|
||||
|
||||
DEFAULT_MAX_LENGTH = 42
|
||||
|
||||
class ScoreDisplay:
|
||||
def __init__(self):
|
||||
self.progressNodes = readScoreDisplayJson()
|
||||
|
||||
def getStatus(self, percentage):
|
||||
if percentage >= 100.0:
|
||||
return {
|
||||
"Balloon": TOTAL_NUMBER_OF_BALLOONS,
|
||||
"Key": TOTAL_NUMBER_OF_KEYS,
|
||||
"TTAmulet": TOTAL_NUMBER_OF_TT_AMULETS,
|
||||
"WizpigAmulet": TOTAL_NUMBER_OF_WIZPIG_AMULETS,
|
||||
"Trophy": TOTAL_NUMBER_OF_TROPHIES,
|
||||
"Msg": "COMPLETED!"
|
||||
}
|
||||
out = {
|
||||
"Balloon": 0,
|
||||
"Key": 0,
|
||||
"TTAmulet": 0,
|
||||
"WizpigAmulet": 0,
|
||||
"Trophy": 0,
|
||||
"Msg": 'Not Started'
|
||||
}
|
||||
if percentage <= 0.0:
|
||||
return out
|
||||
numberOfCompletedNodes = int((percentage / 100.0) * len(self.progressNodes))
|
||||
currentNodeProgress = ((percentage / 100.0) * len(self.progressNodes)) - numberOfCompletedNodes
|
||||
for i in range(0, numberOfCompletedNodes):
|
||||
rewards = self.progressNodes[i]["rewards"]
|
||||
for reward in rewards:
|
||||
out[reward] += rewards[reward]
|
||||
out['Msg'] = self.progressNodes[numberOfCompletedNodes]['msg']
|
||||
nodeType = self.progressNodes[numberOfCompletedNodes]['type']
|
||||
#if nodeType != 'Task':
|
||||
# out['Msg'] += '\n'
|
||||
if nodeType == 'Race':
|
||||
out['Msg'] += ' (Lap ' + str(int(currentNodeProgress*3)+1) + '/3)'
|
||||
elif nodeType == 'Collecting':
|
||||
collectingName = self.progressNodes[numberOfCompletedNodes]['collecting']['name']
|
||||
collectingMax = self.progressNodes[numberOfCompletedNodes]['collecting']['max']
|
||||
out['Msg'] += ' (' + str(int(currentNodeProgress * collectingMax)) + '/' + str(collectingMax) + ' ' + collectingName + 's)'
|
||||
elif nodeType == 'SilverCoinsRace':
|
||||
out['Msg'] += ' (' + str(int(currentNodeProgress*9)) + '/8 silver coins)'
|
||||
elif nodeType == 'TrophyRace':
|
||||
if currentNodeProgress < 0.25:
|
||||
out['Msg'] += ' (Round One)'
|
||||
elif currentNodeProgress < 0.50:
|
||||
out['Msg'] += ' (Round Two)'
|
||||
elif currentNodeProgress < 0.75:
|
||||
out['Msg'] += ' (Round Three)'
|
||||
elif currentNodeProgress < 1.00:
|
||||
out['Msg'] += ' (Round Four)'
|
||||
elif nodeType == 'Battle':
|
||||
if currentNodeProgress < 0.34:
|
||||
out['Msg'] += ' (3 opponents remain)'
|
||||
elif currentNodeProgress < 0.67:
|
||||
out['Msg'] += ' (2 opponents remain)'
|
||||
elif currentNodeProgress < 1.00:
|
||||
out['Msg'] += ' (1 opponent remains)'
|
||||
return out
|
||||
|
||||
def makeLine(self, char, length, title=None):
|
||||
if title == None:
|
||||
return ' ' + (char * length) + ' \n'
|
||||
else:
|
||||
lineSideLength = (length - len(title) - 2) // 2
|
||||
leftLength = lineSideLength
|
||||
rightLength = lineSideLength
|
||||
if (leftLength + rightLength + len(title) + 2) < length:
|
||||
rightLength += 1
|
||||
if leftLength + rightLength <= 0:
|
||||
if leftLength + rightLength == 0:
|
||||
return ' ' + title + ' \n'
|
||||
else:
|
||||
return ' ' + title + ' \n'
|
||||
else:
|
||||
return ' ' + (char * leftLength) + ' ' + title + ' ' + (char * rightLength) + ' \n'
|
||||
|
||||
def getGameStatusDisplay(self, status, dashLen):
|
||||
out = ''
|
||||
out += self.makeLine('-', dashLen, 'Game Status')
|
||||
firstStatusLine = ''
|
||||
secondStatusLine = ''
|
||||
firstStatusLine += 'Balloons: {:}/{:},'.format(status['Balloon'], TOTAL_NUMBER_OF_BALLOONS)
|
||||
firstStatusLine += ' Keys: {:}/{:},'.format(status['Key'], TOTAL_NUMBER_OF_KEYS)
|
||||
firstStatusLine += ' Trophies: {:}/{:}'.format(status['Trophy'], TOTAL_NUMBER_OF_TROPHIES)
|
||||
secondStatusLine += 'T.T. Amulets: {:}/{:},'.format(status['TTAmulet'], TOTAL_NUMBER_OF_TT_AMULETS)
|
||||
secondStatusLine += ' Wizpig Amulets: {:}/{:}'.format(status['WizpigAmulet'], TOTAL_NUMBER_OF_WIZPIG_AMULETS)
|
||||
out += self.makeLine(' ', dashLen, firstStatusLine)
|
||||
out += self.makeLine(' ', dashLen, secondStatusLine)
|
||||
out += self.makeLine('-', dashLen)
|
||||
out += self.makeLine(' ', dashLen, status['Msg'])
|
||||
return [out, dashLen]
|
||||
|
||||
def getDisplay(self, advOnePer, advTwoPer, showFlags=3, totalDecompFunctions=0, totalGlobalAsm=0, totalDocumented=0, totalUndocumented=0):
|
||||
advOneStatus = self.getStatus(advOnePer)
|
||||
advTwoStatus = self.getStatus(advTwoPer)
|
||||
if showFlags == 3:
|
||||
dashLen = max(len(advOneStatus['Msg']), len(advTwoStatus['Msg']), DEFAULT_MAX_LENGTH)
|
||||
elif showFlags == 1:
|
||||
dashLen = max(len(advOneStatus['Msg']), DEFAULT_MAX_LENGTH)
|
||||
elif showFlags == 2:
|
||||
dashLen = max(len(advTwoStatus['Msg']), DEFAULT_MAX_LENGTH)
|
||||
else:
|
||||
dashLen = DEFAULT_MAX_LENGTH
|
||||
advOneGameStatusDisplay = self.getGameStatusDisplay(advOneStatus, dashLen)
|
||||
advTwoGameStatusDisplay = self.getGameStatusDisplay(advTwoStatus, dashLen)
|
||||
out = ''
|
||||
if showFlags & 1:
|
||||
out += self.makeLine('=', dashLen)
|
||||
out += self.makeLine(' ', dashLen, 'ADVENTURE ONE (ASM -> C Decompilation)')
|
||||
if advOnePer >= 100.0:
|
||||
out += self.makeLine('-', dashLen, '{:5.1f}% Complete'.format(advOnePer))
|
||||
else:
|
||||
out += self.makeLine('-', dashLen, '{:5.2f}% Complete'.format(advOnePer))
|
||||
out += self.makeLine(' ', dashLen, '# Decompiled functions: ' + str(totalDecompFunctions))
|
||||
out += self.makeLine(' ', dashLen, '# GLOBAL_ASM remaining: ' + str(totalGlobalAsm))
|
||||
out += advOneGameStatusDisplay[0]
|
||||
if showFlags & 2:
|
||||
out += self.makeLine('=', dashLen)
|
||||
out += self.makeLine(' ', dashLen, ' ADVENTURE TWO (Cleanup & Documentation)')
|
||||
if advTwoPer >= 100.0:
|
||||
out += self.makeLine('-', dashLen, '{:5.1f}% Complete'.format(advTwoPer))
|
||||
else:
|
||||
out += self.makeLine('-', dashLen, '{:5.2f}% Complete'.format(advTwoPer))
|
||||
out += self.makeLine(' ', dashLen, '# Documented functions: ' + str(totalDocumented))
|
||||
out += self.makeLine(' ', dashLen, '# Undocumented remaining: ' + str(totalUndocumented))
|
||||
out += advTwoGameStatusDisplay[0]
|
||||
out += self.makeLine('=', dashLen)[:-1]
|
||||
return out
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="")
|
||||
parser.add_argument("adventureOnePercentage", help="Value within [0.0, 100.0] that describes how complete the decomp is.")
|
||||
parser.add_argument("adventureTwoPercentage", help="Value within [0.0, 100.0] that describes how complete the documentation is.")
|
||||
parser.add_argument("-a", "--adventure", help="(Optional) Only shows adventure 1 or 2 based on passed in value.", choices=['1', '2'])
|
||||
args = parser.parse_args()
|
||||
adventureSelect = 3 # Show both adventures by default
|
||||
if args.adventure != None:
|
||||
adventureSelect = int(args.adventure)
|
||||
scoreDisplay = ScoreDisplay()
|
||||
print(scoreDisplay.getDisplay(float(args.adventureOnePercentage), float(args.adventureTwoPercentage), adventureSelect))
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
[
|
||||
{
|
||||
"msg": "We are collecting the first balloon on Timber's Island.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting the second balloon on Timber's Island.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting the third balloon on Timber's Island.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting the fourth balloon on Timber's Island.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Ancient Lake.",
|
||||
"rewards": { "Balloon": 1, "Key": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Fossil Canyon.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Jungle Falls.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Hot Top Volcano.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing the dinosaur boss Trickytops",
|
||||
"rewards": {},
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting eggs in Fire Mountain.",
|
||||
"rewards": { "TTAmulet": 1 },
|
||||
"type": "Collecting",
|
||||
"collecting": { "name": "Egg", "max": 3 }
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Ancient Lake.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Fossil Canyon.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Jungle Falls.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Hot Top Volcano.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in the rematch against Trickytops.",
|
||||
"rewards": { "WizpigAmulet": 1 },
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are participating in the Trophy Race of Dino Domain.",
|
||||
"rewards": { "Trophy": 1 },
|
||||
"type": "TrophyRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing Taj in the Car Challenge.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Everfrost Peak.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Walrus Cove.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Snowball Valley.",
|
||||
"rewards": { "Balloon": 1, "Key": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Frosty Village.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing the walrus boss Bluey.",
|
||||
"rewards": {},
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are battling in Icicle Pyramid.",
|
||||
"rewards": { "TTAmulet": 1 },
|
||||
"type": "Battle"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Everfrost Peak.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Walrus Cove.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Snowball Valley.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Frosty Village.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in the rematch against Bluey.",
|
||||
"rewards": { "WizpigAmulet": 1 },
|
||||
"type": "Task"
|
||||
},
|
||||
{
|
||||
"msg": "We are participating in the Trophy Race of Snowflake Mountain.",
|
||||
"rewards": { "Trophy": 1 },
|
||||
"type": "TrophyRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing Taj in the Hover Challenge.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Whale Bay.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Crescent Island.",
|
||||
"rewards": { "Balloon": 1, "Key": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Pirate Lagoon.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Treasure Caves.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing the octopus boss Bubbler.",
|
||||
"rewards": {},
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are battling in Darkwater Beach.",
|
||||
"rewards": { "TTAmulet": 1 },
|
||||
"type": "Battle"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Whale Bay.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Crescent Island.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Pirate Lagoon.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Treasure Caves.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in the rematch against Bubbler.",
|
||||
"rewards": { "WizpigAmulet": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are participating in the Trophy Race of Sherbet Island.",
|
||||
"rewards": { "Trophy": 1 },
|
||||
"type": "TrophyRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing Taj in the Plane Challenge.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Windmill Plains.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Greenwood Village.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Boulder Canyon.",
|
||||
"rewards": { "Balloon": 1, "Key": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Haunted Woods.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing the dragon boss Smokey.",
|
||||
"rewards": {},
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting bananas in Smokey Castle.",
|
||||
"rewards": { "TTAmulet": 1 },
|
||||
"type": "Collecting",
|
||||
"collecting": { "name": "Banana", "max": 10 }
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Windmill Plains.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Greenwood Village.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Boulder Canyon.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Haunted Woods.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in the rematch against Smokey.",
|
||||
"rewards": { "WizpigAmulet": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are participating in the Trophy Race of Dragon Forest.",
|
||||
"rewards": { "Trophy": 1 },
|
||||
"type": "TrophyRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing the wizard pig boss Wizpig.",
|
||||
"rewards": {},
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Spacedust Alley.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Darkmoon Caverns.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Spaceport Alpha.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in Star City.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Spacedust Alley.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Darkmoon Caverns.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Spaceport Alpha.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are collecting silver coins in Star City.",
|
||||
"rewards": { "Balloon": 1 },
|
||||
"type": "SilverCoinsRace"
|
||||
},
|
||||
{
|
||||
"msg": "We are racing in the rematch against Wizpig.",
|
||||
"rewards": {},
|
||||
"type": "Race"
|
||||
},
|
||||
{
|
||||
"msg": "We are participating in the Trophy Race of Future Fun Land.",
|
||||
"rewards": {},
|
||||
"type": "TrophyRace"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user