Merge pull request #113 from SamuelT24/develop
spellbook: Add some new magic words
This commit is contained in:
commit
a5ecbb8b1e
7 changed files with 195 additions and 21 deletions
|
@ -618,6 +618,7 @@ dclass DistributedToon : DistributedPlayer {
|
||||||
setNeverStartedPartyRefunded(uint64, int8, uint16) ownrecv;
|
setNeverStartedPartyRefunded(uint64, int8, uint16) ownrecv;
|
||||||
setDISLname(string) ram;
|
setDISLname(string) ram;
|
||||||
setDISLid(uint32) ram db airecv;
|
setDISLid(uint32) ram db airecv;
|
||||||
|
toggleSleep() ownrecv;
|
||||||
};
|
};
|
||||||
|
|
||||||
dclass DistributedCCharBase : DistributedObject {
|
dclass DistributedCCharBase : DistributedObject {
|
||||||
|
|
|
@ -61,6 +61,7 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis
|
||||||
self.soundRun = None
|
self.soundRun = None
|
||||||
self.soundWalk = None
|
self.soundWalk = None
|
||||||
self.sleepFlag = 0
|
self.sleepFlag = 0
|
||||||
|
self.noSleep = 0
|
||||||
self.isDisguised = 0
|
self.isDisguised = 0
|
||||||
self.movingFlag = 0
|
self.movingFlag = 0
|
||||||
self.swimmingFlag = 0
|
self.swimmingFlag = 0
|
||||||
|
@ -984,7 +985,7 @@ class LocalAvatar(DistributedAvatar.DistributedAvatar, DistributedSmoothNode.Dis
|
||||||
return
|
return
|
||||||
|
|
||||||
def gotoSleep(self):
|
def gotoSleep(self):
|
||||||
if not self.sleepFlag:
|
if not self.sleepFlag and not self.noSleep:
|
||||||
self.b_setAnimState('Sleep', self.animMultiplier)
|
self.b_setAnimState('Sleep', self.animMultiplier)
|
||||||
self.sleepFlag = 1
|
self.sleepFlag = 1
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,8 @@ class BattleCalculatorAI:
|
||||||
return (1, 95)
|
return (1, 95)
|
||||||
else:
|
else:
|
||||||
return (0, 0)
|
return (0, 0)
|
||||||
if self.toonsAlwaysHit:
|
toon = self.battle.getToon(attackIndex)
|
||||||
|
if self.toonsAlwaysHit or toon.instantKillMode:
|
||||||
return (1, 95)
|
return (1, 95)
|
||||||
elif self.toonsAlwaysMiss:
|
elif self.toonsAlwaysMiss:
|
||||||
return (0, 0)
|
return (0, 0)
|
||||||
|
@ -529,6 +530,9 @@ class BattleCalculatorAI:
|
||||||
if attackLevel == -1 and not atkTrack == FIRE:
|
if attackLevel == -1 and not atkTrack == FIRE:
|
||||||
result = LURE_SUCCEEDED
|
result = LURE_SUCCEEDED
|
||||||
elif atkTrack != TRAP:
|
elif atkTrack != TRAP:
|
||||||
|
toon = self.battle.getToon(toonId)
|
||||||
|
if atkTrack != HEAL and toon.instantKillMode:
|
||||||
|
attackDamage = 32767
|
||||||
result = attackDamage
|
result = attackDamage
|
||||||
if atkTrack == HEAL:
|
if atkTrack == HEAL:
|
||||||
if not self.__attackHasHit(attack, suit=0):
|
if not self.__attackHasHit(attack, suit=0):
|
||||||
|
|
|
@ -176,7 +176,6 @@ class MagicWord(DirectObject):
|
||||||
def handleWord(self, invoker, avId, toon, *args):
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class SetHP(MagicWord):
|
class SetHP(MagicWord):
|
||||||
aliases = ["hp", "setlaff", "laff"]
|
aliases = ["hp", "setlaff", "laff"]
|
||||||
desc = "Sets the target's current laff."
|
desc = "Sets the target's current laff."
|
||||||
|
@ -200,7 +199,6 @@ class SetHP(MagicWord):
|
||||||
toon.b_setHp(hp)
|
toon.b_setHp(hp)
|
||||||
return "{}'s laff has been set to {}.".format(toon.getName(), hp)
|
return "{}'s laff has been set to {}.".format(toon.getName(), hp)
|
||||||
|
|
||||||
|
|
||||||
class SetMaxHP(MagicWord):
|
class SetMaxHP(MagicWord):
|
||||||
aliases = ["maxhp", "setmaxlaff", "maxlaff"]
|
aliases = ["maxhp", "setmaxlaff", "maxlaff"]
|
||||||
desc = "Sets the target's max laff."
|
desc = "Sets the target's max laff."
|
||||||
|
@ -219,7 +217,6 @@ class SetMaxHP(MagicWord):
|
||||||
toon.toonUp(maxhp)
|
toon.toonUp(maxhp)
|
||||||
return "{}'s max laff has been set to {}.".format(toon.getName(), maxhp)
|
return "{}'s max laff has been set to {}.".format(toon.getName(), maxhp)
|
||||||
|
|
||||||
|
|
||||||
class ToggleOobe(MagicWord):
|
class ToggleOobe(MagicWord):
|
||||||
aliases = ["oobe"]
|
aliases = ["oobe"]
|
||||||
desc = "Toggles the out of body experience mode, which lets you move the camera freely."
|
desc = "Toggles the out of body experience mode, which lets you move the camera freely."
|
||||||
|
@ -232,7 +229,6 @@ class ToggleOobe(MagicWord):
|
||||||
base.oobe()
|
base.oobe()
|
||||||
return "Oobe mode has been toggled."
|
return "Oobe mode has been toggled."
|
||||||
|
|
||||||
|
|
||||||
class ToggleRun(MagicWord):
|
class ToggleRun(MagicWord):
|
||||||
aliases = ["run"]
|
aliases = ["run"]
|
||||||
desc = "Toggles run mode, which gives you a faster running speed."
|
desc = "Toggles run mode, which gives you a faster running speed."
|
||||||
|
@ -308,8 +304,6 @@ class Inventory(MagicWord):
|
||||||
toon.d_setInventory(toon.inventory.makeNetString())
|
toon.d_setInventory(toon.inventory.makeNetString())
|
||||||
return ("Zeroing inventory for " + toon.getName() + ".")
|
return ("Zeroing inventory for " + toon.getName() + ".")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SetPinkSlips(MagicWord):
|
class SetPinkSlips(MagicWord):
|
||||||
# this command gives the target toon the specified amount of pink slips
|
# this command gives the target toon the specified amount of pink slips
|
||||||
# default is 255
|
# default is 255
|
||||||
|
@ -332,6 +326,51 @@ class AbortMinigame(MagicWord):
|
||||||
messenger.send("minigameAbort")
|
messenger.send("minigameAbort")
|
||||||
return "Requested minigame abort."
|
return "Requested minigame abort."
|
||||||
|
|
||||||
|
class SkipMiniGolfHole(MagicWord):
|
||||||
|
aliases = ["skipgolfhole", "skipgolf", "skiphole"]
|
||||||
|
desc = "Skips the current golf hole."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
arguments = []
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
from toontown.golf.DistributedGolfCourseAI import DistributedGolfCourseAI
|
||||||
|
course = None
|
||||||
|
for do in simbase.air.doId2do.values(): # For all doids, check whether it's a golf course, then check if our target is part of it.
|
||||||
|
if isinstance(do, DistributedGolfCourseAI):
|
||||||
|
if invoker.doId in do.avIdList:
|
||||||
|
course = do
|
||||||
|
break
|
||||||
|
if not course:
|
||||||
|
return "You aren't in a golf course!"
|
||||||
|
|
||||||
|
if course.isPlayingLastHole(): # If the Toon is on the final hole, calling holeOver() will softlock, so instead we move onto the reward screen.
|
||||||
|
course.demand('WaitReward')
|
||||||
|
else:
|
||||||
|
course.holeOver()
|
||||||
|
|
||||||
|
return "Skipped the current hole."
|
||||||
|
|
||||||
|
class AbortGolfCourse(MagicWord):
|
||||||
|
aliases = ["abortminigolf", "abortgolf", "abortcourse", "leavegolf", "leavecourse"]
|
||||||
|
desc = "Aborts the current golf course."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
arguments = []
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
from toontown.golf.DistributedGolfCourseAI import DistributedGolfCourseAI
|
||||||
|
course = None
|
||||||
|
for do in simbase.air.doId2do.values(): # For all doids, check whether it's a golf course, then check if our target is part of it.
|
||||||
|
if isinstance(do, DistributedGolfCourseAI):
|
||||||
|
if invoker.doId in do.avIdList:
|
||||||
|
course = do
|
||||||
|
break
|
||||||
|
if not course:
|
||||||
|
return "You aren't in a golf course!"
|
||||||
|
|
||||||
|
course.setCourseAbort()
|
||||||
|
|
||||||
|
return "Aborted golf course."
|
||||||
|
|
||||||
class Minigame(MagicWord):
|
class Minigame(MagicWord):
|
||||||
aliases = ["mg"]
|
aliases = ["mg"]
|
||||||
desc = "Teleport to or request the next trolley minigame."
|
desc = "Teleport to or request the next trolley minigame."
|
||||||
|
@ -516,7 +555,7 @@ class BossBattle(MagicWord):
|
||||||
if not start:
|
if not start:
|
||||||
respText += " in Frolic state"
|
respText += " in Frolic state"
|
||||||
|
|
||||||
return respText + ", teleporting...", ["cogHQLoader", "cogHQBossBattle", "movie" if start else "teleportIn", boss.getHoodId(), boss.zoneId, 0]
|
return respText + ", teleporting...", toon.doId, ["cogHQLoader", "cogHQBossBattle", "movie" if start else "teleportIn", boss.getHoodId(), boss.zoneId, 0]
|
||||||
|
|
||||||
elif command == "list":
|
elif command == "list":
|
||||||
# List all the ongoing boss battles.
|
# List all the ongoing boss battles.
|
||||||
|
@ -558,7 +597,7 @@ class BossBattle(MagicWord):
|
||||||
return "Index out of range!"
|
return "Index out of range!"
|
||||||
|
|
||||||
boss = AllBossCogs[index]
|
boss = AllBossCogs[index]
|
||||||
return "Teleporting to boss battle...", ["cogHQLoader", "cogHQBossBattle", "", boss.getHoodId(), boss.zoneId, 0]
|
return "Teleporting to boss battle...", toon.doId, ["cogHQLoader", "cogHQBossBattle", "", boss.getHoodId(), boss.zoneId, 0]
|
||||||
|
|
||||||
|
|
||||||
# The following commands needs the invoker to be in a boss battle.
|
# The following commands needs the invoker to be in a boss battle.
|
||||||
|
@ -597,13 +636,129 @@ class BossBattle(MagicWord):
|
||||||
|
|
||||||
# The create command is already described when the invoker is not in a battle. These are the commands
|
# The create command is already described when the invoker is not in a battle. These are the commands
|
||||||
# they can use INSIDE the battle.
|
# they can use INSIDE the battle.
|
||||||
return respText + f"Unknown command: \"{command}\". Valid commands: \"start\", \"stop\", \"skip\", \"final\", \"kill\"."
|
return f"Unknown command: \"{command}\". Valid commands: \"start\", \"stop\", \"skip\", \"final\", \"kill\"."
|
||||||
|
|
||||||
def __destroyBoss(self, boss):
|
def __destroyBoss(self, boss):
|
||||||
bossZone = boss.zoneId
|
bossZone = boss.zoneId
|
||||||
boss.requestDelete()
|
boss.requestDelete()
|
||||||
self.air.deallocateZone(bossZone)
|
self.air.deallocateZone(bossZone)
|
||||||
|
|
||||||
|
class GlobalTeleport(MagicWord):
|
||||||
|
aliases = ["globaltp", "tpaccess"]
|
||||||
|
desc = "Enables teleport access to all zones."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
from toontown.toonbase import ToontownGlobals
|
||||||
|
toon.b_setHoodsVisited(ToontownGlobals.HoodsForTeleportAll)
|
||||||
|
toon.b_setTeleportAccess(ToontownGlobals.HoodsForTeleportAll)
|
||||||
|
return f"Enabled teleport access to all zones for {toon.getName()}."
|
||||||
|
|
||||||
|
class Teleport(MagicWord):
|
||||||
|
aliases = ["tp", "goto"]
|
||||||
|
desc = "Teleport to a specified zone."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
arguments = [("zoneName", str, False, '')]
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
from toontown.hood import ZoneUtil
|
||||||
|
from toontown.toonbase import ToontownGlobals
|
||||||
|
zoneName = args[0]
|
||||||
|
|
||||||
|
# Can add stuff like streets to this too if you wanted, but if you do you'll want it to be a valid zone on that street. eg: 2100 is invalid, but any value 2101 to 2156 is fine.
|
||||||
|
# so if you wanted to add a silly street key, theroetically you could do something like this: 'sillystreet': ToontownGlobals.SillyStreet +1,
|
||||||
|
zoneName2Id = {'ttc': ToontownGlobals.ToontownCentral,
|
||||||
|
'dd': ToontownGlobals.DonaldsDock,
|
||||||
|
'dg': ToontownGlobals.DaisyGardens,
|
||||||
|
'mml': ToontownGlobals.MinniesMelodyland,
|
||||||
|
'tb': ToontownGlobals.TheBrrrgh,
|
||||||
|
'ddl': ToontownGlobals.DonaldsDreamland,
|
||||||
|
'gs': ToontownGlobals.GoofySpeedway,
|
||||||
|
'oz': ToontownGlobals.OutdoorZone,
|
||||||
|
'aa': ToontownGlobals.OutdoorZone,
|
||||||
|
'gz': ToontownGlobals.GolfZone,
|
||||||
|
'sbhq': ToontownGlobals.SellbotHQ,
|
||||||
|
'factory': ToontownGlobals.SellbotFactoryExt,
|
||||||
|
'cbhq': ToontownGlobals.CashbotHQ,
|
||||||
|
'lbhq': ToontownGlobals.LawbotHQ,
|
||||||
|
'bbhq': ToontownGlobals.BossbotHQ}
|
||||||
|
|
||||||
|
try:
|
||||||
|
zone = zoneName2Id[zoneName]
|
||||||
|
except KeyError:
|
||||||
|
return "Unknown zone name!"
|
||||||
|
|
||||||
|
return f"Requested to teleport {toon.getName()} to zone {zone}.", toon.doId, [ZoneUtil.getBranchLoaderName(zone), ZoneUtil.getToonWhereName(zone), "", ZoneUtil.getHoodId(zone), zone, 0]
|
||||||
|
|
||||||
|
class ToggleSleep(MagicWord):
|
||||||
|
aliases = ["sleep", "nosleep", "neversleep", "togglesleeping", "insomnia"]
|
||||||
|
desc = "Toggles sleeping for the target."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
toon.d_toggleSleep()
|
||||||
|
return f"Toggled sleeping for {toon.getName()}."
|
||||||
|
|
||||||
|
class ToggleImmortal(MagicWord):
|
||||||
|
aliases = ["immortal", "invincible", "invulnerable"]
|
||||||
|
desc = "Toggle immortal mode. This makes the Toon immune to damage."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
toon.setImmortalMode(not toon.immortalMode)
|
||||||
|
return f"Toggled immortal mode for {toon.getName()}"
|
||||||
|
|
||||||
|
class ToggleGhost(MagicWord):
|
||||||
|
aliases = ["ghost", "invisible", "spy"]
|
||||||
|
desc = "Toggle ghost mode."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
# 1 is for the attic, 2 enables you to see yourself other ghost toons. 0 is off.
|
||||||
|
toon.b_setGhostMode(2 if not toon.ghostMode else 0) # As it's primarily for moderation purposes, we set it to 2 here, or 0 if it's already on.
|
||||||
|
return f"Toggled ghost mode for {toon.getName()}"
|
||||||
|
|
||||||
|
class SetGM(MagicWord):
|
||||||
|
aliases = ["icon", "seticon", "gm", "gmicon", "setgmicon"]
|
||||||
|
desc = "Sets the GM icon on the target."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
arguments = [("iconRequest", int, False, 0),]
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
from toontown.toonbase import TTLocalizer
|
||||||
|
|
||||||
|
iconRequest = args[0]
|
||||||
|
if iconRequest > len(TTLocalizer.GM_NAMES) or iconRequest < 0:
|
||||||
|
return "Invalid GM icon ID!"
|
||||||
|
|
||||||
|
toon.b_setGM(0) # Reset it first, otherwise the Toon keeps the old icon, but the name still changes.
|
||||||
|
toon.b_setGM(iconRequest)
|
||||||
|
return f"GM icon set to {iconRequest} for {toon.getName()}"
|
||||||
|
|
||||||
|
class SetMaxCarry(MagicWord):
|
||||||
|
aliases = ["gagpouch", "pouch", "gagcapacity"]
|
||||||
|
desc = "Set a Toon's gag pouch size."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
arguments = [("pouchSize", int, True)]
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
pouchSize = args[0]
|
||||||
|
|
||||||
|
if pouchSize > 255 or pouchSize < 0:
|
||||||
|
return "Specified pouch size must be between 1 and 255."
|
||||||
|
|
||||||
|
toon.b_setMaxCarry(pouchSize)
|
||||||
|
return f"Set gag pouch size to {pouchSize} for {toon.getName()}"
|
||||||
|
|
||||||
|
class ToggleInstantKill(MagicWord):
|
||||||
|
aliases = ["instantkill", "instakill"]
|
||||||
|
desc = "Toggle the ability to instantly kill a Cog with any gag."
|
||||||
|
execLocation = MagicWordConfig.EXEC_LOC_SERVER
|
||||||
|
|
||||||
|
def handleWord(self, invoker, avId, toon, *args):
|
||||||
|
toon.setInstantKillMode(not toon.instantKillMode)
|
||||||
|
return f"Toggled instant-kill mode for {toon.getName()}"
|
||||||
|
|
||||||
class Fireworks(MagicWord):
|
class Fireworks(MagicWord):
|
||||||
aliases = ["firework"]
|
aliases = ["firework"]
|
||||||
desc = "Starts a firework show."
|
desc = "Starts a firework show."
|
||||||
|
|
|
@ -275,6 +275,7 @@ class ToontownMagicWordManager(DistributedObject.DistributedObject):
|
||||||
hoodId = place.loader.hood.id
|
hoodId = place.loader.hood.id
|
||||||
if avId == 0:
|
if avId == 0:
|
||||||
avId = -1
|
avId = -1
|
||||||
|
try:
|
||||||
place.fsm.forceTransition('teleportOut',
|
place.fsm.forceTransition('teleportOut',
|
||||||
[{"loader": loaderId,
|
[{"loader": loaderId,
|
||||||
"where": whereId,
|
"where": whereId,
|
||||||
|
@ -283,3 +284,5 @@ class ToontownMagicWordManager(DistributedObject.DistributedObject):
|
||||||
"zoneId": zoneId,
|
"zoneId": zoneId,
|
||||||
"shardId": None,
|
"shardId": None,
|
||||||
"avId": avId}])
|
"avId": avId}])
|
||||||
|
except Exception: # Most likely cause is the place the avatar is in has no teleportOut state, for example, boss lobbies.
|
||||||
|
place.fsm.request('DFAReject') # We have to do this, or the avatar will be stuck.
|
||||||
|
|
|
@ -2528,7 +2528,7 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
|
||||||
self._handleGMName()
|
self._handleGMName()
|
||||||
|
|
||||||
def _handleGMName(self):
|
def _handleGMName(self):
|
||||||
name = self.name
|
name = self._name
|
||||||
self.setDisplayName(name)
|
self.setDisplayName(name)
|
||||||
if self._isGM:
|
if self._isGM:
|
||||||
self.setNametagStyle(5)
|
self.setNametagStyle(5)
|
||||||
|
@ -2589,3 +2589,6 @@ class DistributedToon(DistributedPlayer.DistributedPlayer, Toon.Toon, Distribute
|
||||||
|
|
||||||
def getTransitioning(self):
|
def getTransitioning(self):
|
||||||
return self.transitioning
|
return self.transitioning
|
||||||
|
|
||||||
|
def toggleSleep(self):
|
||||||
|
base.localAvatar.noSleep = not base.localAvatar.noSleep
|
|
@ -155,6 +155,7 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
|
||||||
self.savedCheesyExpireTime = 0
|
self.savedCheesyExpireTime = 0
|
||||||
self.ghostMode = 0
|
self.ghostMode = 0
|
||||||
self.immortalMode = 0
|
self.immortalMode = 0
|
||||||
|
self.instantKillMode = 0
|
||||||
self.numPies = 0
|
self.numPies = 0
|
||||||
self.pieType = 0
|
self.pieType = 0
|
||||||
self._isGM = False
|
self._isGM = False
|
||||||
|
@ -2375,6 +2376,9 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
|
||||||
def setImmortalMode(self, flag):
|
def setImmortalMode(self, flag):
|
||||||
self.immortalMode = flag
|
self.immortalMode = flag
|
||||||
|
|
||||||
|
def setInstantKillMode(self, flag):
|
||||||
|
self.instantKillMode = flag
|
||||||
|
|
||||||
def b_setSpeedChatStyleIndex(self, index):
|
def b_setSpeedChatStyleIndex(self, index):
|
||||||
self.setSpeedChatStyleIndex(index)
|
self.setSpeedChatStyleIndex(index)
|
||||||
self.d_setSpeedChatStyleIndex(index)
|
self.d_setSpeedChatStyleIndex(index)
|
||||||
|
@ -4129,6 +4133,9 @@ class DistributedToonAI(DistributedPlayerAI.DistributedPlayerAI, DistributedSmoo
|
||||||
zoneId])
|
zoneId])
|
||||||
self.air.send(dg)
|
self.air.send(dg)
|
||||||
|
|
||||||
|
def d_toggleSleep(self):
|
||||||
|
self.sendUpdate('toggleSleep', [])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def staticGetLogicalZoneChangeAllEvent():
|
def staticGetLogicalZoneChangeAllEvent():
|
||||||
return 'DOLogicalChangeZone-all'
|
return 'DOLogicalChangeZone-all'
|
||||||
|
|
Loading…
Reference in a new issue