2019-11-02 17:27:54 -05:00
import copy
import random
from direct . directnotify import DirectNotifyGlobal
from direct . distributed import DistributedObjectAI
from direct . distributed . ClockDelta import *
from direct . fsm import ClassicFSM , State
from direct . task import Timer
from toontown . toon import NPCToons
from otp . ai . AIBaseGlobal import *
from toontown . ai import ToonBarrier
from toontown . battle import BattleBase
from toontown . cogdominium import DistributedCogdoBattleBldgAI
from toontown . building . ElevatorConstants import *
from toontown . suit . SuitDNA import SuitDNA
from toontown . toonbase . ToontownBattleGlobals import *
from toontown . hood import ZoneUtil
from toontown . minigame . MinigameGlobals import SafeZones
from toontown . toon import NPCToons
2019-12-30 00:07:56 -06:00
from . DistributedCogdoElevatorIntAI import DistributedCogdoElevatorIntAI
2019-11-02 17:27:54 -05:00
from toontown . cogdominium import CogdoBarrelRoomConsts
from toontown . cogdominium import CogdoBarrelRoomAI
2019-12-30 00:07:56 -06:00
from . DistCogdoBoardroomGameAI import DistCogdoBoardroomGameAI
2019-11-02 17:27:54 -05:00
from toontown . cogdominium . DistCogdoCraneGameAI import DistCogdoCraneGameAI
from toontown . cogdominium . DistCogdoMazeGameAI import DistCogdoMazeGameAI
from toontown . cogdominium . DistCogdoFlyingGameAI import DistCogdoFlyingGameAI
from toontown . cogdominium import CogdoGameConsts
CogdoGames = {
' boardroom ' : DistCogdoBoardroomGameAI ,
' crane ' : DistCogdoCraneGameAI ,
' maze ' : DistCogdoMazeGameAI ,
' flying ' : DistCogdoFlyingGameAI }
IntGames = set ( [
' boardroom ' ,
' crane ' ,
' flying ' ,
' defense ' ] )
simbase . forcedCogdoGame = config . GetString ( ' cogdo-game ' , ' ' )
GameRequests = { }
class DistributedCogdoInteriorAI ( DistributedObjectAI . DistributedObjectAI ) :
def __init__ ( self , air , elevator ) :
self . air = air
DistributedObjectAI . DistributedObjectAI . __init__ ( self , air )
( self . extZoneId , self . zoneId ) = elevator . bldg . getExteriorAndInteriorZoneId ( )
self . _numFloors = elevator . bldg . planner . numFloors
self . layout = elevator . bldg . _cogdoLayout
self . avatarExitEvents = [ ]
self . toons = [ ]
self . toonSkillPtsGained = { }
self . toonExp = { }
self . toonOrigQuests = { }
self . toonItems = { }
self . toonOrigMerits = { }
self . toonMerits = { }
self . toonParts = { }
self . helpfulToons = [ ]
self . shopOwnerNpcId = 0
npcDesc = NPCToons . zone2NpcDict . get ( self . zoneId )
if npcDesc :
self . shopOwnerNpcId = npcDesc [ 0 ]
if not self . shopOwnerNpcId :
self . notify . warning ( ' No npcs found for current cogdo building ' )
self . currentFloor = 0
self . bldg = elevator . bldg
self . elevator = elevator
self . _game = None
self . _CogdoGameRepeat = config . GetBool ( ' cogdo-game-repeat ' , 0 )
self . suits = [ ]
self . activeSuits = [ ]
self . reserveSuits = [ ]
self . joinedReserves = [ ]
self . suitsKilled = [ ]
self . suitsKilledPerFloor = [ ]
self . battle = None
self . timer = Timer . Timer ( )
self . _wantBarrelRoom = config . GetBool ( ' cogdo-want-barrel-room ' , 0 )
self . barrelRoom = None
self . responses = { }
self . ignoreResponses = 0
self . ignoreElevatorDone = 0
self . ignoreReserveJoinDone = 0
self . toonIds = copy . copy ( elevator . seats )
for toonId in self . toonIds :
if toonId != None :
self . __addToon ( toonId )
self . savedByMap = { }
self . fsm = ClassicFSM . ClassicFSM ( ' DistributedCogdoInteriorAI ' , [
State . State ( ' WaitForAllToonsInside ' , self . enterWaitForAllToonsInside , self . exitWaitForAllToonsInside , [
' Elevator ' ] ) ,
State . State ( ' Elevator ' , self . enterElevator , self . exitElevator , [
' Game ' ] ) ,
State . State ( ' Game ' , self . enterGame , self . exitGame , [
' Resting ' ,
' Failed ' ,
' BattleIntro ' ,
' Off ' ] ) ,
State . State ( ' BarrelRoomIntro ' , self . enterBarrelRoomIntro , self . exitBarrelRoomIntro , [
' CollectBarrels ' ,
' Off ' ] ) ,
State . State ( ' CollectBarrels ' , self . enterCollectBarrels , self . exitCollectBarrels , [
' BarrelRoomReward ' ,
' Off ' ] ) ,
State . State ( ' BarrelRoomReward ' , self . enterBarrelRoomReward , self . exitBarrelRoomReward , [
' Battle ' ,
' ReservesJoining ' ,
' BattleIntro ' ,
' Off ' ] ) ,
State . State ( ' BattleIntro ' , self . enterBattleIntro , self . exitBattleIntro , [
' Battle ' ,
' ReservesJoining ' ,
' Off ' ] ) ,
State . State ( ' Battle ' , self . enterBattle , self . exitBattle , [
' ReservesJoining ' ,
' BattleDone ' ,
' Off ' ] ) ,
State . State ( ' ReservesJoining ' , self . enterReservesJoining , self . exitReservesJoining , [
' Battle ' ,
' Off ' ] ) ,
State . State ( ' BattleDone ' , self . enterBattleDone , self . exitBattleDone , [
' Resting ' ,
' Reward ' ,
' Off ' ] ) ,
State . State ( ' Resting ' , self . enterResting , self . exitResting , [
' Elevator ' ,
' Off ' ] ) ,
State . State ( ' Reward ' , self . enterReward , self . exitReward , [
' Off ' ] ) ,
State . State ( ' Failed ' , self . enterFailed , self . exitFailed , [
' Off ' ] ) ,
State . State ( ' Off ' , self . enterOff , self . exitOff , [
' WaitForAllToonsInside ' ] ) ] , ' Off ' , ' Off ' , onUndefTransition = ClassicFSM . ClassicFSM . ALLOW )
self . fsm . enterInitialState ( )
safeZone = ZoneUtil . getCanonicalHoodId ( self . extZoneId )
difficulty = SafeZones . index ( safeZone )
self . SOSCard = self . chooseSOSCard ( difficulty )
def generateWithRequired ( self , zoneId ) :
self . _disCleanupTask = None
self . _sadCleanupTask = None
DistributedObjectAI . DistributedObjectAI . generateWithRequired ( self , zoneId )
def delete ( self ) :
self . ignoreAll ( )
self . toons = [ ]
self . toonIds = [ ]
self . fsm . requestFinalState ( )
del self . fsm
del self . bldg
del self . elevator
self . timer . stop ( )
del self . timer
self . _cogdoLayout = None
self . __cleanupFloorBattle ( )
if self . barrelRoom :
self . barrelRoom . destroy ( )
self . barrelRoom = None
taskName = self . taskName ( ' deleteInterior ' )
taskMgr . remove ( taskName )
if self . _disCleanupTask :
taskMgr . remove ( self . _disCleanupTask )
if self . _sadCleanupTask :
taskMgr . remove ( self . _sadCleanupTask )
DistributedObjectAI . DistributedObjectAI . delete ( self )
def requestDelete ( self ) :
if self . _game :
self . _game . requestDelete ( )
DistributedObjectAI . DistributedObjectAI . requestDelete ( self )
def getShopOwnerNpcId ( self ) :
return self . shopOwnerNpcId
def getSOSNpcId ( self ) :
return self . SOSCard
def __handleUnexpectedExit ( self , toonId ) :
self . notify . warning ( ' toon: %d exited unexpectedly ' % toonId )
self . __removeToon ( toonId )
if self . _game :
self . _game . handleToonDisconnected ( toonId )
if len ( self . toons ) == 0 :
self . timer . stop ( )
if self . fsm . getCurrentState ( ) . getName ( ) == ' Resting ' :
pass
elif self . battle == None :
self . fsm . requestFinalState ( )
self . _disCleanupTask = taskMgr . doMethodLater ( 20 , self . _cleanupAfterLastToonWentDis , self . uniqueName ( ' discleanup ' ) )
def _cleanupAfterLastToonWentDis ( self , task ) :
self . _disCleanupTask = None
self . bldg . deleteCogdoInterior ( )
return task . done
def _handleToonWentSad ( self , toonId ) :
self . notify . info ( ' toon: %d went sad ' % toonId )
self . __removeToon ( toonId )
toon = self . air . getDo ( toonId )
if toon :
self . ignore ( toon . getGoneSadMessage ( ) )
if self . _game :
self . _game . handleToonWentSad ( toonId )
if len ( self . toons ) == 0 :
self . timer . stop ( )
if self . fsm . getCurrentState ( ) . getName ( ) == ' Resting ' :
pass
elif self . battle == None :
self . _sadCleanupTask = taskMgr . doMethodLater ( 20 , self . _cleanupAfterLastToonWentSad , self . uniqueName ( ' sadcleanup ' ) )
def _cleanupAfterLastToonWentSad ( self , task ) :
self . _sadCleanupTask = None
self . bldg . deleteCogdoInterior ( )
return task . done
def __addToon ( self , toonId ) :
2019-12-30 00:07:56 -06:00
if toonId not in self . air . doId2do :
2019-11-02 17:27:54 -05:00
self . notify . warning ( ' addToon() - no toon for doId: %d ' % toonId )
return
event = self . air . getAvatarExitEvent ( toonId )
self . avatarExitEvents . append ( event )
self . accept ( event , self . __handleUnexpectedExit , extraArgs = [
toonId ] )
self . toons . append ( toonId )
self . responses [ toonId ] = 0
def __removeToon ( self , toonId ) :
if self . toons . count ( toonId ) :
self . toons . remove ( toonId )
if self . toonIds . count ( toonId ) :
self . toonIds [ self . toonIds . index ( toonId ) ] = None
2019-12-30 00:07:56 -06:00
if toonId in self . responses :
2019-11-02 17:27:54 -05:00
del self . responses [ toonId ]
event = self . air . getAvatarExitEvent ( toonId )
if self . avatarExitEvents . count ( event ) :
self . avatarExitEvents . remove ( event )
self . ignore ( event )
def __resetResponses ( self ) :
self . responses = { }
for toon in self . toons :
self . responses [ toon ] = 0
self . ignoreResponses = 0
def __allToonsResponded ( self ) :
for toon in self . toons :
if self . responses [ toon ] == 0 :
return 0
self . ignoreResponses = 1
return 1
def getZoneId ( self ) :
return self . zoneId
def getExtZoneId ( self ) :
return self . extZoneId
def getDistBldgDoId ( self ) :
return self . bldg . getDoId ( )
def getNumFloors ( self ) :
return self . _numFloors
def d_setToons ( self ) :
self . sendUpdate ( ' setToons ' , self . getToons ( ) )
def getToons ( self ) :
sendIds = [ ]
for toonId in self . toonIds :
if toonId == None :
sendIds . append ( 0 )
else :
sendIds . append ( toonId )
return [
sendIds ,
0 ]
def getDroneCogDNA ( self ) :
dna = SuitDNA ( )
dna . newSuitRandom ( level = 2 )
return dna
def d_setSuits ( self ) :
self . sendUpdate ( ' setSuits ' , self . getSuits ( ) )
def getSuits ( self ) :
suitIds = [ ]
for suit in self . activeSuits :
suitIds . append ( suit . doId )
reserveIds = [ ]
values = [ ]
for info in self . reserveSuits :
reserveIds . append ( info [ 0 ] . doId )
values . append ( info [ 1 ] )
return [
suitIds ,
reserveIds ,
values ]
def b_setState ( self , state ) :
self . d_setState ( state )
self . setState ( state )
def d_setState ( self , state ) :
stime = globalClock . getRealTime ( ) + BattleBase . SERVER_BUFFER_TIME
self . sendUpdate ( ' setState ' , [
state ,
globalClockDelta . localToNetworkTime ( stime ) ] )
def setState ( self , state ) :
self . fsm . request ( state )
def getState ( self ) :
return [
self . fsm . getCurrentState ( ) . getName ( ) ,
globalClockDelta . getRealNetworkTime ( ) ]
def setAvatarJoined ( self ) :
avId = self . air . getAvatarIdFromSender ( )
if self . toons . count ( avId ) == 0 :
self . air . writeServerEvent ( ' suspicious ' , avId , ' DistributedCogdoInteriorAI.setAvatarJoined from toon not in %s . ' % self . toons )
self . notify . warning ( ' setAvatarJoined() - av: %d not in list ' % avId )
return
if self . fsm . getCurrentState ( ) . getName ( ) != ' WaitForAllToonsInside ' :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.setAvatarJoined: not in wait state ' )
return
avatar = self . air . doId2do . get ( avId )
if avatar == None :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.setAvatarJoined: avatar not present ' )
return
else :
self . savedByMap [ avId ] = ( avatar . getName ( ) , avatar . dna . asTuple ( ) )
if avId not in self . responses :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.setAvatarJoined: avId not in responses ' )
self . notify . warning ( ' CogdoInteriorAI.setAvatarJoined: avId not in responses ' )
return
if self . responses [ avId ] > 0 :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.setAvatarJoined: av already responded ' )
return
self . responses [ avId ] + = 1
if self . __allToonsResponded ( ) :
self . fsm . request ( ' Elevator ' )
def elevatorDone ( self ) :
toonId = self . air . getAvatarIdFromSender ( )
if self . ignoreResponses == 1 :
return
elif self . toons . count ( toonId ) == 0 :
self . air . writeServerEvent ( ' suspicious ' , toonId , ' CogdoInteriorAI.elevatorDone: toon not in participant list ' )
self . notify . warning ( ' elevatorDone() - toon not in toon list: %d ' % toonId )
return
if self . fsm . getCurrentState ( ) . getName ( ) != ' Elevator ' :
self . air . writeServerEvent ( ' suspicious ' , toonId , ' CogdoInteriorAI.elevatorDone: not in Elevator state ' )
return
if toonId not in self . responses :
self . air . writeServerEvent ( ' suspicious ' , toonId , ' CogdoInteriorAI.elevatorDone: toon not in responses ' )
self . notify . warning ( ' CogdoInteriorAI.elevatorDone: avId not in responses ' )
return
self . responses [ toonId ] + = 1
if self . __allToonsResponded ( ) and self . ignoreElevatorDone == 0 :
self . b_setState ( ' Game ' )
def reserveJoinDone ( self ) :
toonId = self . air . getAvatarIdFromSender ( )
if self . ignoreResponses == 1 :
return
elif self . toons . count ( toonId ) == 0 :
self . air . writeServerEvent ( ' suspicious ' , toonId , ' CogdoInteriorAI.reserveJoinDone: toon not in participant list ' )
self . notify . warning ( ' reserveJoinDone() - toon not in list: %d ' % toonId )
return
if self . fsm . getCurrentState ( ) . getName ( ) != ' ReservesJoining ' :
self . air . writeServerEvent ( ' suspicious ' , toonId , ' CogdoInteriorAI.reserveJoinDone: not in ReservesJoining state ' )
return
if toonId not in self . responses :
self . air . writeServerEvent ( ' suspicious ' , toonId , ' CogdoInteriorAI.reserveJoinDone: toon not in responses ' )
self . notify . warning ( ' CogdoInteriorAI.reserveJoinDone: avId not in responses ' )
return
self . responses [ toonId ] + = 1
if self . __allToonsResponded ( ) and self . ignoreReserveJoinDone == 0 :
self . b_setState ( ' Battle ' )
def isBossFloor ( self , floorNum ) :
if self . layout . hasBossBattle ( ) :
if self . layout . getBossBattleFloor ( ) == floorNum :
return True
return False
def isTopFloor ( self , floorNum ) :
return self . layout . getNumFloors ( ) - 1 == floorNum
def enterOff ( self ) :
return None
def exitOff ( self ) :
return None
def enterWaitForAllToonsInside ( self ) :
self . __resetResponses ( )
return None
def exitWaitForAllToonsInside ( self ) :
self . __resetResponses ( )
return None
def enterElevator ( self ) :
if self . isBossFloor ( self . currentFloor ) :
self . _populateFloorSuits ( )
else :
self . d_setToons ( )
self . __resetResponses ( )
if self . _wantBarrelRoom :
if self . barrelRoom :
self . barrelRoom . reset ( )
else :
self . barrelRoom = CogdoBarrelRoomAI . CogdoBarrelRoomAI ( self )
self . _game = self . _createGame ( )
if self . _game :
self . _game . makeVisible ( )
self . d_setState ( ' Elevator ' )
self . timer . startCallback ( BattleBase . ELEVATOR_T + ElevatorData [ ELEVATOR_NORMAL ] [ ' openTime ' ] + BattleBase . SERVER_BUFFER_TIME , self . __serverElevatorDone )
return None
def _createGame ( self ) :
game = None
if not self . isBossFloor ( self . currentFloor ) :
for toonId in self . toonIds :
if toonId :
toon = self . air . getDo ( toonId )
if toon :
self . accept ( toon . getGoneSadMessage ( ) , Functor ( self . _handleToonWentSad , toonId ) )
forcedGame = simbase . forcedCogdoGame
diff = None
pgId = None
for toonId in self . toonIds :
if toonId :
if toonId in GameRequests :
( forcedGame , keep , diff , pgId ) = GameRequests [ toonId ]
if not keep :
GameRequests . pop ( toonId )
if forcedGame :
gameCtor = CogdoGames [ forcedGame ]
else :
name = None
while name is None or name in IntGames :
2019-12-30 00:07:56 -06:00
name = random . choice ( list ( CogdoGames . keys ( ) ) )
2019-11-02 17:27:54 -05:00
gameCtor = CogdoGames [ name ]
game = gameCtor ( self . air , self )
game . setExteriorZone ( self . extZoneId )
game . setDifficultyOverrides ( diff , pgId )
game . generateWithRequired ( self . zoneId )
return game
def __serverElevatorDone ( self ) :
self . ignoreElevatorDone = 1
self . b_setState ( ' Game ' )
def exitElevator ( self ) :
self . timer . stop ( )
self . __resetResponses ( )
return None
def enterGame ( self ) :
self . notify . info ( ' Entering Maze Game ' )
self . _gameScore = None
self . _rewardedLaff = { }
self . _penaltyLaff = { }
self . d_setState ( ' Game ' )
self . elevator . d_setFloor ( self . currentFloor )
if self . _game :
self . _game . start ( )
else :
self . _gameDone ( )
def _populateFloorSuits ( self ) :
suitHandles = self . bldg . planner . genFloorSuits ( self . currentFloor )
self . suits = suitHandles [ ' activeSuits ' ]
self . activeSuits = [ ]
for suit in self . suits :
self . activeSuits . append ( suit )
self . reserveSuits = suitHandles [ ' reserveSuits ' ]
self . d_setToons ( )
self . d_setSuits ( )
def _setGameScore ( self , score ) :
self . _gameScore = score
def getGameScore ( self ) :
return self . _gameScore
def _gameDone ( self ) :
self . __calcLaff ( )
2019-12-30 00:07:56 -06:00
for ( toonId , reward ) in self . _rewardedLaff . items ( ) :
2019-11-02 17:27:54 -05:00
if reward :
av = self . air . doId2do . get ( toonId )
av . toonUp ( reward )
2019-12-30 00:07:56 -06:00
for ( toonId , penalty ) in self . _penaltyLaff . items ( ) :
2019-11-02 17:27:54 -05:00
if penalty :
av = self . air . doId2do . get ( toonId )
if config . GetBool ( ' want-cogdo-maze-no-sad ' , 1 ) :
avHp = av . getHp ( )
if avHp < 1 :
avHp = 1
if penalty > = avHp :
penalty = avHp - 1
if penalty :
av . takeDamage ( penalty , quietly = 0 )
if self . _game and self . _game . wasEnded ( ) :
self . b_setState ( ' Resting ' )
elif self . _game and self . _game . isDoorOpen ( ) :
self . b_setState ( ' Resting ' )
elif self . _game and not self . _game . isDoorOpen ( ) :
self . b_setState ( ' Failed ' )
else :
self . b_setState ( ' BattleIntro ' )
def exitGame ( self ) :
self . sendUpdate ( ' setSOSNpcId ' , [
self . SOSCard ] )
self . sendUpdate ( ' setFOType ' , [
ord ( self . bldg . track ) ] )
def __calcLaff ( self ) :
self . notify . debug ( ' __calcLaff() ' )
self . _rewardedLaff = { }
self . _penaltyLaff = { }
if self . _game :
score = self . getGameScore ( )
if score :
maxToAward = self . _game . getDifficulty ( ) * CogdoGameConsts . LaffRewardRange + CogdoGameConsts . LaffRewardMin
reward = score * maxToAward
for toonId in self . toons :
if self . _game . isToonInDoor ( toonId ) :
self . _rewardedLaff [ toonId ] = reward
if self . _rewardedLaff :
2019-12-30 00:07:56 -06:00
self . air . writeServerEvent ( ' CogdoLaffReward ' , list ( self . _rewardedLaff . keys ( ) ) , ' Awarded %s Laff for difficulty %s and score %s ' % ( reward , self . _game . getDifficulty ( ) , score ) )
2019-11-02 17:27:54 -05:00
penalty = self . _game . getDifficulty ( ) * CogdoGameConsts . LaffPenalty
for toonId in self . toons :
if not self . _game . isToonInDoor ( toonId ) :
self . _penaltyLaff [ toonId ] = penalty
if self . _penaltyLaff :
2019-12-30 00:07:56 -06:00
self . air . writeServerEvent ( ' CogdoLaffPenalty ' , list ( self . _penaltyLaff . keys ( ) ) , ' Penalized %s Laff for difficulty %s (did not reach exit) ' % ( penalty , self . _game . getDifficulty ( ) ) )
2019-11-02 17:27:54 -05:00
def toonBarrelRoomIntroDone ( self ) :
avId = self . air . getAvatarIdFromSender ( )
if self . fsm . getCurrentState ( ) . getName ( ) != ' BarrelRoomIntro ' :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.toonBarrelRoomIntroDone: not in BarrelRoomIntro state ' )
return
if avId not in self . responses :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.toonBarrelRoomIntroDone: unknown avId ' )
return
if hasattr ( self , ' brBarrier ' ) :
self . brBarrier . clear ( avId )
else :
self . notify . warning ( ' toonBarrelRoomIntroDone from %s in invalid state ' % avId )
def __brIntroDone ( self , clearedAvIds = [ ] ) :
self . b_setState ( ' CollectBarrels ' )
def enterBarrelRoomIntro ( self ) :
if not self . _wantBarrelRoom :
pass
if self . _wantBarrelRoom and not self . isBossFloor ( self . currentFloor ) :
self . barrelRoom . setScore ( 1.0 )
self . brBarrier = ToonBarrier . ToonBarrier ( ' waitBrIntroDone ' , self . uniqueName ( ' waitBrIntroDone ' ) , self . toons , CogdoBarrelRoomConsts . BarrelRoomIntroTimeout , doneFunc = self . __brIntroDone )
else :
self . __brIntroDone ( )
def exitBarrelRoomIntro ( self ) :
if hasattr ( self , ' brBarrier ' ) :
self . brBarrier . cleanup ( )
del self . brBarrier
def __endCollectBarrels ( self ) :
if len ( self . toons ) > 0 :
self . notify . info ( ' %d toons in barrel room. ' % len ( self . toons ) )
self . b_setState ( ' BarrelRoomReward ' )
else :
self . notify . warning ( ' 0 toons in barrel room. ' )
self . bldg . deleteCogdoInterior ( )
def toonLeftBarrelRoom ( self ) :
avId = self . air . getAvatarIdFromSender ( )
self . notify . info ( ' avId= %s left the barrel room via teleport ' % avId )
if self . fsm . getCurrentState ( ) . getName ( ) != ' CollectBarrels ' :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.toonLeftBarrelRoom called outside of CollectBarrels state ' )
return
if avId not in self . responses :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.toonLeftBarrelRoom: unknown avId ' )
return
self . __removeToon ( avId )
self . notify . info ( ' %d toon(s) remaining in barrel room. ' % len ( self . toons ) )
if len ( self . toons ) == 0 :
self . notify . warning ( ' 0 toons in barrel room. ' )
self . bldg . deleteCogdoInterior ( )
def enterCollectBarrels ( self ) :
if self . _wantBarrelRoom and not self . isBossFloor ( self . currentFloor ) :
self . acceptOnce ( self . barrelRoom . collectionDoneEvent , self . __endCollectBarrels )
self . barrelRoom . activate ( )
else :
self . __endCollectBarrels ( )
def exitCollectBarrels ( self ) :
if self . barrelRoom :
self . ignore ( self . barrelRoom . collectionDoneEvent )
self . barrelRoom . deactivate ( )
def toonBarrelRoomRewardDone ( self ) :
avId = self . air . getAvatarIdFromSender ( )
if self . fsm . getCurrentState ( ) . getName ( ) != ' BarrelRoomReward ' :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.toonBarrelRoomIntroDone: not in BarrelRoomReward state ' )
return
if avId not in self . responses :
self . air . writeServerEvent ( ' suspicious ' , avId , ' CogdoInteriorAI.toonBarrelRoomRewardDone: unknown avId ' )
return
if hasattr ( self , ' brBarrier ' ) :
self . brBarrier . clear ( avId )
else :
self . notify . warning ( ' toonBarrelRoomRewardDone from %s in invalid state ' % avId )
def __brRewardDone ( self , clearedAvIds = [ ] ) :
if len ( self . toons ) > 0 :
if not self . isBossFloor ( self . currentFloor ) :
self . _populateFloorSuits ( )
self . b_setState ( ' Battle ' )
else :
self . b_setState ( ' BattleIntro ' )
else :
self . notify . warning ( ' 0 toons in barrel room. ' )
self . bldg . deleteCogdoInterior ( )
def enterBarrelRoomReward ( self ) :
if self . _wantBarrelRoom and not self . isBossFloor ( self . currentFloor ) :
self . sendUpdate ( ' setBarrelRoomReward ' , self . barrelRoom . results )
self . brBarrier = ToonBarrier . ToonBarrier ( ' waitBrRewardDone ' , self . uniqueName ( ' waitBrRewardDone ' ) , self . toons , CogdoBarrelRoomConsts . RewardUiTime + 5.0 , doneFunc = self . __brRewardDone )
else :
self . __brRewardDone ( )
def exitBarrelRoomReward ( self ) :
if hasattr ( self , ' brBarrier ' ) :
self . brBarrier . cleanup ( )
del self . brBarrier
def __createFloorBattle ( self ) :
if self . isBossFloor ( self . currentFloor ) :
self . notify . info ( ' %d toon(s) in boss battle ' % len ( self . toons ) )
bossBattle = 1
else :
self . notify . info ( ' %d toon(s) in barrel battle ' % len ( self . toons ) )
bossBattle = 0
self . battle = DistributedCogdoBattleBldgAI . DistributedCogdoBattleBldgAI ( self . air , self . zoneId , self . __handleRoundDone , self . __handleBattleDone , bossBattle = bossBattle )
self . battle . suitsKilled = self . suitsKilled
self . battle . suitsKilledPerFloor = self . suitsKilledPerFloor
self . battle . battleCalc . toonSkillPtsGained = self . toonSkillPtsGained
self . battle . toonExp = self . toonExp
self . battle . toonOrigQuests = self . toonOrigQuests
self . battle . toonItems = self . toonItems
self . battle . toonOrigMerits = self . toonOrigMerits
self . battle . toonMerits = self . toonMerits
self . battle . toonParts = self . toonParts
self . battle . helpfulToons = self . helpfulToons
self . battle . setInitialMembers ( self . toons , self . suits )
self . battle . generateWithRequired ( self . zoneId )
mult = getCreditMultiplier ( self . currentFloor )
if self . air . suitInvasionManager . getInvading ( ) :
mult * = getInvasionMultiplier ( )
self . battle . battleCalc . setSkillCreditMultiplier ( mult )
def __cleanupFloorBattle ( self ) :
for suit in self . suits :
self . notify . debug ( ' cleaning up floor suit: %d ' % suit . doId )
if suit . isDeleted ( ) :
self . notify . debug ( ' whoops, suit %d is deleted. ' % suit . doId )
else :
suit . requestDelete ( )
self . suits = [ ]
self . reserveSuits = [ ]
self . activeSuits = [ ]
if self . battle != None :
self . battle . requestDelete ( )
self . battle = None
def __handleRoundDone ( self , toonIds , totalHp , deadSuits ) :
totalMaxHp = 0
for suit in self . suits :
totalMaxHp + = suit . maxHP
for suit in deadSuits :
self . activeSuits . remove ( suit )
if len ( self . reserveSuits ) > 0 and len ( self . activeSuits ) < 4 :
self . joinedReserves = [ ]
hpPercent = 100 - ( totalHp / totalMaxHp ) * 100.0
for info in self . reserveSuits :
if info [ 1 ] < = hpPercent and len ( self . activeSuits ) < 4 :
self . suits . append ( info [ 0 ] )
self . activeSuits . append ( info [ 0 ] )
self . joinedReserves . append ( info )
for info in self . joinedReserves :
self . reserveSuits . remove ( info )
if len ( self . joinedReserves ) > 0 :
self . fsm . request ( ' ReservesJoining ' )
self . d_setSuits ( )
return
if len ( self . activeSuits ) == 0 :
self . fsm . request ( ' BattleDone ' , [
toonIds ] )
else :
self . battle . resume ( )
def __handleBattleDone ( self , zoneId , toonIds ) :
if len ( toonIds ) == 0 :
self . notify . info ( ' handleBattleDone() - last toon gone ' )
taskName = self . taskName ( ' deleteInterior ' )
taskMgr . doMethodLater ( 10 , self . __doDeleteInterior , taskName )
elif self . isTopFloor ( self . currentFloor ) :
self . setState ( ' Reward ' )
else :
self . b_setState ( ' Resting ' )
def __doDeleteInterior ( self , task ) :
self . bldg . deleteCogdoInterior ( )
def enterBattleIntro ( self ) :
timeLeft = 7.0
self . _battleIntroTaskName = self . taskName ( ' BattleIntro ' )
taskMgr . doMethodLater ( timeLeft , self . _battleIntroDone , self . _battleIntroTaskName )
def _battleIntroDone ( self , task ) :
self . b_setState ( ' Battle ' )
return task . done
def exitBattleIntro ( self ) :
taskMgr . remove ( self . _battleIntroTaskName )
self . _battleIntroTaskName = None
def enterBattle ( self ) :
if self . battle == None :
self . __createFloorBattle ( )
def exitBattle ( self ) :
return None
def enterReservesJoining ( self ) :
self . __resetResponses ( )
self . timer . startCallback ( ElevatorData [ ELEVATOR_NORMAL ] [ ' openTime ' ] + SUIT_HOLD_ELEVATOR_TIME + BattleBase . SERVER_BUFFER_TIME , self . __serverReserveJoinDone )
return None
def __serverReserveJoinDone ( self ) :
self . ignoreReserveJoinDone = 1
self . b_setState ( ' Battle ' )
def exitReservesJoining ( self ) :
self . timer . stop ( )
self . __resetResponses ( )
for info in self . joinedReserves :
self . battle . suitRequestJoin ( info [ 0 ] )
self . battle . resume ( )
self . joinedReserves = [ ]
return None
def enterBattleDone ( self , toonIds ) :
if len ( toonIds ) != len ( self . toons ) :
deadToons = [ ]
for toon in self . toons :
if toonIds . count ( toon ) == 0 :
deadToons . append ( toon )
for toon in deadToons :
self . __removeToon ( toon )
self . d_setToons ( )
if len ( self . toons ) == 0 :
self . bldg . deleteCogdoInterior ( )
elif self . isTopFloor ( self . currentFloor ) :
self . notify . info ( ' %d Toon(s) beat the executive suite building ' % len ( self . toons ) )
self . battle . resume ( self . currentFloor , topFloor = 1 )
else :
self . battle . resume ( self . currentFloor , topFloor = 0 )
return None
def exitBattleDone ( self ) :
self . __cleanupFloorBattle ( )
self . d_setSuits ( )
return None
def __handleEnterElevator ( self ) :
self . fsm . request ( ' Elevator ' )
def enterResting ( self ) :
if self . _game :
self . _game . requestDelete ( )
self . _game = None
for toonId in self . toonIds :
if toonId :
toon = self . air . getDo ( toonId )
if toon :
self . ignore ( toon . getGoneSadMessage ( ) )
self . handleAllAboard ( )
def handleAllAboard ( self , seats = None ) :
if seats == None :
seats = copy . copy ( self . toonIds )
if not hasattr ( self , ' fsm ' ) :
return None
numOfEmptySeats = seats . count ( None )
if numOfEmptySeats == 4 :
self . bldg . deleteCogdoInterior ( )
return None
elif numOfEmptySeats > = 0 and numOfEmptySeats < = 3 :
pass
else :
self . error ( ' Bad number of empty seats: %s ' % numOfEmptySeats )
for toon in self . toons :
if seats . count ( toon ) == 0 :
self . __removeToon ( toon )
self . toonIds = copy . copy ( seats )
self . toons = [ ]
for toonId in self . toonIds :
if toonId != None :
self . toons . append ( toonId )
self . d_setToons ( )
if not self . _CogdoGameRepeat :
self . currentFloor + = 1
self . fsm . request ( ' Elevator ' )
def exitResting ( self ) :
return None
def enterReward ( self ) :
victors = self . toonIds [ : ]
savedBy = [ ]
for v in victors :
tuple = self . savedByMap . get ( v )
if tuple :
savedBy . append ( [
v ,
tuple [ 0 ] ,
tuple [ 1 ] ] )
toon = self . air . doId2do . get ( v )
if toon :
self . notify . info ( ' Reward State: toonId: %d laff: %d / %d get ready for the victors to come outside ' % ( toon . doId , toon . hp , toon . maxHp ) )
if not toon . attemptAddNPCFriend ( self . SOSCard , numCalls = 1 ) :
self . notify . info ( ' %s .unable to add NPCFriend %s to %s . ' % ( self . doId , self . SOSCard , v ) )
self . bldg . fsm . request ( ' waitForVictorsFromCogdo ' , [
victors ,
savedBy ] )
self . d_setState ( ' Reward ' )
return None
def exitReward ( self ) :
return None
def enterFailed ( self ) :
victors = self . toonIds [ : ]
savedBy = [ ]
anyVictors = victors . count ( None ) < 4
if anyVictors :
self . bldg . fsm . request ( ' waitForVictorsFromCogdo ' , [
victors ,
savedBy ] )
def exitFailed ( self ) :
return None
def chooseSOSCard ( self , difficulty ) :
if difficulty < 0 or difficulty > 5 :
return None
if difficulty < = 1 :
card = random . choice ( NPCToons . npcFriendsMinMaxStars ( 0 , 1 ) )
elif difficulty < = 3 :
card = random . choice ( NPCToons . npcFriendsMinMaxStars ( 1 , 1 ) )
else :
card = random . choice ( NPCToons . npcFriendsMinMaxStars ( 2 , 2 ) )
return card