Merge branch 'develop' into friends
This commit is contained in:
commit
607145c425
|
|
@ -791,7 +791,7 @@ class OTPClientRepository(ClientRepositoryBase):
|
|||
def doneWait(task, self = self):
|
||||
self.loginFSM.request('waitForShardList')
|
||||
|
||||
if __dev__:
|
||||
if __debug__:
|
||||
delay = 0.0
|
||||
else:
|
||||
delay = 6.5 + random.random() * 2.0
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class DistributedBattleFinalAI(DistributedBattleBaseAI.DistributedBattleBaseAI):
|
|||
DistributedBattleBaseAI.DistributedBattleBaseAI.__init__(self, air, bossCog.zoneId, finishCallback)
|
||||
self.bossCogId = bossCog.doId
|
||||
self.battleNumber = bossCog.battleNumber
|
||||
self.rewardDuration = bossCog.getEndOfBattleMovieDuration()
|
||||
self.battleSide = battleSide
|
||||
self.streetBattle = 0
|
||||
self.roundCallback = roundCallback
|
||||
|
|
@ -112,7 +113,7 @@ class DistributedBattleFinalAI(DistributedBattleBaseAI.DistributedBattleBaseAI):
|
|||
return None
|
||||
|
||||
def enterReward(self):
|
||||
self.timer.startCallback(FLOOR_REWARD_TIMEOUT + 5, self.serverRewardDone)
|
||||
self.timer.startCallback(FLOOR_REWARD_TIMEOUT + self.rewardDuration, self.serverRewardDone)
|
||||
return None
|
||||
|
||||
def exitReward(self):
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ class CharLonelyStateAI(StateData.StateData):
|
|||
|
||||
class CharChattyStateAI(StateData.StateData):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('CharChattyStateAI')
|
||||
notify.setDebug(True)
|
||||
|
||||
def __init__(self, doneEvent, character):
|
||||
StateData.StateData.__init__(self, doneEvent)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import random
|
||||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import Sequence, Func, Parallel, Wait, LerpHprInterval, LerpScaleInterval, LerpFunctionInterval
|
||||
from otp.otpbase import OTPGlobals
|
||||
from toontown.toonbase import ToontownGlobals
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from direct.interval.IntervalGlobal import LerpFunc, ActorInterval, LerpPosInter
|
|||
from direct.interval.MetaInterval import Sequence
|
||||
from direct.directutil import Mopath
|
||||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from toontown.toonbase import ToontownGlobals
|
||||
from toontown.suit import Suit
|
||||
from toontown.suit import SuitDNA
|
||||
|
|
|
|||
|
|
@ -4,24 +4,23 @@ from direct.directnotify import DirectNotifyGlobal
|
|||
from direct.distributed import ClockDelta
|
||||
from .FireworkShow import FireworkShow
|
||||
from .FireworkShows import getShowDuration
|
||||
import random
|
||||
from direct.task import Task
|
||||
|
||||
class DistributedFireworkShowAI(DistributedObjectAI.DistributedObjectAI):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedFireworkShowAI')
|
||||
|
||||
def __init__(self, air, fireworkMgr = None):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory("DistributedFireworkShowAI")
|
||||
def __init__(self, air, fireworkMgr=None):
|
||||
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
|
||||
self.fireworkMgr = fireworkMgr
|
||||
self.eventId = None
|
||||
self.eventId = None # either a holiday name constant from ToontownGlobals
|
||||
# or a FireworkShows from PartyGlobals
|
||||
self.style = None
|
||||
self.timestamp = None
|
||||
self.throwAwayShow = FireworkShow()
|
||||
return
|
||||
|
||||
def delete(self):
|
||||
del self.throwAwayShow
|
||||
taskMgr.remove(self.taskName('waitForShowDone'))
|
||||
taskMgr.remove(self.taskName("waitForShowDone"))
|
||||
DistributedObjectAI.DistributedObjectAI.delete(self)
|
||||
|
||||
def d_startShow(self, eventId, style):
|
||||
|
|
@ -29,34 +28,39 @@ class DistributedFireworkShowAI(DistributedObjectAI.DistributedObjectAI):
|
|||
self.eventId = eventId
|
||||
self.style = style
|
||||
self.timestamp = timestamp
|
||||
self.sendUpdate('startShow', (self.eventId, self.style, self.timestamp))
|
||||
self.sendUpdate("startShow",
|
||||
(self.eventId, self.style, self.timestamp))
|
||||
if simbase.air.config.GetBool('want-old-fireworks', 0):
|
||||
duration = getShowDuration(self.eventId, self.style)
|
||||
taskMgr.doMethodLater(duration, self.fireworkShowDone, self.taskName('waitForShowDone'))
|
||||
taskMgr.doMethodLater(duration, self.fireworkShowDone, self.taskName("waitForShowDone"))
|
||||
else:
|
||||
|
||||
duration = self.throwAwayShow.getShowDuration(self.eventId)
|
||||
|
||||
assert( DistributedFireworkShowAI.notify.debug("startShow: event: %s, networkTime: %s, showDuration: %s" \
|
||||
% (self.eventId, self.timestamp, duration) ) )
|
||||
|
||||
# Add the start and postShow delays and give ample time for postshow to complete
|
||||
duration += 20.0
|
||||
taskMgr.doMethodLater(duration, self.fireworkShowDone, self.taskName('waitForShowDone'))
|
||||
taskMgr.doMethodLater(duration, self.fireworkShowDone, self.taskName("waitForShowDone"))
|
||||
|
||||
def fireworkShowDone(self, task):
|
||||
self.notify.debug('fireworkShowDone')
|
||||
self.notify.debug("fireworkShowDone")
|
||||
# Tell the firework manager to stop us, we are done
|
||||
if self.fireworkMgr:
|
||||
self.fireworkMgr.stopShow(self.zoneId)
|
||||
return Task.done
|
||||
|
||||
def requestFirework(self, x, y, z, style, color1, color2):
|
||||
avId = self.air.getAvatarIdFromSender()
|
||||
self.notify.debug('requestFirework: avId: %s, style: %s' % (avId, style))
|
||||
self.notify.debug("requestFirework: avId: %s, style: %s" % (avId, style))
|
||||
# TODO: check permissions, check cost, etc
|
||||
if self.fireworkMgr:
|
||||
if self.fireworkMgr.isShowRunning(self.zoneId):
|
||||
self.d_shootFirework(x, y, z, style, color1, color2)
|
||||
# Charge the avId some jellybeans
|
||||
else:
|
||||
self.d_shootFirework(x, y, z, style, color1, color2)
|
||||
self.d_shootFirework(x, y, z, style, color1,color2)
|
||||
|
||||
def d_shootFirework(self, x, y, z, style, color1, color2):
|
||||
self.sendUpdate('shootFirework', (x,
|
||||
y,
|
||||
z,
|
||||
style,
|
||||
color1,
|
||||
color2))
|
||||
self.sendUpdate("shootFirework", (x, y, z, style, color1, color2))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .EffectController import EffectController
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from direct.particles import ParticleEffect
|
|||
from direct.particles import Particles
|
||||
from direct.particles import ForceGroup
|
||||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
import random
|
||||
from .FireworkGlobals import *
|
||||
colors = {WHITE: Vec4(1, 1, 1, 1),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .PooledEffect import PooledEffect
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .EffectController import EffectController
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .EffectController import EffectController
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .EffectController import EffectController
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .EffectController import EffectController
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .PooledEffect import PooledEffect
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .PooledEffect import PooledEffect
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.particles import ParticleEffect, Particles, ForceGroup
|
||||
from .EffectController import EffectController
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ from direct.interval.SoundInterval import SoundInterval
|
|||
|
||||
class VineBat(NodePath, DirectObject):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('VineBat')
|
||||
notify.setDebug(True)
|
||||
RADIUS = 1.7
|
||||
|
||||
def __init__(self, batIndex, timeToTraverseField):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from direct.directnotify import DirectNotifyGlobal
|
||||
from direct.showbase.PythonUtil import list2dict, Enum
|
||||
from enum import IntEnum
|
||||
from toontown.pets import PetTricks
|
||||
import types
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('PetObserve')
|
||||
|
|
@ -16,8 +16,8 @@ def send(zoneIds, petObserve):
|
|||
messenger.send(getEventName(zoneId), [petObserve])
|
||||
|
||||
|
||||
Phrases = Enum('HI, BYE, YES, NO, SOOTHE, PRAISE, CRITICISM, HAPPY,SAD, ANGRY, HURRY, QUESTION, FRIENDLY, LETS_PLAY,COME, FOLLOW_ME, STAY, NEED_LAFF, NEED_GAGS, NEED_JB,GO_AWAY, DO_TRICK,')
|
||||
Actions = Enum('FEED, SCRATCH,ATTENDED_START, ATTENDED_STOP,ATTENDING_START, ATTENDING_STOP,CHANGE_ZONE, LOGOUT,GARDEN')
|
||||
Phrases = IntEnum('Phrases', ('HI', 'BYE', 'YES', 'NO', 'SOOTHE', 'PRAISE', 'CRITICISM', 'HAPPY', 'SAD', 'ANGRY', 'HURRY', 'QUESTION', 'FRIENDLY', 'LETS_PLAY', 'COME', 'FOLLOW_ME', 'STAY', 'NEED_LAFF', 'NEED_GAGS', 'NEED_JB','GO_AWAY', 'DO_TRICK'), start=0)
|
||||
Actions = IntEnum('Actions', ('FEED', 'SCRATCH', 'ATTENDED_START', 'ATTENDED_STOP', 'ATTENDING_START', 'ATTENDING_STOP', 'CHANGE_ZONE', 'LOGOUT', 'GARDEN'), start=0)
|
||||
|
||||
class PetObserve:
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ class PetPhraseObserve(PetObserve):
|
|||
petBrain._handlePhraseObserve(self)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s,%s)' % (self.__class__.__name__, Phrases.getString(self.petPhrase), self.avId)
|
||||
return '%s(%s,%s)' % (self.__class__.__name__, Phrases(self.petPhrase).name, self.avId)
|
||||
|
||||
|
||||
class SCObserve(PetPhraseObserve):
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from direct.distributed.ClockDelta import *
|
|||
from direct.interval.IntervalGlobal import *
|
||||
from direct.gui.DirectGui import *
|
||||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.fsm import FSM
|
||||
from direct.distributed import DistributedSmoothNode
|
||||
from direct.interval.IntervalGlobal import *
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from direct.showbase.PythonUtil import *
|
|||
from direct.showbase.DirectObject import DirectObject
|
||||
from direct.task import Task
|
||||
from panda3d.core import *
|
||||
from panda3d.physics import *
|
||||
from direct.fsm import FSM
|
||||
from direct.distributed import DistributedSmoothNode
|
||||
from otp.avatar import ShadowCaster
|
||||
|
|
|
|||
|
|
@ -13,11 +13,14 @@ import collections, types
|
|||
|
||||
from direct.distributed.ClockDelta import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
from direct.showbase.DirectObject import DirectObject
|
||||
from direct.showbase.PythonUtil import *
|
||||
|
||||
from panda3d.otp import NametagGroup, WhisperPopup
|
||||
|
||||
from otp.otpbase import OTPLocalizer
|
||||
from otp.otpbase import OTPGlobals
|
||||
from otp.otpbase.PythonUtil import *
|
||||
|
||||
from . import MagicWordConfig
|
||||
import time, random, re, json
|
||||
|
|
@ -25,7 +28,7 @@ import time, random, re, json
|
|||
magicWordIndex = collections.OrderedDict()
|
||||
|
||||
|
||||
class MagicWord:
|
||||
class MagicWord(DirectObject):
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('MagicWord')
|
||||
|
||||
# Whether this Magic word should be considered "hidden"
|
||||
|
|
@ -424,13 +427,12 @@ class BossBattle(MagicWord):
|
|||
except ValueError:
|
||||
start = 1
|
||||
|
||||
from toontown.suit.DistributedBossCogAI import DistributedBossCogAI
|
||||
from toontown.suit.DistributedBossCogAI import AllBossCogs
|
||||
boss = None
|
||||
for do in self.air.doId2do.values():
|
||||
if isinstance(do, DistributedBossCogAI):
|
||||
if do.isToonKnown(invoker.doId):
|
||||
boss = do
|
||||
break
|
||||
for bc in AllBossCogs:
|
||||
if bc.isToonKnown(invoker.doId):
|
||||
boss = bc
|
||||
break
|
||||
|
||||
if command == "create":
|
||||
if boss:
|
||||
|
|
@ -457,6 +459,8 @@ class BossBattle(MagicWord):
|
|||
boss.b_setState('WaitForToons')
|
||||
else:
|
||||
boss.b_setState('Frolic')
|
||||
|
||||
self.acceptOnce(boss.uniqueName('BossDone'), self.__destroyBoss, extraArgs=[boss])
|
||||
|
||||
respText = f"Created {type.upper()} boss battle"
|
||||
if not start:
|
||||
|
|
@ -464,6 +468,49 @@ class BossBattle(MagicWord):
|
|||
|
||||
return respText + ", teleporting...", ["cogHQLoader", "cogHQBossBattle", "movie" if start else "teleportIn", boss.getHoodId(), boss.zoneId, 0]
|
||||
|
||||
elif command == "list":
|
||||
# List all the ongoing boss battles.
|
||||
dept2name = {'c': 'ceo',
|
||||
'l': 'cj',
|
||||
'm': 'cfo',
|
||||
's': 'vp'}
|
||||
name2dept = invertDict(dept2name)
|
||||
|
||||
if not AllBossCogs:
|
||||
return "No ongoing boss battles."
|
||||
|
||||
respText = "\nBoss Battles:"
|
||||
|
||||
if type:
|
||||
# Filter by boss type
|
||||
dept = name2dept.get(type)
|
||||
if not dept:
|
||||
return f"Can't filter by unknown type \"{type.upper()}\""
|
||||
bossBattles = (boss for boss in AllBossCogs if boss.dept == dept)
|
||||
else:
|
||||
bossBattles = AllBossCogs
|
||||
|
||||
for boss in bossBattles:
|
||||
index = AllBossCogs.index(boss)
|
||||
respText += f"\n - #{index}: {dept2name.get(boss.dept, '???').upper()}, {boss.zoneId}, {boss.state}, {len(boss.involvedToons)}"
|
||||
return respText
|
||||
|
||||
elif command == "join":
|
||||
# Join an ongoing boss battle.
|
||||
if boss:
|
||||
return "You're already in a boss battle. Please finish this one."
|
||||
try:
|
||||
index = int(type)
|
||||
except ValueError:
|
||||
return "Boss index not an integer!"
|
||||
|
||||
if index not in range(len(AllBossCogs)):
|
||||
return "Index out of range!"
|
||||
|
||||
boss = AllBossCogs[index]
|
||||
return "Teleporting to boss battle...", ["cogHQLoader", "cogHQBossBattle", "", boss.getHoodId(), boss.zoneId, 0]
|
||||
|
||||
|
||||
# The following commands needs the invoker to be in a boss battle.
|
||||
if not boss:
|
||||
return "You ain't in a boss battle! Use the \"create\" command to create a boss battle."
|
||||
|
|
@ -502,6 +549,77 @@ class BossBattle(MagicWord):
|
|||
# they can use INSIDE the battle.
|
||||
return respText + f"Unknown command: \"{command}\". Valid commands: \"start\", \"stop\", \"skip\", \"final\", \"kill\"."
|
||||
|
||||
def __destroyBoss(self, boss):
|
||||
bossZone = boss.zoneId
|
||||
boss.requestDelete()
|
||||
self.air.deallocateZone(bossZone)
|
||||
|
||||
class Fireworks(MagicWord):
|
||||
aliases = ["firework"]
|
||||
desc = "Starts a firework show."
|
||||
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||
arguments = [("name", str, False, "newyear"), ("hood", str, False, "")]
|
||||
|
||||
# List of firework shows currently in progress
|
||||
fireworkShows = {}
|
||||
|
||||
def handleWord(self, invoker, avId, toon, *args):
|
||||
name = args[0]
|
||||
hood = args[1]
|
||||
|
||||
from toontown.toonbase import ToontownGlobals
|
||||
from toontown.parties import PartyGlobals
|
||||
name2showId = {
|
||||
'newyear': ToontownGlobals.NEWYEARS_FIREWORKS,
|
||||
'newyears': ToontownGlobals.NEWYEARS_FIREWORKS,
|
||||
'summer': ToontownGlobals.JULY4_FIREWORKS,
|
||||
'combo': ToontownGlobals.COMBO_FIREWORKS,
|
||||
'party': PartyGlobals.FireworkShows.Summer
|
||||
}
|
||||
|
||||
if name not in name2showId:
|
||||
return f"Unknown firework name \"{name}\". Valid names: {list(name2showId.keys())}"
|
||||
showId = name2showId[name]
|
||||
|
||||
zoneToStyleDict = {
|
||||
ToontownGlobals.DonaldsDock : 5,
|
||||
ToontownGlobals.ToontownCentral : 0,
|
||||
ToontownGlobals.TheBrrrgh : 4,
|
||||
ToontownGlobals.MinniesMelodyland : 3,
|
||||
ToontownGlobals.DaisyGardens : 1,
|
||||
ToontownGlobals.OutdoorZone : 0,
|
||||
ToontownGlobals.GoofySpeedway : 0,
|
||||
ToontownGlobals.DonaldsDreamland : 2
|
||||
}
|
||||
|
||||
from toontown.hood import ZoneUtil
|
||||
zones = []
|
||||
if not hood:
|
||||
zones = (toon.zoneId,)
|
||||
elif hood == "all":
|
||||
zones = zoneToStyleDict.keys()
|
||||
else:
|
||||
return "Missing hood argument."
|
||||
|
||||
# Generate our firework shows
|
||||
from toontown.effects.DistributedFireworkShowAI import DistributedFireworkShowAI
|
||||
count = 0
|
||||
for zone in zones:
|
||||
if zone not in self.fireworkShows:
|
||||
show = DistributedFireworkShowAI(self.air, self)
|
||||
show.generateWithRequired(zone)
|
||||
self.fireworkShows[zone] = show
|
||||
show.d_startShow(showId, zoneToStyleDict.get(zone, 0))
|
||||
count += 1
|
||||
|
||||
return f"Started firework {'show' if count == 1 else 'shows'} in {count} {'zone' if count == 1 else 'zones'}!"
|
||||
|
||||
def stopShow(self, zoneId):
|
||||
if zoneId in self.fireworkShows:
|
||||
show = self.fireworkShows[zoneId]
|
||||
show.requestDelete()
|
||||
del self.fireworkShows[zoneId]
|
||||
|
||||
|
||||
# Instantiate all classes defined here to register them.
|
||||
# A bit hacky, but better than the old system
|
||||
|
|
|
|||
|
|
@ -524,6 +524,10 @@ class DistributedBossCogAI(DistributedAvatarAI.DistributedAvatarAI):
|
|||
if self.battleB:
|
||||
self.handleRoundDone(self.battleB, self.suitsB, self.activeSuitsB, toonIds, totalHp, deadSuits)
|
||||
|
||||
@staticmethod
|
||||
def getEndOfBattleMovieDuration():
|
||||
return 0
|
||||
|
||||
def handleBattleADone(self, zoneId, toonIds):
|
||||
if self.battleA:
|
||||
self.battleA.requestDelete()
|
||||
|
|
|
|||
|
|
@ -264,6 +264,10 @@ class DistributedLawbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FSM
|
|||
def makeBattleOneBattles(self):
|
||||
self.postBattleState = 'RollToBattleTwo'
|
||||
self.initializeBattles(1, ToontownGlobals.LawbotBossBattleOnePosHpr)
|
||||
|
||||
@staticmethod
|
||||
def getEndOfBattleMovieDuration():
|
||||
return 5
|
||||
|
||||
def generateSuits(self, battleNumber):
|
||||
if battleNumber == 1:
|
||||
|
|
|
|||
|
|
@ -217,6 +217,10 @@ class DistributedSellbotBossAI(DistributedBossCogAI.DistributedBossCogAI, FSM.FS
|
|||
def makeBattleOneBattles(self):
|
||||
self.postBattleState = 'RollToBattleTwo'
|
||||
self.initializeBattles(1, ToontownGlobals.SellbotBossBattleOnePosHpr)
|
||||
|
||||
@staticmethod
|
||||
def getEndOfBattleMovieDuration():
|
||||
return 5
|
||||
|
||||
def generateSuits(self, battleNumber):
|
||||
if self.nerfed:
|
||||
|
|
|
|||
Loading…
Reference in New Issue