coghq: mostly non-hacky cbhq

This commit is contained in:
Aidan Noll 2014-05-05 23:30:33 -04:00 committed by Aidan
parent b432f70d81
commit c8d4c785ca
19 changed files with 1356 additions and 132 deletions

View file

@ -9,7 +9,7 @@ from toontown.ai.FishManagerAI import FishManagerAI
from toontown.distributed.ToontownInternalRepository import ToontownInternalRepository
from toontown.toon import NPCToons
from toontown.hood import TTHoodAI, DDHoodAI, DGHoodAI, BRHoodAI, MMHoodAI, DLHoodAI, OZHoodAI, GSHoodAI, GZHoodAI, ZoneUtil
from toontown.hood import SellbotHQAI
from toontown.hood import SellbotHQAI, CashbotHQAI
from toontown.toonbase import ToontownGlobals
from direct.distributed.PyDatagram import *
from otp.ai.AIZoneData import *
@ -43,6 +43,7 @@ from toontown.quest.QuestManagerAI import QuestManagerAI
from toontown.building.DistributedTrophyMgrAI import DistributedTrophyMgrAI
from toontown.shtiker.CogPageManagerAI import CogPageManagerAI
from toontown.coghq.FactoryManagerAI import FactoryManagerAI
from toontown.coghq.MintManagerAI import MintManagerAI
from toontown.coghq.PromotionManagerAI import PromotionManagerAI
from toontown.coghq.CogSuitManagerAI import CogSuitManagerAI
@ -77,6 +78,7 @@ class ToontownAIRepository(ToontownInternalRepository):
self.questManager = QuestManagerAI(self)
self.cogPageManager = CogPageManagerAI()
self.factoryMgr = FactoryManagerAI(self)
self.mintMgr = MintManagerAI(self)
self.promotionMgr = PromotionManagerAI(self)
self.cogSuitMgr = CogSuitManagerAI(self)
self.suitInvasionManager = SuitInvasionManagerAI(self)
@ -194,6 +196,8 @@ class ToontownAIRepository(ToontownInternalRepository):
clearQueue()
self.hoods.append(SellbotHQAI.SellbotHQAI(self))
clearQueue()
self.hoods.append(CashbotHQAI.CashbotHQAI(self))
clearQueue()
for sp in self.suitPlanners.values():
sp.assignInitialSuitBuildings()

View file

@ -1,6 +1,9 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.building.DistributedBossElevatorAI import DistributedBossElevatorAI
from ElevatorConstants import *
import DistributedBossElevatorAI
class DistributedCFOElevatorAI(DistributedBossElevatorAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedCFOElevatorAI")
class DistributedCFOElevatorAI(DistributedBossElevatorAI.DistributedBossElevatorAI):
def __init__(self, air, bldg, zone, antiShuffle = 0, minLaff = 0):
DistributedBossElevatorAI.DistributedBossElevatorAI.__init__(self, air, bldg, zone, antiShuffle=antiShuffle, minLaff=minLaff)
self.type = ELEVATOR_CFO
self.countdownTime = ElevatorData[self.type]['countdown']

View file

@ -9,6 +9,7 @@ from toontown.safezone import Train
class CashbotHQExterior(CogHQExterior.CogHQExterior):
notify = DirectNotifyGlobal.directNotify.newCategory('CashbotHQExterior')
TrackZ = -67
dnaFile = 'phase_10/dna/cog_hq_cashbot_sz.xml'
TrainTracks = [{'start': Point3(-1000, -54.45, TrackZ),
'end': Point3(2200, -54.45, TrackZ)},
{'start': Point3(1800, -133.45, TrackZ),

View file

@ -10,6 +10,7 @@ from direct.task import Task
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from otp.otpbase import OTPGlobals
from otp.nametag import NametagGlobals
import random
class DistributedCashbotBossCrane(DistributedObject.DistributedObject, FSM.FSM):

View file

@ -1,27 +1,75 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from pandac.PandaModules import *
from direct.distributed import DistributedObjectAI
from toontown.toonbase import ToontownGlobals
from otp.otpbase import OTPGlobals
from direct.fsm import FSM
class DistributedCashbotBossCraneAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedCashbotBossCraneAI")
class DistributedCashbotBossCraneAI(DistributedObjectAI.DistributedObjectAI, FSM.FSM):
def setBossCogId(self, todo0):
pass
def __init__(self, air, boss, index):
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
FSM.FSM.__init__(self, 'DistributedCashbotBossCraneAI')
self.boss = boss
self.index = index
cn = CollisionNode('controls')
cs = CollisionSphere(0, -6, 0, 6)
cn.addSolid(cs)
self.goonShield = NodePath(cn)
self.goonShield.setPosHpr(*ToontownGlobals.CashbotBossCranePosHprs[self.index])
self.avId = 0
self.objectId = 0
def setIndex(self, todo0):
pass
def getBossCogId(self):
return self.boss.doId
def setState(self, todo0, todo1):
pass
def getIndex(self):
return self.index
def d_setState(self, state, avId):
self.sendUpdate('setState', [state, avId])
def requestControl(self):
pass
avId = self.air.getAvatarIdFromSender()
if avId in self.boss.involvedToons and self.avId == 0:
craneId = self.__getCraneId(avId)
if craneId == 0:
self.request('Controlled', avId)
def requestFree(self):
pass
avId = self.air.getAvatarIdFromSender()
if avId == self.avId:
self.request('Free')
def clearSmoothing(self, todo0):
pass
def removeToon(self, avId):
if avId == self.avId:
self.request('Free')
def setCablePos(self, todo0, todo1, todo2, todo3, todo4):
pass
def __getCraneId(self, avId):
if self.boss and self.boss.cranes != None:
for crane in self.boss.cranes:
if crane.avId == avId:
return crane.doId
return 0
def enterOff(self):
self.goonShield.detachNode()
def exitOff(self):
self.goonShield.reparentTo(self.boss.scene)
def enterControlled(self, avId):
self.avId = avId
self.d_setState('C', avId)
def exitControlled(self):
if self.objectId:
obj = self.air.doId2do[self.objectId]
obj.request('Dropped', self.avId, self.doId)
def enterFree(self):
self.avId = 0
self.d_setState('F', 0)
def exitFree(self):
pass

View file

@ -1,12 +1,71 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from pandac.PandaModules import *
from toontown.toonbase import ToontownGlobals
from otp.otpbase import OTPGlobals
import DistributedCashbotBossObjectAI
class DistributedCashbotBossSafeAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedCashbotBossSafeAI")
class DistributedCashbotBossSafeAI(DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI):
wantsWatchDrift = 0
def setIndex(self, todo0):
pass
def __init__(self, air, boss, index):
DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI.__init__(self, air, boss)
self.index = index
self.avoidHelmet = 0
cn = CollisionNode('sphere')
cs = CollisionSphere(0, 0, 0, 6)
cn.addSolid(cs)
self.attachNewNode(cn)
def resetToInitialPosition(self):
posHpr = ToontownGlobals.CashbotBossSafePosHprs[self.index]
self.setPosHpr(*posHpr)
def getIndex(self):
return self.index
def hitBoss(self, impact):
avId = self.air.getAvatarIdFromSender()
self.validate(avId, impact <= 1.0, 'invalid hitBoss impact %s' % impact)
if avId not in self.boss.involvedToons:
return
if self.state != 'Dropped' and self.state != 'Grabbed':
return
if self.avoidHelmet or self == self.boss.heldObject:
return
if self.boss.heldObject == None:
if self.boss.attackCode == ToontownGlobals.BossCogDizzy:
damage = int(impact * 50)
self.boss.recordHit(max(damage, 2))
elif self.boss.acceptHelmetFrom(avId):
self.demand('Grabbed', self.boss.doId, self.boss.doId)
self.boss.heldObject = self
elif impact >= ToontownGlobals.CashbotBossSafeKnockImpact:
self.boss.heldObject.demand('Dropped', avId, self.boss.doId)
self.boss.heldObject.avoidHelmet = 1
self.boss.heldObject = None
self.avoidHelmet = 1
self.boss.waitForNextHelmet()
return
def requestInitial(self):
pass
avId = self.air.getAvatarIdFromSender()
if avId == self.avId:
self.demand('Initial')
def enterGrabbed(self, avId, craneId):
DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI.enterGrabbed(self, avId, craneId)
self.avoidHelmet = 0
def enterInitial(self):
self.avoidHelmet = 0
self.resetToInitialPosition()
if self.index == 0:
self.stash()
self.d_setObjectState('I', 0, 0)
def exitInitial(self):
if self.index == 0:
self.unstash()
def enterFree(self):
DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI.enterFree(self)
self.avoidHelmet = 0

View file

@ -1,15 +1,59 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.safezone.DistributedTreasureAI import DistributedTreasureAI
from toontown.safezone import DistributedTreasureAI
from toontown.safezone import TreasureGlobals
class DistributedCashbotBossTreasureAI(DistributedTreasureAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedCashbotBossTreasureAI")
class DistributedCashbotBossTreasureAI(DistributedTreasureAI.DistributedTreasureAI):
def setGoonId(self, todo0):
pass
def __init__(self, air, boss, goon, style, fx, fy, fz):
pos = goon.getPos()
type = TreasureGlobals.SafeZoneTreasureSpawns[style][0]
DistributedTreasureAI.DistributedTreasureAI.__init__(self, air, boss, type, pos[0], pos[1], 0)
self.goonId = goon.doId
self.style = style
self.finalPosition = (fx, fy, fz)
def validAvatar(self, av):
# Avatars can only heal if they are missing some health, but aren't sad.
if av.getHp() < av.getMaxHp() and av.getHp() > 0:
av.toonUp(self.healAmount)
return True
else:
return False
def setFinalPosition(self, todo0, todo1, todo2):
pass
def getGoonId(self):
return self.goonId
def setStyle(self, todo0):
pass
def setGoonId(self, goonId):
self.goonId = goonId
def b_setGoonId(self, goonId):
self.setGoonId(goonId)
self.d_setGoonId(goonId)
def d_setGoonId(self, goonId):
self.sendUpdate('setGoonId', [goonId])
def getStyle(self):
return self.style
def setStyle(self, hoodId):
self.style = hoodId
def b_setStyle(self, hoodId):
self.setStyle(hoodId)
self.d_setStyle(hoodId)
def d_setStyle(self, hoodId):
self.sendUpdate('setStyle', [hoodId])
def getFinalPosition(self):
return self.finalPosition
def setFinalPosition(self, x, y, z):
self.finalPosition = (x, y, z)
def b_setFinalPosition(self, x, y, z):
self.setFinalPosition(x, y, z)
self.d_setFinalPosition(x, y, z)
def d_setFinalPosition(self, x, y, z):
self.sendUpdate('setFinalPosition', [x, y, z])

View file

@ -1,18 +1,71 @@
from direct.distributed import DistributedObjectAI
from otp.level import DistributedLevelAI
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.toonbase import ToontownGlobals
from toontown.coghq import MintLayout, DistributedMintRoomAI
from toontown.coghq import BattleExperienceAggregatorAI
class DistributedMintAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedMintAI")
class DistributedMintAI(DistributedObjectAI.DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMintAI')
def setZoneId(self, todo0):
pass
def __init__(self, air, mintId, zoneId, floorNum, avIds):
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
self.mintId = mintId
self.zoneId = zoneId
self.floorNum = floorNum
self.avIds = avIds
def setMintId(self, todo0):
pass
def generate(self):
DistributedObjectAI.DistributedObjectAI.generate(self)
self.notify.info('generate %s, id=%s, floor=%s' % (self.doId, self.mintId, self.floorNum))
self.layout = MintLayout.MintLayout(self.mintId, self.floorNum)
self.rooms = []
self.battleExpAggreg = BattleExperienceAggregatorAI.BattleExperienceAggregatorAI()
for i in range(self.layout.getNumRooms()):
room = DistributedMintRoomAI.DistributedMintRoomAI(self.air, self.mintId, self.doId, self.zoneId, self.layout.getRoomId(i), i * 2, self.avIds, self.battleExpAggreg)
room.generateWithRequired(self.zoneId)
self.rooms.append(room)
def setFloorNum(self, todo0):
pass
roomDoIds = []
for room in self.rooms:
roomDoIds.append(room.doId)
def setRoomDoIds(self, todo0):
pass
self.sendUpdate('setRoomDoIds', [roomDoIds])
if __dev__:
simbase.mint = self
description = '%s|%s|%s' % (self.mintId, self.floorNum, self.avIds)
for avId in self.avIds:
self.air.writeServerEvent('mintEntered', avId, description)
def requestDelete(self):
self.notify.info('requestDelete: %s' % self.doId)
for room in self.rooms:
room.requestDelete()
DistributedObjectAI.DistributedObjectAI.requestDelete(self)
def delete(self):
self.notify.info('delete: %s' % self.doId)
if __dev__:
if hasattr(simbase, 'mint') and simbase.mint is self:
del simbase.mint
del self.rooms
del self.layout
del self.battleExpAggreg
DistributedObjectAI.DistributedObjectAI.delete(self)
def getTaskZoneId(self):
return self.mintId
def allToonsGone(self):
self.notify.info('allToonsGone')
self.requestDelete()
def getZoneId(self):
return self.zoneId
def getMintId(self):
return self.mintId
def getFloorNum(self):
return self.floorNum

View file

@ -5,6 +5,7 @@ from toontown.coghq import DistributedLevelBattle
from direct.directnotify import DirectNotifyGlobal
from toontown.toon import TTEmote
from otp.avatar import Emote
from otp.nametag import NametagGlobals
from toontown.battle import SuitBattleGlobals
import random
from toontown.suit import SuitDNA

View file

@ -1,6 +1,60 @@
from toontown.toonbase import ToontownGlobals
from toontown.coghq import DistributedLevelBattleAI
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from direct.fsm import State
from direct.fsm import ClassicFSM, State
from toontown.battle.BattleBase import *
import CogDisguiseGlobals
from toontown.toonbase.ToontownBattleGlobals import getMintCreditMultiplier
from direct.showbase.PythonUtil import addListsByValue
class DistributedMintBattleAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedMintBattleAI")
class DistributedMintBattleAI(DistributedLevelBattleAI.DistributedLevelBattleAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMintBattleAI')
def __init__(self, air, battleMgr, pos, suit, toonId, zoneId, level, battleCellId, roundCallback = None, finishCallback = None, maxSuits = 4):
DistributedLevelBattleAI.DistributedLevelBattleAI.__init__(self, air, battleMgr, pos, suit, toonId, zoneId, level, battleCellId, 'MintReward', roundCallback, finishCallback, maxSuits)
self.battleCalc.setSkillCreditMultiplier(1)
if self.bossBattle:
self.level.d_setBossConfronted(toonId)
self.fsm.addState(State.State('MintReward', self.enterMintReward, self.exitMintReward, ['Resume']))
playMovieState = self.fsm.getStateNamed('PlayMovie')
playMovieState.addTransition('MintReward')
def getTaskZoneId(self):
return self.level.mintId
def handleToonsWon(self, toons):
extraMerits = [0,
0,
0,
0]
amount = ToontownGlobals.MintCogBuckRewards[self.level.mintId]
index = ToontownGlobals.cogHQZoneId2deptIndex(self.level.mintId)
extraMerits[index] = amount
for toon in toons:
recovered, notRecovered = self.air.questManager.recoverItems(toon, self.suitsKilled, self.getTaskZoneId())
self.toonItems[toon.doId][0].extend(recovered)
self.toonItems[toon.doId][1].extend(notRecovered)
meritArray = self.air.promotionMgr.recoverMerits(toon, self.suitsKilled, self.getTaskZoneId(), getMintCreditMultiplier(self.getTaskZoneId()), extraMerits=extraMerits)
if toon.doId in self.helpfulToons:
self.toonMerits[toon.doId] = addListsByValue(self.toonMerits[toon.doId], meritArray)
else:
self.notify.debug('toon %d not helpful list, skipping merits' % toon.doId)
def enterMintReward(self):
self.joinableFsm.request('Unjoinable')
self.runableFsm.request('Unrunable')
self.resetResponses()
self.assignRewards()
self.bossDefeated = 1
self.level.setVictors(self.activeToons[:])
self.timer.startCallback(BUILDING_REWARD_TIMEOUT, self.serverRewardDone)
return None
def exitMintReward(self):
return None
def enterResume(self):
DistributedLevelBattleAI.DistributedLevelBattleAI.enterResume(self)
if self.bossBattle and self.bossDefeated:
self.battleMgr.level.b_setDefeated()

View file

@ -1,15 +1,57 @@
from direct.directnotify import DirectNotifyGlobal
from toontown.building.DistributedElevatorExtAI import DistributedElevatorExtAI
from otp.ai.AIBase import *
from toontown.toonbase import ToontownGlobals
from direct.distributed.ClockDelta import *
from toontown.building.ElevatorConstants import *
from toontown.building import DistributedElevatorExtAI
from direct.fsm import ClassicFSM
from direct.fsm import State
from direct.task import Task
import CogDisguiseGlobals
class DistributedMintElevatorExtAI(DistributedElevatorExtAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedMintElevatorExtAI")
class DistributedMintElevatorExtAI(DistributedElevatorExtAI.DistributedElevatorExtAI):
def setMintId(self, todo0):
pass
def __init__(self, air, bldg, mintId, entranceId, antiShuffle = 0, minLaff = 0):
DistributedElevatorExtAI.DistributedElevatorExtAI.__init__(self, air, bldg, antiShuffle=antiShuffle, minLaff=minLaff)
self.mintId = mintId
self.cogDept = ToontownGlobals.cogHQZoneId2deptIndex(self.mintId)
self.type = ELEVATOR_MINT
self.countdownTime = ElevatorData[self.type]['countdown']
def setMintInteriorZone(self, todo0):
pass
def getMintId(self):
return self.mintId
def setMintInteriorZoneForce(self, todo0):
pass
def avIsOKToBoard(self, av):
if not DistributedElevatorExtAI.DistributedElevatorExtAI.avIsOKToBoard(self, av):
return False
return True
def elevatorClosed(self):
numPlayers = self.countFullSeats()
if numPlayers > 0:
players = []
for i in self.seats:
if i not in [None, 0]:
players.append(i)
mintZone = self.bldg.createMint(self.mintId, players)
for seatIndex in range(len(self.seats)):
avId = self.seats[seatIndex]
if avId:
self.sendUpdateToAvatarId(avId, 'setMintInteriorZone', [mintZone])
self.clearFullNow(seatIndex)
else:
self.notify.warning('The elevator left, but was empty.')
self.fsm.request('closed')
return
def enterClosed(self):
DistributedElevatorExtAI.DistributedElevatorExtAI.enterClosed(self)
self.fsm.request('opening')
def sendAvatarsToDestination(self, avIdList):
if len(avIdList) > 0:
mintZone = self.bldg.createMint(self.mintId, avIdList)
for avId in avIdList:
if avId:
self.sendUpdateToAvatarId(avId, 'setMintInteriorZoneForce', [mintZone])

View file

@ -1,24 +1,137 @@
from otp.level import DistributedLevelAI, LevelSpec
from direct.directnotify import DirectNotifyGlobal
from otp.level.DistributedLevelAI import DistributedLevelAI
from direct.task import Task
from otp.level import LevelSpec
from toontown.toonbase import ToontownGlobals, ToontownBattleGlobals
from toontown.coghq import FactoryEntityCreatorAI, MintRoomSpecs
from toontown.coghq import MintRoomBase, LevelSuitPlannerAI
from toontown.coghq import DistributedMintBattleAI
from toontown.suit import DistributedMintSuitAI
class DistributedMintRoomAI(DistributedLevelAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedMintRoomAI")
class DistributedMintRoomAI(DistributedLevelAI.DistributedLevelAI, MintRoomBase.MintRoomBase):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMintRoomAI')
def setMintId(self, todo0):
pass
def __init__(self, air, mintId, mintDoId, zoneId, roomId, roomNum, avIds, battleExpAggreg):
DistributedLevelAI.DistributedLevelAI.__init__(self, air, zoneId, 0, avIds)
MintRoomBase.MintRoomBase.__init__(self)
self.setMintId(mintId)
self.setRoomId(roomId)
self.roomNum = roomNum
self.mintDoId = mintDoId
self.battleExpAggreg = battleExpAggreg
def setRoomId(self, todo0):
pass
def createEntityCreator(self):
return FactoryEntityCreatorAI.FactoryEntityCreatorAI(level=self)
def setRoomNum(self, todo0):
pass
def getBattleCreditMultiplier(self):
return ToontownBattleGlobals.getMintCreditMultiplier(self.mintId)
def setSuits(self, todo0, todo1):
pass
def generate(self):
self.notify.debug('generate %s: room=%s' % (self.doId, self.roomId))
self.notify.debug('loading spec')
specModule = MintRoomSpecs.getMintRoomSpecModule(self.roomId)
roomSpec = LevelSpec.LevelSpec(specModule)
if __dev__:
self.notify.debug('creating entity type registry')
typeReg = self.getMintEntityTypeReg()
roomSpec.setEntityTypeReg(typeReg)
self.notify.debug('creating entities')
DistributedLevelAI.DistributedLevelAI.generate(self, roomSpec)
self.notify.debug('creating cogs')
cogSpecModule = MintRoomSpecs.getCogSpecModule(self.roomId)
self.planner = LevelSuitPlannerAI.LevelSuitPlannerAI(self.air, self, DistributedMintSuitAI.DistributedMintSuitAI, DistributedMintBattleAI.DistributedMintBattleAI, cogSpecModule.CogData, cogSpecModule.ReserveCogData, cogSpecModule.BattleCells, battleExpAggreg=self.battleExpAggreg)
suitHandles = self.planner.genSuits()
messenger.send('plannerCreated-' + str(self.doId))
self.suits = suitHandles['activeSuits']
self.reserveSuits = suitHandles['reserveSuits']
self.d_setSuits()
self.notify.debug('finish mint room %s %s creation' % (self.roomId, self.doId))
def setBossConfronted(self, todo0):
pass
def delete(self):
self.notify.debug('delete: %s' % self.doId)
suits = self.suits
for reserve in self.reserveSuits:
suits.append(reserve[0])
self.planner.destroy()
del self.planner
for suit in suits:
if not suit.isDeleted():
suit.factoryIsGoingDown()
suit.requestDelete()
del self.battleExpAggreg
DistributedLevelAI.DistributedLevelAI.delete(self, deAllocZone=False)
def getMintId(self):
return self.mintId
def getRoomId(self):
return self.roomId
def getRoomNum(self):
return self.roomNum
def getCogLevel(self):
return self.cogLevel
def d_setSuits(self):
self.sendUpdate('setSuits', [self.getSuits(), self.getReserveSuits()])
def getSuits(self):
suitIds = []
for suit in self.suits:
suitIds.append(suit.doId)
return suitIds
def getReserveSuits(self):
suitIds = []
for suit in self.reserveSuits:
suitIds.append(suit[0].doId)
return suitIds
def d_setBossConfronted(self, toonId):
if toonId not in self.avIdList:
self.notify.warning('d_setBossConfronted: %s not in list of participants' % toonId)
return
self.sendUpdate('setBossConfronted', [toonId])
def setVictors(self, victorIds):
activeVictors = []
activeVictorIds = []
for victorId in victorIds:
toon = self.air.doId2do.get(victorId)
if toon is not None:
activeVictors.append(toon)
activeVictorIds.append(victorId)
description = '%s|%s' % (self.mintId, activeVictorIds)
for avId in activeVictorIds:
self.air.writeServerEvent('mintDefeated', avId, description)
for toon in activeVictors:
simbase.air.questManager.toonDefeatedMint(toon, self.mintId, activeVictors)
return
def b_setDefeated(self):
self.d_setDefeated()
self.setDefeated()
def d_setDefeated(self):
self.sendUpdate('setDefeated')
def setDefeated(self):
pass
def allToonsGone(self, toonsThatCleared):
DistributedLevelAI.DistributedLevelAI.allToonsGone(self, toonsThatCleared)
if self.roomNum == 0:
mint = simbase.air.doId2do.get(self.mintDoId)
if mint is not None:
mint.allToonsGone()
else:
self.notify.warning('no mint %s in allToonsGone' % self.mintDoId)
return

View file

@ -5,6 +5,7 @@ from direct.fsm import State
from direct.showbase import BulletinBoardWatcher
from pandac.PandaModules import *
from otp.distributed.TelemetryLimiter import RotationLimitToH, TLGatherAllAvs
from otp.nametag import NametagGlobals
from toontown.toon import Toon
from toontown.toonbase import ToontownGlobals
from toontown.hood import ZoneUtil

View file

@ -0,0 +1,52 @@
from CogHoodAI import CogHoodAI
from toontown.toonbase import ToontownGlobals
from toontown.suit.DistributedCashbotBossAI import DistributedCashbotBossAI
from toontown.coghq.DistributedMintElevatorExtAI import DistributedMintElevatorExtAI
from toontown.building.DistributedCFOElevatorAI import DistributedCFOElevatorAI
from toontown.coghq.DistributedCogHQDoorAI import DistributedCogHQDoorAI
from toontown.building import DoorTypes
from toontown.building import FADoorCodes
class CashbotHQAI(CogHoodAI):
HOOD = ToontownGlobals.CashbotHQ
def __init__(self, air):
CogHoodAI.__init__(self, air)
self.createZone()
def createDoor(self):
interiorDoor = DistributedCogHQDoorAI(self.air, 0, DoorTypes.INT_COGHQ, self.HOOD, doorIndex=0)
exteriorDoor = DistributedCogHQDoorAI(self.air, 0, DoorTypes.EXT_COGHQ, ToontownGlobals.CashbotLobby, doorIndex=0, lockValue=FADoorCodes.CB_DISGUISE_INCOMPLETE)
exteriorDoor.setOtherDoor(interiorDoor)
exteriorDoor.zoneId = self.HOOD
exteriorDoor.generateWithRequired(self.HOOD)
exteriorDoor.sendUpdate('setDoorIndex', [0])
self.doors.append(exteriorDoor)
interiorDoor.setOtherDoor(exteriorDoor)
interiorDoor.zoneId = ToontownGlobals.CashbotLobby
interiorDoor.generateWithRequired(ToontownGlobals.CashbotLobby)
interiorDoor.sendUpdate('setDoorIndex', [0])
self.doors.append(interiorDoor)
def createZone(self):
CogHoodAI.createZone(self)
# Create lobby manager...
self.createLobbyManager(DistributedCashbotBossAI, ToontownGlobals.CashbotLobby)
# Create VP elevator.
self.createElevator(DistributedCFOElevatorAI, self.lobbyMgr, ToontownGlobals.CashbotLobby, ToontownGlobals.CashbotLobby, boss=True)
# Make our doors.
self.createDoor()
# Create Suit Planners in the cog playground and factory waiting area.
self.createSuitPlanner(self.HOOD)
# Create factory elevators.
mins = ToontownGlobals.FactoryLaffMinimums[1]
self.createElevator(DistributedMintElevatorExtAI, self.air.mintMgr, self.HOOD, ToontownGlobals.CashbotMintIntA, 0, minLaff=mins[0])
self.createElevator(DistributedMintElevatorExtAI, self.air.mintMgr, self.HOOD, ToontownGlobals.CashbotMintIntB, 1, minLaff=mins[1])
self.createElevator(DistributedMintElevatorExtAI, self.air.mintMgr, self.HOOD, ToontownGlobals.CashbotMintIntC, 2, minLaff=mins[2])

View file

@ -50,4 +50,4 @@ class SellbotHQAI(CogHoodAI):
# Create factory elevators.
mins = ToontownGlobals.FactoryLaffMinimums[0]
self.createElevator(DistributedFactoryElevatorExtAI, self.air.factoryMgr, ToontownGlobals.SellbotFactoryExt, ToontownGlobals.SellbotFactoryInt, 0, minLaff=mins[0])
self.createElevator(DistributedFactoryElevatorExtAI, self.air.factoryMgr, ToontownGlobals.SellbotFactoryExt, ToontownGlobals.SellbotFactoryInt, 1, minLaff=mins[0])
self.createElevator(DistributedFactoryElevatorExtAI, self.air.factoryMgr, ToontownGlobals.SellbotFactoryExt, ToontownGlobals.SellbotFactoryInt, 1, minLaff=mins[1])

View file

@ -19,6 +19,9 @@ from toontown.distributed import DelayDelete
from toontown.chat import ResistanceChat
from toontown.coghq import CogDisguiseGlobals
from pandac.PandaModules import *
from otp.nametag import NametagGroup
from otp.nametag.NametagConstants import *
from otp.nametag import NametagGlobals
import random
import math
OneBossCog = None
@ -69,7 +72,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
gravity = LinearVectorForce(0, 0, -32)
fn.addForce(gravity)
self.physicsMgr.addLinearForce(gravity)
localAvatar.chatMgr.chatInputSpeedChat.addCFOMenu()
#base.localAvatar.chatMgr.chatInputSpeedChat.addCFOMenu()
global OneBossCog
if OneBossCog != None:
self.notify.warning('Multiple BossCogs visible.')
@ -310,12 +313,12 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
rToon = self.resistanceToon
rToon.setPosHpr(*ToontownGlobals.CashbotRTBattleOneStartPosHpr)
track = Sequence(
Func(camera.setPosHpr, 82, -219, 5, 267, 0, 0),
Func(base.camera.setPosHpr, 82, -219, 5, 267, 0, 0),
Func(rToon.setChatAbsolute, TTL.ResistanceToonWelcome, CFSpeech),
Wait(3),
Sequence(goonTrack, duration=0),
Parallel(
camera.posHprInterval(4, Point3(108, -244, 4), VBase3(211.5, 0, 0)),
base.camera.posHprInterval(4, Point3(108, -244, 4), VBase3(211.5, 0, 0)),
Sequence(
Func(rToon.suit.setPlayRate, 1.4, 'walk'),
Func(rToon.suit.loop, 'walk'),
@ -329,8 +332,8 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
self.door2.posInterval(3, VBase3(0, 0, 30)))),
Func(rToon.setHpr, 0, 0, 0),
Func(rToon.setChatAbsolute, TTL.ResistanceToonTooLate, CFSpeech),
Func(camera.reparentTo, render),
Func(camera.setPosHpr, 61.1, -228.8, 10.2, -90, 0, 0),
Func(base.camera.reparentTo, render),
Func(base.camera.setPosHpr, 61.1, -228.8, 10.2, -90, 0, 0),
self.door1.posInterval(2, VBase3(0, 0, 30)),
Parallel(
bossTrack,
@ -339,7 +342,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
Func(rToon.clearChat),
self.door1.posInterval(3, VBase3(0, 0, 0)))),
Func(self.setChatAbsolute, TTL.CashbotBossDiscoverToons1, CFSpeech),
camera.posHprInterval(1.5, Point3(93.3, -230, 0.7), VBase3(-92.9, 39.7, 8.3)),
base.camera.posHprInterval(1.5, Point3(93.3, -230, 0.7), VBase3(-92.9, 39.7, 8.3)),
Func(self.setChatAbsolute, TTL.CashbotBossDiscoverToons2, CFSpeech),
Wait(4),
Func(self.clearChat),
@ -363,11 +366,11 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
self.toonNormalEyes(self.involvedToons),
self.toonNormalEyes([self.resistanceToon], True),
Func(rToon.clearChat),
Func(camera.setPosHpr, 93.3, -230, 0.7, -92.9, 39.7, 8.3),
Func(base.camera.setPosHpr, 93.3, -230, 0.7, -92.9, 39.7, 8.3),
Func(self.setChatAbsolute, attackToons, CFSpeech),
Wait(2),
Func(self.clearChat))
return Sequence(Func(camera.reparentTo, render), track)
return Sequence(Func(base.camera.reparentTo, render), track)
def __makeGoonMovieForBattleThree(self):
goonPosHprs = [[Point3(111, -287, 0),
@ -427,16 +430,16 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
self.door3.posInterval(4.5, VBase3(0, 0, 30)),
bossTrack),
Func(rToon.loop, 'leverNeutral'),
Func(camera.reparentTo, self.geom),
Func(camera.setPosHpr, 105, -326, 5, 136.3, 0, 0),
Func(base.camera.reparentTo, self.geom),
Func(base.camera.setPosHpr, 105, -326, 5, 136.3, 0, 0),
Func(rToon.setChatAbsolute, TTL.ResistanceToonWatchThis, CFSpeech),
Wait(2),
Func(rToon.clearChat),
Func(camera.setPosHpr, 105, -326, 20, -45.3, 11, 0),
Func(base.camera.setPosHpr, 105, -326, 20, -45.3, 11, 0),
Func(self.setChatAbsolute, TTL.CashbotBossGetAwayFromThat, CFSpeech),
Wait(2),
Func(self.clearChat),
camera.posHprInterval(1.5, Point3(105, -326, 5), Point3(136.3, 0, 0), blendType='easeInOut'),
base.camera.posHprInterval(1.5, Point3(105, -326, 5), Point3(136.3, 0, 0), blendType='easeInOut'),
Func(rToon.setChatAbsolute, TTL.ResistanceToonCraneInstructions1, CFSpeech),
Wait(4),
Func(rToon.setChatAbsolute, TTL.ResistanceToonCraneInstructions2, CFSpeech),
@ -446,15 +449,15 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
Func(rToon.setChatAbsolute, TTL.ResistanceToonCraneInstructions4, CFSpeech),
Wait(4),
Func(rToon.clearChat),
Func(camera.setPosHpr, 102, -323.6, 0.9, -10.6, 14, 0),
Func(base.camera.setPosHpr, 102, -323.6, 0.9, -10.6, 14, 0),
Func(goon.request, 'Recovery'),
Wait(2),
Func(camera.setPosHpr, 95.4, -332.6, 4.2, 167.1, -13.2, 0),
Func(base.camera.setPosHpr, 95.4, -332.6, 4.2, 167.1, -13.2, 0),
Func(rToon.setChatAbsolute, TTL.ResistanceToonGetaway, CFSpeech),
Func(rToon.animFSM.request, 'jump'),
Wait(1.8),
Func(rToon.clearChat),
Func(camera.setPosHpr, 109.1, -300.7, 13.9, -15.6, -13.6, 0),
Func(base.camera.setPosHpr, 109.1, -300.7, 13.9, -15.6, -13.6, 0),
Func(rToon.animFSM.request, 'run'),
Func(goon.request, 'Walk'),
Parallel(
@ -466,7 +469,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
Func(self.getGeomNode().setH, 0),
self.moveToonsToBattleThreePos(self.involvedToons),
Func(self.__showToons))
return Sequence(Func(camera.reparentTo, self), Func(camera.setPosHpr, 0, -27, 25, 0, -18, 0), track)
return Sequence(Func(base.camera.reparentTo, self), Func(base.camera.setPosHpr, 0, -27, 25, 0, -18, 0), track)
def moveToonsToBattleThreePos(self, toons):
track = Parallel()
@ -509,8 +512,8 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
(14 * g, car1.posInterval(0.5, Point3(0, -242, 0), startPos=Point3(150, -242, 0))))
bossTrack = Track(
(0.0, Sequence(
Func(camera.reparentTo, render),
Func(camera.setPosHpr, 105, -280, 20, -158, -3, 0),
Func(base.camera.reparentTo, render),
Func(base.camera.setPosHpr, 105, -280, 20, -158, -3, 0),
Func(self.reparentTo, render),
Func(self.show),
Func(self.clearChat),
@ -520,7 +523,7 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
ActorInterval(self, 'Fb_down2Up'))),
(1.0, Func(self.setChatAbsolute, hadEnough, CFSpeech)),
(5.5, Parallel(
Func(camera.setPosHpr, 100, -315, 16, -20, 0, 0),
Func(base.camera.setPosHpr, 100, -315, 16, -20, 0, 0),
Func(self.hideBattleThreeObjects),
Func(self.forwardHead),
Func(self.loop, 'Ff_neutral'),
@ -862,9 +865,9 @@ class DistributedCashbotBoss(DistributedBossCog.DistributedBossCog, FSM.FSM):
self.resistanceToon.setPosHpr(*ToontownGlobals.CashbotBossBattleThreePosHpr)
self.resistanceToon.loop('neutral')
self.__arrangeToonsAroundResistanceToon()
camera.reparentTo(render)
camera.setPos(self.resistanceToon, -9, 12, 6)
camera.lookAt(self.resistanceToon, 0, 0, 3)
base.camera.reparentTo(render)
base.camera.setPos(self.resistanceToon, -9, 12, 6)
base.camera.lookAt(self.resistanceToon, 0, 0, 3)
intervalName = 'EpilogueMovie'
text = ResistanceChat.getChatText(self.rewardId)
menuIndex, itemIndex = ResistanceChat.decodeId(self.rewardId)

View file

@ -1,18 +1,484 @@
from pandac.PandaModules import *
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from toontown.toonbase import ToontownGlobals
from toontown.coghq import DistributedCashbotBossCraneAI
from toontown.coghq import DistributedCashbotBossSafeAI
from toontown.suit import DistributedCashbotBossGoonAI
from toontown.coghq import DistributedCashbotBossTreasureAI
from toontown.battle import BattleExperienceAI
from toontown.chat import ResistanceChat
from direct.fsm import FSM
import DistributedBossCogAI
import SuitDNA
import random
import math
class DistributedCashbotBossAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedCashbotBossAI")
class DistributedCashbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FSM):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCashbotBossAI')
maxGoons = 8
def setState(self, todo0):
pass
def __init__(self, air):
DistributedBossCogAI.DistributedBossCogAI.__init__(self, air, 'm')
FSM.FSM.__init__(self, 'DistributedCashbotBossAI')
self.cranes = None
self.safes = None
self.goons = None
self.treasures = {}
self.grabbingTreasures = {}
self.recycledTreasures = []
self.healAmount = 0
self.rewardId = ResistanceChat.getRandomId()
self.rewardedToons = []
self.scene = NodePath('scene')
self.reparentTo(self.scene)
cn = CollisionNode('walls')
cs = CollisionSphere(0, 0, 0, 13)
cn.addSolid(cs)
cs = CollisionInvSphere(0, 0, 0, 42)
cn.addSolid(cs)
self.attachNewNode(cn)
self.heldObject = None
self.waitingForHelmet = 0
self.avatarHelmets = {}
self.bossMaxDamage = ToontownGlobals.CashbotBossMaxDamage
return
def setBossDamage(self, todo0):
pass
def generate(self):
DistributedBossCogAI.DistributedBossCogAI.generate(self)
if __dev__:
self.scene.reparentTo(self.getRender())
def setRewardId(self, todo0):
pass
def getHoodId(self):
return ToontownGlobals.CashbotHQ
def formatReward(self):
return str(self.rewardId)
def makeBattleOneBattles(self):
self.postBattleState = 'PrepareBattleThree'
self.initializeBattles(1, ToontownGlobals.CashbotBossBattleOnePosHpr)
def generateSuits(self, battleNumber):
cogs = self.invokeSuitPlanner(11, 0)
skelecogs = self.invokeSuitPlanner(12, 1)
activeSuits = cogs['activeSuits'] + skelecogs['activeSuits']
reserveSuits = cogs['reserveSuits'] + skelecogs['reserveSuits']
random.shuffle(activeSuits)
while len(activeSuits) > 4:
suit = activeSuits.pop()
reserveSuits.append((suit, 100))
def compareJoinChance(a, b):
return cmp(a[1], b[1])
reserveSuits.sort(compareJoinChance)
return {'activeSuits': activeSuits,
'reserveSuits': reserveSuits}
def removeToon(self, avId):
if self.cranes != None:
for crane in self.cranes:
crane.removeToon(avId)
if self.safes != None:
for safe in self.safes:
safe.removeToon(avId)
if self.goons != None:
for goon in self.goons:
goon.removeToon(avId)
DistributedBossCogAI.DistributedBossCogAI.removeToon(self, avId)
return
def __makeBattleThreeObjects(self):
if self.cranes == None:
self.cranes = []
for index in range(len(ToontownGlobals.CashbotBossCranePosHprs)):
crane = DistributedCashbotBossCraneAI.DistributedCashbotBossCraneAI(self.air, self, index)
crane.generateWithRequired(self.zoneId)
self.cranes.append(crane)
if self.safes == None:
self.safes = []
for index in range(len(ToontownGlobals.CashbotBossSafePosHprs)):
safe = DistributedCashbotBossSafeAI.DistributedCashbotBossSafeAI(self.air, self, index)
safe.generateWithRequired(self.zoneId)
self.safes.append(safe)
if self.goons == None:
self.goons = []
return
def __resetBattleThreeObjects(self):
if self.cranes != None:
for crane in self.cranes:
crane.request('Free')
if self.safes != None:
for safe in self.safes:
safe.request('Initial')
return
def __deleteBattleThreeObjects(self):
if self.cranes != None:
for crane in self.cranes:
crane.request('Off')
crane.requestDelete()
self.cranes = None
if self.safes != None:
for safe in self.safes:
safe.request('Off')
safe.requestDelete()
self.safes = None
if self.goons != None:
for goon in self.goons:
goon.request('Off')
goon.requestDelete()
self.goons = None
return
def doNextAttack(self, task):
self.__doDirectedAttack()
if self.heldObject == None and not self.waitingForHelmet:
self.waitForNextHelmet()
return
def __doDirectedAttack(self):
if self.toonsToAttack:
toonId = self.toonsToAttack.pop(0)
while toonId not in self.involvedToons:
if not self.toonsToAttack:
self.b_setAttackCode(ToontownGlobals.BossCogNoAttack)
return
toonId = self.toonsToAttack.pop(0)
self.toonsToAttack.append(toonId)
self.b_setAttackCode(ToontownGlobals.BossCogSlowDirectedAttack, toonId)
def reprieveToon(self, avId):
if avId in self.toonsToAttack:
i = self.toonsToAttack.index(avId)
del self.toonsToAttack[i]
self.toonsToAttack.append(avId)
def makeTreasure(self, goon):
if self.state != 'BattleThree':
return
pos = goon.getPos(self)
v = Vec3(pos[0], pos[1], 0.0)
if not v.normalize():
v = Vec3(1, 0, 0)
v = v * 27
angle = random.uniform(0.0, 2.0 * math.pi)
radius = 10
dx = radius * math.cos(angle)
dy = radius * math.sin(angle)
fpos = self.scene.getRelativePoint(self, Point3(v[0] + dx, v[1] + dy, 0))
if goon.strength <= 10:
style = ToontownGlobals.ToontownCentral
healAmount = 3
elif goon.strength <= 15:
style = random.choice([ToontownGlobals.DonaldsDock, ToontownGlobals.DaisyGardens, ToontownGlobals.MinniesMelodyland])
healAmount = 10
else:
style = random.choice([ToontownGlobals.TheBrrrgh, ToontownGlobals.DonaldsDreamland])
healAmount = 12
if self.recycledTreasures:
treasure = self.recycledTreasures.pop(0)
treasure.d_setGrab(0)
treasure.b_setGoonId(goon.doId)
treasure.b_setStyle(style)
treasure.b_setPosition(pos[0], pos[1], 0)
treasure.b_setFinalPosition(fpos[0], fpos[1], 0)
else:
treasure = DistributedCashbotBossTreasureAI.DistributedCashbotBossTreasureAI(self.air, self, goon, style, fpos[0], fpos[1], 0)
treasure.generateWithRequired(self.zoneId)
treasure.healAmount = healAmount
self.treasures[treasure.doId] = treasure
def grabAttempt(self, avId, treasureId):
av = self.air.doId2do.get(avId)
if not av:
return
treasure = self.treasures.get(treasureId)
if treasure:
if treasure.validAvatar(av):
del self.treasures[treasureId]
treasure.d_setGrab(avId)
self.grabbingTreasures[treasureId] = treasure
taskMgr.doMethodLater(5, self.__recycleTreasure, treasure.uniqueName('recycleTreasure'), extraArgs=[treasure])
else:
treasure.d_setReject()
def __recycleTreasure(self, treasure):
if self.grabbingTreasures.has_key(treasure.doId):
del self.grabbingTreasures[treasure.doId]
self.recycledTreasures.append(treasure)
def deleteAllTreasures(self):
for treasure in self.treasures.values():
treasure.requestDelete()
self.treasures = {}
for treasure in self.grabbingTreasures.values():
taskMgr.remove(treasure.uniqueName('recycleTreasure'))
treasure.requestDelete()
self.grabbingTreasures = {}
for treasure in self.recycledTreasures:
treasure.requestDelete()
self.recycledTreasures = []
def getMaxGoons(self):
t = self.getBattleThreeTime()
if t <= 1.0:
return self.maxGoons
elif t <= 1.1:
return self.maxGoons + 1
elif t <= 1.2:
return self.maxGoons + 2
elif t <= 1.3:
return self.maxGoons + 3
elif t <= 1.4:
return self.maxGoons + 4
else:
return self.maxGoons + 8
def makeGoon(self, side = None):
if side == None:
side = random.choice(['EmergeA', 'EmergeB'])
goon = self.__chooseOldGoon()
if goon == None:
if len(self.goons) >= self.getMaxGoons():
return
goon = DistributedCashbotBossGoonAI.DistributedCashbotBossGoonAI(self.air, self)
goon.generateWithRequired(self.zoneId)
self.goons.append(goon)
if self.getBattleThreeTime() > 1.0:
goon.STUN_TIME = 4
goon.b_setupGoon(velocity=8, hFov=90, attackRadius=20, strength=30, scale=1.8)
else:
goon.STUN_TIME = self.progressValue(30, 8)
goon.b_setupGoon(velocity=self.progressRandomValue(3, 7), hFov=self.progressRandomValue(70, 80), attackRadius=self.progressRandomValue(6, 15), strength=int(self.progressRandomValue(5, 25)), scale=self.progressRandomValue(0.5, 1.5))
goon.request(side)
return
def __chooseOldGoon(self):
for goon in self.goons:
if goon.state == 'Off':
return goon
def waitForNextGoon(self, delayTime):
currState = self.getCurrentOrNextState()
if currState == 'BattleThree':
taskName = self.uniqueName('NextGoon')
taskMgr.remove(taskName)
taskMgr.doMethodLater(delayTime, self.doNextGoon, taskName)
def stopGoons(self):
taskName = self.uniqueName('NextGoon')
taskMgr.remove(taskName)
def doNextGoon(self, task):
if self.attackCode != ToontownGlobals.BossCogDizzy:
self.makeGoon()
delayTime = self.progressValue(10, 2)
self.waitForNextGoon(delayTime)
def waitForNextHelmet(self):
currState = self.getCurrentOrNextState()
if currState == 'BattleThree':
taskName = self.uniqueName('NextHelmet')
taskMgr.remove(taskName)
delayTime = self.progressValue(45, 15)
taskMgr.doMethodLater(delayTime, self.__donHelmet, taskName)
self.waitingForHelmet = 1
def __donHelmet(self, task):
self.waitingForHelmet = 0
if self.heldObject == None:
safe = self.safes[0]
safe.request('Grabbed', self.doId, self.doId)
self.heldObject = safe
return
def stopHelmets(self):
self.waitingForHelmet = 0
taskName = self.uniqueName('NextHelmet')
taskMgr.remove(taskName)
def acceptHelmetFrom(self, avId):
now = globalClock.getFrameTime()
then = self.avatarHelmets.get(avId, None)
if then == None or now - then > 300:
self.avatarHelmets[avId] = now
return 1
return 0
def magicWordHit(self, damage, avId):
if self.heldObject:
self.heldObject.demand('Dropped', avId, self.doId)
self.heldObject.avoidHelmet = 1
self.heldObject = None
self.waitForNextHelmet()
else:
self.recordHit(damage)
return
def magicWordReset(self):
if self.state == 'BattleThree':
self.__resetBattleThreeObjects()
def magicWordResetGoons(self):
if self.state == 'BattleThree':
if self.goons != None:
for goon in self.goons:
goon.request('Off')
goon.requestDelete()
self.goons = None
self.__makeBattleThreeObjects()
return
def recordHit(self, damage):
avId = self.air.getAvatarIdFromSender()
if not self.validate(avId, avId in self.involvedToons, 'recordHit from unknown avatar'):
return
if self.state != 'BattleThree':
return
self.b_setBossDamage(self.bossDamage + damage)
if self.bossDamage >= self.bossMaxDamage:
self.b_setState('Victory')
elif self.attackCode != ToontownGlobals.BossCogDizzy:
if damage >= ToontownGlobals.CashbotBossKnockoutDamage:
self.b_setAttackCode(ToontownGlobals.BossCogDizzy)
self.stopHelmets()
else:
self.b_setAttackCode(ToontownGlobals.BossCogNoAttack)
self.stopHelmets()
self.waitForNextHelmet()
def b_setBossDamage(self, bossDamage):
self.d_setBossDamage(bossDamage)
self.setBossDamage(bossDamage)
def setBossDamage(self, bossDamage):
self.reportToonHealth()
self.bossDamage = bossDamage
def d_setBossDamage(self, bossDamage):
self.sendUpdate('setBossDamage', [bossDamage])
def d_setRewardId(self, rewardId):
self.sendUpdate('setRewardId', [rewardId])
def applyReward(self):
pass
avId = self.air.getAvatarIdFromSender()
if avId in self.involvedToons and avId not in self.rewardedToons:
self.rewardedToons.append(avId)
toon = self.air.doId2do.get(avId)
if toon:
toon.doResistanceEffect(self.rewardId)
def enterOff(self):
DistributedBossCogAI.DistributedBossCogAI.enterOff(self)
self.rewardedToons = []
def exitOff(self):
DistributedBossCogAI.DistributedBossCogAI.exitOff(self)
def enterIntroduction(self):
DistributedBossCogAI.DistributedBossCogAI.enterIntroduction(self)
self.__makeBattleThreeObjects()
self.__resetBattleThreeObjects()
def exitIntroduction(self):
DistributedBossCogAI.DistributedBossCogAI.exitIntroduction(self)
self.__deleteBattleThreeObjects()
def enterPrepareBattleThree(self):
self.resetBattles()
self.__makeBattleThreeObjects()
self.__resetBattleThreeObjects()
self.barrier = self.beginBarrier('PrepareBattleThree', self.involvedToons, 55, self.__donePrepareBattleThree)
def __donePrepareBattleThree(self, avIds):
self.b_setState('BattleThree')
def exitPrepareBattleThree(self):
if self.newState != 'BattleThree':
self.__deleteBattleThreeObjects()
self.ignoreBarrier(self.barrier)
def enterBattleThree(self):
self.setPosHpr(*ToontownGlobals.CashbotBossBattleThreePosHpr)
self.__makeBattleThreeObjects()
self.__resetBattleThreeObjects()
self.reportToonHealth()
self.toonsToAttack = self.involvedToons[:]
random.shuffle(self.toonsToAttack)
self.b_setBossDamage(0)
self.battleThreeStart = globalClock.getFrameTime()
self.resetBattles()
self.waitForNextAttack(15)
self.waitForNextHelmet()
self.makeGoon(side='EmergeA')
self.makeGoon(side='EmergeB')
taskName = self.uniqueName('NextGoon')
taskMgr.remove(taskName)
taskMgr.doMethodLater(2, self.__doInitialGoons, taskName)
def __doInitialGoons(self, task):
self.makeGoon(side='EmergeA')
self.makeGoon(side='EmergeB')
self.waitForNextGoon(10)
def exitBattleThree(self):
helmetName = self.uniqueName('helmet')
taskMgr.remove(helmetName)
if self.newState != 'Victory':
self.__deleteBattleThreeObjects()
self.deleteAllTreasures()
self.stopAttacks()
self.stopGoons()
self.stopHelmets()
self.heldObject = None
return
def enterVictory(self):
self.resetBattles()
self.suitsKilled.append({'type': None,
'level': None,
'track': self.dna.dept,
'isSkelecog': 0,
'isForeman': 0,
'isVP': 0,
'isCFO': 1,
'isSupervisor': 0,
'isVirtual': 0,
'activeToons': self.involvedToons[:]})
self.barrier = self.beginBarrier('Victory', self.involvedToons, 30, self.__doneVictory)
return
def __doneVictory(self, avIds):
self.d_setBattleExperience()
self.b_setState('Reward')
BattleExperienceAI.assignRewards(self.involvedToons, self.toonSkillPtsGained, self.suitsKilled, ToontownGlobals.dept2cogHQ(self.dept), self.helpfulToons)
for toonId in self.involvedToons:
toon = self.air.doId2do.get(toonId)
if toon:
toon.addResistanceMessage(self.rewardId)
toon.b_promote(self.deptIndex)
def exitVictory(self):
self.__deleteBattleThreeObjects()
def enterEpilogue(self):
DistributedBossCogAI.DistributedBossCogAI.enterEpilogue(self)
self.d_setRewardId(self.rewardId)

View file

@ -1,33 +1,304 @@
from direct.directnotify import DirectNotifyGlobal
from direct.distributed.DistributedObjectAI import DistributedObjectAI
from pandac.PandaModules import *
from direct.task.TaskManagerGlobal import *
from direct.distributed.ClockDelta import *
from direct.interval.IntervalGlobal import *
import GoonGlobals
from direct.task.Task import Task
from toontown.toonbase import ToontownGlobals
from otp.otpbase import OTPGlobals
from toontown.coghq import DistributedCashbotBossObjectAI
from direct.showbase import PythonUtil
import DistributedGoonAI
import math
import random
class DistributedCashbotBossGoonAI(DistributedObjectAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedCashbotBossGoonAI")
class DistributedCashbotBossGoonAI(DistributedGoonAI.DistributedGoonAI, DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI):
legLength = 10
directionTable = [(0, 15),
(10, 10),
(-10, 10),
(20, 8),
(-20, 8),
(40, 5),
(-40, 5),
(60, 4),
(-60, 4),
(80, 3),
(-80, 3),
(120, 2),
(-120, 2),
(180, 1)]
offMask = BitMask32(0)
onMask = CollisionNode.getDefaultCollideMask()
def requestBattle(self, todo0):
pass
def __init__(self, air, boss):
DistributedGoonAI.DistributedGoonAI.__init__(self, air, 0)
DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI.__init__(self, air, boss)
cn = CollisionNode('tubeNode')
self.tube = CollisionTube(0, 0, 0, 0, 0, 0, 2)
cn.addSolid(self.tube)
self.tubeNode = cn
self.tubeNodePath = self.attachNewNode(self.tubeNode)
self.feelers = []
cn = CollisionNode('feelerNode')
self.feelerLength = self.legLength * 1.5
feelerStart = 1
for heading, weight in self.directionTable:
rad = deg2Rad(heading)
x = -math.sin(rad)
y = math.cos(rad)
seg = CollisionSegment(x * feelerStart, y * feelerStart, 0, x * self.feelerLength, y * self.feelerLength, 0)
cn.addSolid(seg)
self.feelers.append(seg)
def requestStunned(self, todo0):
pass
cn.setIntoCollideMask(self.offMask)
self.feelerNodePath = self.attachNewNode(cn)
self.isWalking = 0
self.cTrav = CollisionTraverser('goon')
self.cQueue = CollisionHandlerQueue()
self.cTrav.addCollider(self.feelerNodePath, self.cQueue)
def setVelocity(self, todo0):
pass
def requestBattle(self, pauseTime):
avId = self.air.getAvatarIdFromSender()
avatar = self.air.doId2do.get(avId)
if avatar:
self.boss.damageToon(avatar, self.strength)
DistributedGoonAI.DistributedGoonAI.requestBattle(self, pauseTime)
def setHFov(self, todo0):
pass
def sendMovie(self, type, avId = 0, pauseTime = 0):
if type == GoonGlobals.GOON_MOVIE_WALK:
self.demand('Walk')
elif type == GoonGlobals.GOON_MOVIE_BATTLE:
self.demand('Battle')
elif type == GoonGlobals.GOON_MOVIE_STUNNED:
self.demand('Stunned')
elif type == GoonGlobals.GOON_MOVIE_RECOVERY:
self.demand('Recovery')
else:
self.notify.warning('Ignoring movie type %s' % type)
def setAttackRadius(self, todo0):
pass
def __chooseTarget(self, extraDelay = 0):
direction = self.__chooseDirection()
if direction == None:
self.target = None
self.arrivalTime = None
self.b_destroyGoon()
return
heading, dist = direction
dist = min(dist, self.legLength)
targetH = PythonUtil.reduceAngle(self.getH() + heading)
origH = self.getH()
h = PythonUtil.fitDestAngle2Src(origH, targetH)
delta = abs(h - origH)
turnTime = delta / (self.velocity * 5)
walkTime = dist / self.velocity
self.setH(targetH)
self.target = self.boss.scene.getRelativePoint(self, Point3(0, dist, 0))
self.departureTime = globalClock.getFrameTime()
self.arrivalTime = self.departureTime + turnTime + walkTime + extraDelay
self.d_setTarget(self.target[0], self.target[1], h, globalClockDelta.localToNetworkTime(self.arrivalTime))
return
def setStrength(self, todo0):
pass
def __chooseDirection(self):
self.tubeNode.setIntoCollideMask(self.offMask)
self.cTrav.traverse(self.boss.scene)
self.tubeNode.setIntoCollideMask(self.onMask)
entries = {}
self.cQueue.sortEntries()
for i in range(self.cQueue.getNumEntries() - 1, -1, -1):
entry = self.cQueue.getEntry(i)
dist = Vec3(entry.getSurfacePoint(self)).length()
if dist < 1.2:
dist = 0
entries[entry.getFrom()] = dist
def setGoonScale(self, todo0):
pass
netScore = 0
scoreTable = []
for i in range(len(self.directionTable)):
heading, weight = self.directionTable[i]
seg = self.feelers[i]
dist = entries.get(seg, self.feelerLength)
score = dist * weight
netScore += score
scoreTable.append(score)
def setTarget(self, todo0, todo1, todo2, todo3):
pass
if netScore == 0:
self.notify.info('Could not find a path for %s' % self.doId)
return None
s = random.uniform(0, netScore)
for i in range(len(self.directionTable)):
s -= scoreTable[i]
if s <= 0:
heading, weight = self.directionTable[i]
seg = self.feelers[i]
dist = entries.get(seg, self.feelerLength)
return (heading, dist)
self.notify.warning('Fell off end of weighted table.')
return (0, self.legLength)
def __startWalk(self):
if self.arrivalTime == None:
return
now = globalClock.getFrameTime()
availableTime = self.arrivalTime - now
if availableTime > 0:
point = self.getRelativePoint(self.boss.scene, self.target)
self.tube.setPointB(point)
self.node().resetPrevTransform()
taskMgr.doMethodLater(availableTime, self.__reachedTarget, self.uniqueName('reachedTarget'))
self.isWalking = 1
else:
self.__reachedTarget(None)
return
def __stopWalk(self, pauseTime = None):
if self.isWalking:
taskMgr.remove(self.uniqueName('reachedTarget'))
if pauseTime == None:
now = globalClock.getFrameTime()
t = (now - self.departureTime) / (self.arrivalTime - self.departureTime)
else:
t = pauseTime / (self.arrivalTime - self.departureTime)
t = min(t, 1.0)
pos = self.getPos()
self.setPos(pos + (self.target - pos) * t)
self.tube.setPointB(0, 0, 0)
self.isWalking = 0
return
def __reachedTarget(self, task):
self.__stopWalk()
self.__chooseTarget()
self.__startWalk()
def __recoverWalk(self, task):
self.demand('Walk')
return Task.done
def doFree(self, task):
DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI.doFree(self, task)
self.demand('Walk')
return Task.done
def requestStunned(self, pauseTime):
avId = self.air.getAvatarIdFromSender()
if avId not in self.boss.involvedToons:
return
if self.state == 'Stunned' or self.state == 'Grabbed':
return
self.__stopWalk(pauseTime)
self.boss.makeTreasure(self)
DistributedGoonAI.DistributedGoonAI.requestStunned(self, pauseTime)
def hitBoss(self, impact):
avId = self.air.getAvatarIdFromSender()
self.validate(avId, impact <= 1.0, 'invalid hitBoss impact %s' % impact)
if avId not in self.boss.involvedToons:
return
if self.state == 'Dropped' or self.state == 'Grabbed':
if not self.boss.heldObject:
damage = int(impact * 25 * self.scale)
self.boss.recordHit(max(damage, 2))
self.b_destroyGoon()
def d_setTarget(self, x, y, h, arrivalTime):
self.sendUpdate('setTarget', [x,
y,
h,
arrivalTime])
def d_destroyGoon(self):
self.sendUpdate('destroyGoon')
def b_destroyGoon(self):
self.d_destroyGoon()
self.destroyGoon()
def destroyGoon(self):
pass
self.demand('Off')
def enterOff(self):
self.tubeNodePath.stash()
self.feelerNodePath.stash()
def exitOff(self):
self.tubeNodePath.unstash()
self.feelerNodePath.unstash()
def enterGrabbed(self, avId, craneId):
DistributedCashbotBossObjectAI.DistributedCashbotBossObjectAI.enterGrabbed(self, avId, craneId)
taskMgr.remove(self.taskName('recovery'))
taskMgr.remove(self.taskName('resumeWalk'))
def enterWalk(self):
self.avId = 0
self.craneId = 0
self.__chooseTarget()
self.__startWalk()
self.d_setObjectState('W', 0, 0)
def exitWalk(self):
self.__stopWalk()
def enterEmergeA(self):
self.avId = 0
self.craneId = 0
h = 0
dist = 15
pos = self.boss.getPos()
walkTime = dist / self.velocity
self.setPosHpr(pos[0], pos[1], pos[2], h, 0, 0)
self.d_setPosHpr(pos[0], pos[1], pos[2], h, 0, 0)
self.target = self.boss.scene.getRelativePoint(self, Point3(0, dist, 0))
self.departureTime = globalClock.getFrameTime()
self.arrivalTime = self.departureTime + walkTime
self.d_setTarget(self.target[0], self.target[1], h, globalClockDelta.localToNetworkTime(self.arrivalTime))
self.__startWalk()
self.d_setObjectState('a', 0, 0)
taskMgr.doMethodLater(walkTime, self.__recoverWalk, self.uniqueName('recoverWalk'))
def exitEmergeA(self):
self.__stopWalk()
taskMgr.remove(self.uniqueName('recoverWalk'))
def enterEmergeB(self):
self.avId = 0
self.craneId = 0
h = 180
dist = 15
pos = self.boss.getPos()
walkTime = dist / self.velocity
self.setPosHpr(pos[0], pos[1], pos[2], h, 0, 0)
self.d_setPosHpr(pos[0], pos[1], pos[2], h, 0, 0)
self.target = self.boss.scene.getRelativePoint(self, Point3(0, dist, 0))
self.departureTime = globalClock.getFrameTime()
self.arrivalTime = self.departureTime + walkTime
self.d_setTarget(self.target[0], self.target[1], h, globalClockDelta.localToNetworkTime(self.arrivalTime))
self.__startWalk()
self.d_setObjectState('b', 0, 0)
taskMgr.doMethodLater(walkTime, self.__recoverWalk, self.uniqueName('recoverWalk'))
def exitEmergeB(self):
self.__stopWalk()
taskMgr.remove(self.uniqueName('recoverWalk'))
def enterBattle(self):
self.d_setObjectState('B', 0, 0)
def exitBattle(self):
taskMgr.remove(self.taskName('resumeWalk'))
def enterStunned(self):
self.d_setObjectState('S', 0, 0)
def exitStunned(self):
taskMgr.remove(self.taskName('recovery'))
def enterRecovery(self):
self.d_setObjectState('R', 0, 0)
taskMgr.doMethodLater(2.0, self.__recoverWalk, self.uniqueName('recoverWalk'))
def exitRecovery(self):
self.__stopWalk()
taskMgr.remove(self.uniqueName('recoverWalk'))

View file

@ -1,6 +1,14 @@
from toontown.suit import DistributedFactorySuitAI
from direct.directnotify import DirectNotifyGlobal
from toontown.suit.DistributedFactorySuitAI import DistributedFactorySuitAI
class DistributedMintSuitAI(DistributedFactorySuitAI):
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedMintSuitAI")
class DistributedMintSuitAI(DistributedFactorySuitAI.DistributedFactorySuitAI):
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMintSuitAI')
def isForeman(self):
return 0
def isSupervisor(self):
return self.boss
def isVirtual(self):
return 0