@@ -218,7 +218,7 @@ class ApplicationWithApi(ConfiguredApplication):
218218 """Application with configured Habitica API"""
219219 api = None # type: Habitipy
220220
221- def main (self ):
221+ def main (self , * _args ):
222222 super ().main ()
223223 self .api = Habitipy (self .config )
224224
@@ -556,15 +556,201 @@ def main(self):
556556 print (f'{ food :<30} : { food_list [food ]} ' )
557557
558558
559+ @HabiticaCli .subcommand ('cast' )
560+ class Cast (ApplicationWithApi ):
561+ """Casts spells"""
562+ DESCRIPTION = _ ("Cast a spell" )
563+
564+ cast_count = cli .SwitchAttr (
565+ ['-C' , '--cast-times' ], argtype = int , default = 1 ,
566+ help = _ ("Number of times to cast the spell." )
567+ ) # noqa: Q000
568+ sleep_time = cli .SwitchAttr (
569+ ['-S' , '--sleep-time' ], argtype = int , default = 1 ,
570+ help = _ ("Time to wait between each cast to avoid overloading the server" )) # noqa: Q000
571+
572+ def main (self , * _arguments ):
573+ super ().main ()
574+
575+
576+ class CastNoArguments (Cast ):
577+ """Cast a spell with no arguments."""
578+ def main (self , * arguments ):
579+ super ().main ()
580+ spell = arguments [0 ]
581+
582+ for _i in range (self .cast_count ):
583+ print (_ (f"casting { spell } ..." ))
584+ _response = self .api .user ["class" ].cast [spell ].post ()
585+ time .sleep (self .sleep_time )
586+
587+
588+ class CastOnTask (Cast ):
589+ """Casts spells on a task"""
590+ def main (self , * arguments ):
591+ super ().main ()
592+ if len (arguments ) != 3 or arguments [1 ] not in ["todos" , "habits" , "dailies" ]:
593+ self .log .error (_ ("usage: cast task (todos|habits|dailies) number" ))
594+ return
595+
596+ (spell , domain , number ) = arguments
597+ number = int (number )
598+ tasks = self .api .tasks .user .get (type = domain )
599+
600+ if number > len (tasks ):
601+ self .log .error (_ ("selection number is too high" ))
602+ return
603+
604+ for _i in range (self .cast_count ):
605+ print (_ (f"casting { spell } ..." ))
606+ self .api .user ["class" ].cast [spell ].post (uri_params = {
607+ 'targetId' : tasks [number - 1 ]['id' ],
608+ })
609+ time .sleep (self .sleep_time )
610+
611+
612+ # Healer spells
613+ @Cast .subcommand ('heal' )
614+ class Heal (CastNoArguments ):
615+ """Cast heal."""
616+ DESCRIPTION = _ ("Cast Healer's Healing Light" )
617+ def main (self , * args , ** kwargs ):
618+ super ().main ('heal' , * args , ** kwargs )
619+
620+
621+ @Cast .subcommand ('brightness' )
622+ class Brightness (CastNoArguments ):
623+ """Cast brightness."""
624+ DESCRIPTION = _ ("Cast Healer's Searing Brightness" )
625+ def main (self , * args , ** kwargs ):
626+ super ().main ('brightness' , * args , ** kwargs )
627+
628+
629+ @Cast .subcommand ('protectAura' )
630+ class ProtectAura (CastNoArguments ):
631+ """Cast protectaura."""
632+ DESCRIPTION = _ ("Cast Healer's Protective Aura" )
633+ def main (self , * args , ** kwargs ):
634+ super ().main ('protectAura' , * args , ** kwargs )
635+
636+
637+ @Cast .subcommand ('healAll' )
638+ class HealAll (CastNoArguments ):
639+ """Cast healall"""
640+ DESCRIPTION = _ ("Cast Healer's Blessing" )
641+ def main (self , * args , ** kwargs ):
642+ super ().main ('healAll' , * args , ** kwargs )
643+
644+
645+ # Mage Spells
646+ @Cast .subcommand ('fireball' )
647+ class FireBall (CastOnTask ):
648+ """Cast fireball."""
649+ DESCRIPTION = _ ("Cast Mage's Burst of Flames on a task" )
650+ def main (self , * args , ** kwargs ):
651+ super ().main ('fireball' , * args , ** kwargs )
652+
653+
654+ @Cast .subcommand ('ethereal' ) # deliberately different
655+ class Ethereal (CastNoArguments ):
656+ """Cast ethereal."""
657+ DESCRIPTION = _ ("Cast Mage's Ethereal Surge" )
658+ def main (self , * args , ** kwargs ):
659+ super ().main ('mpheal' , * args , ** kwargs )
660+
661+
662+ @Cast .subcommand ('earth' )
663+ class Earth (CastNoArguments ):
664+ """Cast earth."""
665+ DESCRIPTION = _ ("Cast Mage's Earthquake" )
666+ def main (self , * args , ** kwargs ):
667+ super ().main ('earth' , * args , ** kwargs )
668+
669+
670+ @Cast .subcommand ('frost' )
671+ class Frost (CastNoArguments ):
672+ """Cast frost."""
673+ DESCRIPTION = _ ("Cast Mage's Chilling Frost" )
674+ def main (self , * args , ** kwargs ):
675+ super ().main ('frost' , * args , ** kwargs )
676+
677+
678+ # Rogue spells
679+
680+ @Cast .subcommand ('backstab' )
681+ class Backstab (CastOnTask ):
682+ "Cast backstab"
683+ DESCRIPTION = _ ("Cast Thief's Backstab on a task" )
684+ def main (self , * args , ** kwargs ):
685+ super ().main ('backStab' , * args , ** kwargs )
686+
687+
688+ @Cast .subcommand ('pickpocket' )
689+ class PickPocket (CastOnTask ):
690+ "Cast pickpocket"
691+ DESCRIPTION = _ ("Cast Thief's Pickpocket on a task" )
692+ def main (self , * args , ** kwargs ):
693+ super ().main ('pickPocket' , * args , ** kwargs )
694+
695+ @Cast .subcommand ('tools' ) # deliberately different
696+ class ToolsOfTrade (CastNoArguments ):
697+ """Cast tools of the trade."""
698+ DESCRIPTION = _ ("Cast Thief's Tools of the Trade" )
699+ def main (self , * args , ** kwargs ):
700+ super ().main ('toolsOfTrade' , * args , ** kwargs )
701+
702+
703+ @Cast .subcommand ('stealth' )
704+ class Stealth (CastNoArguments ):
705+ """Cast stealth."""
706+ DESCRIPTION = _ ("Cast Thief's Stealth" )
707+ def main (self , * args , ** kwargs ):
708+ super ().main ('stealth' , * args , ** kwargs )
709+
710+
711+ # Warrior spells
712+
713+
714+ @Cast .subcommand ('smash' )
715+ class Smash (CastOnTask ):
716+ """Cast smash."""
717+ DESCRIPTION = _ ("Cast Warrior's Brutal Smash on a task" )
718+ def main (self , * args , ** kwargs ):
719+ super ().main ('smash' , * args , ** kwargs )
720+
721+
722+ @Cast .subcommand ('defense' ) # deliberately different
723+ class DefensiveStance (CastNoArguments ):
724+ """Cast defense."""
725+ DESCRIPTION = _ ("Cast Warrior's Defensive Stance" )
726+ def main (self , * args , ** kwargs ):
727+ super ().main ('defensiveStance' , * args , ** kwargs )
728+
729+
730+ @Cast .subcommand ('intimidate' )
731+ class Intimidate (CastNoArguments ):
732+ """Cast intimidate."""
733+ DESCRIPTION = _ ("Cast Warrior's Intimidating Gaze" )
734+ def main (self , * args , ** kwargs ):
735+ super ().main ('intimidate' , * args , ** kwargs )
736+
737+
738+ @Cast .subcommand ('presence' )
739+ class ValorousPresence (CastNoArguments ):
740+ """Cast ValorousPresence"""
741+ DESCRIPTION = _ ("Cast Warrior's Valorous Presence" )
742+ def main (self , * args , ** kwargs ):
743+ super ().main ('valorousPresence' , * args , ** kwargs )
744+
745+
559746@HabiticaCli .subcommand ('habits' )
560- class Habits (TasksPrint ): # pylint: disable=missing-class- docstring
747+ class Habits (TasksPrint ): # pylint: disable=missing-docstring
561748 DESCRIPTION = _ ("List, up and down habit tasks" ) # noqa: Q000
562749 domain = 'habits'
563750 def domain_format (self , habit ): # pylint: disable=arguments-renamed
564751 score = ScoreInfo (self .config ['show_style' ], habit ['value' ])
565752 return _ ("{0} {text}" ).format (score , ** habit ) # noqa: Q000
566753
567-
568754@HabiticaCli .subcommand ('dailies' )
569755class Dailys (TasksPrint ): # pylint: disable=missing-class-docstring
570756 DESCRIPTION = _ ("List, check, uncheck daily tasks" ) # noqa: Q000
0 commit comments