├── .editorconfig
├── .gitignore
├── .vscode
├── extensions.json
└── settings.json
├── BAN-MEMO.md
├── Discord_Link.png
├── Images
├── MIRA_HQ_Random_Map.png
├── Mira_HQ_Random_Map.png
├── Polus_Random_Map.png
├── The_Airship_Random_Map.png
├── The_Skeld_Random_Map.png
├── TownOfHost HideCode.png
├── TownOfHost-Discord.png
└── TownOfHost-Title.png
├── LICENSE
├── Lotus.csproj
├── NuGet.Config
├── ProjectLotus.cs
├── README.md
├── SourceGenerators
└── RoleEditorGenerator
│ └── src
│ ├── .idea
│ └── .idea.src.dir
│ │ └── .idea
│ │ ├── .gitignore
│ │ ├── indexLayout.xml
│ │ └── vcs.xml
│ ├── REGenerator.cs
│ └── RoleEditorGenerator.csproj
├── VentFramework.dll
├── assets
├── Alert.png
├── Blackmail.png
├── CircleButtonBack.png
├── Content
│ └── Results_Icon.png
├── CycleBack.png
├── CycleForward.png
├── Douse.png
├── Flash.png
├── Guess.png
├── Hack.png
├── HighRes
│ ├── CrewmateIcon_HighRes.png
│ ├── Crewmate_HighRes2.png
│ ├── HideAndSeek_HighRes.png
│ ├── ImpostorIcon_HighRes.png
│ ├── MiscIcon_HighRes.png
│ ├── NeutralIcon_HighRes.png
│ ├── TabIcon_ColorWras.png
│ └── TabIcon_FreeForAll.png
├── HintButton.png
├── History.png
├── HistoryMenu
│ └── ResultsIcon.png
├── HistoryTab.png
├── Ignite.png
├── Infect.png
├── Janitor.png
├── KillMusic.raw
├── LotusBanner.png
├── LotusBanner1.png
├── Lotus_Icon.png
├── Mediate.png
├── Mimic.png
├── Mine.png
├── NameMenu
│ ├── AddSpace.png
│ ├── ArrowDown.png
│ ├── ArrowLeft.png
│ ├── ArrowRight.png
│ ├── ArrowUp.png
│ ├── RemoveSpace.png
│ ├── Visibility.png
│ ├── ZoomIn.png
│ └── ZoomOut.png
├── NinjaAssassinateButton.png
├── NinjaMarkButton.png
├── Poison.png
├── Poisoned.png
├── Protect.png
├── Rampage.png
├── Remember.png
├── Seer.png
├── Settings
│ ├── AddonBlank.png
│ ├── AddonButton.png
│ ├── AddonSettings.png
│ ├── ExitBlank.png
│ ├── ExitButton.png
│ ├── ExitIcon.png
│ ├── GeneralBlank.png
│ ├── GeneralButton.png
│ ├── GeneralSettings.png
│ ├── GraphicBlank.png
│ ├── GraphicSettings.png
│ ├── GraphicsButton.png
│ ├── MenuBackground.png
│ ├── ProgressBarFill.png
│ ├── ProgressBarMask.png
│ ├── ReturnBlank.png
│ ├── ReturnButton.png
│ ├── ReturnIcon.png
│ ├── SelectButton.png
│ ├── SoundBlank.png
│ ├── SoundButton.png
│ ├── SoundSettings.png
│ ├── UnselectButton.png
│ ├── UpdateMenuBackground.png
│ ├── VentButton.png
│ ├── VentLibBlank.png
│ └── VentLibSettings.png
├── Sheriff.png
├── Swoop.png
├── TOHTORBackground.png
├── TabIcons
│ ├── ColorWarsIcon.png
│ ├── CrewmatesIcon.png
│ ├── GeneralIcon.png
│ ├── HideAndSeekIcon.png
│ ├── ImpostorsIcon.png
│ ├── ImpostorsIcon1.png
│ ├── ImpostorsIcon2.png
│ ├── MiscIcon.png
│ └── NeutralsIcon.png
├── Tabs
│ ├── Debug_Tab.png
│ ├── HideAndSeek_HighRes.png
│ ├── TabIcon-old.png
│ ├── TabIcon_Addons.png
│ ├── TabIcon_CaptureTheFlag.png
│ ├── TabIcon_ColorWars.png
│ ├── TabIcon_CrewmateRoles.png
│ ├── TabIcon_FreeForAll.png
│ ├── TabIcon_HideAndSeek.png
│ ├── TabIcon_ImpostorRoles.png
│ ├── TabIcon_MainSettings.png
│ ├── TabIcon_MiscRoles.png
│ ├── TabIcon_NeutralRoles.png
│ ├── among-us-6008615_1280.webp
│ └── primether5348.txt
├── TownOfHost-Logo.png
├── Transport.png
├── Vest.png
├── Winners.png
├── arlrdbd.ttf
├── main_menu
│ ├── AnnouncementIconRedone.png
│ ├── InventoryIconRedone.png
│ ├── LittleDudeIcon.png
│ ├── ShopIconRedone.png
│ └── discord_button_icon.png
├── tohtor-logo-old.png
├── tohtor-logo-rold.png
└── tohtor-logo.png
└── src
├── API
├── AUSettings.cs
├── Api.Local.cs
├── Api.cs
├── GameStates.cs
├── ModVersion.cs
├── Odyssey
│ ├── Game.cs
│ ├── MatchData.Statuses.cs
│ ├── MatchData.cs
│ └── VanillaRoleTracker.cs
├── Player
│ ├── FrozenPlayer.cs
│ ├── Players.cs
│ └── UniquePlayerId.cs
├── Priority.cs
├── Processes
│ └── NameUpdateProcess.cs
├── ProtectedRpc.cs
├── Reactive
│ ├── Hook.cs
│ ├── HookEvents
│ │ ├── CastVoteHookEvent.cs
│ │ ├── ClientConnectHookEvent.cs
│ │ ├── EmptyHookEvent.cs
│ │ ├── ExiledHookEvent.cs
│ │ ├── GameJoinHookEvent.cs
│ │ ├── GameStateHookEvent.cs
│ │ ├── LosersHookEvent.cs
│ │ ├── MeetingHookEvent.cs
│ │ ├── PlayerActionHookEvent.cs
│ │ ├── PlayerDeathHookEvent.cs
│ │ ├── PlayerHookEvent.cs
│ │ ├── PlayerMessageHookEvent.cs
│ │ ├── PlayerMurderHookEvent.cs
│ │ ├── PlayerShapeshiftHookEvent.cs
│ │ ├── PlayerStatusReceivedHook.cs
│ │ ├── PlayerTaskHookEvent.cs
│ │ ├── PlayerTeleportedHookEvent.cs
│ │ ├── ReceiveVersionHookEvent.cs
│ │ ├── RpcHookEvent.cs
│ │ ├── SabotageFixHookEvent.cs
│ │ ├── SabotageHookEvent.cs
│ │ └── WinnersHookEvent.cs
│ ├── Hooks.cs
│ ├── IHookEvent.cs
│ └── SimpleHook.cs
├── Stats
│ ├── AccumulatingStatistic.cs
│ ├── BoundStatistic.cs
│ ├── DefaultStatisticManager.cs
│ ├── Statistic.cs
│ ├── StatisticDump.cs
│ ├── Statistics.cs
│ └── VanillaStatistics.cs
├── Tasks.cs
└── Vanilla
│ ├── MatchState.cs
│ ├── Meetings
│ ├── MeetingApi.cs
│ ├── MeetingDelegate.cs
│ └── MeetingPrep.cs
│ ├── Sabotages
│ ├── CommsSabotage.cs
│ ├── DoorSabotage.cs
│ ├── ElectricSabotage.cs
│ ├── HelicopterSabotage.cs
│ ├── ISabotage.cs
│ ├── OxygenSabotage.cs
│ ├── ReactorSabotage.cs
│ └── SabotageType.cs
│ └── VentApi.cs
├── Addons
├── AddonException.cs
├── AddonInfo.cs
├── AddonManager.cs
└── TOHAddon.cs
├── Chat
├── ChatHandler.cs
├── ChatHandlers.cs
├── Commands
│ ├── BasicCommands.cs
│ ├── CommandTranslations.cs
│ ├── DeathCommand.cs
│ ├── FriendCommands.cs
│ ├── Help
│ │ ├── HelpAllCommand.cs
│ │ └── RoleCommand.cs
│ ├── HistoryCommands.cs
│ ├── KickBanCommands.cs
│ ├── LastResultCommand.cs
│ ├── MyRoleCommand.cs
│ ├── NowCommand.cs
│ ├── PreventCommand.cs
│ ├── StatCommand.cs
│ ├── StatusCommand.cs
│ ├── TemplateCommands.cs
│ └── WordListCommands.cs
├── OptionUtils.cs
└── Patches
│ ├── ChatBubblePatch.cs
│ ├── ChatCommandPatch.cs
│ ├── OnChatPatch.cs
│ ├── RpcSendChatPatch.cs
│ └── TextBoxPatch.cs
├── Constraints
└── DLLConstraint.cs
├── DisableDevice.cs
├── Discord
└── Patches
│ └── DiscordPresencePatch.cs
├── Extensions
├── AssemblyExtensions.cs
├── CooldownExtensions.cs
├── CustomRoleExtension.cs
├── DebugExtensions.cs
├── EnumerableExtensions.cs
├── FileInfoExtensions.cs
├── GameOptionsExtensions.cs
├── IGameManagerEx.cs
├── OptionBuilderExtensions.cs
├── OutfitExtension.cs
├── PassiveButtonExtension.cs
├── PlayerControlExtensions.cs
├── PlayerInfoExtensions.cs
├── PlayerRPCExtensions.cs
├── RangeExtensions.cs
├── RoleTypesExtension.cs
├── RpcCallExtension.cs
├── ShipStatusExtension.cs
├── StatisticExtensions.cs
└── StringExtension.cs
├── Factions
├── Crew
│ └── Crewmates.cs
├── Faction.cs
├── FactionExtensions.cs
├── FactionInstances.cs
├── Impostors
│ ├── ImpostorFaction.cs
│ └── Madmates.cs
├── Interfaces
│ ├── IFaction.cs
│ └── ISubFaction.cs
├── Modifiers.cs
├── Neutrals
│ └── Neutral.cs
├── Relation.cs
└── Undead
│ ├── TheUndead.Converted.cs
│ ├── TheUndead.Origin.cs
│ ├── TheUndead.Unconverted.cs
│ └── TheUndead.cs
├── GUI
├── Components
│ ├── LazyProgressBar.cs
│ └── UpdateComponent.cs
├── Cooldown.cs
├── Counters
│ ├── ICounter.cs
│ ├── LiveCounter.cs
│ └── StaticCounter.cs
├── Menus
│ ├── CustomNameMenu
│ │ ├── CustomNameMenu.cs
│ │ └── CustomNameMenuPane.cs
│ ├── HistoryMenu.cs
│ ├── HistoryMenu2
│ │ ├── GameLogMenu.cs
│ │ ├── HM2.cs
│ │ ├── IHistoryMenuChild.cs
│ │ └── ResultsMenu.cs
│ ├── ModUpdateMenu.cs
│ ├── OptionsMenu
│ │ ├── Components
│ │ │ ├── MonoToggleButton.cs
│ │ │ ├── SimpleDropdownButton.cs
│ │ │ └── TiledToggleButton.cs
│ │ ├── CustomOptionBar.cs
│ │ ├── CustomOptionContainer.cs
│ │ ├── OptionMenuResources.cs
│ │ ├── Patches
│ │ │ └── GameOptionMenuOpenPatch.cs
│ │ └── Submenus
│ │ │ ├── GeneralMenu.cs
│ │ │ ├── GraphicsMenu.cs
│ │ │ ├── IBaseOptionMenuComponent.cs
│ │ │ ├── SoundMenu.cs
│ │ │ └── VentLibMenu.cs
│ ├── Patches
│ │ └── RolesOptionsPatch.cs
│ └── WinnersMenu.cs
├── Name
│ ├── Components
│ │ ├── ColoredNameComponent.cs
│ │ ├── CooldownComponent.cs
│ │ ├── CounterComponent.cs
│ │ ├── IndicatorComponent.cs
│ │ ├── NameComponent.cs
│ │ ├── RoleComponent.cs
│ │ ├── SimpleComponent.cs
│ │ ├── SimpleIndicatorComponent.cs
│ │ ├── SubroleComponent.cs
│ │ └── TextComponent.cs
│ ├── Holders
│ │ ├── ComponentHolder.cs
│ │ ├── CooldownHolder.cs
│ │ ├── CounterHolder.cs
│ │ ├── IndicatorHolder.cs
│ │ ├── NameHolder.cs
│ │ ├── RoleHolder.cs
│ │ ├── SubroleHolder.cs
│ │ └── TextHolder.cs
│ ├── Impl
│ │ ├── SimpleNameModel.cs
│ │ └── Ubifix.cs
│ ├── Interfaces
│ │ ├── IComponentHolder.cs
│ │ ├── INameModel.cs
│ │ └── INameModelComponent.cs
│ ├── LiveString.cs
│ ├── TextUtils.cs
│ ├── UI.cs
│ └── ViewMode.cs
├── Patches
│ ├── HideBanButtonPatch.cs
│ ├── KillOverlayPatch.cs
│ └── SplashPatch.cs
├── PersistentAssetLoader.cs
└── UIComponent.cs
├── Gamemodes
├── CaptureTheFlag
│ ├── CTFAssignRoles.cs
│ ├── CTFGamemode.cs
│ ├── CTFWinConditions.cs
│ └── Striker.cs
├── Colorwars
│ ├── ColorWarsWinCondition.cs
│ ├── ColorwarsAssignRoles.cs
│ ├── ColorwarsGamemode.cs
│ ├── CwPainter.cs
│ └── FFAAssignRoles.cs
├── Debug
│ └── DebugGamemode.cs
├── GameAction.cs
├── Gamemode.cs
├── GamemodeManager.cs
├── IGamemode.cs
├── Standard
│ ├── IAdditionalAssignmentLogic.cs
│ ├── IllegalRoleCombos.cs
│ ├── Lotteries
│ │ ├── CrewmateLottery.cs
│ │ ├── ImpostorLottery.cs
│ │ ├── NeutralKillingLottery.cs
│ │ ├── NeutralLottery.cs
│ │ └── SubRoleLottery.cs
│ ├── OptimizeRoleAlgorithm.cs
│ ├── RoleDistribution.cs
│ ├── StandardGamemode.cs
│ ├── StandardRoleAssignmentLogic.cs
│ ├── StandardWinConditions.cs
│ └── WinCons
│ │ └── SoloKillingWinCondition.cs
└── TestHnsGamemode.cs
├── Logging
└── DevLogger.cs
├── Managers
├── AntiBlackoutLogic.cs
├── BanManager.cs
├── BlackscreenResolver.cs
├── ChatManager.cs
├── CustomRoleManager.cs
├── DataFileAccessor.cs
├── Date
│ ├── ISpecialDate.cs
│ └── SpecialDate.cs
├── Friends
│ ├── FriendManager.cs
│ └── LastKnownAs.cs
├── Hacking
│ ├── HackingManager.cs
│ └── MonitoredRpcs.cs
├── History
│ ├── Events
│ │ ├── CustomDeathEvent.cs
│ │ ├── DeathEvent.cs
│ │ ├── ExiledEvent.cs
│ │ ├── IDeathEvent.cs
│ │ ├── IHistoryEvent.cs
│ │ ├── IKillEvent.cs
│ │ ├── IMultiTargetEvent.cs
│ │ ├── IRecipientEvent.cs
│ │ ├── IRoleChangeEvent.cs
│ │ ├── IRoleEvent.cs
│ │ ├── ITargetedEvent.cs
│ │ ├── IWinEvent.cs
│ │ ├── KillEvent.cs
│ │ ├── PlayerSavedEvent.cs
│ │ ├── ProtectEvent.cs
│ │ ├── RoleChangeEvent.cs
│ │ ├── ShapeshiftEvent.cs
│ │ ├── SuicideEvent.cs
│ │ └── TaskCompleteEvent.cs
│ ├── GameHistory.cs
│ ├── HistoryEvent.cs
│ ├── PlayerHistory.cs
│ ├── RoleChangeEvent.cs
│ └── Timestamp.cs
├── Hotkeys
│ ├── Hotkey.cs
│ ├── HotkeyManager.cs
│ └── ModKeybindings.cs
├── Models
│ ├── BanPlayerFile.cs
│ ├── BannedPlayer.cs
│ └── BannedWordFile.cs
├── PluginDataManager.cs
├── Reporting
│ ├── AnticheatReporter.cs
│ ├── IReportProducer.cs
│ ├── RProfiler.cs
│ ├── ReportInfo.cs
│ ├── ReportManager.cs
│ ├── ReportSignal.cs
│ ├── ReportTag.cs
│ └── RpcReporter.cs
├── Templates
│ ├── ConditionalParsers.cs
│ ├── Models
│ │ ├── Backing
│ │ │ ├── InlineConditionEvaluator.cs
│ │ │ └── TUAllRoles.cs
│ │ ├── ResolvedTrigger.cs
│ │ ├── TCondition.cs
│ │ ├── TTrigger.cs
│ │ ├── Template.cs
│ │ ├── TemplateFile.cs
│ │ ├── TemplateTrigger.cs
│ │ └── Units
│ │ │ ├── IConditionalUnit.cs
│ │ │ ├── Impl
│ │ │ ├── CommonConditionalUnit.cs
│ │ │ ├── StringListConditionalUnit.cs
│ │ │ ├── TConditionalDefault.cs
│ │ │ ├── TConditionalEnabledRoles.cs
│ │ │ ├── TConditionalEvaluate.cs
│ │ │ ├── TConditionalNotRole.cs
│ │ │ ├── TConditionalPlayerFlag.cs
│ │ │ ├── TConditionalRoles.cs
│ │ │ ├── TConditionalState.cs
│ │ │ ├── TConditionalStatuses.cs
│ │ │ ├── TConditionalUser.cs
│ │ │ ├── TConditionalVitals.cs
│ │ │ └── TRecursiveCondition.cs
│ │ │ └── TemplateUnit.cs
│ ├── TemplateCommandMigrator.cs
│ ├── TemplateLegacy.cs
│ ├── TemplateManager.cs
│ ├── TemplateMigration.cs
│ └── TemplateTriggers.cs
├── TimeoutManager.cs
└── Titles
│ ├── CustomTitle.cs
│ └── TitleManager.cs
├── ModConstants.cs
├── Options
├── Client
│ └── VideoOptions.cs
├── ClientOptions.cs
├── DefaultTabs.cs
├── DesyncOptions.cs
├── General
│ ├── AdminOptions.cs
│ ├── DebugOptions.cs
│ ├── GameplayOptions.cs
│ ├── MayhemOptions.cs
│ ├── MeetingOptions.cs
│ ├── MiscellaneousOptions.cs
│ └── SabotageOptions.cs
├── GeneralOptionTranslations.cs
├── GeneralOptions.cs
├── OptionShower.cs
├── OptionValue.cs
├── RoleOptions.cs
├── Roles
│ ├── MadmateOptions.cs
│ ├── NeutralOptions.cs
│ └── SubroleOptions.cs
└── ShowerPages.cs
├── Patches
├── Actions
│ ├── EnterVentPatch.cs
│ ├── FixedUpdatePatch.cs
│ ├── MurderPatches.cs
│ ├── PetPatch.cs
│ ├── ProtectPlayerPatch.cs
│ ├── ReportDeadBodyPatch.cs
│ ├── ShapeshiftPatch.cs
│ └── TaskCompletePatch.cs
├── AssignRoleOnDeathPatch.cs
├── BasicWrapperPatches.cs
├── Client
│ ├── ClientPatch.cs
│ ├── EndGameManagerPatch.cs
│ ├── SetKillTimerPatch.cs
│ └── UseVentPatch.cs
├── CoStartGamePatch.cs
├── EndGamePatch.cs
├── ExilePatch.cs
├── GameManagerPatch.cs
├── GameOptionsMenuPatch.cs
├── GameStartManagerPatch.cs
├── Hud
│ ├── HighlightPatches.cs
│ ├── HudPatch.cs
│ ├── SetHudActivePatch.cs
│ └── TaskTextPatch.cs
├── Intro
│ ├── BeginCrewmatePatch.cs
│ ├── BeginImpostorPatch.cs
│ ├── CoBeginPatch.cs
│ ├── IntroDestroyPatch.cs
│ └── ShowRolePatch.cs
├── JoinGameButtonPatch.cs
├── LadderPatch.cs
├── Meetings
│ ├── CastVotePatch.cs
│ ├── CheckForEndVotingPatch.cs
│ ├── MeetingHudPatch.cs
│ ├── MeetingStartPatch.cs
│ ├── MeetingUpdatePatch.cs
│ └── PlayerVoteAreaPatch.cs
├── Network
│ ├── CredentialsPatch.cs
│ ├── GameJoinPatch.cs
│ ├── PingTrackerPatch.cs
│ ├── PlayerJoinPatch.cs
│ ├── PlayerLeavePatch.cs
│ ├── RpcV3WrapperPatches.cs
│ └── ShipStatusPatch.cs
├── NoBlackoutPatch.cs
├── PlayerControlPatch.cs
├── SelectRolesPatch.cs
└── Systems
│ ├── CheckEndGameViaTasksPatch.cs
│ ├── DeteriorateCrashCoursePatch.cs
│ ├── DeteriorateOxygenPatch.cs
│ ├── DeteriorateReactorPatch.cs
│ ├── DoorsPatch.cs
│ ├── RecomputeTaskPatch.cs
│ ├── RpcSetTasksPatch.cs
│ ├── SabotagePatch.cs
│ ├── TaskAssignPatch.cs
│ └── UsablesPatch.cs
├── ROLE_TO_TEST
├── RPC
├── CheckedRpc.cs
├── HostRpc.cs
└── ModCalls.cs
├── RandomSpawn.cs
├── Roles
├── AbstractBaseRole.cs
├── CustomRole.cs
├── Debugger
│ ├── CustomSyncOptions.cs
│ └── Debugger.cs
├── Events
│ ├── AbilityEvent.cs
│ ├── BittenEvent.cs
│ ├── BombedEvent.cs
│ ├── CursedEvent.cs
│ ├── GenericAbilityEvent.cs
│ ├── GenericTargetedEvent.cs
│ ├── ManipulatedEvent.cs
│ ├── MisfiredEvent.cs
│ └── TargetedAbilityEvent.cs
├── Extra
│ ├── Fox.cs
│ ├── GM.cs
│ └── Troll.cs
├── Interactions
│ ├── DelayedInteraction.cs
│ ├── FakeFatalIntent.cs
│ ├── FatalIntent.cs
│ ├── HelpfulIntent.cs
│ ├── HostileIntent.cs
│ ├── IndirectInteraction.cs
│ ├── Interfaces
│ │ ├── IDelayedInteraction.cs
│ │ ├── IFatalIntent.cs
│ │ ├── IHelpfulIntent.cs
│ │ ├── IHostileIntent.cs
│ │ ├── IIndirectInteraction.cs
│ │ ├── IKillingIntent.cs
│ │ ├── IManipulatedInteraction.cs
│ │ ├── INeutralIntent.cs
│ │ ├── IRangedInteraction.cs
│ │ ├── IUnblockedInteraction.cs
│ │ ├── Intent.cs
│ │ ├── Interaction.cs
│ │ └── InteractionModifier.cs
│ ├── LotusInteraction.cs
│ ├── ManipulatedInteraction.cs
│ ├── NeutralIntent.cs
│ ├── RangedInteraction.cs
│ └── UnblockedInteraction.cs
├── Interfaces
│ ├── IModdable.cs
│ ├── IOverridenTaskHolderRole.cs
│ ├── IPhantomRole.cs
│ ├── ISabotagerRole.cs
│ ├── ISubrole.cs
│ ├── ITaskHolderRole.cs
│ ├── IVariableRole.cs
│ └── IVariantSubrole.cs
├── Internals
│ ├── ActionHandle.cs
│ ├── ActionMethod.cs
│ ├── ActivationType.cs
│ ├── Attributes
│ │ ├── ModifiedActionAttribute.cs
│ │ ├── NewOnSetupAttribute.cs
│ │ ├── RoleActionAttribute.cs
│ │ └── StaticEditor.cs
│ ├── EnforceFunctionOrderingRole.cs
│ ├── IllegalRole.cs
│ ├── InteractionResult.cs
│ ├── Interfaces
│ │ └── ICloneOnSetup.cs
│ ├── ModifiedAction.cs
│ ├── NewOnSetup.cs
│ ├── RoleAction.cs
│ ├── SpecialType.cs
│ └── Trackers
│ │ ├── IPlayerSelector.cs
│ │ ├── MeetingPlayerSelector.cs
│ │ └── VoteResult.cs
├── Legacy
│ ├── OldRoleSystemBridge.cs
│ └── Roles
│ │ ├── EgoistOld.cs
│ │ ├── Guesser.cs
│ │ ├── NecromancerOld.cs
│ │ ├── NinjaOld.cs
│ │ ├── SabotageMasterOLD.cs
│ │ └── TeamEgoist.cs
├── NotImplemented.cs
├── Overrides
│ ├── AdditiveOverride.cs
│ ├── GameOptionOverride.cs
│ ├── IndirectKillCooldown.cs
│ ├── MultiplicativeOverride.cs
│ └── Override.cs
├── RoleAbilityFlag.cs
├── RoleFlag.cs
├── RoleGroups
│ ├── Crew
│ │ ├── Alchemist
│ │ │ ├── Alchemist.Crafting.cs
│ │ │ ├── Alchemist.Effects.cs
│ │ │ ├── Alchemist.IngredientCollection.cs
│ │ │ ├── Alchemist.IngredientSpawning.cs
│ │ │ ├── Alchemist.Settings.cs
│ │ │ ├── Alchemist.cs
│ │ │ ├── Ingredients
│ │ │ │ ├── IngredientCatalyst.cs
│ │ │ │ ├── IngredientChaos.cs
│ │ │ │ ├── IngredientDeath.cs
│ │ │ │ ├── IngredientPurity.cs
│ │ │ │ ├── IngredientSight.cs
│ │ │ │ ├── IngredientTinkering.cs
│ │ │ │ └── Internal
│ │ │ │ │ ├── IAlchemyIngredient.cs
│ │ │ │ │ ├── IWorldIngredient.cs
│ │ │ │ │ ├── Ingredient.cs
│ │ │ │ │ └── IngredientInfo.cs
│ │ │ └── Potions
│ │ │ │ ├── ICraftable.cs
│ │ │ │ ├── Potion.cs
│ │ │ │ ├── PotionKilling.cs
│ │ │ │ ├── PotionProtection.cs
│ │ │ │ ├── PotionRandom.cs
│ │ │ │ ├── PotionRevealing.cs
│ │ │ │ ├── PotionSabotage.cs
│ │ │ │ ├── PotionSeeing.cs
│ │ │ │ ├── PotionShifting.cs
│ │ │ │ ├── PotionTeleportation.cs
│ │ │ │ └── PotionVoting.cs
│ │ ├── Bastion.cs
│ │ ├── Bodyguard.cs
│ │ ├── Chameleon.cs
│ │ ├── Charmer.cs
│ │ ├── Crusader.cs
│ │ ├── Demolitionist.cs
│ │ ├── Dictator.cs
│ │ ├── Doctor.cs
│ │ ├── Escort.cs
│ │ ├── ExConvict.cs
│ │ ├── Herbalist.cs
│ │ ├── Investigator.cs
│ │ ├── Mayor.cs
│ │ ├── Medic.cs
│ │ ├── Medium.cs
│ │ ├── Mystic.cs
│ │ ├── Observer.cs
│ │ ├── Oracle.cs
│ │ ├── Psychic.cs
│ │ ├── Repairman.cs
│ │ ├── Sheriff.cs
│ │ ├── Snitch.cs
│ │ ├── Speedrunner.cs
│ │ ├── Tracker.cs
│ │ ├── Transporter.cs
│ │ ├── Trapster.cs
│ │ ├── Veteran.cs
│ │ └── Vigilante.cs
│ ├── Impostors
│ │ ├── Assassin.cs
│ │ ├── Blackmailer.cs
│ │ ├── BountyHunter.cs
│ │ ├── Camouflager.cs
│ │ ├── Conman.cs
│ │ ├── Consort.cs
│ │ ├── Creeper.cs
│ │ ├── Disperser.cs
│ │ ├── Escapist.cs
│ │ ├── EvilGuesser.cs
│ │ ├── EvilTracker.cs
│ │ ├── FallenOracle.cs
│ │ ├── FireWorks.cs
│ │ ├── Freezer.cs
│ │ ├── Grenadier.cs
│ │ ├── IdentityThief.cs
│ │ ├── Janitor.cs
│ │ ├── Mafioso.cs
│ │ ├── Mare.cs
│ │ ├── Mastermind.cs
│ │ ├── Miner.cs
│ │ ├── Ninja.cs
│ │ ├── Pickpocket.cs
│ │ ├── Puppeteer.cs
│ │ ├── SerialKiller.cs
│ │ ├── Silencer.cs
│ │ ├── Sniper.cs
│ │ ├── Swooper.cs
│ │ ├── TimeThief.cs
│ │ ├── Traitor.cs
│ │ ├── Vampire.cs
│ │ ├── Vampiress.cs
│ │ ├── VoteStealer.cs
│ │ ├── Warlock.cs
│ │ ├── Witch.cs
│ │ └── YinYanger.cs
│ ├── Madmates
│ │ └── Roles
│ │ │ ├── MadCrewmate.cs
│ │ │ ├── MadGuardian.cs
│ │ │ ├── MadSnitch.cs
│ │ │ ├── Madmate.cs
│ │ │ └── Parasite.cs
│ ├── Neutral
│ │ ├── Amalgamation.cs
│ │ ├── Amnesiac.cs
│ │ ├── Archangel.cs
│ │ ├── Copycat.cs
│ │ ├── Executioner.cs
│ │ ├── Hacker.cs
│ │ ├── Harbinger.cs
│ │ ├── Hitman.cs
│ │ ├── Jester.cs
│ │ ├── Opportunist.cs
│ │ ├── Phantom.cs
│ │ ├── Pirate.cs
│ │ ├── Postman.cs
│ │ ├── SchrodingersCat.cs
│ │ ├── Survivor.cs
│ │ ├── Swapper.cs
│ │ ├── Terrorist.cs
│ │ ├── Trickster.cs
│ │ └── Vulture.cs
│ ├── NeutralKilling
│ │ ├── AgiTater.cs
│ │ ├── Arsonist.cs
│ │ ├── BloodKnight.cs
│ │ ├── CrewPostor.cs
│ │ ├── Demon.cs
│ │ ├── Egoist.cs
│ │ ├── Glitch.cs
│ │ ├── Jackal.cs
│ │ ├── Juggernaut.cs
│ │ ├── Marksman.cs
│ │ ├── NeutWitch.cs
│ │ ├── NeutralKillingBase.cs
│ │ ├── Occultist.cs
│ │ ├── Pelican.cs
│ │ ├── Pestilence.cs
│ │ ├── Pirate.cs
│ │ ├── PlagueBearer.cs
│ │ ├── PoisonMaster.cs
│ │ ├── Sidekick.cs
│ │ └── Werewolf.cs
│ ├── Stock
│ │ └── TaskRoleBase.cs
│ ├── Undead
│ │ ├── Events
│ │ │ ├── ConvertEvent.cs
│ │ │ └── InitiateEvent.cs
│ │ ├── Roles
│ │ │ ├── Deathknight.cs
│ │ │ ├── Necromancer.cs
│ │ │ ├── Retributionist.cs
│ │ │ └── UndeadRole.cs
│ │ └── UndeadWinCondition.cs
│ └── Vanilla
│ │ ├── Crewmate.cs
│ │ ├── CrewmateGhost.cs
│ │ ├── Engineer.cs
│ │ ├── GuardianAngel.cs
│ │ ├── Impostor.cs
│ │ ├── ImpostorGhost.cs
│ │ ├── Mechanic.cs
│ │ ├── Morphling.cs
│ │ ├── Physicist.cs
│ │ ├── Scientist.cs
│ │ └── Shapeshifter.cs
├── RoleLottery.cs
├── RoleRPC.cs
├── RoleTranslations.cs
├── RoleUtils.cs
└── Subroles
│ ├── Bait.cs
│ ├── Bewilder.cs
│ ├── Bloodlust.cs
│ ├── Deadly.cs
│ ├── Diseased.cs
│ ├── Escalation.cs
│ ├── Flash.cs
│ ├── Guesser.cs
│ ├── Honed.cs
│ ├── LoversReal.cs
│ ├── LoversSecondary.cs
│ ├── Nimble.cs
│ ├── Oblivious.cs
│ ├── Romantics
│ ├── Partner.cs
│ ├── Romantic.cs
│ ├── RomanticFaction.cs
│ ├── RuthlessRomantic.cs
│ └── VengefulRomantic.cs
│ ├── Sleuth.cs
│ ├── Subrole.cs
│ ├── TieBreaker.cs
│ ├── Torch.cs
│ ├── Unstoppable.cs
│ ├── Watcher.cs
│ └── Workhorse.cs
├── Statuses
├── IStatus.cs
├── Status.cs
└── StatusFlag.cs
├── Utilities
├── AssetLoader.cs
├── ColorMapper.cs
├── FixedUpdateLock.cs
├── FriendUtils.cs
├── GameObjectUtils.cs
├── JsonUtils.cs
├── ResolutionUtils.cs
├── TranslationUtil.cs
└── Utils.cs
└── Victory
├── CheckEndGamePatch.cs
├── Conditions
├── FallbackCondition.cs
├── IFactionWinCondition.cs
├── IWinCondition.cs
├── ManualWin.cs
├── ReasonType.cs
├── SabotageWin.cs
├── VanillaCrewmateWin.cs
└── VanillaImpostorWin.cs
├── VictoryScreen.cs
└── WinDelegate.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | obj/
3 | bin/
4 | FodyWeavers.xsd
5 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "editorconfig.editorconfig"
4 | ]
5 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "omnisharp.enableEditorConfigSupport": true,
3 | "omnisharp.enableRoslynAnalyzers": true,
4 | "editor.formatOnSave": true
5 | }
--------------------------------------------------------------------------------
/BAN-MEMO.md:
--------------------------------------------------------------------------------
1 | # 送るとBANされるRPC
2 | - 名前を勝手に変えるRPC
3 | - インポスターの人数・プレイヤーの速度を本来の範囲を超えて設定するRPC
4 | - 他人のバイザーを変更するRPC
5 | - 他人を追放するRPC
6 | - 他人に成りすましてチャットを送るRPC
7 | - 他人を変身させるRPC
8 | # 多分送るとBANされるRPC
9 | - インポスター以外がキルを行うCheckMurderRPC
10 | - 守護天使以外がプレイヤーを守るCheckProtectRPC
11 | # 送ってもBANされないRPC
12 | - 他人の色を変えるRPC
13 | - インポスター以外がキルを行うMurderPlayerRPC
14 | - 守護天使以外がプレイヤーを守るProtectPlayerRPC
15 | - 他人の役職を勝手に変えるRPC(ただし、守護天使以外は役職の上書きができない)
16 | - 他人の帽子・スキン・ペット・ネームプレートを変更するRPC
17 | - 特定の個人にチャットを送るRPC
--------------------------------------------------------------------------------
/Discord_Link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Discord_Link.png
--------------------------------------------------------------------------------
/Images/MIRA_HQ_Random_Map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/MIRA_HQ_Random_Map.png
--------------------------------------------------------------------------------
/Images/Mira_HQ_Random_Map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/Mira_HQ_Random_Map.png
--------------------------------------------------------------------------------
/Images/Polus_Random_Map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/Polus_Random_Map.png
--------------------------------------------------------------------------------
/Images/The_Airship_Random_Map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/The_Airship_Random_Map.png
--------------------------------------------------------------------------------
/Images/The_Skeld_Random_Map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/The_Skeld_Random_Map.png
--------------------------------------------------------------------------------
/Images/TownOfHost HideCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/TownOfHost HideCode.png
--------------------------------------------------------------------------------
/Images/TownOfHost-Discord.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/TownOfHost-Discord.png
--------------------------------------------------------------------------------
/Images/TownOfHost-Title.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/Images/TownOfHost-Title.png
--------------------------------------------------------------------------------
/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SourceGenerators/RoleEditorGenerator/src/.idea/.idea.src.dir/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Rider ignored files
5 | /projectSettingsUpdater.xml
6 | /contentModel.xml
7 | /.idea.src.iml
8 | /modules.xml
9 | # Editor-based HTTP Client requests
10 | /httpRequests/
11 | # Datasource local storage ignored files
12 | /dataSources/
13 | /dataSources.local.xml
14 |
--------------------------------------------------------------------------------
/SourceGenerators/RoleEditorGenerator/src/.idea/.idea.src.dir/.idea/indexLayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SourceGenerators/RoleEditorGenerator/src/.idea/.idea.src.dir/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/SourceGenerators/RoleEditorGenerator/src/RoleEditorGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 | false
8 | true
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/VentFramework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/VentFramework.dll
--------------------------------------------------------------------------------
/assets/Alert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Alert.png
--------------------------------------------------------------------------------
/assets/Blackmail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Blackmail.png
--------------------------------------------------------------------------------
/assets/CircleButtonBack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/CircleButtonBack.png
--------------------------------------------------------------------------------
/assets/Content/Results_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Content/Results_Icon.png
--------------------------------------------------------------------------------
/assets/CycleBack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/CycleBack.png
--------------------------------------------------------------------------------
/assets/CycleForward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/CycleForward.png
--------------------------------------------------------------------------------
/assets/Douse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Douse.png
--------------------------------------------------------------------------------
/assets/Flash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Flash.png
--------------------------------------------------------------------------------
/assets/Guess.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Guess.png
--------------------------------------------------------------------------------
/assets/Hack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Hack.png
--------------------------------------------------------------------------------
/assets/HighRes/CrewmateIcon_HighRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/CrewmateIcon_HighRes.png
--------------------------------------------------------------------------------
/assets/HighRes/Crewmate_HighRes2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/Crewmate_HighRes2.png
--------------------------------------------------------------------------------
/assets/HighRes/HideAndSeek_HighRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/HideAndSeek_HighRes.png
--------------------------------------------------------------------------------
/assets/HighRes/ImpostorIcon_HighRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/ImpostorIcon_HighRes.png
--------------------------------------------------------------------------------
/assets/HighRes/MiscIcon_HighRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/MiscIcon_HighRes.png
--------------------------------------------------------------------------------
/assets/HighRes/NeutralIcon_HighRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/NeutralIcon_HighRes.png
--------------------------------------------------------------------------------
/assets/HighRes/TabIcon_ColorWras.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/TabIcon_ColorWras.png
--------------------------------------------------------------------------------
/assets/HighRes/TabIcon_FreeForAll.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HighRes/TabIcon_FreeForAll.png
--------------------------------------------------------------------------------
/assets/HintButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HintButton.png
--------------------------------------------------------------------------------
/assets/History.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/History.png
--------------------------------------------------------------------------------
/assets/HistoryMenu/ResultsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HistoryMenu/ResultsIcon.png
--------------------------------------------------------------------------------
/assets/HistoryTab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/HistoryTab.png
--------------------------------------------------------------------------------
/assets/Ignite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Ignite.png
--------------------------------------------------------------------------------
/assets/Infect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Infect.png
--------------------------------------------------------------------------------
/assets/Janitor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Janitor.png
--------------------------------------------------------------------------------
/assets/KillMusic.raw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/KillMusic.raw
--------------------------------------------------------------------------------
/assets/LotusBanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/LotusBanner.png
--------------------------------------------------------------------------------
/assets/LotusBanner1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/LotusBanner1.png
--------------------------------------------------------------------------------
/assets/Lotus_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Lotus_Icon.png
--------------------------------------------------------------------------------
/assets/Mediate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Mediate.png
--------------------------------------------------------------------------------
/assets/Mimic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Mimic.png
--------------------------------------------------------------------------------
/assets/Mine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Mine.png
--------------------------------------------------------------------------------
/assets/NameMenu/AddSpace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/AddSpace.png
--------------------------------------------------------------------------------
/assets/NameMenu/ArrowDown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/ArrowDown.png
--------------------------------------------------------------------------------
/assets/NameMenu/ArrowLeft.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/ArrowLeft.png
--------------------------------------------------------------------------------
/assets/NameMenu/ArrowRight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/ArrowRight.png
--------------------------------------------------------------------------------
/assets/NameMenu/ArrowUp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/ArrowUp.png
--------------------------------------------------------------------------------
/assets/NameMenu/RemoveSpace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/RemoveSpace.png
--------------------------------------------------------------------------------
/assets/NameMenu/Visibility.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/Visibility.png
--------------------------------------------------------------------------------
/assets/NameMenu/ZoomIn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/ZoomIn.png
--------------------------------------------------------------------------------
/assets/NameMenu/ZoomOut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NameMenu/ZoomOut.png
--------------------------------------------------------------------------------
/assets/NinjaAssassinateButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NinjaAssassinateButton.png
--------------------------------------------------------------------------------
/assets/NinjaMarkButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/NinjaMarkButton.png
--------------------------------------------------------------------------------
/assets/Poison.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Poison.png
--------------------------------------------------------------------------------
/assets/Poisoned.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Poisoned.png
--------------------------------------------------------------------------------
/assets/Protect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Protect.png
--------------------------------------------------------------------------------
/assets/Rampage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Rampage.png
--------------------------------------------------------------------------------
/assets/Remember.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Remember.png
--------------------------------------------------------------------------------
/assets/Seer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Seer.png
--------------------------------------------------------------------------------
/assets/Settings/AddonBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/AddonBlank.png
--------------------------------------------------------------------------------
/assets/Settings/AddonButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/AddonButton.png
--------------------------------------------------------------------------------
/assets/Settings/AddonSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/AddonSettings.png
--------------------------------------------------------------------------------
/assets/Settings/ExitBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ExitBlank.png
--------------------------------------------------------------------------------
/assets/Settings/ExitButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ExitButton.png
--------------------------------------------------------------------------------
/assets/Settings/ExitIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ExitIcon.png
--------------------------------------------------------------------------------
/assets/Settings/GeneralBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/GeneralBlank.png
--------------------------------------------------------------------------------
/assets/Settings/GeneralButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/GeneralButton.png
--------------------------------------------------------------------------------
/assets/Settings/GeneralSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/GeneralSettings.png
--------------------------------------------------------------------------------
/assets/Settings/GraphicBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/GraphicBlank.png
--------------------------------------------------------------------------------
/assets/Settings/GraphicSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/GraphicSettings.png
--------------------------------------------------------------------------------
/assets/Settings/GraphicsButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/GraphicsButton.png
--------------------------------------------------------------------------------
/assets/Settings/MenuBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/MenuBackground.png
--------------------------------------------------------------------------------
/assets/Settings/ProgressBarFill.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ProgressBarFill.png
--------------------------------------------------------------------------------
/assets/Settings/ProgressBarMask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ProgressBarMask.png
--------------------------------------------------------------------------------
/assets/Settings/ReturnBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ReturnBlank.png
--------------------------------------------------------------------------------
/assets/Settings/ReturnButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ReturnButton.png
--------------------------------------------------------------------------------
/assets/Settings/ReturnIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/ReturnIcon.png
--------------------------------------------------------------------------------
/assets/Settings/SelectButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/SelectButton.png
--------------------------------------------------------------------------------
/assets/Settings/SoundBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/SoundBlank.png
--------------------------------------------------------------------------------
/assets/Settings/SoundButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/SoundButton.png
--------------------------------------------------------------------------------
/assets/Settings/SoundSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/SoundSettings.png
--------------------------------------------------------------------------------
/assets/Settings/UnselectButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/UnselectButton.png
--------------------------------------------------------------------------------
/assets/Settings/UpdateMenuBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/UpdateMenuBackground.png
--------------------------------------------------------------------------------
/assets/Settings/VentButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/VentButton.png
--------------------------------------------------------------------------------
/assets/Settings/VentLibBlank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/VentLibBlank.png
--------------------------------------------------------------------------------
/assets/Settings/VentLibSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Settings/VentLibSettings.png
--------------------------------------------------------------------------------
/assets/Sheriff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Sheriff.png
--------------------------------------------------------------------------------
/assets/Swoop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Swoop.png
--------------------------------------------------------------------------------
/assets/TOHTORBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TOHTORBackground.png
--------------------------------------------------------------------------------
/assets/TabIcons/ColorWarsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/ColorWarsIcon.png
--------------------------------------------------------------------------------
/assets/TabIcons/CrewmatesIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/CrewmatesIcon.png
--------------------------------------------------------------------------------
/assets/TabIcons/GeneralIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/GeneralIcon.png
--------------------------------------------------------------------------------
/assets/TabIcons/HideAndSeekIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/HideAndSeekIcon.png
--------------------------------------------------------------------------------
/assets/TabIcons/ImpostorsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/ImpostorsIcon.png
--------------------------------------------------------------------------------
/assets/TabIcons/ImpostorsIcon1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/ImpostorsIcon1.png
--------------------------------------------------------------------------------
/assets/TabIcons/ImpostorsIcon2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/ImpostorsIcon2.png
--------------------------------------------------------------------------------
/assets/TabIcons/MiscIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/MiscIcon.png
--------------------------------------------------------------------------------
/assets/TabIcons/NeutralsIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TabIcons/NeutralsIcon.png
--------------------------------------------------------------------------------
/assets/Tabs/Debug_Tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/Debug_Tab.png
--------------------------------------------------------------------------------
/assets/Tabs/HideAndSeek_HighRes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/HideAndSeek_HighRes.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon-old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon-old.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_Addons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_Addons.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_CaptureTheFlag.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_CaptureTheFlag.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_ColorWars.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_ColorWars.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_CrewmateRoles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_CrewmateRoles.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_FreeForAll.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_FreeForAll.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_HideAndSeek.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_HideAndSeek.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_ImpostorRoles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_ImpostorRoles.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_MainSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_MainSettings.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_MiscRoles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_MiscRoles.png
--------------------------------------------------------------------------------
/assets/Tabs/TabIcon_NeutralRoles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/TabIcon_NeutralRoles.png
--------------------------------------------------------------------------------
/assets/Tabs/among-us-6008615_1280.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Tabs/among-us-6008615_1280.webp
--------------------------------------------------------------------------------
/assets/Tabs/primether5348.txt:
--------------------------------------------------------------------------------
1 | type:sforce
2 | code:primether#5348
3 | color:#FF0000
4 | toptext:YouTuber
5 | name:AnonWorks
--------------------------------------------------------------------------------
/assets/TownOfHost-Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/TownOfHost-Logo.png
--------------------------------------------------------------------------------
/assets/Transport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Transport.png
--------------------------------------------------------------------------------
/assets/Vest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Vest.png
--------------------------------------------------------------------------------
/assets/Winners.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/Winners.png
--------------------------------------------------------------------------------
/assets/arlrdbd.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/arlrdbd.ttf
--------------------------------------------------------------------------------
/assets/main_menu/AnnouncementIconRedone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/main_menu/AnnouncementIconRedone.png
--------------------------------------------------------------------------------
/assets/main_menu/InventoryIconRedone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/main_menu/InventoryIconRedone.png
--------------------------------------------------------------------------------
/assets/main_menu/LittleDudeIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/main_menu/LittleDudeIcon.png
--------------------------------------------------------------------------------
/assets/main_menu/ShopIconRedone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/main_menu/ShopIconRedone.png
--------------------------------------------------------------------------------
/assets/main_menu/discord_button_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/main_menu/discord_button_icon.png
--------------------------------------------------------------------------------
/assets/tohtor-logo-old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/tohtor-logo-old.png
--------------------------------------------------------------------------------
/assets/tohtor-logo-rold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/tohtor-logo-rold.png
--------------------------------------------------------------------------------
/assets/tohtor-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ImaMapleTree/Lotus/4a834956a1e590f62a6b2f3cddacb3675f8c32d0/assets/tohtor-logo.png
--------------------------------------------------------------------------------
/src/API/Api.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API;
2 |
3 | public partial class Api
4 | {
5 |
6 |
7 | }
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/API/Odyssey/MatchData.Statuses.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.Statuses;
3 |
4 | namespace Lotus.API.Odyssey;
5 |
--------------------------------------------------------------------------------
/src/API/Priority.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API;
2 |
3 | public enum Priority: uint
4 | {
5 | First = 0,
6 | VeryHigh = 200,
7 | High = 400,
8 | Normal = 600,
9 | Low = 800,
10 | VeryLow = 1000,
11 | Last = uint.MaxValue
12 | }
--------------------------------------------------------------------------------
/src/API/ProtectedRpc.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Extensions;
2 | using VentLib.Logging;
3 | using VentLib.Networking.RPC;
4 | using VentLib.Utilities;
5 |
6 | namespace Lotus.API;
7 |
8 | public class ProtectedRpc
9 | {
10 | public static void CheckMurder(PlayerControl killer, PlayerControl target)
11 | {
12 | VentLogger.Trace("Protected Check Murder", "ProtectedRpc::CheckMurder");
13 | if (AmongUsClient.Instance.IsGameOver || !AmongUsClient.Instance.AmHost) return;
14 | if (target == null) return;
15 | GameData.PlayerInfo data = target.Data;
16 | if (data == null) return;
17 |
18 | if (MeetingHud.Instance != null)
19 | {
20 | killer.RpcVaporize(target);
21 | RpcV3.Immediate(killer.NetId, RpcCalls.MurderPlayer).Write(target).Send(target.GetClientId());
22 | return;
23 | }
24 |
25 | if (AmongUsClient.Instance.AmHost) killer.MurderPlayer(target);
26 | RpcV3.Immediate(killer.NetId, RpcCalls.MurderPlayer).Write(target).Send();
27 | target.Data.IsDead = true;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/CastVoteHookEvent.cs:
--------------------------------------------------------------------------------
1 | using VentLib.Utilities.Optionals;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class CastVoteHookEvent: IHookEvent
6 | {
7 | public PlayerControl Voter;
8 | public Optional Vote;
9 |
10 | public CastVoteHookEvent(PlayerControl voter, Optional vote)
11 | {
12 | this.Voter = voter;
13 | this.Vote = vote;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/ClientConnectHookEvent.cs:
--------------------------------------------------------------------------------
1 | using InnerNet;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class ClientConnectHookEvent: IHookEvent
6 | {
7 | public ClientData Client;
8 |
9 | public ClientConnectHookEvent(ClientData client)
10 | {
11 | Client = client;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/EmptyHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Reactive.HookEvents;
2 |
3 | public class EmptyHookEvent: IHookEvent
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/ExiledHookEvent.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class ExiledHookEvent: IHookEvent
6 | {
7 | public GameData.PlayerInfo ExiledPlayer;
8 | public List Voters;
9 |
10 | public ExiledHookEvent(GameData.PlayerInfo exiledPlayer, List voters)
11 | {
12 | ExiledPlayer = exiledPlayer;
13 | Voters = voters;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/GameJoinHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Reactive.HookEvents;
2 |
3 | public class GameJoinHookEvent: IHookEvent
4 | {
5 | public bool IsNewLobby;
6 |
7 | public GameJoinHookEvent(bool isNewLobby)
8 | {
9 | IsNewLobby = isNewLobby;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/GameStateHookEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Odyssey;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class GameStateHookEvent : IHookEvent
6 | {
7 | public MatchData MatchData;
8 |
9 | public GameStateHookEvent(MatchData matchData)
10 | {
11 | this.MatchData = matchData;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/LosersHookEvent.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.API.Player;
3 |
4 | namespace Lotus.API.Reactive.HookEvents;
5 |
6 | public class LosersHookEvent: IHookEvent
7 | {
8 | public List Losers;
9 |
10 | public LosersHookEvent(List losers)
11 | {
12 | Losers = losers;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/MeetingHookEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Vanilla.Meetings;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class MeetingHookEvent : IHookEvent
6 | {
7 | public PlayerControl Caller;
8 | public GameData.PlayerInfo? Reported;
9 | public MeetingDelegate Delegate;
10 |
11 | public MeetingHookEvent(PlayerControl caller, GameData.PlayerInfo? reporter, MeetingDelegate meetingDelegate)
12 | {
13 | Caller = caller;
14 | Reported = reporter;
15 | Delegate = meetingDelegate;
16 | }
17 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerActionHookEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Roles.Internals;
2 | using Lotus.Extensions;
3 |
4 | namespace Lotus.API.Reactive.HookEvents;
5 |
6 | public class PlayerActionHookEvent: IHookEvent
7 | {
8 | public PlayerControl Source;
9 | public RoleAction Action;
10 | public object[] Params;
11 |
12 | public PlayerActionHookEvent(PlayerControl source, RoleAction action, object[] parameters)
13 | {
14 | Source = source;
15 | Action = action;
16 | Params = parameters;
17 | }
18 |
19 | public void Trigger()
20 | {
21 | ActionHandle handle = ActionHandle.NoInit();
22 | Source.Trigger(Action.ActionType, ref handle, Params);
23 | }
24 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerDeathHookEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Managers.History.Events;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class PlayerDeathHookEvent: PlayerHookEvent
6 | {
7 | public IDeathEvent CauseOfDeath;
8 |
9 | public PlayerDeathHookEvent(PlayerControl player, IDeathEvent causeOfDeath) : base(player)
10 | {
11 | CauseOfDeath = causeOfDeath;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Reactive.HookEvents;
2 |
3 | public class PlayerHookEvent : IHookEvent
4 | {
5 | public PlayerControl Player;
6 |
7 | public PlayerHookEvent(PlayerControl player)
8 | {
9 | Player = player;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerMessageHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Reactive.HookEvents;
2 |
3 | public class PlayerMessageHookEvent : IHookEvent
4 | {
5 | public PlayerControl Player;
6 | public string Message;
7 |
8 | public PlayerMessageHookEvent(PlayerControl player, string message)
9 | {
10 | Player = player;
11 | Message = message;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerMurderHookEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Managers.History.Events;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class PlayerMurderHookEvent: PlayerDeathHookEvent
6 | {
7 | public PlayerControl Killer;
8 | public PlayerControl Victim;
9 |
10 | public PlayerMurderHookEvent(PlayerControl killer, PlayerControl victim, IDeathEvent causeOfDeath) : base(victim, causeOfDeath)
11 | {
12 | Killer = killer;
13 | Victim = victim;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerShapeshiftHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Reactive.HookEvents;
2 |
3 | public class PlayerShapeshiftHookEvent: IHookEvent
4 | {
5 | public PlayerControl Player;
6 | public GameData.PlayerInfo Target;
7 | public bool Reverted;
8 |
9 | public PlayerShapeshiftHookEvent(PlayerControl player, GameData.PlayerInfo target, bool reverted)
10 | {
11 | Player = player;
12 | Target = target;
13 | Reverted = reverted;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerStatusReceivedHook.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Statuses;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class PlayerStatusReceivedHook: PlayerHookEvent
6 | {
7 | public PlayerControl? Infector;
8 | public IStatus Status;
9 |
10 | public PlayerStatusReceivedHook(PlayerControl target, IStatus status, PlayerControl? infector = null) : base(target)
11 | {
12 | Infector = infector;
13 | Status = status;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerTaskHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Reactive.HookEvents;
2 |
3 | public class PlayerTaskHookEvent: IHookEvent
4 | {
5 | public PlayerControl Player;
6 | public NormalPlayerTask? PlayerTask;
7 |
8 | public PlayerTaskHookEvent(PlayerControl player, NormalPlayerTask? playerTask)
9 | {
10 | Player = player;
11 | PlayerTask = playerTask;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/PlayerTeleportedHookEvent.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class PlayerTeleportedHookEvent: PlayerHookEvent
6 | {
7 | public Vector2 OriginalLocation;
8 | public Vector2 NewLocation;
9 |
10 | public PlayerTeleportedHookEvent(PlayerControl player, Vector2 originalLocation, Vector2 newLocation) : base(player)
11 | {
12 | OriginalLocation = originalLocation;
13 | NewLocation = newLocation;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/ReceiveVersionHookEvent.cs:
--------------------------------------------------------------------------------
1 | using VentLib.Version;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class ReceiveVersionHookEvent: IHookEvent
6 | {
7 | public PlayerControl Player;
8 | public Version Version;
9 |
10 | public ReceiveVersionHookEvent(PlayerControl player, Version version)
11 | {
12 | Player = player;
13 | Version = version;
14 | }
15 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/RpcHookEvent.cs:
--------------------------------------------------------------------------------
1 | using VentLib.Networking.RPC;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public struct RpcHookEvent : IHookEvent
6 | {
7 | public RpcMeta Meta { get; }
8 |
9 | public RpcHookEvent(RpcMeta meta)
10 | {
11 | Meta = meta;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/SabotageFixHookEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Vanilla.Sabotages;
2 | using VentLib.Utilities.Optionals;
3 |
4 | namespace Lotus.API.Reactive.HookEvents;
5 |
6 | public class SabotageFixHookEvent : SabotageHookEvent
7 | {
8 | public Optional Fixer;
9 |
10 | public SabotageFixHookEvent(PlayerControl? fixer, ISabotage sabotage) : base(sabotage)
11 | {
12 | Fixer = fixer == null ? Optional.Null() : Optional.Of(fixer);
13 | }
14 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/SabotageHookEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Vanilla.Sabotages;
2 |
3 | namespace Lotus.API.Reactive.HookEvents;
4 |
5 | public class SabotageHookEvent: IHookEvent
6 | {
7 | public ISabotage Sabotage;
8 |
9 | public SabotageHookEvent(ISabotage sabotage)
10 | {
11 | Sabotage = sabotage;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/API/Reactive/HookEvents/WinnersHookEvent.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.API.Player;
3 |
4 | namespace Lotus.API.Reactive.HookEvents;
5 |
6 | public class WinnersHookEvent: IHookEvent
7 | {
8 | public List Winners;
9 |
10 | public WinnersHookEvent(List winners)
11 | {
12 | Winners = winners;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/API/Reactive/IHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Reactive;
2 |
3 | public interface IHookEvent
4 | {
5 | }
--------------------------------------------------------------------------------
/src/API/Stats/StatisticDump.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Lotus.API.Stats;
4 |
5 | public class StatisticDump
6 | {
7 | public Dictionary> Statistics { get; set; }
8 | }
--------------------------------------------------------------------------------
/src/API/Vanilla/MatchState.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.API.Vanilla;
2 |
3 | public static class MatchState
4 | {
5 | public static bool IsCountDown => GameStartManager.InstanceExists && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown;
6 | }
--------------------------------------------------------------------------------
/src/API/Vanilla/Sabotages/ISabotage.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using VentLib.Utilities.Optionals;
3 |
4 | namespace Lotus.API.Vanilla.Sabotages;
5 |
6 | public interface ISabotage
7 | {
8 | public SabotageType SabotageType();
9 |
10 | public bool Fix(PlayerControl? fixer = null);
11 |
12 | public Optional Caller();
13 |
14 | public void CallSabotage(PlayerControl sabotageCaller);
15 |
16 | public static ISabotage From(SabotageType type, PlayerControl? caller = null)
17 | {
18 | return type switch
19 | {
20 | Sabotages.SabotageType.Lights => new ElectricSabotage(caller),
21 | Sabotages.SabotageType.Communications => new CommsSabotage(caller),
22 | Sabotages.SabotageType.Oxygen => new OxygenSabotage(caller),
23 | Sabotages.SabotageType.Reactor => new ReactorSabotage(caller),
24 | Sabotages.SabotageType.Helicopter => new HelicopterSabotage(caller),
25 | _ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
26 | };
27 | }
28 | }
--------------------------------------------------------------------------------
/src/API/Vanilla/Sabotages/SabotageType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Lotus.API.Vanilla.Sabotages;
4 |
5 | [Flags]
6 | public enum SabotageType
7 | {
8 | Lights = 1,
9 | Communications = 2,
10 | Oxygen = 4,
11 | Reactor = 8,
12 | Door = 16,
13 | Helicopter = 32
14 | }
15 |
16 |
17 | public static class SabotageTypeMethods
18 | {
19 | public static SystemTypes ToSystemType(this SabotageType sabotageType)
20 | {
21 | return sabotageType switch
22 | {
23 | SabotageType.Lights => SystemTypes.Electrical,
24 | SabotageType.Communications => SystemTypes.Comms,
25 | SabotageType.Oxygen => SystemTypes.LifeSupp,
26 | SabotageType.Reactor => GameOptionsManager.Instance.CurrentGameOptions.MapId == 2
27 | ? SystemTypes.Laboratory
28 | : SystemTypes.Reactor,
29 | SabotageType.Door => SystemTypes.Doors,
30 | SabotageType.Helicopter => SystemTypes.Reactor,
31 | _ => throw new ArgumentOutOfRangeException(nameof(sabotageType), sabotageType, null)
32 | };
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Addons/AddonException.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 |
4 | namespace Lotus.Addons;
5 |
6 | public class AddonException : Exception
7 | {
8 | public AddonException(string? message, Exception? innerException) : base(message, innerException)
9 | { }
10 | }
--------------------------------------------------------------------------------
/src/Chat/ChatHandlers.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Chat.Commands;
2 | using VentLib.Utilities;
3 |
4 | namespace Lotus.Chat;
5 |
6 | public class ChatHandlers: CommandTranslations
7 | {
8 | public static ChatHandler NotPermitted()
9 | {
10 | return ChatHandler.Of(NotPermittedText, ModConstants.Palette.KillingColor.Colorize(NotPermittedTitle)).LeftAlign();
11 | }
12 |
13 | public static ChatHandler InvalidCmdUsage(string? message = null)
14 | {
15 | return ChatHandler.Of(message ?? InvalidUsage, ModConstants.Palette.InvalidUsage.Colorize(InvalidUsage)).LeftAlign();
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Chat/Commands/HistoryCommands.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using HarmonyLib;
3 | using Lotus.API.Odyssey;
4 | using Lotus.Utilities;
5 | using Lotus.API;
6 | using VentLib.Commands;
7 | using VentLib.Commands.Attributes;
8 | using VentLib.Commands.Interfaces;
9 |
10 | namespace Lotus.Chat.Commands;
11 |
12 | [Command("history")]
13 | public class HistoryCommands : ICommandReceiver
14 | {
15 | public void Receive(PlayerControl source, CommandContext context)
16 | {
17 | if (Game.MatchData.GameHistory == null!) return;
18 | ChatHandler.Send(source, Game.MatchData.GameHistory.Events.Where(e => e.IsCompletion()).Select(e => e.GenerateMessage()).Join(delimiter: "\n"));
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Chat/Commands/WordListCommands.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Managers;
2 | using UnityEngine;
3 | using VentLib.Commands;
4 | using VentLib.Commands.Attributes;
5 | using VentLib.Utilities;
6 |
7 | namespace Lotus.Chat.Commands;
8 |
9 | [Command(CommandFlag.HostOnly, "wordlist", "wl")]
10 | public class WordListCommands: CommandTranslations
11 | {
12 | [Command("reload")]
13 | private static void Reload(PlayerControl source)
14 | {
15 | string? exception = PluginDataManager.ChatManager.Reload();
16 | if (exception != null) ErrorMsg(exception).Send(source);
17 | else SuccessMsg("Success Reloading").Send(source);
18 | }
19 |
20 | private static ChatManager ChatManager => PluginDataManager.ChatManager;
21 |
22 | private static ChatHandler SuccessMsg(string message) => ChatHandler.Of(message, title: Color.green.Colorize("Success")).LeftAlign();
23 |
24 | private static ChatHandler ErrorMsg(string message) => ChatHandler.Of(message, title: CommandError).LeftAlign();
25 | }
--------------------------------------------------------------------------------
/src/Chat/OptionUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using VentLib.Options;
3 | using VentLib.Utilities.Extensions;
4 |
5 | namespace Lotus.Chat;
6 |
7 | public class OptionUtils
8 | {
9 | public static string OptionText(Option opt, int level = 0)
10 | {
11 | string levelText = level == 0 ? "" : " ".Repeat(level - 1);
12 | string text = $"{levelText}• {opt.Name()}: {opt.GetValueText()}\n";
13 | return text + opt.Children.GetConditionally(opt.GetValue()).Select(o => OptionText(o, level + 1)).Fuse("");
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Chat/Patches/ChatBubblePatch.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using HarmonyLib;
3 | using VentLib.Logging;
4 | using VentLib.Utilities.Harmony.Attributes;
5 |
6 | namespace Lotus.Chat.Patches;
7 |
8 | static class ChatBubblePatch
9 | {
10 | internal static readonly Queue SetLeftQueue = new();
11 |
12 | [QuickPostfix(typeof(ChatBubble), nameof(ChatBubble.SetRight))]
13 | public static void SetBubbleRight(ChatBubble __instance)
14 | {
15 | if (SetLeftQueue.TryDequeue(out int _)) __instance.SetLeft();
16 |
17 | __instance.TextArea.richText = true;
18 | }
19 |
20 | [QuickPostfix(typeof(ChatBubble), nameof(ChatBubble.SetLeft))]
21 | public static void SetBubbleLeft(ChatBubble __instance)
22 | {
23 | SetLeftQueue.TryDequeue(out int _);
24 | __instance.TextArea.richText = true;
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Chat/Patches/TextBoxPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.Logging;
3 | using VentLib.Utilities;
4 | using VentLib.Utilities.Harmony.Attributes;
5 |
6 | namespace Lotus.Chat.Patches;
7 |
8 | [HarmonyPatch(typeof(TextBoxTMP), nameof(TextBoxTMP.IsCharAllowed))]
9 | public class TextBoxPatch
10 | {
11 | public static void Postfix(TextBoxTMP __instance, char i, ref bool __result)
12 | {
13 | /*Async.Schedule(() => DevLogger.Log($"{__instance.text} | {__instance.text.Length} | {(int)__instance.text[0]}"), 0.01f);*/
14 | __result = i > 31 && i is not ('\r' or '\n');
15 | }
16 |
17 | [QuickPrefix(typeof(TextBoxTMP), nameof(TextBoxTMP.SetText))]
18 | public static void ModifyCharacterLimit(TextBoxTMP __instance) => __instance.characterLimit = AmongUsClient.Instance.AmHost ? 2000 : 300;
19 | }
--------------------------------------------------------------------------------
/src/Discord/Patches/DiscordPresencePatch.cs:
--------------------------------------------------------------------------------
1 | /*
2 | using Discord;
3 | using HarmonyLib;
4 |
5 | namespace Lotus.Discord.Patches;
6 |
7 | [HarmonyPatch(typeof(ActivityManager), nameof(ActivityManager.UpdateActivity))]
8 | public class DiscordPresencePatch
9 | {
10 | public static void Prefix(ActivityManager __instance, ref Activity activity)
11 | {
12 | activity.Details = $"Project Lotus {ProjectLotus.Instance.CurrentVersion.ToSimpleName()}";
13 | }
14 | }
15 | */
16 |
--------------------------------------------------------------------------------
/src/Extensions/AssemblyExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | namespace Lotus.Extensions;
4 |
5 | public static class AssemblyExtensions
6 | {
7 | public static string GetIdentity(this Assembly assembly, bool includeVersion = true)
8 | {
9 | AssemblyName name = assembly.GetName();
10 | string versionText = includeVersion ? $"Version={name.Version}, " : "";
11 | return $"{name.Name}, {versionText}PublicKey={name.GetPublicKey()}";
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Extensions/CooldownExtensions.cs:
--------------------------------------------------------------------------------
1 | using Lotus.GUI;
2 | using Lotus.Options;
3 | using VentLib.Utilities.Extensions;
4 |
5 | namespace Lotus.Extensions;
6 |
7 | public static class CooldownExtensions
8 | {
9 | public static string Format(this Cooldown cooldown, string str, bool autoFormat = false)
10 | {
11 | if (cooldown.IsReady()) return "";
12 | return autoFormat ? str.Formatted(cooldown + GeneralOptionTranslations.SecondsSuffix) : str;
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Extensions/CustomRoleExtension.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Roles;
2 | using VentLib.Utilities;
3 |
4 | namespace Lotus.Extensions;
5 |
6 | public static class CustomRoleExtension
7 | {
8 | public static string ColoredRoleName(this AbstractBaseRole abr) => abr.RoleColorGradient?.Apply(abr.RoleName) ?? abr.RoleColor.Colorize(abr.RoleName);
9 | }
--------------------------------------------------------------------------------
/src/Extensions/EnumerableExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using VentLib.Utilities.Extensions;
5 |
6 | namespace Lotus.Extensions;
7 |
8 | public static class EnumerableExtensions
9 | {
10 | public static List ToList(this Il2CppSystem.Collections.Generic.HashSet hashSet)
11 | {
12 | List list = new();
13 | foreach (T item in hashSet)
14 | list.Add(item);
15 | return list;
16 | }
17 |
18 | private static Random rng = new Random();
19 |
20 | public static void Shuffle(this IList list)
21 | {
22 | int n = list.Count;
23 | while (n > 1) {
24 | n--;
25 | int k = rng.Next(n + 1);
26 | (list[k], list[n]) = (list[n], list[k]);
27 | }
28 | }
29 |
30 | public static T RemoveLast(this IList list)
31 | {
32 | int index = list.Count - 1;
33 | T item = list[index];
34 | list.RemoveAt(index);
35 | return item;
36 | }
37 | }
--------------------------------------------------------------------------------
/src/Extensions/FileInfoExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using VentLib.Utilities.Extensions;
3 |
4 | namespace Lotus.Extensions;
5 |
6 | public static class FileInfoExtensions
7 | {
8 | public static void Rename(this FileInfo fileInfo, string name, bool overwrite = false)
9 | {
10 | DirectoryInfo directory = fileInfo.Directory!;
11 | fileInfo.MoveTo(directory.GetFile(name).FullName, overwrite);
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Extensions/GameOptionsExtensions.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | using System;
3 | using AmongUs.GameOptions;
4 |
5 | namespace Lotus.Extensions;
6 |
7 | public static class GameOptionsExtensions
8 | {
9 | [Obsolete("Looking into new TOH code to figure out a better way to do this")]
10 | public static NormalGameOptionsV07? AsNormalOptions(this IGameOptions options)
11 | {
12 | return options.Cast();
13 | }
14 |
15 | public static Byte[] ToBytes(this IGameOptions gameOptions)
16 | {
17 | return GameOptionsManager.Instance.gameOptionsFactory.ToBytes(gameOptions);
18 | }
19 |
20 | public static IGameOptions DeepCopy(this IGameOptions opt)
21 | {
22 | return GameOptionsManager.Instance.gameOptionsFactory.FromBytes(opt.ToBytes());
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Extensions/OutfitExtension.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Extensions;
2 |
3 | public static class OutfitExtension
4 | {
5 | public static GameData.PlayerOutfit Clone(this GameData.PlayerOutfit outfit)
6 | {
7 | GameData.PlayerOutfit copied = new()
8 | {
9 | PlayerName = outfit.PlayerName,
10 | ColorId = outfit.ColorId,
11 | dontCensorName = false,
12 | HatId = outfit.HatId,
13 | PetId = outfit.PetId,
14 | SkinId = outfit.SkinId,
15 | VisorId = outfit.VisorId,
16 | NamePlateId = outfit.NamePlateId
17 | };
18 | return copied;
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Extensions/PassiveButtonExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine.UI;
3 |
4 | namespace Lotus.Extensions;
5 |
6 | public static class PassiveButtonExtension
7 | {
8 | public static void Modify(this PassiveButton passiveButton, Action action)
9 | {
10 | if (passiveButton == null) return;
11 | passiveButton.OnClick = new Button.ButtonClickedEvent();
12 | passiveButton.OnClick.AddListener(action);
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Extensions/PlayerInfoExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Extensions;
2 |
3 | public static class PlayerInfoExtensions
4 | {
5 | public static string ColoredName(this GameData.PlayerInfo playerInfo)
6 | {
7 | return playerInfo == null! ? "Unknown" : playerInfo.ColorName.Trim('(', ')');
8 | }
9 | }
--------------------------------------------------------------------------------
/src/Extensions/PlayerRPCExtensions.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Player;
2 |
3 | namespace Lotus.Extensions;
4 |
5 | public static class PlayerRPCExtensions
6 | {
7 | public static void SetChatName(this PlayerControl player, string name)
8 | {
9 | if (player == null) return;
10 | player.Data.PlayerName = name;
11 | Players.SendPlayerData(player.Data, autoSetName: false);
12 | }
13 | }
--------------------------------------------------------------------------------
/src/Extensions/RangeExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Lotus.Extensions;
5 |
6 | public static class RangeExtensions
7 | {
8 | public static IEnumerable ToEnumerator(this Range range)
9 | {
10 | List ints = new();
11 | int start = range.Start.Value;
12 | int end = range.End.Value;
13 | if (end > start)
14 | for (int i = start; i <= end; i++) ints.Add(i);
15 | else
16 | for (int i = end; i <= start; i++) ints.Add(i);
17 | return ints;
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Extensions/RoleTypesExtension.cs:
--------------------------------------------------------------------------------
1 | using AmongUs.GameOptions;
2 |
3 | namespace Lotus.Extensions;
4 |
5 | public static class RoleTypesExtension
6 | {
7 | public static bool IsImpostor(this RoleTypes roleTypes) => roleTypes is RoleTypes.Impostor or RoleTypes.Shapeshifter;
8 | public static bool IsCrewmate(this RoleTypes roleTypes) => roleTypes is not (RoleTypes.Impostor or RoleTypes.Shapeshifter);
9 | }
--------------------------------------------------------------------------------
/src/Extensions/ShipStatusExtension.cs:
--------------------------------------------------------------------------------
1 | #nullable enable
2 | namespace Lotus.Extensions;
3 |
4 | public static class ShipStatusExtension
5 | {
6 | public static ISystemType? GetSystem(this ShipStatus shipStatus, SystemTypes system)
7 | {
8 | return shipStatus.Systems.ContainsKey(system) ? shipStatus.Systems[system] : null;
9 | }
10 |
11 | public static bool TryGetSystem(this ShipStatus shipStatus, SystemTypes system, out ISystemType? systemType)
12 | {
13 | systemType = null;
14 | if (!shipStatus.Systems.ContainsKey(system)) return false;
15 | systemType = shipStatus.Systems[system];
16 | return true;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Extensions/StatisticExtensions.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Player;
2 | using Lotus.API.Stats;
3 |
4 | namespace Lotus.Extensions;
5 |
6 | public static class StatisticExtensions
7 | {
8 | public static void Increment(this IAccumulativeStatistic statistic, UniquePlayerId uniquePlayerId)
9 | {
10 | statistic.Update(uniquePlayerId, i => i + 1);
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Extensions/StringExtension.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 | using Lotus.Utilities;
3 | using UnityEngine;
4 |
5 | namespace Lotus.Extensions;
6 |
7 | public static class StringExtension
8 | {
9 | public static string RemoveColorTags(this string str) => Regex.Replace(str, "<[^size>]*?>", "");
10 |
11 | public static Color? ToColor(this string str) => Utils.ConvertHexToColor(str);
12 |
13 | public static ulong SemiConsistentHash(this object obj)
14 | {
15 | string read = obj.ToString() ?? "null";
16 | ulong hashedValue = 3074457345618258791ul;
17 | foreach (var ch in read)
18 | {
19 | hashedValue += ch;
20 | hashedValue *= 3074457345618258799ul;
21 | }
22 | return hashedValue;
23 | }
24 |
25 | public static string ReplaceN(this string str, string oldText, string newText, int count)
26 | {
27 | Regex regex = new Regex(Regex.Escape(oldText));
28 | return regex.Replace(str, newText, count);
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Factions/Crew/Crewmates.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Impostors;
2 | using Lotus.Factions.Interfaces;
3 | using Lotus.Factions.Neutrals;
4 | using Lotus.Factions.Undead;
5 | using UnityEngine;
6 |
7 | namespace Lotus.Factions.Crew;
8 |
9 | public class Crewmates : Faction
10 | {
11 | public override Relation Relationship(Crewmates sameFaction) => Relation.FullAllies;
12 |
13 | public override bool CanSeeRole(PlayerControl player) => false;
14 |
15 | public override Color Color => ModConstants.Palette.CrewmateColor;
16 |
17 | public override Relation RelationshipOther(IFaction other)
18 | {
19 | return other switch
20 | {
21 | TheUndead => Relation.None,
22 | ImpostorFaction => Relation.None,
23 | Neutral when other.GetType() == typeof(Neutral) => Relation.None,
24 | _ => other.Relationship(this)
25 | };
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Factions/FactionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Interfaces;
2 | using Lotus.Roles;
3 | using Lotus.Extensions;
4 |
5 | namespace Lotus.Factions;
6 |
7 | public static class FactionExtensions
8 | {
9 | public static Relation Relationship(this PlayerControl player, PlayerControl other) => player.GetCustomRole().Relationship(other);
10 |
11 | public static Relation Relationship(this PlayerControl player, CustomRole other) => player.Relationship(other.Faction);
12 |
13 | public static Relation Relationship(this PlayerControl player, IFaction faction) => player.GetCustomRole().Relationship(faction);
14 |
15 | public static Relation Relationship(this CustomRole role, CustomRole other) => role.Relationship(other.Faction);
16 |
17 | public static Relation Relationship(this CustomRole role, IFaction faction) => role.Faction.Relationship(faction);
18 | }
--------------------------------------------------------------------------------
/src/Factions/FactionInstances.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Crew;
2 | using Lotus.Factions.Impostors;
3 | using Lotus.Factions.Neutrals;
4 | using Lotus.Factions.Undead;
5 |
6 | namespace Lotus.Factions;
7 |
8 | public class FactionInstances
9 | {
10 | public static Crewmates Crewmates { get; } = new();
11 | public static ImpostorFaction Impostors { get; } = new();
12 | public static Madmates Madmates { get; } = new();
13 | public static TheUndead TheUndead { get; } = new TheUndead.Origin();
14 | public static Neutral Neutral { get; } = new();
15 | public static Modifiers Modifiers { get; } = new();
16 | }
--------------------------------------------------------------------------------
/src/Factions/Impostors/ImpostorFaction.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Crew;
2 | using Lotus.Factions.Interfaces;
3 | using Lotus.Factions.Neutrals;
4 | using Lotus.Factions.Undead;
5 | using UnityEngine;
6 |
7 | namespace Lotus.Factions.Impostors;
8 |
9 | public class ImpostorFaction : Faction
10 | {
11 | public override Relation Relationship(ImpostorFaction sameFaction) => Relation.FullAllies;
12 |
13 | public override bool CanSeeRole(PlayerControl player) => true;
14 |
15 | public override Color Color => Color.red;
16 |
17 | public override string Name() => "Impostors";
18 |
19 | public override Relation RelationshipOther(IFaction other)
20 | {
21 | return other switch
22 | {
23 | TheUndead => Relation.None,
24 | Crewmates => Relation.None,
25 | Neutral when other.GetType() == typeof(Neutral) => Relation.None,
26 | _ => other.Relationship(this)
27 | };
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Factions/Impostors/Madmates.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Interfaces;
2 | using VentLib.Localization.Attributes;
3 |
4 | namespace Lotus.Factions.Impostors;
5 |
6 | [Localized("Factions.Madmates")]
7 | public class Madmates : ImpostorFaction, ISubFaction
8 | {
9 | [Localized(nameof(Name))]
10 | private static string name = "Madmates";
11 |
12 | public override string Name() => name;
13 |
14 | public Relation MainFactionRelationship() => Relation.SharedWinners;
15 |
16 | public Relation Relationship(ISubFaction subFaction)
17 | {
18 | return subFaction is Madmates ? Relation.SharedWinners : subFaction.Relationship(this);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Factions/Interfaces/IFaction.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Roles;
2 | using UnityEngine;
3 |
4 | namespace Lotus.Factions.Interfaces;
5 |
6 | public interface IFaction
7 | {
8 | public string Name();
9 |
10 | public Relation Relationship(IFaction other);
11 |
12 | public Relation Relationship(CustomRole otherRole);
13 |
14 | public bool CanSeeRole(PlayerControl player);
15 |
16 | public Color Color { get; }
17 | }
18 |
19 | public interface IFaction : IFaction where T : IFaction
20 | {
21 | public Relation Relationship(T sameFaction);
22 | }
--------------------------------------------------------------------------------
/src/Factions/Interfaces/ISubFaction.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Factions.Interfaces;
2 |
3 | public interface ISubFaction where T: IFaction
4 | {
5 | public string Name();
6 |
7 | public Relation MainFactionRelationship();
8 |
9 | public Relation Relationship(ISubFaction subFaction);
10 | }
--------------------------------------------------------------------------------
/src/Factions/Modifiers.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Interfaces;
2 | using Lotus.Roles;
3 | using UnityEngine;
4 | using VentLib.Localization.Attributes;
5 |
6 | namespace Lotus.Factions;
7 |
8 | [Localized("Factions.Modifiers")]
9 | public class Modifiers: IFaction
10 | {
11 | [Localized(nameof(Name))]
12 | private static string name = "Modifiers";
13 |
14 | public string Name() => name;
15 |
16 | public Relation Relationship(Modifiers sameFaction) => Relation.None;
17 |
18 | public Relation Relationship(IFaction other) => Relation.None;
19 |
20 | public Relation Relationship(CustomRole otherRole) => Relation.None;
21 |
22 | public bool CanSeeRole(PlayerControl player) => false;
23 |
24 | public Color Color => new(0.45f, 1f, 0.7f);
25 | }
--------------------------------------------------------------------------------
/src/Factions/Neutrals/Neutral.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Interfaces;
2 | using Lotus.Options;
3 | using UnityEngine;
4 | using VentLib.Localization.Attributes;
5 |
6 | namespace Lotus.Factions.Neutrals;
7 |
8 | [Localized($"Factions.{nameof(Neutral)}")]
9 | public class Neutral : Faction
10 | {
11 | [Localized(nameof(Name))]
12 | private static string _name = "Neutrals";
13 |
14 | private readonly string factionName;
15 |
16 | public Neutral(string? factionName = null)
17 | {
18 | this.factionName = factionName ?? _name;
19 | }
20 |
21 | public override string Name() => this.factionName;
22 |
23 | public override Relation Relationship(Neutral sameFaction) => Relation.None;
24 |
25 | public override bool CanSeeRole(PlayerControl player) => RoleOptions.NeutralOptions.KnowAlliedRoles;
26 |
27 | public override Color Color => Color.gray;
28 |
29 | public override Relation RelationshipOther(IFaction other) => Relation.None;
30 | }
--------------------------------------------------------------------------------
/src/Factions/Relation.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Factions;
2 |
3 | public enum Relation
4 | {
5 | None,
6 | SharedWinners,
7 | FullAllies
8 | }
--------------------------------------------------------------------------------
/src/Factions/Undead/TheUndead.Converted.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Interfaces;
2 | using Lotus.GUI.Name.Components;
3 |
4 | namespace Lotus.Factions.Undead;
5 |
6 | public partial class TheUndead
7 | {
8 | public class Converted : TheUndead, ISubFaction
9 | {
10 | public NameComponent NameComponent { get; }
11 |
12 | public Converted(NameComponent component)
13 | {
14 | NameComponent = component;
15 | }
16 |
17 | public Relation MainFactionRelationship() => Relation.FullAllies;
18 |
19 | public Relation Relationship(ISubFaction subFaction)
20 | {
21 | return subFaction switch
22 | {
23 | Origin => Relation.FullAllies,
24 | Converted => Relation.FullAllies,
25 | Unconverted => Relation.SharedWinners,
26 | _ => subFaction.Relationship(this)
27 | };
28 | }
29 |
30 | public override bool CanSeeRole(PlayerControl player) => true;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/Factions/Undead/TheUndead.Origin.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Interfaces;
2 |
3 | namespace Lotus.Factions.Undead;
4 |
5 | public partial class TheUndead
6 | {
7 | public class Origin : TheUndead, ISubFaction
8 | {
9 | public override bool CanSeeRole(PlayerControl player) => true;
10 |
11 | public Relation MainFactionRelationship() => Relation.FullAllies;
12 |
13 | public Relation Relationship(ISubFaction subFaction)
14 | {
15 | return subFaction switch
16 | {
17 | Origin => Relation.FullAllies,
18 | Converted => Relation.FullAllies,
19 | Unconverted => Relation.SharedWinners,
20 | _ => subFaction.Relationship(this)
21 | };
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Factions/Undead/TheUndead.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Factions.Crew;
2 | using Lotus.Factions.Impostors;
3 | using Lotus.Factions.Interfaces;
4 | using Lotus.Factions.Neutrals;
5 | using UnityEngine;
6 |
7 | namespace Lotus.Factions.Undead;
8 |
9 | public abstract partial class TheUndead : Faction
10 | {
11 | public override string Name() => "The Undead";
12 |
13 | public override Relation Relationship(TheUndead sameFaction) => Relation.FullAllies;
14 |
15 | public override Relation RelationshipOther(IFaction other)
16 | {
17 | return other switch
18 | {
19 | ImpostorFaction => Relation.None,
20 | Crewmates => Relation.None,
21 | Neutral => Relation.None,
22 | _ => other.Relationship(this)
23 | };
24 | }
25 |
26 | public override Color Color => new(0.59f, 0.76f, 0.36f);
27 | }
--------------------------------------------------------------------------------
/src/GUI/Counters/ICounter.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.GUI.Counters;
2 |
3 | public interface ICounter
4 | {
5 | public int Count();
6 |
7 | public string CountString();
8 | }
--------------------------------------------------------------------------------
/src/GUI/Counters/LiveCounter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 | using VentLib.Utilities;
4 |
5 | namespace Lotus.GUI.Counters;
6 |
7 | public class LiveCounter : ICounter
8 | {
9 | private int type;
10 | private Func topSupplier;
11 | private Func? botSupplier;
12 | private Color color = new(0.92f, 0.77f, 0.22f);
13 |
14 | public LiveCounter(Func topSupplier, Func botSupplier, Color? color = null)
15 | {
16 | if (color != null) this.color = color.Value;
17 | this.topSupplier = topSupplier;
18 | this.botSupplier = botSupplier;
19 | type = 1;
20 | }
21 |
22 | public LiveCounter(Func topSupplier, Color? color = null)
23 | {
24 | if (color != null) this.color = color.Value;
25 | this.topSupplier = topSupplier;
26 | }
27 |
28 | public string CountString()
29 | {
30 | string innerString = color.Colorize(type == 0 ? "" + topSupplier() : $"{topSupplier()}/{botSupplier!()}");
31 | return Color.white.Colorize($"({innerString})");
32 | }
33 |
34 | public int Count() => topSupplier();
35 | }
--------------------------------------------------------------------------------
/src/GUI/Counters/StaticCounter.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using VentLib.Utilities;
3 |
4 | namespace Lotus.GUI.Counters;
5 |
6 | public class StaticCounter : ICounter
7 | {
8 | private int type;
9 | private int topValue;
10 | private int botValue;
11 | private Color color = new(0.92f, 0.77f, 0.22f);
12 |
13 | public StaticCounter(int topValue, int botValue, Color? color = null)
14 | {
15 | if (color != null) this.color = color.Value;
16 | this.topValue = topValue;
17 | this.botValue = botValue;
18 | type = 1;
19 | }
20 |
21 | public StaticCounter(int topValue, Color? color = null)
22 | {
23 | if (color != null) this.color = color.Value;
24 | this.topValue = topValue;
25 | }
26 |
27 | public void Increment() => topValue++;
28 |
29 | public void Decrement() => botValue++;
30 |
31 | public string CountString()
32 | {
33 | string innerString = color.Colorize(type == 0 ? "" + topValue : $"{topValue}/{botValue}");
34 | return Color.white.Colorize($"({innerString})");
35 | }
36 |
37 | public int Count() => topValue;
38 | }
--------------------------------------------------------------------------------
/src/GUI/Menus/HistoryMenu2/IHistoryMenuChild.cs:
--------------------------------------------------------------------------------
1 | using VentLib.Localization.Attributes;
2 |
3 | namespace Lotus.GUI.Menus.HistoryMenu2;
4 |
5 | [Localized("GUI.HistoryMenu")]
6 | public interface IHistoryMenuChild
7 | {
8 | public PassiveButton CreateTabButton(PassiveButton prefab);
9 |
10 | public void Open();
11 |
12 | public void Close();
13 | }
--------------------------------------------------------------------------------
/src/GUI/Menus/OptionsMenu/Components/SimpleDropdownButton.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 | using UnityEngine.UI;
4 | using VentLib.Utilities.Attributes;
5 |
6 | namespace Lotus.GUI.Menus.OptionsMenu.Components;
7 |
8 | [RegisterInIl2Cpp]
9 | public class SimpleDropdownButton: MonoBehaviour
10 | {
11 | private GameObject anchorObject;
12 | private Dropdown dropdown;
13 |
14 | public SimpleDropdownButton(IntPtr intPtr) : base(intPtr)
15 | {
16 | anchorObject = new GameObject("Anchor");
17 | anchorObject.transform.localScale = new Vector3(10f, 10f, 10f);
18 | anchorObject.transform.SetParent(transform);
19 | dropdown = anchorObject.AddComponent();
20 | }
21 |
22 | private void Start()
23 | {
24 | Il2CppSystem.Collections.Generic.List options = new();
25 | options.Add("480 x 1080");
26 | options.Add("900 x 3280");
27 |
28 | dropdown.ClearOptions();
29 | dropdown.AddOptions(options);
30 | }
31 | }
--------------------------------------------------------------------------------
/src/GUI/Menus/OptionsMenu/Patches/GameOptionMenuOpenPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.Logging;
3 | using VentLib.Utilities.Harmony.Attributes;
4 |
5 | namespace Lotus.GUI.Menus.OptionsMenu.Patches;
6 |
7 | [HarmonyPatch(typeof(OptionsMenuBehaviour), nameof(OptionsMenuBehaviour.Start))]
8 | public class GameOptionMenuOpenPatch
9 | {
10 | private static CustomOptionContainer customOptionContainer;
11 | public static void Postfix(OptionsMenuBehaviour __instance)
12 | {
13 | DevLogger.Log("Starting in here");
14 | customOptionContainer = __instance.gameObject.AddComponent();
15 | customOptionContainer.PassMenu(__instance);
16 |
17 | DevLogger.Log("finishing here");
18 | }
19 |
20 | [QuickPrefix(typeof(OptionsMenuBehaviour), nameof(OptionsMenuBehaviour.ResetText))]
21 | public static bool DisableResetTextFunc(OptionsMenuBehaviour __instance) => false;
22 | }
--------------------------------------------------------------------------------
/src/GUI/Menus/OptionsMenu/Submenus/IBaseOptionMenuComponent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.GUI.Menus.OptionsMenu.Submenus;
2 |
3 | public interface IBaseOptionMenuComponent
4 | {
5 | public void PassMenu(OptionsMenuBehaviour menuBehaviour);
6 |
7 | public void Open();
8 |
9 | public void Close();
10 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Components/SimpleIndicatorComponent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Odyssey;
2 | using Lotus.API;
3 | using UnityEngine;
4 | using VentLib.Utilities;
5 |
6 | namespace Lotus.GUI.Name.Components;
7 |
8 | public class SimpleIndicatorComponent : IndicatorComponent
9 | {
10 | public SimpleIndicatorComponent(string mainText, Color color, GameState gameState, params PlayerControl[] viewers) : base(color.Colorize(mainText), gameState, Name.ViewMode.Additive, viewers)
11 | {
12 | }
13 |
14 | public SimpleIndicatorComponent(string mainText, Color color, GameState[] gameStates, params PlayerControl[] viewers) : base(color.Colorize(mainText), gameStates, Name.ViewMode.Additive, viewers)
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Holders/CooldownHolder.cs:
--------------------------------------------------------------------------------
1 | using Lotus.GUI.Name.Components;
2 |
3 | namespace Lotus.GUI.Name.Holders;
4 |
5 | public class CooldownHolder : ComponentHolder
6 | {
7 | public CooldownHolder(int line = 0) : base(line)
8 | {
9 | }
10 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Holders/CounterHolder.cs:
--------------------------------------------------------------------------------
1 | using Lotus.GUI.Name.Components;
2 |
3 | namespace Lotus.GUI.Name.Holders;
4 |
5 | public class CounterHolder : ComponentHolder
6 | {
7 | public CounterHolder(int line = 0) : base(line)
8 | {
9 | }
10 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Holders/IndicatorHolder.cs:
--------------------------------------------------------------------------------
1 | using Lotus.GUI.Name.Components;
2 |
3 | namespace Lotus.GUI.Name.Holders;
4 |
5 | public class IndicatorHolder : ComponentHolder
6 | {
7 | public IndicatorHolder(int line = 0) : base(line)
8 | {
9 | }
10 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Holders/NameHolder.cs:
--------------------------------------------------------------------------------
1 | using Lotus.GUI.Name.Components;
2 | using VentLib.Utilities.Collections;
3 |
4 | namespace Lotus.GUI.Name.Holders;
5 |
6 | public class NameHolder : ComponentHolder
7 | {
8 | public NameComponent? TrueName;
9 |
10 | public NameHolder(int line = 0) : base(line)
11 | {
12 | Spacing = 1;
13 | }
14 |
15 | public override Remote Add(NameComponent component)
16 | {
17 | TrueName = component;
18 | return base.Add(component);
19 | }
20 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Holders/RoleHolder.cs:
--------------------------------------------------------------------------------
1 | using Lotus.GUI.Name.Components;
2 |
3 | namespace Lotus.GUI.Name.Holders;
4 |
5 | public class RoleHolder : ComponentHolder
6 | {
7 | public RoleHolder(int line = 0) : base(line)
8 | {
9 | Spacing = 1;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Holders/TextHolder.cs:
--------------------------------------------------------------------------------
1 | using Lotus.GUI.Name.Components;
2 |
3 | namespace Lotus.GUI.Name.Holders;
4 |
5 | public class TextHolder : ComponentHolder
6 | {
7 | public TextHolder(int line = 0) : base(line)
8 | {
9 | Spacing = 1;
10 | }
11 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Impl/Ubifix.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.GUI.Name.Interfaces;
3 | using UnityEngine;
4 |
5 | namespace Lotus.GUI.Name.Impl;
6 |
7 | public class Ubifix
8 | {
9 | private List<(INameModelComponent, int)> fixes = new();
10 | private LiveString liveString;
11 |
12 |
13 | public Ubifix(LiveString liveString)
14 | {
15 | this.liveString = liveString;
16 | }
17 |
18 | public Ubifix(string str, Color color) : this(new LiveString(str, color))
19 | {
20 | }
21 |
22 | public void AddComponent(INameModelComponent nameModelComponent, int fix) => fixes.Add((nameModelComponent, fix));
23 |
24 | public void Delete() => fixes.ForEach(f =>
25 | {
26 | if (f.Item2 == 0) f.Item1.RemovePrefix(this);
27 | if (f.Item2 == 1) f.Item1.RemoveSuffix(this);
28 | });
29 |
30 | public override string ToString() => liveString.ToString();
31 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Interfaces/IComponentHolder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Lotus.API.Odyssey;
5 | using Lotus.API;
6 | using VentLib.Utilities.Collections;
7 |
8 | namespace Lotus.GUI.Name.Interfaces;
9 |
10 | public interface IComponentHolder : IComponentHolder where T: INameModelComponent
11 | {
12 | List IComponentHolder.Components() => this.Components().Cast().ToList();
13 |
14 | public new RemoteList Components();
15 | }
16 |
17 | public interface IComponentHolder
18 | {
19 | public List Components();
20 |
21 | public void SetSize(float size);
22 |
23 | public void SetLine(int line);
24 |
25 | public int Line();
26 |
27 | public void SetSpacing(int spacing);
28 |
29 | public string Render(PlayerControl player, GameState state);
30 |
31 | public bool Updated(byte playerId);
32 |
33 | public void AddListener(Action eventConsumer);
34 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Interfaces/INameModel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.API.Odyssey;
3 |
4 | namespace Lotus.GUI.Name.Interfaces;
5 |
6 | public interface INameModel
7 | {
8 | public bool Updated();
9 |
10 | public void Render(List players) => players.ForEach(p => this.RenderFor(p));
11 |
12 | public string Render(GameState? state = null, bool sendToPlayer = true, bool force = false);
13 |
14 | public string RenderFor(PlayerControl player, GameState? state = null, bool sendToPlayer = true, bool force = false);
15 |
16 | public List ComponentHolders();
17 |
18 | public T GetComponentHolder() where T : IComponentHolder;
19 |
20 | // ReSharper disable once InconsistentNaming
21 | public T GCH() where T : IComponentHolder;
22 | }
--------------------------------------------------------------------------------
/src/GUI/Name/Interfaces/INameModelComponent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Lotus.API.Odyssey;
4 | using Lotus.GUI.Name.Impl;
5 | using Lotus.API;
6 | using VentLib.Utilities.Optionals;
7 |
8 | namespace Lotus.GUI.Name.Interfaces;
9 |
10 | public interface INameModelComponent
11 | {
12 | public void AddPrefix(Ubifix prefix);
13 |
14 | public void AddSuffix(Ubifix suffix);
15 |
16 | public void AddViewer(PlayerControl player);
17 |
18 | public INameModelComponent Clone();
19 |
20 | public GameState[] GameStates();
21 |
22 | public string GenerateText();
23 |
24 | public void SetMainText(LiveString liveString);
25 |
26 | public void SetViewerSupplier(Func> viewers);
27 |
28 | public Optional Size();
29 |
30 | public void RemovePrefix(Ubifix prefix);
31 |
32 | public void RemoveSuffix(Ubifix suffix);
33 |
34 | public void RemoveViewer(byte playerId);
35 |
36 | public List Viewers();
37 |
38 | public ViewMode ViewMode();
39 |
40 |
41 | }
--------------------------------------------------------------------------------
/src/GUI/Name/LiveString.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using UnityEngine;
3 | using VentLib.Utilities;
4 |
5 | namespace Lotus.GUI.Name;
6 |
7 | public class LiveString
8 | {
9 | public static LiveString Empty = new("");
10 |
11 | private readonly Color? mainColor;
12 | private readonly Func valueSupplier;
13 |
14 | public LiveString(Func supplier, Color? color = null)
15 | {
16 | mainColor = color;
17 | valueSupplier = supplier;
18 | }
19 |
20 | public LiveString(string value, Color? color = null) : this(() => value, color)
21 | {
22 | }
23 |
24 | public static explicit operator LiveString(Func supplier) => new(supplier);
25 |
26 | public static implicit operator Func(LiveString liveString) => liveString.valueSupplier;
27 |
28 | public override string ToString() => mainColor == null ? valueSupplier() : mainColor.Value.Colorize(valueSupplier());
29 | }
--------------------------------------------------------------------------------
/src/GUI/Name/TextUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.RegularExpressions;
3 | using UnityEngine;
4 | using VentLib.Utilities;
5 |
6 | namespace Lotus.GUI.Name;
7 |
8 | public class TextUtils
9 | {
10 | private static Regex utf32Regex = new(@"\\u[a-zA-Z0-9]*");
11 |
12 | public static string ApplySize(float size, string str)
13 | {
14 | return $"{str}";
15 | }
16 |
17 | public string ToUTF32(string input)
18 | {
19 | string output = input;
20 |
21 | while (output.Contains(@"\u"))
22 | {
23 | output = utf32Regex.Replace(output, @"\U000" + output.Substring(output.IndexOf(@"\u", StringComparison.Ordinal) + 2, 5), 1);
24 | }
25 |
26 | return output;
27 | }
28 |
29 | public static string ApplyGradient(string str, params Color[] colors)
30 | {
31 | return new ColorGradient(colors).Apply(str);
32 | }
33 |
34 | public static string ApplyMark(string str, Color color)
35 | {
36 | return $"{str}";
37 | }
38 | }
--------------------------------------------------------------------------------
/src/GUI/Name/UI.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.GUI.Name;
2 |
3 | public enum UI
4 | {
5 | Name,
6 | Role,
7 | Subrole,
8 | Cooldown,
9 | Counter,
10 | Indicator,
11 | Text
12 | }
--------------------------------------------------------------------------------
/src/GUI/Name/ViewMode.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.GUI.Name;
2 |
3 | public enum ViewMode
4 | {
5 | Additive,
6 | Replace,
7 | Absolute,
8 | Overriden
9 | }
--------------------------------------------------------------------------------
/src/GUI/Patches/HideBanButtonPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 |
3 | namespace Lotus.GUI.Patches;
4 |
5 | [HarmonyPatch(typeof(ChatController), nameof(ChatController.Toggle))]
6 | class CancelBanMenuStuckPatch
7 | {
8 | public static void Prefix(ChatController __instance)
9 | {
10 | if (__instance.IsOpen && !__instance.animating) // (IsOpen==true) == 今から閉じないといけない
11 | {
12 | // BanButtonを非表示にする
13 | __instance.BanButton.SetVisible(false);
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/GUI/Patches/KillOverlayPatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using HarmonyLib;
3 | using Lotus.Logging;
4 | using Lotus.Utilities;
5 |
6 | namespace Lotus.GUI.Patches;
7 |
8 | [HarmonyPatch(typeof(KillOverlay), nameof(KillOverlay.ShowKillAnimation), typeof(GameData.PlayerInfo), typeof(GameData.PlayerInfo))]
9 | public class KillOverlayPatch
10 | {
11 | private static readonly FixedUpdateLock FixedUpdateLock = new(0.5f);
12 |
13 | public static bool Prefix(KillOverlay __instance)
14 | {
15 | if (!FixedUpdateLock.AcquireLock()) return false;
16 |
17 | DevLogger.Log("Showing Kill Animation");
18 |
19 | return true;
20 | }
21 | }
--------------------------------------------------------------------------------
/src/GUI/UIComponent.cs:
--------------------------------------------------------------------------------
1 | extern alias JBAnnotations;
2 | using System;
3 | using JBAnnotations::JetBrains.Annotations;
4 | using Lotus.API.Odyssey;
5 | using Lotus.GUI.Name;
6 |
7 | namespace Lotus.GUI;
8 |
9 | [MeansImplicitUse]
10 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method)]
11 | public class UIComponent: Attribute
12 | {
13 | public UI Component;
14 | public ViewMode ViewMode;
15 | public GameState[] GameStates;
16 |
17 | public UIComponent(UI component, ViewMode viewMode = ViewMode.Additive, params GameState[] gameStates)
18 | {
19 | this.Component = component;
20 | this.ViewMode = viewMode;
21 | this.GameStates = gameStates.Length > 0 ? gameStates : new [] { GameState.Roaming };
22 | }
23 | }
--------------------------------------------------------------------------------
/src/Gamemodes/Colorwars/ColorWarsWinCondition.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Lotus.API.Odyssey;
4 | using Lotus.Victory.Conditions;
5 | using Lotus.API;
6 |
7 | namespace Lotus.Gamemodes.Colorwars;
8 |
9 | public class ColorWarsWinCondition: IWinCondition
10 | {
11 | public bool IsConditionMet(out List winners)
12 | {
13 | winners = null;
14 | // get the colors of all alive players, then get distinct color ids, then if there's 1 id remaining after all that it means a team has won
15 | List currentColors = Game.GetAlivePlayers().Select(p => p.cosmetics.bodyMatProperties.ColorId).Distinct().ToList();
16 | if (currentColors.Count != 1) return false;
17 | int winningColor = currentColors[0];
18 | winners = Game.GetAllPlayers().Where(p => p.cosmetics.bodyMatProperties.ColorId == winningColor).ToList();
19 |
20 | return true;
21 | }
22 |
23 | public WinReason GetWinReason() => new WinReason(ReasonType.GamemodeSpecificWin);
24 | }
--------------------------------------------------------------------------------
/src/Gamemodes/GameAction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Lotus.Gamemodes;
4 |
5 | [Flags]
6 | public enum GameAction
7 | {
8 | ReportBody = 1,
9 | CallMeeting = 2,
10 | KillPlayers = 4,
11 | CallSabotage = 8,
12 | CloseDoors = 16,
13 | EnterVent = 32,
14 |
15 | // These flags cannot be blocked so it doesn't matter if we set them to the following
16 | GameJoin,
17 | GameLeave,
18 | GameStart,
19 | }
--------------------------------------------------------------------------------
/src/Gamemodes/IGamemode.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.Victory;
3 | using VentLib.Options.Game;
4 | using VentLib.Options.Game.Tabs;
5 | using VentLib.Utilities.Extensions;
6 |
7 | namespace Lotus.Gamemodes;
8 |
9 | public interface IGamemode
10 | {
11 | string GetName();
12 |
13 | GameAction IgnoredActions();
14 |
15 | IEnumerable EnabledTabs();
16 |
17 | void Activate();
18 |
19 | void Deactivate();
20 |
21 | void FixedUpdate();
22 |
23 | void AssignRoles(List players);
24 |
25 | void Setup();
26 |
27 | void SetupWinConditions(WinDelegate winDelegate);
28 |
29 | internal void InternalActivate()
30 | {
31 | Activate();
32 | EnabledTabs().ForEach(GameOptionController.AddTab);
33 | }
34 |
35 | internal void InternalDeactivate()
36 | {
37 | Deactivate();
38 | EnabledTabs().ForEach(GameOptionController.RemoveTab);
39 | }
40 |
41 | public void Trigger(GameAction action, params object[] args);
42 | }
--------------------------------------------------------------------------------
/src/Gamemodes/Standard/IAdditionalAssignmentLogic.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.API;
3 | using Lotus.Roles;
4 | using Lotus.API.Odyssey;
5 |
6 | namespace Lotus.Gamemodes.Standard;
7 |
8 | public interface IAdditionalAssignmentLogic
9 | {
10 | ///
11 | /// Allows for injecting custom role assignment into the standard gamemode.
12 | ///
13 | /// Important
14 | ///
15 | /// You should have a rough understanding of how role assignment works and roles should ALWAYS call
16 | /// Additionally, the standard-algorithm uses for actually applying the role to players. You should replicate
17 | /// this behaviour but DO NOT set sendToClient=true
18 | ///
19 | /// a list of all the players
20 | /// list of players who don't have roles assigned. You are responsible for updating this list
21 | public void AssignRoles(List allPlayers, List unassignedPlayers);
22 | }
--------------------------------------------------------------------------------
/src/Gamemodes/Standard/Lotteries/ImpostorLottery.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Lotus.Factions.Impostors;
3 | using Lotus.Managers;
4 | using Lotus.Roles;
5 | using VentLib.Utilities.Extensions;
6 |
7 | namespace Lotus.Gamemodes.Standard.Lotteries;
8 |
9 | public class ImpostorLottery: RoleLottery
10 | {
11 | public ImpostorLottery() : base(CustomRoleManager.Static.Impostor)
12 | {
13 | CustomRoleManager.AllRoles.Where(r => r.Faction is ImpostorFaction).ForEach(r => AddRole(r));
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Gamemodes/Standard/Lotteries/NeutralKillingLottery.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Lotus.Managers;
3 | using Lotus.Roles;
4 | using Lotus.Roles.Internals;
5 | using VentLib.Utilities.Extensions;
6 |
7 | namespace Lotus.Gamemodes.Standard.Lotteries;
8 |
9 | public class NeutralKillingLottery: RoleLottery
10 | {
11 | // TODO: maybe change this default role
12 | public NeutralKillingLottery() : base(CustomRoleManager.Special.IllegalRole)
13 | {
14 | CustomRoleManager.AllRoles.Where(r => r.SpecialType is SpecialType.NeutralKilling or SpecialType.Undead).ForEach(r => AddRole(r));
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Gamemodes/Standard/Lotteries/NeutralLottery.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Lotus.Managers;
3 | using Lotus.Roles;
4 | using Lotus.Roles.Internals;
5 | using VentLib.Utilities.Extensions;
6 |
7 | namespace Lotus.Gamemodes.Standard.Lotteries;
8 |
9 | public class NeutralLottery: RoleLottery
10 | {
11 | public NeutralLottery() : base(CustomRoleManager.Special.IllegalRole)
12 | {
13 | CustomRoleManager.AllRoles.Where(r => r.SpecialType is SpecialType.Neutral).ForEach(r => AddRole(r));
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Gamemodes/Standard/Lotteries/SubRoleLottery.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Lotus.Managers;
3 | using Lotus.Roles;
4 | using VentLib.Utilities.Extensions;
5 |
6 | namespace Lotus.Gamemodes.Standard.Lotteries;
7 |
8 | public class SubRoleLottery: RoleLottery
9 | {
10 | public SubRoleLottery() : base(CustomRoleManager.Special.IllegalRole)
11 | {
12 | CustomRoleManager.AllRoles.Where(r => r.RoleFlags.HasFlag(RoleFlag.IsSubrole)).ForEach(r => AddRole(r));
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Gamemodes/Standard/RoleDistribution.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Gamemodes.Standard;
2 |
3 | public class RoleDistribution
4 | {
5 | public int Impostors;
6 |
7 | public int MinimumNeutralPassive;
8 | public int MaximumNeutralPassive;
9 |
10 | public int MinimumNeutralKilling;
11 | public int MaximumNeutralKilling;
12 |
13 | public int MinimumMadmates;
14 | public int MaximumMadmates;
15 | }
--------------------------------------------------------------------------------
/src/Gamemodes/TestHnsGamemode.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.Options;
3 | using Lotus.Utilities;
4 | using Lotus.Victory;
5 | using VentLib.Options.Game.Tabs;
6 |
7 | namespace Lotus.Gamemodes;
8 |
9 | public class TestHnsGamemode: Gamemode
10 | {
11 | public override string GetName() => "Hide and Seek";
12 |
13 | public static GameOptionTab HnsTab = new("Hide & Seek Options", () => Utils.LoadSprite("Lotus.assets.TabIcons.HideAndSeekIcon.png", 675));
14 |
15 | public override void Setup()
16 | {
17 | }
18 |
19 | public override void AssignRoles(List players)
20 | {
21 | throw new System.NotImplementedException();
22 | }
23 |
24 | public override IEnumerable EnabledTabs() => new[] { DefaultTabs.GeneralTab, HnsTab };
25 |
26 | public override void SetupWinConditions(WinDelegate winDelegate)
27 | {
28 | throw new System.NotImplementedException();
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Managers/DataFileAccessor.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using VentLib.Utilities.Extensions;
3 |
4 | namespace Lotus.Managers;
5 |
6 | public class DataFileAccessor
7 | {
8 | protected FileInfo SourceFile;
9 | protected string SourceText;
10 |
11 | public DataFileAccessor(FileInfo sourceFileInfo)
12 | {
13 | SourceFile = sourceFileInfo;
14 | SourceText = SourceFile.ReadAll(!SourceFile.Exists);
15 | }
16 |
17 | public DataFileAccessor(string path) : this(new FileInfo(path))
18 | {
19 | }
20 | }
--------------------------------------------------------------------------------
/src/Managers/Date/ISpecialDate.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using HarmonyLib;
4 |
5 | namespace Lotus.Managers.Date;
6 |
7 | public interface ISpecialDate
8 | {
9 | internal static List SpecialDates = new();
10 |
11 | bool IsDate();
12 |
13 | void DoDuringDate();
14 |
15 | public void Create() {
16 | SpecialDates.Add(this);
17 | }
18 |
19 | internal static void CheckDates()
20 | {
21 | SpecialDates.Where(d => d.IsDate()).Do(d => d.DoDuringDate());
22 | }
23 | }
--------------------------------------------------------------------------------
/src/Managers/Hacking/HackingManager.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Hacking;
2 |
3 | public class HackingManager
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/src/Managers/Hacking/MonitoredRpcs.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Hacking;
2 |
3 | public class MonitoredRpcs
4 | {
5 | // RpcMurderPlayer
6 | // RpcSetRole
7 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/CustomDeathEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.History.Events;
2 |
3 | public class CustomDeathEvent: DeathEvent
4 | {
5 | private string deathType;
6 |
7 | public CustomDeathEvent(PlayerControl deadPlayer, PlayerControl? killer, string deathType) : base(deadPlayer, killer)
8 | {
9 | this.deathType = deathType;
10 | }
11 |
12 | public override string SimpleName() => deathType;
13 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/ExiledEvent.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Lotus.Managers.History.Events;
4 |
5 | public class ExiledEvent : DeathEvent
6 | {
7 | private List voters;
8 | private List abstainers;
9 |
10 | public ExiledEvent(PlayerControl deadPlayer, List voters, List abstainers) : base(deadPlayer, null)
11 | {
12 | this.voters = voters;
13 | this.abstainers = abstainers;
14 | }
15 |
16 | public List Abstainers() => abstainers;
17 |
18 | public List Voters() => voters;
19 |
20 | public override string SimpleName() => ModConstants.DeathNames.Exiled;
21 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IDeathEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.History.Events;
2 |
3 | public interface IDeathEvent : IRecipientEvent
4 | {
5 | ///
6 | /// Non-descriptive name of the event IE "Exiled", "Murdered", "Suicide", etc
7 | ///
8 | /// Simple name of the event
9 | public string SimpleName();
10 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IHistoryEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Roles;
2 | using VentLib.Utilities.Optionals;
3 |
4 | namespace Lotus.Managers.History.Events;
5 |
6 | public interface IHistoryEvent
7 | {
8 | public PlayerControl Player();
9 | public Optional RelatedRole();
10 | public Timestamp Timestamp();
11 |
12 | ///
13 | /// An open-ended indicator that confirms this event "led to a new, un-revertable state"
14 | /// For example:
15 | /// A player trying to kill another player (but for some reason failing) is not a completed event
16 | /// BUT, in a similar scenario- if a player DOES kill another player than that event would be considered completed.
17 | ///
18 | /// This field is used to get a rough end-game metric
19 | ///
20 | ///
21 | public bool IsCompletion();
22 |
23 | public string Message();
24 |
25 | public string GenerateMessage() => $"[{Timestamp().ToString(@"mm\:ss")}] {Message()}";
26 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IKillEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.History.Events;
2 |
3 | public interface IKillEvent : ITargetedEvent
4 | {
5 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IMultiTargetEvent.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Lotus.Managers.History.Events;
4 |
5 | public interface IMultiTargetEvent : IHistoryEvent
6 | {
7 | public List Targets();
8 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IRecipientEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Player;
2 | using Lotus.Roles;
3 | using VentLib.Utilities.Optionals;
4 |
5 | namespace Lotus.Managers.History.Events;
6 |
7 | public interface IRecipientEvent : IHistoryEvent
8 | {
9 | public Optional Instigator();
10 |
11 | public Optional InstigatorRole();
12 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IRoleChangeEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Roles;
2 |
3 | namespace Lotus.Managers.History.Events;
4 |
5 | public interface IRoleChangeEvent : IHistoryEvent
6 | {
7 | public CustomRole OriginalRole();
8 |
9 | public CustomRole NewRole();
10 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IRoleEvent.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.History.Events;
2 |
3 | public interface IRoleEvent : IHistoryEvent
4 | {
5 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/ITargetedEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Roles;
2 | using VentLib.Utilities.Optionals;
3 |
4 | namespace Lotus.Managers.History.Events;
5 |
6 | public interface ITargetedEvent : IHistoryEvent
7 | {
8 | public PlayerControl Target();
9 |
10 | public Optional TargetRole();
11 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/IWinEvent.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.Victory.Conditions;
3 |
4 | namespace Lotus.Managers.History.Events;
5 |
6 | public interface IWinEvent : IHistoryEvent
7 | {
8 | public ReasonType WinReason();
9 |
10 | public List Winners();
11 | }
--------------------------------------------------------------------------------
/src/Managers/History/Events/SuicideEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Odyssey;
2 | using Lotus.API;
3 |
4 | namespace Lotus.Managers.History.Events;
5 |
6 | public class SuicideEvent : DeathEvent
7 | {
8 | public SuicideEvent(PlayerControl player) : base(player, player)
9 | {
10 | }
11 |
12 | public override string SimpleName() => ModConstants.DeathNames.Suicide;
13 |
14 | public override string Message() => $"{Game.GetName(Player())} suicided.";
15 | }
--------------------------------------------------------------------------------
/src/Managers/History/HistoryEvent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Lotus.API.Odyssey;
3 | using Lotus.API;
4 |
5 | namespace Lotus.Managers.History;
6 |
7 | //[Localization(Group = "Hello")]
8 | public abstract class HistoryEvent
9 | {
10 | private DateTime timestamp = DateTime.Now;
11 |
12 | public abstract string CreateReport();
13 |
14 | public string RelativeTimestamp() => $"[{(timestamp - Game.MatchData.StartTime):mm\\:ss\\.ff]}";
15 | }
--------------------------------------------------------------------------------
/src/Managers/History/RoleChangeEvent.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Roles;
2 | using Lotus.Extensions;
3 | using Lotus.Options;
4 | using VentLib.Localization.Attributes;
5 |
6 | namespace Lotus.Managers.History;
7 |
8 | [Localized("HistoryEvent")]
9 | public class RoleChangeEvent: HistoryEvent
10 | {
11 | private PlayerControl player;
12 | private CustomRole role;
13 |
14 | [Localized("PlayerChangedRole")]
15 | private static string roleChangedString;
16 |
17 | public RoleChangeEvent(PlayerControl player, CustomRole role)
18 | {
19 | this.player = player;
20 | this.role = role;
21 | }
22 |
23 | public override string CreateReport()
24 | {
25 | string timestamp = /*StaticOptions.ShowHistoryTimestamp*/true ? RelativeTimestamp() + " " : "";
26 | return $"{timestamp}{player.name} {roleChangedString} {role.RoleName}";
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Managers/History/Timestamp.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Lotus.API.Odyssey;
4 | using Lotus.API;
5 |
6 | namespace Lotus.Managers.History;
7 |
8 | ///
9 | /// Simple class that stores its creation time
10 | ///
11 | public class Timestamp
12 | {
13 | private TimeSpan time;
14 |
15 | public Timestamp()
16 | {
17 | time = DateTime.Now.Subtract(Game.MatchData.StartTime);
18 | }
19 |
20 | public bool IsBefore(Timestamp other) => time.CompareTo(other.time) < 0;
21 |
22 | public bool IsAfter(Timestamp other) => time.CompareTo(other.time) > 0;
23 |
24 | public TimeSpan TimeSpan() => time;
25 |
26 | public override string ToString() => time.ToString();
27 |
28 | public string ToString(string formatter) => time.ToString(formatter, new CultureInfo("en-US"));
29 | }
--------------------------------------------------------------------------------
/src/Managers/Hotkeys/HotkeyManager.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using UnityEngine;
3 | using VentLib.Utilities.Harmony.Attributes;
4 |
5 | namespace Lotus.Managers.Hotkeys;
6 |
7 | public class HotkeyManager
8 | {
9 | private static readonly List Hotkeys = new();
10 |
11 | public static bool HoldingLeftShift;
12 | public static bool HoldingRightShift;
13 |
14 |
15 | [QuickPostfix(typeof(ControllerManager), nameof(ControllerManager.Update))]
16 | private static void DoHotkeyCheck()
17 | {
18 | Hotkeys.ForEach(h => h.Update());
19 | HoldingLeftShift = Input.GetKey(KeyCode.LeftShift);
20 | HoldingRightShift = Input.GetKey(KeyCode.RightShift);
21 | }
22 |
23 | public static Hotkey AddHokey(Hotkey hotkey)
24 | {
25 | Hotkeys.Add(hotkey);
26 | return hotkey;
27 | }
28 |
29 | public static Hotkey Bind(params KeyCode[] keyCodes)
30 | {
31 | return AddHokey(Hotkey.When(keyCodes));
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/src/Managers/Models/BanPlayerFile.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Lotus.Managers.Models;
4 |
5 | public class BanPlayerFile
6 | {
7 | public List Players { get; set; } = new();
8 | }
--------------------------------------------------------------------------------
/src/Managers/Models/BannedPlayer.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Models;
2 |
3 | public class BannedPlayer
4 | {
5 | public string FriendCode { get; set; } = null!;
6 | public string Name { get; set; } = null!;
7 | public string? Reason { get; set; } = "None Specified";
8 |
9 | public BannedPlayer()
10 | {
11 |
12 | }
13 |
14 | public BannedPlayer(string? reason)
15 | {
16 | if (reason != null) Reason = reason;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Managers/Models/BannedWordFile.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Lotus.Managers.Models;
4 |
5 | public class BannedWordFile
6 | {
7 | public List GlobalBannedWords { get; set; } = new() { "YourGlobally", "BannedWordsHere" };
8 | public List LobbyBannedWords { get; set; } = new() { "YourLobby", "BannedWordsHere" };
9 | }
--------------------------------------------------------------------------------
/src/Managers/Reporting/AnticheatReporter.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using InnerNet;
3 | using VentLib.Logging;
4 |
5 | namespace Lotus.Managers.Reporting;
6 |
7 | [HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.HandleDisconnect))]
8 | public class AnticheatReporter
9 | {
10 | private static void Postfix(DisconnectReasons reason, string stringReason)
11 | {
12 | switch (reason)
13 | {
14 | case DisconnectReasons.Hacking:
15 | ReportManager.GenerateReport(ReportTag.KickByAnticheat);
16 | break;
17 | case DisconnectReasons.Custom:
18 | if (stringReason.Contains("Reliable packet")) ReportManager.GenerateReport(ReportTag.KickByPacket);
19 | break;
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Managers/Reporting/IReportProducer.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Reporting;
2 |
3 | public interface IReportProducer
4 | {
5 | ReportInfo ProduceReport();
6 | }
--------------------------------------------------------------------------------
/src/Managers/Reporting/RProfiler.cs:
--------------------------------------------------------------------------------
1 | using VentLib.Utilities.Debug.Profiling;
2 |
3 | namespace Lotus.Managers.Reporting;
4 |
5 | public class RProfiler : Profiler, IReportProducer
6 | {
7 | public RProfiler(string name) : base(name)
8 | {
9 | }
10 |
11 |
12 | public ReportInfo ProduceReport() => ReportInfo.Create($"Profiler \"{Name}\" Report", $"profiler-{Name}-report").Attach(GetCurrentData().ToString());
13 |
14 | public void HandleSignal(ReportSignal signal)
15 | {
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Managers/Reporting/ReportSignal.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Reporting;
2 |
3 | public enum ReportSignal
4 | {
5 | GameStart,
6 | GameEnd,
7 | Anticheat
8 | }
--------------------------------------------------------------------------------
/src/Managers/Reporting/ReportTag.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace Lotus.Managers.Reporting;
5 |
6 | public enum ReportTag
7 | {
8 | KickByAnticheat,
9 | KickByPacket,
10 | Performance
11 | }
12 |
13 | public static class ReportTags
14 | {
15 | public static ReportTag[] Excluding(params ReportTag[] tags)
16 | {
17 | return Enum.GetValues().Except(tags).ToArray();
18 | }
19 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/ResolvedTrigger.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Templates.Models;
2 |
3 | public class ResolvedTrigger
4 | {
5 | public PlayerControl? Player;
6 | public string? Data;
7 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/TCondition.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Lotus.Managers.Templates.Models.Units;
4 |
5 | namespace Lotus.Managers.Templates.Models;
6 |
7 | // ReSharper disable once InconsistentNaming
8 | public class TCondition: Dictionary
9 | {
10 | public List? ParsedConditions;
11 | public string? Fallback { get; set; }
12 |
13 | public bool Evaluate(object? data)
14 | {
15 | ParsedConditions ??= this.Select(kv => ConditionalParsers.Parse(kv.Key, kv.Value)).ToList();
16 | return ParsedConditions.All(c => c.Evaluate(data));
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/TemplateFile.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Lotus.Managers.Templates.Models.Units;
3 |
4 | namespace Lotus.Managers.Templates.Models;
5 |
6 | public class TemplateFile
7 | {
8 | public Dictionary? Variables { get; set; } = new();
9 | public List? Templates { get; set; } = new();
10 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/TemplateTrigger.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Templates.Models;
2 |
3 | public enum TemplateTrigger
4 | {
5 | PlayerDeath,
6 | PlayerExiled,
7 | PlayerDisconnect,
8 | PlayerChat,
9 | StatusReceived,
10 | TaskComplete
11 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/Units/IConditionalUnit.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Templates.Models.Units;
2 |
3 | public interface IConditionalUnit
4 | {
5 | public bool Evaluate(object? data);
6 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/Units/Impl/CommonConditionalUnit.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Templates.Models.Units.Impl;
2 |
3 | public abstract class CommonConditionalUnit: IConditionalUnit
4 | {
5 | protected object Input;
6 |
7 | public CommonConditionalUnit(object input)
8 | {
9 | Input = input;
10 | }
11 |
12 | public abstract bool Evaluate(object? data);
13 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/Units/Impl/StringListConditionalUnit.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 |
4 | namespace Lotus.Managers.Templates.Models.Units.Impl;
5 |
6 | public abstract class StringListConditionalUnit: CommonConditionalUnit
7 | {
8 | protected HashSet Values = new();
9 |
10 | public StringListConditionalUnit(object input) : base(input)
11 | {
12 | if (Input is ICollection collection)
13 | {
14 | foreach (object o in collection)
15 | {
16 | string? value = o.ToString();
17 | if (value != null) Values.Add(value);
18 | }
19 |
20 | return;
21 | }
22 |
23 | string? inputValue = input.ToString();
24 | if (inputValue != null) Values.Add(inputValue);
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/Units/Impl/TConditionalDefault.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers.Templates.Models.Units.Impl;
2 |
3 | public class TConditionalDefault: IConditionalUnit
4 | {
5 | public bool Evaluate(object? data) => true;
6 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/Units/Impl/TConditionalEvaluate.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Managers.Templates.Models.Backing;
2 | using VentLib.Logging;
3 |
4 | namespace Lotus.Managers.Templates.Models.Units.Impl;
5 |
6 | public class TConditionalEvaluate: CommonConditionalUnit
7 | {
8 | private string inlineCondition;
9 |
10 | public TConditionalEvaluate(object input) : base(input)
11 | {
12 | string? parsed = input.ToString();
13 | if (parsed == null)
14 | {
15 | VentLogger.Warn("Error parsing \"Evaluate\" statement to string");
16 | parsed = "True == True";
17 | }
18 |
19 | inlineCondition = parsed;
20 | }
21 |
22 | public override bool Evaluate(object? data) => InlineConditionEvaluator.Evaluate(inlineCondition, data);
23 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/Units/Impl/TConditionalStatuses.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using Lotus.API.Odyssey;
4 |
5 | namespace Lotus.Managers.Templates.Models.Units.Impl;
6 |
7 | public class TConditionStatuses: StringListConditionalUnit
8 | {
9 | private HashSet? statusesLower;
10 |
11 | public TConditionStatuses(object input) : base(input)
12 | {
13 | }
14 |
15 | public override bool Evaluate(object? data)
16 | {
17 | return data is not PlayerControl player || VerifyStatus(player);
18 | }
19 |
20 | public bool VerifyStatus(PlayerControl? player)
21 | {
22 | if (player == null) return true;
23 | statusesLower ??= Values.Select(r => r.ToLower()).ToHashSet();
24 | return statusesLower.Any(status => MatchData.GetStatuses(player)?.Any(st => st.Name.ToLower().Equals(status.ToLower())) ?? false);
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Managers/Templates/Models/Units/Impl/TConditionalVitals.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Lotus.Extensions;
3 | using VentLib.Logging;
4 |
5 | namespace Lotus.Managers.Templates.Models.Units.Impl;
6 |
7 | public class TConditionalVitals: CommonConditionalUnit
8 | {
9 | private PlayerVital playerVital;
10 |
11 | public TConditionalVitals(object input) : base(input)
12 | {
13 | if (!Enum.TryParse(input as string, true, out PlayerVital status)) VentLogger.Warn($"Could not parse \"{input}\" as type \"{nameof(PlayerVital)}\"");
14 | else playerVital = status;
15 | }
16 |
17 | public override bool Evaluate(object? data)
18 | {
19 | return data is not PlayerControl player || VerifyStatus(player);
20 | }
21 |
22 | private bool VerifyStatus(PlayerControl? player)
23 | {
24 | if (playerVital is PlayerVital.Any || player == null) return true;
25 | return playerVital is PlayerVital.Alive ? player.IsAlive() : !player.IsAlive();
26 | }
27 |
28 | private enum PlayerVital
29 | {
30 | Any,
31 | Dead,
32 | Alive
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Managers/TimeoutManager.cs:
--------------------------------------------------------------------------------
1 | namespace Lotus.Managers;
2 |
3 | public class TimeoutManager
4 | {
5 |
6 | }
--------------------------------------------------------------------------------
/src/Options/ClientOptions.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Options.Client;
2 | using VentLib.Utilities.Attributes;
3 |
4 | namespace Lotus.Options;
5 |
6 | [LoadStatic]
7 | public class ClientOptions
8 | {
9 | public static VideoOptions VideoOptions = new VideoOptions();
10 | }
--------------------------------------------------------------------------------
/src/Options/RoleOptions.cs:
--------------------------------------------------------------------------------
1 | using Lotus.Options.Roles;
2 | using VentLib.Localization.Attributes;
3 |
4 | namespace Lotus.Options;
5 |
6 | [Localized(ModConstants.Options)]
7 | public class RoleOptions
8 | {
9 | public static MadmateOptions MadmateOptions = null!;
10 | public static NeutralOptions NeutralOptions = null!;
11 | public static SubroleOptions SubroleOptions = null!;
12 |
13 | internal static MadmateOptions LoadMadmateOptions() => MadmateOptions ??= new MadmateOptions();
14 |
15 | internal static NeutralOptions LoadNeutralOptions() => NeutralOptions ??= new NeutralOptions();
16 |
17 | internal static SubroleOptions LoadSubroleOptions() => SubroleOptions ??= new SubroleOptions();
18 | }
--------------------------------------------------------------------------------
/src/Patches/Actions/ProtectPlayerPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.Extensions;
3 | using VentLib.Logging;
4 |
5 | namespace Lotus.Patches.Actions;
6 |
7 | [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.ProtectPlayer))]
8 | class ProtectPlayerPatch
9 | {
10 | public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target)
11 | {
12 | VentLogger.Old($"{__instance.GetNameWithRole()} => {target.GetNameWithRole()}", "ProtectPlayer");
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Patches/AssignRoleOnDeathPatch.cs:
--------------------------------------------------------------------------------
1 | using AmongUs.GameOptions;
2 | using HarmonyLib;
3 | using Lotus.API.Reactive;
4 | using Lotus.API.Reactive.HookEvents;
5 | using Lotus.Extensions;
6 | using VentLib.Logging;
7 |
8 | namespace Lotus.Patches;
9 |
10 | [HarmonyPatch(typeof(RoleManager), nameof(RoleManager.AssignRoleOnDeath))]
11 | public class AssignRoleOnDeathPatch
12 | {
13 | public static bool Prefix(RoleManager __instance, [HarmonyArgument(0)] PlayerControl player)
14 | {
15 | return false;
16 | }
17 |
18 |
19 | public static void Postfix(RoleManager __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] bool specialRolesAllowed)
20 | {
21 | player.RpcSetRole(player.GetVanillaRole().IsImpostor() ? RoleTypes.ImpostorGhost : RoleTypes.CrewmateGhost);
22 | VentLogger.Debug($"Dead Player {player.name} => {player.Data.Role.Role}");
23 | }
24 | }
--------------------------------------------------------------------------------
/src/Patches/BasicWrapperPatches.cs:
--------------------------------------------------------------------------------
1 | using Lotus.API.Odyssey;
2 | using Lotus.Utilities;
3 | using VentLib.Utilities.Harmony.Attributes;
4 |
5 | namespace Lotus.Patches;
6 |
7 | public class BasicWrapperPatches
8 | {
9 | [QuickPrefix(typeof(PlayerControl), nameof(PlayerControl.RawSetName))]
10 | public static bool WrapSetNamePatch(PlayerControl __instance, string name)
11 | {
12 | __instance.cosmetics.SetName(name);
13 | __instance.cosmetics.SetNameMask(true);
14 | if (Game.State is GameState.InLobby) __instance.name = name.RemoveHtmlTags();
15 | return false;
16 | }
17 | }
--------------------------------------------------------------------------------
/src/Patches/Client/SetKillTimerPatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using HarmonyLib;
3 | using Lotus.API;
4 |
5 | namespace Lotus.Patches.Client;
6 |
7 | [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.SetKillTimer))]
8 | public class SetKillTimerPatch
9 | {
10 | public static bool Prefix(PlayerControl __instance, float time)
11 | {
12 | __instance.killTimer = Math.Max(time, 0);
13 | DestroyableSingleton.Instance.KillButton.SetCoolDown(__instance.killTimer, Math.Max(AUSettings.KillCooldown(), __instance.killTimer));
14 | return false;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/Patches/Client/UseVentPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.Roles;
3 | using Lotus.Extensions;
4 |
5 | namespace Lotus.Patches.Client;
6 |
7 | [HarmonyPatch(typeof(Vent), nameof(Vent.CanUse))]
8 | class UseVentPatch
9 | {
10 | public static bool Prefix(Vent __instance, [HarmonyArgument(0)] GameData.PlayerInfo pc, [HarmonyArgument(1)] ref bool canUse)
11 | {
12 | if (pc.Object == null) return true;
13 | CustomRole role = pc.Object.GetCustomRole();
14 |
15 | if (role.BaseCanVent) return true;
16 | return canUse = false;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Patches/Intro/ShowRolePatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.Roles;
3 | using Lotus.Utilities;
4 | using Lotus.Extensions;
5 | using Lotus.Roles.Legacy;
6 | using VentLib.Utilities;
7 |
8 | namespace Lotus.Patches.Intro;
9 |
10 | [HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.ShowRole))]
11 | class ShowRolePatch
12 | {
13 | public static void Postfix(IntroCutscene __instance)
14 | {
15 | Async.Schedule(() =>
16 | {
17 | CustomRole role = PlayerControl.LocalPlayer.GetCustomRole();
18 | if (true)
19 | {
20 | __instance.YouAreText.color = role.RoleColor;
21 | __instance.RoleText.text = role.RoleName;
22 | __instance.RoleText.color = role.RoleColor;
23 | __instance.RoleBlurbText.color = role.RoleColor;
24 |
25 | __instance.RoleBlurbText.text = PlayerControl.LocalPlayer.GetCustomRole().Blurb;
26 | }
27 |
28 | __instance.RoleText.text += Utils.GetSubRolesText(PlayerControl.LocalPlayer.PlayerId);
29 |
30 | }, 0.01f);
31 |
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Patches/JoinGameButtonPatch.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 | using HarmonyLib;
3 | using UnityEngine;
4 | using VentLib.Logging;
5 |
6 | namespace Lotus.Patches
7 | {
8 | [HarmonyPatch(typeof(JoinGameButton), nameof(JoinGameButton.OnClick))]
9 | class JoinGameButtonPatch
10 | {
11 | public static void Prefix(JoinGameButton __instance)
12 | {
13 | if (__instance.GameIdText == null) return;
14 | if (__instance.GameIdText.text == "" && Regex.IsMatch(GUIUtility.systemCopyBuffer.Trim('\r', '\n'), @"^[A-Z]{6}$"))
15 | {
16 | VentLogger.Old($"{GUIUtility.systemCopyBuffer}", "ClipBoard");
17 | __instance.GameIdText.SetText(GUIUtility.systemCopyBuffer.Trim('\r', '\n'));
18 | }
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Patches/Meetings/MeetingUpdatePatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.API;
3 | using Lotus.Utilities;
4 | using Lotus.Extensions;
5 | using UnityEngine;
6 | using VentLib.Logging;
7 |
8 | namespace Lotus.Patches.Meetings;
9 |
10 | [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Update))]
11 | class MeetingUpdatePatch
12 | {
13 | public static void Postfix(MeetingHud __instance)
14 | {
15 | if (!AmongUsClient.Instance.AmHost) return;
16 | if (Input.GetMouseButtonUp(1) && Input.GetKey(KeyCode.LeftControl))
17 | __instance.playerStates.DoIf(x => x.HighlightedFX.enabled, x =>
18 | {
19 | PlayerControl? player = Utils.GetPlayerById(x.TargetPlayerId);
20 | ProtectedRpc.CheckMurder(PlayerControl.LocalPlayer, player);
21 |
22 | VentLogger.High($"Execute: {player.GetNameWithRole()}", "Execution");
23 | });
24 | }
25 | }
--------------------------------------------------------------------------------
/src/Patches/Meetings/PlayerVoteAreaPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using UnityEngine;
3 |
4 | namespace Lotus.Patches.Meetings;
5 |
6 | [HarmonyPatch(typeof(PlayerVoteArea), nameof(PlayerVoteArea.Start))]
7 | public class PlayerVoteAreaPatch
8 | {
9 | public static void Postfix(PlayerVoteArea __instance)
10 | {
11 | if (__instance == null || __instance.ColorBlindName == null) return;
12 | __instance.ColorBlindName.transform.localPosition -= new Vector3(1.25f, 0.15f);
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Patches/Network/RpcV3WrapperPatches.cs:
--------------------------------------------------------------------------------
1 | using Hazel;
2 | using VentLib.Networking.RPC;
3 | using VentLib.Utilities.Attributes;
4 | using VentLib.Utilities.Harmony.Attributes;
5 |
6 | namespace Lotus.Patches.Network;
7 |
8 | [LoadStatic]
9 | public class RpcV3WrapperPatches
10 | {
11 | [QuickPrefix(typeof(PlayerControl), nameof(PlayerControl.RpcSetName))]
12 | public static bool RpcSetName(PlayerControl __instance, string name)
13 | {
14 |
15 | __instance.SetName(name);
16 | RpcV3 rpcV3 = (RpcV3)RpcV3.Immediate(__instance.NetId, RpcCalls.SetName, SendOption.None).Write(name);
17 | rpcV3.Send();
18 |
19 | return false;
20 | }
21 | }
--------------------------------------------------------------------------------
/src/Patches/NoBlackoutPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 |
3 | namespace Lotus.Patches;
4 |
5 | [HarmonyPatch(typeof(LogicGameFlowNormal), nameof(LogicGameFlowNormal.IsGameOverDueToDeath))]
6 | class DontBlackoutPatch
7 | {
8 | public static void Postfix(ref bool __result)
9 | {
10 | __result = false;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Patches/Systems/CheckEndGameViaTasksPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 |
3 | namespace Lotus.Patches.Systems;
4 |
5 | [HarmonyPatch(typeof(GameManager), nameof(GameManager.CheckEndGameViaTasks))]
6 | public class CheckEndGameViaTasksPatch
7 | {
8 | public static bool Prefix(GameManager __instance)
9 | {
10 | return false;
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Patches/Systems/DeteriorateCrashCoursePatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.Options;
3 |
4 | namespace Lotus.Patches.Systems;
5 |
6 | [HarmonyPatch(typeof(HeliSabotageSystem), nameof(HeliSabotageSystem.Detoriorate))]
7 | public static class DeteriorateCrashCoursePatch
8 | {
9 | public static void Prefix(HeliSabotageSystem __instance)
10 | {
11 | if (!__instance.IsActive) return;
12 |
13 | if (!GeneralOptions.SabotageOptions.CustomAirshipReactorCountdown) return;
14 |
15 | if (__instance.Countdown > GeneralOptions.SabotageOptions.AirshipReactorCountdown)
16 | __instance.Countdown = GeneralOptions.SabotageOptions.AirshipReactorCountdown;
17 | }
18 | }
--------------------------------------------------------------------------------
/src/Patches/Systems/RecomputeTaskPatch.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using HarmonyLib;
4 | using Lotus.Extensions;
5 | using Lotus.Roles.Interfaces;
6 | using Lotus.Utilities;
7 | using Lotus.Roles.Legacy;
8 | using VentLib.Utilities.Extensions;
9 |
10 | namespace Lotus.Patches.Systems;
11 |
12 | [HarmonyPatch(typeof(GameData), nameof(GameData.RecomputeTaskCounts))]
13 | public class RecomputeTaskPatch
14 | {
15 | public static bool Prefix(GameData __instance)
16 | {
17 | __instance.TotalTasks = 0;
18 | __instance.CompletedTasks = 0;
19 | __instance.AllPlayers.ToArray()
20 | .Where(Utils.HasTasks)
21 | .Where(p => p.GetCustomRole() is ITaskHolderRole taskHolder && taskHolder.TasksApplyToTotal())
22 | .SelectMany(p => p?.Tasks?.ToArray() ?? Array.Empty())
23 | .ForEach(task =>
24 | {
25 | __instance.TotalTasks++;
26 | if (task.Complete) __instance.CompletedTasks++;
27 | });
28 |
29 | return false;
30 | }
31 | }
--------------------------------------------------------------------------------
/src/Patches/Systems/UsablesPatch.cs:
--------------------------------------------------------------------------------
1 | using HarmonyLib;
2 | using Lotus.Utilities;
3 |
4 | namespace Lotus.Patches.Systems;
5 |
6 | // This is not a very fun patch
7 | /*[HarmonyPatch(typeof(Console), nameof(Console.CanUse))]
8 | class CanUsePatch
9 | {
10 | public static bool Prefix(ref float __result, Console __instance, [HarmonyArgument(0)] GameData.PlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse)
11 | {
12 | canUse = couldUse = false;
13 | //こいつをfalseでreturnしても、タスク(サボ含む)以外の使用可能な物は使えるまま(ボタンなど)
14 | return __instance.AllowImpostor || Utils.HasTasks(PlayerControl.LocalPlayer.Data);
15 | }
16 | }*/
--------------------------------------------------------------------------------
/src/ROLE_TO_TEST:
--------------------------------------------------------------------------------
1 | Mare
2 | Invesigator X
3 | Oracle X
4 | Bounty Hunter X
5 | Vigilante X
6 | Veteran X
7 | Transporter
8 | Puppeteer
9 | Witch
10 | Archangel X?,
11 | Executioner X
12 | Phantom X
13 | Agitater
14 | Arsonist
15 | Neut Witch (should work if puppeteer works)
16 | Retributionist X
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Broken:
25 | - Report call
26 | - Puppet
27 | - Phantom
28 | - Mare completely broken
29 |
30 |
31 |
32 |
33 |
34 | Swapper
35 | Lovers
--------------------------------------------------------------------------------
/src/RPC/HostRpc.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Lotus.Options;
3 | using Lotus.Extensions;
4 | using Lotus.Utilities;
5 | using VentLib;
6 | using VentLib.Utilities.Extensions;
7 | using VentLib.Logging;
8 | using VentLib.Networking.RPC.Attributes;
9 | using VentLib.Options;
10 | using VentLib.Utilities.Collections;
11 |
12 | namespace Lotus.RPC;
13 |
14 | public static class HostRpc
15 | {
16 | [ModRPC((uint) ModCalls.SendOptionPreview, RpcActors.Host, RpcActors.NonHosts)]
17 | public static void RpcSendOptions(BatchList