Compare commits

...
Author SHA1 Message Date
Atony 0aa4a82d48 Add options to list (no logic)
Issue is mainly the button scale, that needs to update as soon as the change is made
2025-09-09 21:50:45 -05:00
Atony da7aab9aa2 Merge pull request #64 from All-Of-Us-Mods/vanilla-keybind-bindings
Vanilla keybindings
2025-09-09 18:44:18 -05:00
Atony 3d274c2f61 KEYBINDS WORK NOW 2025-09-09 05:05:56 -05:00
Atony b94e20c6f7 Add Ability Button bind 2025-09-08 20:29:33 -05:00
Chipseq 5a0428c7c0 Merge branch 'dev' into vanilla-keybind-bindings 2025-09-08 21:08:53 +02:00
xChipseq c41dd27f88 init vanilla keybinds after input manager init 2025-09-08 19:38:07 +02:00
xChipseq 6872ca6866 basekeybind class, vanilla keybindings 2025-09-08 18:37:09 +02:00
xChipseq 4b7fa906b9 fix misaligned options after labels 2025-09-07 22:49:23 +02:00
xChipseq b7173d18ab change mira config 2025-09-07 22:45:06 +02:00
xChipseq ffc7a1a4fd fix keybind icon clipping 2025-09-07 22:43:08 +02:00
XtraCube a1611f5f7a fix merge errors 2025-09-07 16:34:57 -04:00
XtraCube 1664aa1003 Merge branch 'fork/xChipseq/local-settings-rework' into dev
# Conflicts:
#	MiraAPI/MiraApiConfig.cs
#	MiraAPI/PluginLoading/MiraPluginManager.cs
#	MiraAPI/Utilities/Helpers.cs
2025-09-07 16:29:33 -04:00
xChipseq af3d99eafe wip 2025-09-07 21:25:15 +02:00
xChipseq 94197e38dd cleanup 2025-09-07 20:47:59 +02:00
angxl wtf 97a0b2084a Merge pull request #61 from WanderingPix/timed-modifiers-taskadder-icon
Timed modifier QOL changes in Task Adder
2025-09-07 13:50:48 -04:00
Atony 1d87790212 Merge pull request #62 from All-Of-Us-Mods/vote-event-tweaks
Add Before and After Vote Events
2025-09-06 22:54:04 -05:00
xChipseq 9d130a53de fix typo 2025-09-07 00:54:44 +02:00
Atony d8afc6887d Merge branch 'dev' into vote-event-tweaks 2025-09-06 14:36:22 -05:00
Atony c0a406610d Merge pull request #60 from WanderingPix/Roleicons-in-options-menu
Role icons in options menu
2025-09-06 14:32:14 -05:00
Atony d73c21936c Add Before and After vote events
Useful for local checks before a vote is placed (like with TOU Mira Prosecutor)
2025-09-06 14:19:17 -05:00
xChipseq 449192f0ef remove this annoying log 2025-09-06 19:02:40 +02:00
xChipseq f3614b9a5c fix null errors 2025-09-05 23:33:01 +02:00
angxl wtf a62c6d496c Merge pull request #57 from xChipseq/button-improvements
Custom Button Improvements + Major Keybind API rewrite
2025-09-04 19:02:07 -04:00
xChipseq bebd648691 remove null check, it's always none when null 2025-09-04 21:51:45 +02:00
xChipseq ecadfa86dd remove invoke log 2025-09-04 21:51:26 +02:00
WanderingPixel 5ad53f695f Update TaskAdderPatches.cs 2025-09-04 14:29:39 +01:00
WanderingPixel 31a9c0c98d Update TaskAdderPatches.cs 2025-09-04 13:23:31 +01:00
WanderingPixel ea389b986f Update TaskAdderPatches.cs 2025-09-04 12:58:09 +01:00
WanderingPixel ef85fab6a6 Update TaskAdderPatches.cs 2025-09-04 12:35:40 +01:00
WanderingPixel b2fdaaf89f Timed Modifier Enhancements in TaskAdderGame 2025-09-04 12:29:19 +01:00
WanderingPixel e6043b6f5f Fix Masking issue 2025-09-03 21:27:38 +01:00
WanderingPixel ffe0db0e9e Add role icons in role settings menu 2025-09-03 21:14:07 +01:00
xChipseq 705ef64b4d fix helper method returning null if no keybind 2025-09-02 22:27:04 +02:00
xChipseq ebdb4a09ca make number options accept floats 2025-09-02 19:24:34 +02:00
xChipseq ac113b6a7f add tab open method and fixes 2025-09-02 18:55:27 +02:00
xChipseq 1f6962efe9 add local setting buttons 2025-09-01 23:34:17 +02:00
xChipseq 6b37b9c09c add an error 2025-09-01 22:28:30 +02:00
xChipseq f515516937 remove the two million test tabs 2025-09-01 22:24:58 +02:00
xChipseq 8b2d24ccc1 more stuff 2025-09-01 22:22:32 +02:00
xChipseq 57bab258e5 enum and int options and lots of other stuff i forgot 2025-09-01 21:54:13 +02:00
ang-xd 04d5e72caa Add slider float value 2025-08-31 18:45:22 -04:00
ang-xd b4e6e448f2 Major work/rewrite on local settings 2025-08-31 18:04:52 -04:00
xChipseq b19a0178ad add a limit to multitarget buttons 2025-08-31 23:41:35 +02:00
xChipseq 8a71f13874 fix for keybind loading 2025-08-31 20:26:22 +02:00
xChipseq 809e7a07ab literally one dot 2025-08-31 20:21:50 +02:00
xChipseq 47394c6afe fix example mod 2025-08-31 18:06:53 +02:00
xChipseq a2a1e91439 replace EffectCancelable with a method 2025-08-31 18:03:17 +02:00
xChipseq 2f5ca32475 multitarget buttons 2025-08-31 17:59:38 +02:00
xChipseq 5fb59408fa wip 2025-08-31 17:51:02 +02:00
xChipseq 57c842ece6 Merge remote-tracking branch 'origin/local-settings-rework' into local-settings-rework 2025-08-30 23:08:55 +02:00
Chipseq 63e552245d Sync local settings branch with dev 2025-08-30 23:05:03 +02:00
xChipseq 43d7f80660 add show keybinds setting 2025-08-30 21:41:04 +02:00
xChipseq 45291b0e98 change default keybinds to make sense 2025-08-30 21:31:34 +02:00
xChipseq 45972f71a9 major rework of the keybinds api 2025-08-30 21:13:42 +02:00
xChipseq a6f7171b71 add PauseTimerInVent 2025-08-29 14:32:13 +02:00
xChipseq e6d3819517 add uses mode for buttons 2025-08-29 14:20:19 +02:00
xChipseq b97ada22bc allow the duration to be 0 2025-08-29 13:58:06 +02:00
xChipseq 5f67960b28 cancelable abilities 2025-08-29 13:38:35 +02:00
xChipseq b4e30b2b68 wip 2025-08-29 13:04:18 +02:00
ang-xd 2237d3a2df Additional changes to keybind icons 2025-08-28 12:33:19 -04:00
ang-xd e708c23f81 Fix checks and positions for keybinds 2025-08-28 11:26:45 -04:00
ang-xd 3ca33b1d86 Merge branch 'master' into dev 2025-08-28 11:08:57 -04:00
angxl wtf 8967348cd3 Merge pull request #55 from CallOfCreator/keybinds
Keybind Icons
2025-08-28 11:08:26 -04:00
angxl wtf 305d2c3714 Merge pull request #54 from AtonyGit/dev
Adjust Keybinds for Buttons + Add IntroRoleRevealEvent
2025-08-28 11:08:14 -04:00
Atony 85a0275eea Add IntroRoleRevealEvent
Also needs to be changed for the android branch
2025-08-24 19:48:43 -05:00
Atony f006deab3f Fix Send Immediately warning from Reactor 2025-08-24 18:33:52 -05:00
CallOfCreator a274f23e65 Merge pull request #1 from WanderingPix/keybinds
Add Keybind Icons
2025-08-21 11:36:08 -07:00
Atony f1a5aef581 Remove requirement but allow blank keybind 2025-08-17 20:52:46 -05:00
Atony ce15e93e59 Fix DefaultKeybind name + remove requirement
By default, buttons will use no keybind, and will not add a new keybind option in doing so.
2025-08-17 20:40:03 -05:00
XtraCube 08ca995eb1 Merge pull request #52 from All-Of-Us-Mods/dev
mira api 0.2.1
2025-08-17 16:39:35 -04:00
XtraCube 453259df98 Merge branch 'master' into dev 2025-08-17 16:36:16 -04:00
XtraCube 2ec3eec370 bump version 2025-08-17 16:34:56 -04:00
ang-xd 2ee8730ba4 WIP Left side Modifiers HUD option 2025-08-14 00:56:29 -04:00
XtraCube c89e5938cc Merge pull request #43 from CallOfCreator/keybinds
Implement Keybind API
2025-08-13 09:32:42 -04:00
WanderingPixel 513be01c02 Add Keybind icons for custom buttons 2025-08-09 22:12:15 +01:00
CallOfCreator 01fa1f0915 Update conflict system 2025-08-09 11:41:43 +00:00
CallOfCreator 355eef509b Add support for modifier keys 2025-08-06 18:03:48 +00:00
XtraCube 763a493283 Merge pull request #51 from xChipseq/dummy-improvements
Dummies Fix
2025-08-05 16:50:09 -04:00
xChipseq 68e421bf91 literally just a dot 2025-08-05 22:35:39 +02:00
xChipseq c343ab5e9f dummy fix 2025-08-05 22:34:00 +02:00
XtraCube 9c1ef70ea7 Merge pull request #50 from xChipseq/dummy-improvements
Dummy Voting Improvements
2025-08-04 21:19:18 -04:00
xChipseq c0c8fa08ff changed DidVote to check VotesRemaining instead of Votes 2025-08-04 20:58:24 +02:00
xChipseq e7fba386aa dummy changes 2025-08-04 20:53:50 +02:00
XtraCube 72e5e0c137 Merge pull request #49 from xChipseq/round-start-event
Invoke RoundStartEvent when starting freeplay
2025-08-04 12:30:09 -04:00
XtraCube 4422072060 Merge pull request #48 from AtonyGit/dev
Add BeforeRoundEvent for edge case scenarios
2025-08-04 12:29:51 -04:00
xChipseq 8145c8e599 patch 2025-08-04 15:33:04 +02:00
Atony afd6fbc3b6 Add BeforeRoundStartEvent 2025-08-02 14:24:53 -05:00
XtraCube 74741b41a7 Merge pull request #47 from WanderingPix/Ghosts-included-in-GetClosestPlayer
Add argument for PlayerControl.GetClosestPlayer() to include ghosts
2025-07-31 09:13:04 -04:00
WanderingPixel f98429b5f9 Update GetClosestPlayer method 2025-07-31 09:09:37 -04:00
XtraCube bf7edb30ab fix warnings 2025-07-20 07:30:38 -04:00
XtraCube b4527014b7 Merge pull request #44 from AtonyGit/dev
Allow modifiers to have freeplay colors
2025-07-16 14:41:01 -04:00
Atony 277391ef1c Add freeplay modifier colors 2025-07-11 22:30:09 -05:00
CallOfCreator dfe124d67a Add missing credit from previous commit 2025-07-11 18:06:06 +00:00
CallOfCreator 2b06633488 Cleanup 2025-07-11 18:00:58 +00:00
CallOfCreator 4784b1f0ad Rename CurrentKeybind to DefaultKeybind 2025-07-09 13:48:38 +00:00
CallOfCreator d9d0d6bc62 Implement Keybind API 2025-07-08 20:41:20 +00:00
XtraCube 6b3038f397 shuffle modifiers before assigning 2025-07-07 18:47:12 -04:00
XtraCube 4e1db039a0 Merge pull request #42 from AtonyGit/dev
Fix Regions Dropdown in "Find Game" & Add Tab Count for Cosmetics Menu
2025-07-05 15:36:08 -04:00
Atony 62bee24789 Fix Server Dropdown for Game Finder 2025-07-04 22:43:13 -05:00
Atony 2156c80467 Cosmetic Tab Count Improvements 2025-07-04 22:42:47 -05:00
XtraCube 0ff60071c2 fix canuse event 2025-06-30 20:47:17 -04:00
XtraCube de2f3f0d95 update assetbundle 2025-06-29 22:31:21 -04:00
XtraCube 05f132c506 expose modifiers 2025-06-29 20:03:20 -04:00
XtraCube ab54c44434 expose custom roles in CustomRoleManager.cs 2025-06-29 19:57:58 -04:00
XtraCube bf652b68c3 fix warnings 2025-06-28 23:04:30 -04:00
XtraCube 00377c7926 Merge remote-tracking branch 'origin/dev' into dev 2025-06-28 22:57:09 -04:00
XtraCube 55555604f3 error proof buttons 2025-06-28 22:57:04 -04:00
ang-xd de77a9fa92 Add page counter in options screen 2025-06-28 20:55:22 -04:00
ang-xd eba2a037d3 Bug fixes and chat pasting 2025-06-28 19:21:47 -04:00
ang-xd bc7f772de9 Add ModdedPlayerOption and fix role options scroll 2025-06-28 18:44:31 -04:00
ang-xd f43191c4f2 Fix role option visibility & shift 5 increments on chance 2025-06-27 19:16:56 -04:00
XtraCube cd818a18cf Merge pull request #40 from All-Of-Us-Mods/dev
0.2.0 Update
2025-06-27 15:52:24 -04:00
XtraCube 56d4e399d9 Merge branch 'master' into dev 2025-06-27 15:50:58 -04:00
XtraCube 0d41ebbc13 adjust server dropdown to fit 2 columns 2025-06-27 15:47:38 -04:00
XtraCube 9388ff487a fix scrolling bug on role menu 2025-06-27 15:21:58 -04:00
XtraCube 720491e5cf make role options wrap around 2025-06-27 15:16:14 -04:00
XtraCube 9884df356e hide hidden role settings in advanced menu 2025-06-27 14:28:09 -04:00
XtraCube 7ec4addacc cleanup 2025-06-24 23:13:00 -04:00
XtraCube bc9bc0ce24 brace style 2025-06-24 21:38:36 -04:00
XtraCube aff1c311fa update readme 2025-06-24 21:24:40 -04:00
XtraCube 0d2a9d9700 fix warnings 2025-06-24 15:06:45 -04:00
XtraCube 669c541279 fix advanced role settings scroll 2025-06-24 14:57:48 -04:00
XtraCube 2e5f9639b3 fix role settings menu 2025-06-24 12:32:13 -04:00
XtraCube e6d1f440c8 adjust it 2025-06-24 12:27:02 -04:00
XtraCube 2ac8bdc240 fix lobby view settings scroll issues 2025-06-24 12:26:22 -04:00
XtraCube d5d99001ea privacy change 2025-06-23 19:14:22 -04:00
XtraCube 5628b79814 Merge remote-tracking branch 'origin/presets' into dev
# Conflicts:
#	MiraAPI/GameOptions/IModdedOption.cs
#	MiraAPI/GameOptions/ModdedOptionsManager.cs
#	MiraAPI/GameOptions/OptionTypes/ModdedOption.cs
#	MiraAPI/Patches/Options/GameSettingMenuPatches.cs
#	MiraAPI/Patches/Options/LobbyViewPanePatches.cs
#	MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
#	MiraAPI/Utilities/Assets/MiraAssets.cs
#	MiraAPI/Utilities/Assets/SpriteTools.cs
#	MiraAPI/Utilities/Extensions.cs
2025-06-23 11:44:30 -04:00
XtraCube 72a44f65f1 fix role menu scrolling bug 2025-06-23 11:31:49 -04:00
XtraCube db6a336a63 Add modifier tab scroll positions and fix scroll positions not saving in some cases. 2025-06-23 11:07:28 -04:00
XtraCube 90b23ec2ca fix role scroll position issue 2025-06-23 10:31:47 -04:00
XtraCube 20e927208c make options wrap around in values 2025-06-21 20:17:57 -04:00
XtraCube 13ef3bdd49 add format string for cooldown timers 2025-06-21 19:32:28 -04:00
XtraCube b3ff6755bb suppress naming warnings 2025-06-21 18:52:18 -04:00
XtraCube 67604600cd remove obsolete code 2025-06-21 18:52:09 -04:00
XtraCube 6e35de6185 add BeforeGameEndEvent.cs 2025-06-21 18:43:56 -04:00
XtraCube a26ec51c7d send murder RPC immediately 2025-06-21 18:24:32 -04:00
XtraCube 3f6ae4cc41 send gameover immediately 2025-06-21 18:21:37 -04:00
XtraCube 15a2cdcd5b Merge pull request #36 from All-Of-Us-Mods/2025.5.20
Update to 2025.5.20
2025-06-21 17:27:23 -04:00
XtraCube cf0bd6ec38 fixed presets 2025-06-20 08:43:11 -04:00
XtraCube 130236e899 oops fix bad code 2025-06-20 08:38:31 -04:00
XtraCube 3b7b247ac0 refresh presets when opening preset menu 2025-06-20 08:32:24 -04:00
XtraCube 52de9a22de fix preset loading networking 2025-06-19 23:24:02 -04:00
XtraCube 372a9e3aa9 suppress RPC warnings 2025-06-16 21:31:58 -04:00
XtraCube 10a9dcfa34 suppress RPC warnings 2025-06-11 21:26:08 -04:00
XtraCube d46fdb0185 comments about rpcmurder inlining 2025-05-30 17:15:52 -04:00
XtraCube a361afbcbf add comment about meetinghud inline issue 2025-05-30 17:12:03 -04:00
XtraCube 24cdac0243 Fix role options collection inlining 2025-05-30 17:07:11 -04:00
XtraCube 5fe75843ad fix haunt menu inlining 2025-05-30 17:01:43 -04:00
XtraCube a0436dcbba Fix ToggleOption inlining 2025-05-30 16:58:32 -04:00
XtraCube 35be381a77 Fix LobbyViewPane inlining 2025-05-30 16:53:15 -04:00
XtraCube 1298beb517 fix kill anim inlining 2025-05-30 16:06:21 -04:00
XtraCube d41c19a176 Adjust kill anim patch for inlining 2025-05-30 15:45:59 -04:00
XtraCube 476f4400ad Fix ReportBodyEventPatch.cs 2025-05-29 22:04:34 -04:00
XtraCube 2b46d90570 Merge branch 'dev' into 2025.5.20 2025-05-27 16:09:29 -04:00
XtraCube ae4aaf7af9 adjust mirabundle name to work on epic 2025-05-27 16:09:14 -04:00
XtraCube 757b9436ca adjust role message 2025-05-27 16:09:05 -04:00
XtraCube 7ea10afffb dont need reactor dev nuget anymore 2025-05-21 18:18:10 -04:00
XtraCube 0ab80c42f9 Update discord badge 2025-05-20 22:25:21 -04:00
XtraCube bc144568f4 fix harmony error due to renamed parameter 2025-05-20 18:51:55 -04:00
XtraCube 07f402e659 update reactor 2025-05-20 18:42:59 -04:00
XtraCube 1a6aed539a fix lobbyview modifier options showing in game options 2025-05-18 14:49:40 -04:00
XtraCube 023cdaa470 fix role setting menu bug 2025-05-18 14:46:24 -04:00
XtraCube 98dd5ca056 fix more warnings 2025-05-18 12:40:40 -04:00
XtraCube 1f3e21ce19 cleanup more warnings 2025-05-18 10:01:48 -04:00
XtraCube 15e441dd71 add documentation in mira assets 2025-05-18 09:37:27 -04:00
XtraCube 8c67bbbd44 cleanup warnings 2025-05-18 09:32:33 -04:00
XtraCube aa584a8f44 update role notifications to match custom role colors 2025-05-18 09:25:26 -04:00
XtraCube a8a584b61b Fix bug with CustomRoleSingleton.cs 2025-05-18 09:09:14 -04:00
XtraCube acc4b1c8dd Save scroll positions on options and roles pages 2025-05-17 23:27:25 -04:00
XtraCube f9600bc906 fix chameleon role again 2025-05-17 23:27:14 -04:00
XtraCube f3da06870f fix chameleon role errors 2025-05-17 23:20:26 -04:00
XtraCube 9180dec9e1 update example mod to fit new role update 2025-05-17 23:16:01 -04:00
XtraCube ef6dedbd55 add errors for incorrect usage of registrations 2025-05-17 22:40:02 -04:00
XtraCube 5d3c3ed319 Update example events and catch exceptions in events 2025-05-17 22:32:29 -04:00
XtraCube 5b22d667fd remove redundant ICustomRole methods 2025-05-17 22:31:34 -04:00
XtraCube fb894c9f2c add wrappers around modifiers to catch exceptions 2025-05-17 17:42:19 -04:00
XtraCube d0449f57b5 adjust naming in plugin manager 2025-05-17 17:40:05 -04:00
XtraCube 5ffd591258 add dead body to death and murder events 2025-05-17 17:34:04 -04:00
XtraCube cc0ac1b988 Merge remote-tracking branch 'origin/dev' into dev 2025-05-17 17:28:08 -04:00
XtraCube 00b96f6e61 Merge pull request #34 from All-Of-Us-Mods/2025.3.25
2025.3.25 (16.0.0) support
2025-05-17 17:28:06 -04:00
XtraCube 6cb7f9f145 add unregistration of events 2025-05-17 17:26:29 -04:00
XtraCube b94472ee07 save options scroll states 2025-05-16 19:42:59 -04:00
XtraCube f8056c29da Merge branch 'dev' into presets 2025-05-16 19:27:26 -04:00
XtraCube e7f9a3bb60 hide roles in lobby view pane 2025-05-16 19:27:12 -04:00
XtraCube 8d4f2baf1e Merge remote-tracking branch 'origin/presets' into presets 2025-05-16 19:24:52 -04:00
XtraCube 11ba3dae64 save scroll position in roles menu 2025-05-16 19:24:47 -04:00
AlchlcDvl 86145f94f4 Merge branch 'dev' into presets 2025-05-04 22:29:23 -04:00
AlchlcDvl a9ded0b313 Modifier display improvement 2025-05-04 22:15:08 -04:00
XtraCube e0da386567 fix lag and broken roles saving/loading 2025-05-04 18:10:34 -04:00
XtraCube 6f1da2de9f add roles to presets 2025-05-02 19:25:03 -04:00
XtraCube b85358e304 Merge branch '2025.3.25' into presets 2025-05-02 19:19:33 -04:00
XtraCube 2c901bb9b9 remove unused thingy 2025-05-02 14:56:28 -04:00
XtraCube 68f40a96b7 fix preset system 2025-05-02 14:54:42 -04:00
XtraCube a96ffc42f2 fix saving default preset only 2025-04-29 17:23:05 -04:00
XtraCube 0907b14893 Merge branch 'feat-addressables-2' into presets 2025-04-29 17:22:57 -04:00
ang-xd 7a7204b0e0 Fix minigame crashes 2025-04-22 18:14:45 -04:00
ang-xd e57e88c179 Update AbstractOptionGroup.cs 2025-04-19 13:35:03 -04:00
ang-xd 878eab25b8 Merge branch 'dev' into 2025.3.25 2025-04-16 20:11:51 -04:00
angxl wtf e4f15f2ed9 Merge pull request #33 from All-Of-Us-Mods/feat-addressables-2
Addressables Loading
2025-04-16 19:51:27 -04:00
ang-xd bdc9fa28ac oops 2025-04-15 18:20:24 -04:00
ang-xd 64604aff98 Fix bug if you change hideonui 2025-04-15 18:05:20 -04:00
ang-xd 32a44d646d Futher progress on presets UI 2025-04-12 23:29:09 -04:00
ang-xd 8f590b94a8 Merge branch 'feat-addressables-2' into presets 2025-04-12 20:54:35 -04:00
ang-xd 3ba71d8f19 Add pagination 2025-04-12 16:22:55 -04:00
ang-xd 96a47d480a Add Modifiers HUD 2025-04-12 12:35:09 -04:00
XtraCube bb72d885cf Merge remote-tracking branch 'origin/feat-addressables-2' into feat-addressables-2 2025-04-09 22:06:37 -04:00
XtraCube e242975d75 fix modifier errors in end game win patch 2025-04-09 22:06:28 -04:00
ang-xd be6bc07a62 Merge branch 'dev' into feat-addressables-2 2025-04-06 19:53:32 -04:00
ang-xd a6d55ec90f Fix confirm ejects 2025-04-06 19:52:47 -04:00
ang-xd e5b6400eb8 Fix CastVote event issue 2025-04-06 14:50:29 -04:00
XtraCube 0d1d1891a8 Merge branch 'dev' into 2025.3.25 2025-04-05 16:30:17 -04:00
XtraCube 54d85a6996 Merge branch 'dev' into feat-addressables-2 2025-04-05 16:28:41 -04:00
XtraCube 531a799a24 fix double initialization of roles 2025-04-05 16:28:34 -04:00
XtraCube 3e6eb49d93 fix scroller in freeplay role menu 2025-04-05 15:00:51 -04:00
XtraCube 3fabe85a18 fix scroller in freeplay role menu 2025-04-05 15:00:35 -04:00
XtraCube a3fc847d07 Merge branch 'dev' into 2025.3.25 2025-04-05 14:32:26 -04:00
XtraCube ddfad0752d proper fix for meeting vote issue (I HATE IL2CPP) 2025-04-05 14:31:46 -04:00
ang-xd f1846375ca Fix end game stuff 2025-04-05 14:31:46 -04:00
XtraCube fcb693e899 fix modifier adding/removing AGAIN 2025-04-05 14:31:46 -04:00
XtraCube 21bec074fa improve GetAlivePlayers 2025-04-05 14:31:45 -04:00
ang-xd 30516104aa Merge branch 'feat-addressables-2' of https://github.com/All-Of-Us-Mods/MiraAPI into feat-addressables-2 2025-04-05 14:31:43 -04:00
ang-xd e7508e299b Faster loading of hats 2025-04-05 14:31:37 -04:00
XtraCube b0cd1d30b3 Merge remote-tracking branch 'origin/feat-addressables-2' into feat-addressables-2 2025-04-05 14:30:57 -04:00
XtraCube 9f3a40b48f proper fix for meeting vote issue (I HATE IL2CPP) 2025-04-05 14:30:52 -04:00
XtraCube 31ffe6274c fix silly mistake with settings 2025-04-05 14:19:52 -04:00
ang-xd 91c9a27df8 Fix end game stuff 2025-04-05 13:06:35 -04:00
MyDragonBreath 7484dd1a9f possible pagination... 2025-04-05 23:17:55 +11:00
XtraCube 9c9964eecf fix modifier adding/removing AGAIN 2025-04-04 18:26:16 -04:00
XtraCube 78fad65b97 improve GetAlivePlayers 2025-04-04 18:25:57 -04:00
XtraCube aef4d6daf1 actually fix meetinghud vote issue 2025-04-04 13:09:11 -04:00
XtraCube 87b94b1b6d actually fix meetinghud vote issue 2025-04-04 13:08:35 -04:00
XtraCube cf92b97e8b slight logic adjustment to fix inactive modifier checks 2025-04-04 12:42:24 -04:00
XtraCube bd0aa68cb8 slight logic adjustment to fix inactive modifier checks 2025-04-04 12:42:12 -04:00
XtraCube f43a542134 fix voting never ends bug 2025-04-04 12:35:26 -04:00
XtraCube efd176f7a4 fix timer bug related to effects 2025-04-04 12:35:26 -04:00
XtraCube b2fabdb139 add check inactive variants of hasmodifier 2025-04-04 12:35:26 -04:00
XtraCube a651099217 fix voting never ends bug 2025-04-04 12:34:41 -04:00
XtraCube e2f39c29a8 fix timer bug related to effects 2025-04-04 12:18:37 -04:00
XtraCube 140b697aaf add check inactive variants of hasmodifier 2025-04-04 09:33:59 -04:00
XtraCube a56b6d52ef rework modifier assignment 2025-04-03 21:05:44 -04:00
XtraCube 3a36acd131 rework modifier assignment 2025-04-03 20:37:09 -04:00
XtraCube 3adb7ef018 Merge branch 'dev' into feat-addressables-2 2025-04-01 21:22:41 -04:00
XtraCube 8c763e2a57 fix mira event priorities 2025-04-01 21:22:34 -04:00
XtraCube 2df50112eb Merge branch 'dev' into feat-addressables-2 2025-04-01 17:03:29 -04:00
XtraCube ce330325e4 fix broken submerged compat patch 2025-04-01 17:03:13 -04:00
XtraCube 516cc83170 Merge branch 'dev' into feat-addressables-2 2025-04-01 13:09:10 -04:00
XtraCube 89cd32d4a4 fix round start event 2025-04-01 13:09:00 -04:00
XtraCube f0e37daf0e Merge branch 'dev' into 2025.3.25 2025-04-01 12:25:59 -04:00
XtraCube 71e2f2e375 Merge branch 'dev' into feat-addressables-2 2025-03-31 22:16:38 -04:00
XtraCube a5ddec48c8 attempt at better config I/O during setup 2025-03-31 22:16:32 -04:00
XtraCube 9e6524817a Merge branch 'dev' into feat-addressables-2 2025-03-30 20:25:39 -04:00
XtraCube 5f4461f7e5 suppress il2cpp warnings 2025-03-30 16:26:22 -04:00
XtraCube 5e2ca191ba proper submerged compat 2025-03-30 16:19:52 -04:00
XtraCube 5af10b52a4 Merge branch 'dev' into feat-addressables-2 2025-03-30 15:44:47 -04:00
XtraCube a0d3afc7c7 add onmeeting event 2025-03-30 15:38:05 -04:00
XtraCube 2e769d79f2 try fix 2025-03-30 14:56:18 -04:00
XtraCube 41305ad0e2 Merge branch 'dev' into presets 2025-03-30 12:09:32 -04:00
XtraCube a8ac00d270 Merge branch 'dev' into feat-addressables-2 2025-03-29 22:07:24 -04:00
XtraCube 3cd7acbc70 fix ejection patch for submerged and airship 2025-03-29 22:07:12 -04:00
XtraCube ce583d11de Merge branch 'dev' into feat-addressables-2 2025-03-29 21:51:43 -04:00
XtraCube 31132e6e65 add RoundStartEvent.cs 2025-03-29 21:51:31 -04:00
XtraCube 1a53e2b045 add new meeting and intro events 2025-03-29 21:39:44 -04:00
XtraCube 2418e17af6 this doesnt work 2025-03-29 21:29:46 -04:00
XtraCube 6fb0afe14e add folder button 2025-03-29 21:29:40 -04:00
XtraCube 32b368c1ef update other addressable related things 2025-03-29 17:58:05 -04:00
XtraCube 103c32f386 finish AddressablesLoader.cs 2025-03-29 17:56:50 -04:00
XtraCube 662b867dc5 Merge remote-tracking branch 'origin/feat-addressables-2' into feat-addressables-2 2025-03-29 17:40:17 -04:00
XtraCube adae0225e9 fix merge error 2025-03-29 17:40:00 -04:00
XtraCube 0d347b8b1b Merge branch 'dev' into feat-addressables-2
# Conflicts:
#	MiraAPI.Example/ExampleEventHandlers.cs
2025-03-29 17:39:46 -04:00
XtraCube ab0063dd99 update preset system 2025-03-29 14:56:07 -04:00
XtraCube a35bf60870 add rounded box sprite 2025-03-29 14:26:15 -04:00
XtraCube 692b9d7180 improve spritetools 2025-03-29 14:26:06 -04:00
XtraCube b99efaa420 create loadable asset wrapper 2025-03-29 14:25:57 -04:00
XtraCube 2ecfa267d6 Merge branch 'dev' into presets
# Conflicts:
#	MiraAPI/Patches/Options/LobbyViewPanePatches.cs
2025-03-29 13:55:18 -04:00
XtraCube 4fad586aa7 use new alternate color in lobby 2025-03-29 13:53:58 -04:00
XtraCube 6d51e6806a fix warning in role stubs 2025-03-29 13:37:06 -04:00
XtraCube b28a0a1253 cleanup CustomPlayerMenu.cs 2025-03-29 13:35:16 -04:00
XtraCube 51b54d4340 reorganize vent patch 2025-03-29 13:12:19 -04:00
XtraCube ea9bf162ea rework modifier component caching 2025-03-29 13:12:12 -04:00
XtraCube 57105f487b cleanup 2025-03-29 13:11:15 -04:00
XtraCube c5e424e8ff hide empty role groups in settings 2025-03-29 12:26:38 -04:00
MyDragonBreath d3b40aec5a remove tou and me specific example 2025-03-29 23:25:55 +11:00
XtraCube 521e5a12fd more accurate doc 2025-03-29 00:27:07 -04:00
XtraCube e6e4a86546 fix stupid innerscuff code 2025-03-28 15:20:31 -04:00
XtraCube 9afe821b0f fix stupid innerscuff code 2025-03-27 18:09:27 -04:00
XtraCube a8d076656d more WIP presets 2025-03-26 18:45:48 -04:00
XtraCube be46ee7329 fix custom murder stats 2025-03-25 17:11:51 -04:00
XtraCube 75a15dc090 fix minigame patch 2025-03-25 17:09:16 -04:00
XtraCube cffb104392 update libs 2025-03-25 17:06:02 -04:00
XtraCube bb0b678747 fix VERY stupid issue with LobbyViewPanePatches.cs 2025-03-24 18:57:06 -04:00
XtraCube 429b64fc03 preset v2 2025-03-23 17:28:22 -04:00
XtraCube bf5dadc6a0 that def doesnt work 2025-03-23 15:34:20 -04:00
XtraCube b2137230da Merge branch 'dev' into presets 2025-03-23 15:19:51 -04:00
XtraCube f48143610c fix incorrect chunking algorithm 2025-03-23 15:15:21 -04:00
XtraCube 9e8c05f21d text input WIP 2025-03-23 15:01:31 -04:00
XtraCube 2cfc5ac039 update example 2025-03-23 14:00:12 -04:00
XtraCube 2f56c95b39 Merge branch 'dev' into presets
# Conflicts:
#	MiraAPI/GameOptions/OptionTypes/ModdedOption.cs
2025-03-23 13:45:49 -04:00
XtraCube 38f72c42a3 presets v1 2025-03-23 13:44:40 -04:00
MyDragonBreath 71b537dba9 final addressables 2025-03-23 22:59:11 +11:00
XtraCube e9beb3b423 fix weird behaviour 2025-03-21 15:24:48 -04:00
XtraCube 5b608f5b3a preset WIP 2025-03-21 15:21:18 -04:00
MyDragonBreath 23c0397afe an approach to addressables 2025-03-19 23:07:09 +11:00
XtraCube 2248726450 IncludeInPreset property 2025-03-17 09:12:26 -04:00
XtraCube c60537cbd1 add comments to imoddedoption 2025-03-17 09:02:24 -04:00
ang-xd 7917d4b5d9 Make some changes to role registration for sounds 2025-03-16 19:05:12 -04:00
ang-xd bf795a2e36 Bug fixes with option screen & modifiers options 2025-03-15 23:47:05 -04:00
angxl wtf 144a95fa3b Merge pull request #31 from All-Of-Us-Mods/voting
Voting API
2025-03-15 21:10:19 -04:00
ang-xd e25b78705b Merge branch 'dev' into voting 2025-03-15 17:34:42 -04:00
ang-xd 19ba9da2c3 Remove debug method 2025-03-15 17:22:01 -04:00
ang-xd ce9864ae8b Lots of new Util methods, and fix opt header colors 2025-03-15 17:21:26 -04:00
XtraCube 8f76f21cb1 fix dummy voting in freeplay 2025-03-15 16:12:05 -04:00
ang-xd bc7b835dc8 Admit defeat to custom sprite assets 2025-03-15 15:04:57 -04:00
XtraCube f0b2f9ee2a fix bad naming 2025-03-14 17:39:27 -04:00
XtraCube 25eafe664b improve MeetingSelectEvent 2025-03-13 12:53:00 -04:00
XtraCube db327604c5 Remove PopulateResultsRpc and simplify. 2025-03-13 12:19:08 -04:00
XtraCube 1462061df9 fix REALLY stupid bug 2025-03-13 09:23:26 -04:00
XtraCube fb40664bd0 add CheckForEndVotingEvent.cs 2025-03-12 22:56:41 -04:00
XtraCube 3cba870980 add ProcessVotesEvent.cs and remove "weighting" 2025-03-12 22:30:54 -04:00
XtraCube ab2f03ee4d still broken 2025-03-12 20:13:20 -04:00
ang-xd 645d1dad1c Broken thing 2025-03-12 18:01:58 -04:00
XtraCube a04e0d28db WTF GIT FAIL! 2025-03-12 17:24:40 -04:00
XtraCube b04d9619b8 Merge branch 'dev' into voting
# Conflicts:
#	MiraAPI/Events/Vanilla/Meeting/ReportBodyEvent.cs
#	MiraAPI/Patches/Events/ReportBodyEventPatch.cs
#	MiraAPI/Utilities/Extensions.cs
2025-03-12 17:23:29 -04:00
XtraCube 33fd657eb3 add "OptionsMenuColor" to ICustomRole 2025-03-12 16:48:04 -04:00
XtraCube 529fc89fc5 add WCAG 2.1 compliant alternate color 2025-03-12 16:45:29 -04:00
XtraCube 6ab283d39c increase accessibility of properties in CustomActionButton.cs 2025-03-12 16:04:26 -04:00
XtraCube 08d8a48701 make Player not nullable in basemodifier (because it shouldnt ever be) 2025-03-12 16:02:15 -04:00
XtraCube 708534ed5c make Player not nullable in basemodifier (because it shouldnt ever be) 2025-03-12 16:01:34 -04:00
XtraCube 886ef0e31f fix ToAdd/ToRemove modifier bug 2025-03-12 15:26:24 -04:00
XtraCube 0b9e54eb50 voting API improvements 2025-03-10 22:29:33 -04:00
XtraCube bad6648f44 add weight to CustomVote 2025-03-10 21:52:16 -04:00
XtraCube 86f970c989 copy new meeting event from voting branch 2025-03-08 10:11:19 -05:00
XtraCube 7aafaf478c bump version 2025-03-08 10:10:55 -05:00
XtraCube 451a626370 Merge pull request #30 from All-Of-Us-Mods/optionable
Optionable Types
2025-03-04 18:50:20 -05:00
XtraCube e02c06ca07 final cleanup 2025-03-04 18:29:30 -05:00
XtraCube e43cd0ceff remove debug log 2025-03-04 17:00:16 -05:00
XtraCube e680b5c872 unity lifetime check 2025-03-04 17:00:05 -05:00
XtraCube b6f304fe1d organize example 2025-03-04 16:59:55 -05:00
XtraCube e52f48c20d allow any groups to be shown in modifiers menu 2025-03-03 19:28:20 -05:00
XtraCube d97588b356 add lobby view pane settings 2025-03-03 19:12:09 -05:00
XtraCube 68304a5eb8 simplify + partial unscuff 2025-03-03 17:10:14 -05:00
XtraCube f2add2a65b this is very broken idk why 2025-03-02 19:21:37 -05:00
XtraCube bbff2dd2d9 modifier options (WIP) 2025-03-01 18:34:18 -05:00
ang-xd 664f8cb2e8 Add PopulateResultsEvent.cs 2025-03-01 15:31:48 -05:00
ang-xd d9081ed17b Outline text method 2025-03-01 15:30:14 -05:00
XtraCube 6f248221d6 remove extra log 2025-03-01 12:38:04 -05:00
ang-xd 989b511276 Voting "API" 2025-02-28 23:19:34 -05:00
XtraCube b67fdf5ab1 optionable v1 2025-02-28 23:11:31 -05:00
XtraCube 26afd47d2a attribute event registration 2025-02-28 15:41:18 -05:00
XtraCube 2e0ecd95a6 fix things i forgot to commit 2025-02-28 10:17:39 -05:00
XtraCube 669d5765e6 add winner info to verify condition in gameover 2025-02-28 10:14:24 -05:00
XtraCube 309094bdf8 better error message 2025-02-28 06:25:53 -05:00
XtraCube 49d09bb44f use NotNullWhen attribute 2025-02-28 06:24:26 -05:00
XtraCube f77b694e78 cleanup code 2025-02-27 20:41:45 -05:00
XtraCube e3cf884975 add player to verify condition 2025-02-27 20:40:57 -05:00
XtraCube 3d91c8de25 allow any player to trigger gameover, but add verification 2025-02-27 20:34:27 -05:00
XtraCube 3387564f2d Merge pull request #29 from All-Of-Us-Mods/custom-game-over
Custom game over
2025-02-27 20:20:11 -05:00
XtraCube 9e2787b781 fix intro cutscene bug 2025-02-27 20:19:34 -05:00
XtraCube 90ed9b2a98 finalize custom gameover 2025-02-27 20:11:24 -05:00
XtraCube 530cb79981 custom game over 2025-02-27 19:33:14 -05:00
XtraCube 6f4eff7b38 Merge pull request #19 from All-Of-Us-Mods/rpc-modifier-arguments
Modifier Rework
2025-02-27 18:33:35 -05:00
XtraCube 2159b6aa89 Merge pull request #28 from Zeo666/IntroTeam
Custom Intro Team Screen
2025-02-27 18:33:24 -05:00
XtraCube 9ec270bd68 use precomputed shader ID 2025-02-27 18:22:42 -05:00
XtraCube c9ff839f12 improve flexibility of setup team intro 2025-02-27 18:21:04 -05:00
XtraCube d1116b3fce comment on miraapiplugin 2025-02-27 15:15:21 -05:00
XtraCube 65a81d0fb4 fix broken wav audio resource loader 2025-02-26 21:34:31 -05:00
XtraCube 26b94b0127 fix ordering of properties in BaseModifier.cs 2025-02-26 17:29:46 -05:00
XtraCube 6443b5932b modifier converter + cleanup 2025-02-26 17:24:41 -05:00
XtraCube a619a975d7 fix modifier factory issue 2025-02-26 17:24:05 -05:00
XtraCube 81834a7f1a allow modifier in lobby with error 2025-02-26 15:38:25 -05:00
Zeo 3015c6dd6a Added method to override the intro team screen to be based on custom role 2025-02-26 18:26:07 +00:00
XtraCube 0e2eeea069 add check to prevent adding modifiers before a game has started 2025-02-25 22:01:52 -05:00
XtraCube 7e4a71739c better modifier unique IDs 2025-02-25 21:57:38 -05:00
XtraCube caa27642db further modifier improvements (massive changes) 2025-02-25 17:22:00 -05:00
XtraCube 4a8fb38380 improvements to timed modifier 2025-02-25 17:17:40 -05:00
XtraCube 66375e884f use invariant info to shut up warnings 2025-02-24 21:52:53 -05:00
XtraCube 9ae9094a85 oops fix that 2025-02-24 21:52:06 -05:00
XtraCube 1c6fa9a84d major modifier overhaul 2025-02-24 21:51:02 -05:00
XtraCube 0ebec6d0f1 fix testing thing 2025-02-23 20:28:24 -05:00
XtraCube 0bed367eda Merge branch 'dev' into rpc-modifier-arguments
# Conflicts:
#	MiraAPI/Patches/PlayerControlPatches.cs
#	MiraAPI/Patches/VentPatches.cs
2025-02-23 20:27:20 -05:00
XtraCube 176a1d5e5c Merge pull request #27 from All-Of-Us-Mods/modifier-improvements
Modifier improvements
2025-02-23 20:15:53 -05:00
XtraCube fb19b4bc04 better naming for "stackable" modifier 2025-02-23 20:13:12 -05:00
XtraCube 8fb8d18be9 fix name 2025-02-23 19:10:57 -05:00
XtraCube b1846fae26 Merge branch 'dev' into modifier-improvements
# Conflicts:
#	MiraAPI/Modifiers/BaseModifier.cs
#	MiraAPI/Patches/Freeplay/TaskAdderPatches.cs
2025-02-23 19:08:57 -05:00
XtraCube 8b8f9ea5db utilize new modifier extension stuff 2025-02-23 19:06:59 -05:00
XtraCube bbec3c1958 fix something i almost broke 2025-02-23 19:06:12 -05:00
XtraCube 758b1d3183 organize task add patches 2025-02-23 19:06:12 -05:00
XtraCube d8131d1f5d fix pietros mistake and cleanup things 2025-02-23 19:06:12 -05:00
XtraCube 9ccf7104cb better summary comment 2025-02-23 19:06:12 -05:00
Pietrodjaowjao bc12c5a5f7 Change util to TMP_Text (all textmeshpro render components) 2025-02-23 19:06:12 -05:00
XtraCube 5dfbd5dc8f add masking to task adder roles 2025-02-23 19:06:12 -05:00
XtraCube 84c8f743f8 i dont know why this is even a bug 2025-02-23 19:06:12 -05:00
XtraCube 3905a3b394 . 2025-02-23 19:06:12 -05:00
XtraCube fb5ff4b53e freeplay modifiers 2025-02-23 19:06:09 -05:00
XtraCube 047312a197 Merge pull request #26 from All-Of-Us-Mods/freeplay-modifiers
freeplay modifiers
2025-02-23 19:05:01 -05:00
XtraCube 8e0a8f0585 fix something i almost broke 2025-02-23 19:02:22 -05:00
XtraCube 4849b52b47 organize task add patches 2025-02-23 18:59:14 -05:00
XtraCube 9cc9a137cc fix pietros mistake and cleanup things 2025-02-23 18:54:51 -05:00
XtraCube 055b097c21 better summary comment 2025-02-23 18:32:23 -05:00
XtraCube 87187fe205 improve modifier extensions and add more method for dealing with modifiers 2025-02-23 18:25:25 -05:00
XtraCube 975e8cb9b7 allow stackable modifiers 2025-02-23 18:24:56 -05:00
Pietrodjaowjao 6775294a19 Change util to TMP_Text (all textmeshpro render components) 2025-02-23 20:22:11 -03:00
XtraCube 2af89a678f add masking to task adder roles 2025-02-23 16:34:59 -05:00
XtraCube dda46e5903 i dont know why this is even a bug 2025-02-23 15:45:31 -05:00
ang-xd ba92d9608c Updated role settings appearance + role options 2025-02-22 21:12:54 -05:00
XtraCube 52ff4bfbfc . 2025-02-22 18:59:19 -05:00
XtraCube b6dda5f970 freeplay modifiers 2025-02-22 18:54:20 -05:00
XtraCube 9504862bea add format string option to number options 2025-02-21 12:01:28 -05:00
XtraCube 4b6ffc65df fix after murder event 2025-02-21 09:26:53 -05:00
XtraCube ccde63068b fix lobby view pane issues 2025-02-18 21:49:54 -05:00
XtraCube 5e16429acf fix more scrolling issues 2025-02-18 11:15:13 -05:00
XtraCube 1e47500686 fix scrolling issues 2025-02-18 11:03:50 -05:00
XtraCube 0b1cf998f8 fix coloring issues and hidden roles in rolesettingsmenu 2025-02-17 21:59:58 -05:00
XtraCube 14a3669031 fix rolebehaviour stubs cuz im an idiot 2025-02-17 11:52:57 -05:00
XtraCube ae79cd87d9 :shush: 2025-02-17 11:37:02 -05:00
XtraCube fb99f02549 i forgor 2025-02-17 11:10:26 -05:00
XtraCube 8382b9adf1 clearer naming 2025-02-17 11:08:12 -05:00
XtraCube cb1a818377 role configuration improvements 2025-02-17 11:03:39 -05:00
XtraCube e950278bf9 seperate some role configs 2025-02-17 10:58:25 -05:00
XtraCube 3de9482233 add missing minigame stubs 2025-02-17 10:32:28 -05:00
XtraCube 4508aaeb55 add role stubs 2025-02-17 10:32:18 -05:00
XtraCube ee15a1acbe fix neutral default role group title 2025-02-17 09:46:09 -05:00
XtraCube 113c716fd3 hide role groups in settings menu 2025-02-17 00:00:37 -05:00
ang-xd f7c34fb5cd Add ShowInFreeplay configuration 2025-02-16 23:13:04 -05:00
XtraCube 37446964c5 change neutral team to Custom and add more customization 2025-02-16 22:33:16 -05:00
ang-xd 0af392d60e Make buttons act more like vanilla 2025-02-16 01:04:15 -05:00
ang-xd e910805e50 Delete log 2025-02-15 23:54:47 -05:00
ang-xd 2b1db0ee24 Whoops 2025-02-15 17:59:40 -05:00
ang-xd 2bb1d41e65 Fix issue #24 2025-02-15 13:49:38 -05:00
Pietrodjaowjao 7bf35fc8ae Fix player skin resetting on no-teleport murder 2025-02-15 15:49:09 -03:00
XtraCube 719ee0400d for MDB fr this time 🙏 2025-02-13 18:21:36 -05:00
ang-xd 4db7605d27 Some changes to role visibility name text 2025-02-13 18:10:42 -05:00
ang-xd c7d16f7fc9 Try fix console spam bug 2025-02-13 17:43:24 -05:00
ang-xd 8ed38c02ce This ones for Xtra 2025-02-13 17:37:44 -05:00
ang-xd 328ee52549 SetRole event 2025-02-13 17:08:21 -05:00
ang-xd e412e5ead5 Some fixes 2025-02-13 16:51:00 -05:00
XtraCube 59ab2736ab further optimization? 2025-02-13 16:19:12 -05:00
XtraCube bb27f83e8b miradisable -> miraignore 2025-02-13 16:18:53 -05:00
XtraCube 7fe2341be0 fix miradisable bug 2025-02-10 16:43:45 -05:00
XtraCube 5bf39593c5 get rid of annoying log 2025-02-10 16:41:00 -05:00
XtraCube 1e56c8860a Merge pull request #18 from All-Of-Us-Mods/optimization
optimize plugin loading (and other optimizations if I find them)
2025-02-09 22:11:31 -05:00
ang-xd 7042c6e646 New events & extensions 2025-02-09 16:42:09 -05:00
XtraCube 4fe301511d remove annoying logs 2025-02-09 14:47:02 -05:00
ang-xd 22718a708c New events and more flexibility 2025-02-06 20:24:53 -05:00
XtraCube e569c27010 replace most attributes and add MiraDisableAttribute.cs 2025-02-03 21:58:57 -05:00
XtraCube 145ae304eb remove extra thingy 2025-02-02 20:59:44 -05:00
XtraCube dcf557ca46 optimize plugin loading 2025-02-02 20:57:10 -05:00
XtraCube a65de5a938 Epic CI Win! 2025-02-02 20:46:56 -05:00
XtraCube 8e2535ada2 yes it works 2025-02-02 20:42:23 -05:00
XtraCube ce81d8c1ff it works? 2025-02-02 20:36:14 -05:00
XtraCube 9485099ab9 RPC add modifier with arguments 2025-02-02 16:09:06 -05:00
ang-xd 35689487ae Updated events 2025-02-02 16:08:29 -05:00
XtraCube 51fcc2c88f add ModdedEnumOption<T> 2025-01-29 20:57:21 -05:00
XtraCube d5ac231811 initial cooldown zero in freeplay 2025-01-29 18:07:04 -05:00
XtraCube 3538bea933 implicit conversions for explicit option classes 2025-01-29 18:04:01 -05:00
XtraCube 1d34e82503 implement changfe for MDB 2025-01-26 16:41:01 -05:00
XtraCube f5b4bdd1d4 Update discord links 2025-01-26 15:25:27 -05:00
XtraCube cd6c4f5390 Update README.md 2025-01-26 14:01:44 -05:00
XtraCube 5cc29d903a Update README.md 2025-01-26 14:01:30 -05:00
XtraCube c32eabcdff add InitialCooldown property to buttons 2025-01-03 19:05:00 -05:00
XtraCube 96f108ab92 use exception for invalid resource name in spritetools 2025-01-02 11:16:31 -05:00
XtraCube 204d1fe123 Merge pull request #16 from All-Of-Us-Mods/modifier-assignment-priority-2
Modifier assignment priority 2
2024-12-31 14:36:49 -05:00
XtraCube 7b51d9b6e6 fix modifier related errors 2024-12-30 13:48:24 -05:00
XtraCube 786450c7c1 fix SetUses bug in buttons and make effect and use limit optional 2024-12-27 18:48:43 -05:00
XtraCube 82050b9d2b bump version cuz i forgor 2024-12-27 14:15:10 -05:00
XtraCube e2b8c0c0a9 remove unnecessary tolist() 2024-12-26 22:34:40 -05:00
XtraCube 69635e02f1 cleanup 2024-12-26 13:41:26 -05:00
XtraCube f39442785f fix button event bug 2024-12-25 10:37:39 -05:00
XtraCube ed7e9949f5 silly bug 2024-12-23 12:55:47 -05:00
XtraCube 0fe6d98c67 remove unnecessary stuff 2024-12-21 16:21:38 -05:00
AlchlcDvl 9fb8a6bda4 make click handler public to allow forced behaviour 2024-12-21 15:16:25 -05:00
AlchlcDvl 3d2f53ce25 not get the count twice 2024-12-21 15:16:24 -05:00
AlchlcDvl ed0c75acf8 move max count down a bit 2024-12-21 15:16:24 -05:00
AlchlcDvl 246e40539c finally works 2024-12-21 15:16:24 -05:00
AlchlcDvl 160d424707 adding some logging to see what's wrong 2024-12-21 15:16:23 -05:00
AlchlcDvl 14276b6c2b why check the players twice 2024-12-21 15:16:23 -05:00
AlchlcDvl b909fb7447 insurance 2024-12-21 15:16:22 -05:00
AlchlcDvl 8b9621dafa fix up assignment + hide from il2cpp was being annoying 2024-12-21 15:16:21 -05:00
AlchlcDvl 9de2ba8e41 i think i got a better solution to this 2024-12-21 15:16:21 -05:00
AlchlcDvl 23e11fef93 reverse mod assignment order 2024-12-21 15:16:20 -05:00
AlchlcDvl 570bb388b6 add loggin for debugging 2024-12-21 15:16:20 -05:00
AlchlcDvl 5d05a07364 add modifier assignment priority 2024-12-21 15:16:19 -05:00
XtraCube d3a815faa9 Merge pull request #15 from All-Of-Us-Mods/events-system
initial event draft
2024-12-21 15:11:50 -05:00
XtraCube a23de7b51c event system fixes 2024-12-21 14:06:52 -05:00
XtraCube 13268ac70a fix issues with vent events 2024-12-08 17:58:37 -05:00
XtraCube 870c913b5d update to handle emergency meeting 2024-12-08 15:36:41 -05:00
XtraCube c1d2455e4d improve example 2024-12-08 15:20:11 -05:00
XtraCube 29c2939871 improved report body event and added vent events 2024-12-08 15:16:12 -05:00
XtraCube 2567722b52 prolly shouldnt be rpc 2024-12-08 14:57:03 -05:00
XtraCube 04ee35d708 basic "sabotage" event 2024-12-08 14:56:13 -05:00
XtraCube 3ea46d5574 more events 2024-12-08 14:44:01 -05:00
XtraCube 707b5629b4 priority system 2024-11-26 16:27:36 -05:00
XtraCube 8884996c06 button events and stuff properly work 2024-11-24 21:25:51 -05:00
XtraCube eac41a7c9e events 2 electric boogaloo 2024-11-24 18:27:14 -05:00
XtraCube 4c113e5fb8 initial event draft 2024-11-24 15:54:03 -05:00
XtraCube bc756d5c1b real fix for vent 2024-09-23 16:17:58 -04:00
XtraCube bbe7cd5a91 adjust 2024-09-23 16:05:25 -04:00
XtraCube 538ad48d18 modifier didwins 2024-09-23 16:05:24 -04:00
XtraCube 53baac167c custom player menu in mira 2024-09-23 16:05:24 -04:00
XtraCube 167566dc9b fix rpc custom murder 2024-09-23 16:05:23 -04:00
XtraCube 2df1eaa7c0 fix role defaults 2024-09-23 16:05:23 -04:00
XtraCube dd7f643153 only use custom murder 2024-09-23 16:05:23 -04:00
XtraCube 13dd0f4874 fix custom buttons 2024-09-23 16:05:22 -04:00
XtraCube 715d235bdc adjustment to role setting menu 2024-09-23 16:05:22 -04:00
XtraCube 25590242bc fix patch error 2024-09-23 16:05:22 -04:00
XtraCube 49489ff0d1 improvements to custom role (added SetChance and SetCount, improved GetChance and GetCount) 2024-09-23 16:05:21 -04:00
XtraCube aa2350bedf potentially fix mira vent bug 2024-09-23 15:59:42 -04:00
ang-xd 52daf69dfe Fix config disappearing issue 2024-09-17 19:40:14 -04:00
XtraCube 95f78addee oops 2024-09-17 12:33:38 -04:00
XtraCube 12d947748c make plugin manager publicly accessible 2024-09-17 12:31:30 -04:00
XtraCube be28948e7e allow access to plugin information externally 2024-09-17 12:26:01 -04:00
XtraCube d0161ba85c bump version 2024-09-16 16:01:20 -04:00
XtraCube 2411ac28a4 Merge branch 'new-role-configs' into dev 2024-09-16 16:00:59 -04:00
XtraCube 1bc0950acc adjust code 2024-09-14 23:22:19 -04:00
XtraCube 3aecd5a91c fix bug with setting uses of button 2024-09-14 23:22:12 -04:00
XtraCube 836823c477 Merge branch 'master' into dev 2024-09-14 22:56:24 -04:00
XtraCube c24404620b fix bug with modifiers and hud 2024-09-14 19:29:24 -04:00
XtraCube 7471a43d39 fix white button flashing issue 2024-09-14 19:29:14 -04:00
ang-xd dd6d57343e Role singleton 2024-09-14 15:47:02 -04:00
ang-xd fd75c99850 New role options 2024-09-14 14:42:20 -04:00
ang-xd 6e3de08043 New role configs system 2024-09-14 12:55:34 -04:00
XtraCube 1fa30485b0 bump version 2024-09-13 22:10:45 -04:00
XtraCube faed84d0f6 fix issue with example mod 2024-09-13 22:00:45 -04:00
XtraCube 2f7b0692f3 fix error in Polus Outside tasks in TaskAdder 2024-09-13 21:57:03 -04:00
XtraCube 8123381e1e add some more utility methods to timed modifier 2024-09-13 20:43:45 -04:00
XtraCube 4d36c13c5b use .Instance instead of DestroyableSingleton<>.Instance 2024-09-13 20:35:35 -04:00
XtraCube 91b7901528 generic type thingy :) 2024-09-13 20:33:50 -04:00
XtraCube 9a27a0c3d8 slight modification to caching modifier componenets 2024-09-13 20:24:38 -04:00
XtraCube cda441ee56 vent patch improvements 2024-09-13 20:03:46 -04:00
XtraCube 6ee83f8c7d better canvent stuff 2024-09-13 19:52:55 -04:00
XtraCube 8712a2b4e7 add predicate for selecting players in GetClosestPlayer extension method 2024-09-13 19:45:57 -04:00
XtraCube 30d2edfd9c Merge branch 'master' into dev 2024-09-10 09:46:44 -04:00
XtraCube 76cb2a6a59 adjustment to vent patches 2024-09-08 21:52:03 -04:00
XtraCube f20e7459a4 fix issue with hiding/showing options 2024-09-08 12:25:19 -04:00
XtraCube f462a116d7 fix contactfilter thingy 2024-09-08 12:06:01 -04:00
XtraCube 6f771821c8 update nearestobjectsoftype to specify layermask/contactfilter 2024-09-08 12:03:00 -04:00
XtraCube 754b8ef684 Merge branch 'refs/heads/master' into dev 2024-09-07 18:49:37 -04:00
XtraCube d8eb671b49 add pixels per unit to LoadableResourceAsset.cs 2024-09-07 18:46:32 -04:00
XtraCube 24ebee2743 make timers run on all players 2024-09-07 17:13:24 -04:00
XtraCube 878cf15a20 fix timed modifier auto removing if AutoStart is false 2024-09-07 16:47:52 -04:00
XtraCube 2f7cf4d664 fix double deactivation of modifiers when using ClearModifiers 2024-09-07 16:12:20 -04:00
XtraCube 4fcfb2a9ee fix LobbyViewPanePatches.cs AGAIN 2024-09-07 10:38:37 -04:00
XtraCube 41bedd3e16 bump version 2024-09-07 10:24:18 -04:00
XtraCube d27bf67f65 fix lobby view pane issues 2024-09-07 10:23:59 -04:00
XtraCube 76ddfa4126 Merge branch 'dev' 2024-09-05 18:10:04 -04:00
XtraCube 400ad535a4 bump version 2024-09-05 18:09:50 -04:00
XtraCube eaf5890f67 Merge pull request #13 from CallOfCreator/dev 2024-09-05 08:08:52 -04:00
XtraCube b2651adcab adjustments 2024-09-05 07:18:20 -04:00
XtraCube c8c6ab1f61 Update README.md 2024-09-04 18:49:24 -04:00
XtraCube 7f65f2d5bb remove warning from example build 2024-09-04 18:34:45 -04:00
XtraCube 17da594207 fix notif popper issue 2024-09-04 18:34:36 -04:00
ang-xd fa8fdfc4f6 Create ChameleonRole.cs 2024-09-04 17:30:08 -04:00
CallOfCreator 75dd5e8a35 Add CanUseSabotage support in ICustomRole 2024-09-04 16:27:57 +00:00
XtraCube a442f54b82 Merge pull request #12 from Rubyboat1207/audio-resource
Added Loadable Audio Resource Asset
2024-09-03 21:29:50 -04:00
Rubyboat 24dca63df1 File name more descriptive 2024-09-03 20:17:50 -05:00
XtraCube 08a4dc75f2 fix period oops 2024-09-03 21:05:55 -04:00
XtraCube 4e474dc5b2 formatting 2024-09-03 21:05:32 -04:00
XtraCube 3deffb701f Merge branch 'refs/heads/dev' into fork/Rubyboat1207/audio-resource 2024-09-03 21:02:00 -04:00
XtraCube f83dce99ef add group priorities for ordering groups 2024-09-03 20:59:26 -04:00
XtraCube 9c14db0321 slight fix to options Click To Close text 2024-09-03 18:39:03 -04:00
Rubyboat f92d08b825 Added Loadable Audio Resource Asset 2024-09-02 15:37:53 -05:00
XtraCube ae10917f2a hidefromil2cpp 2024-09-02 15:22:56 -04:00
XtraCube 51d08bb168 hide mod in TaskAdder if it has no roles 2024-09-02 15:22:50 -04:00
XtraCube 0e56a30c5c fix most non-documentation warnings 2024-09-02 15:19:32 -04:00
XtraCube 74055b8a17 various code alterations to patches to fix warnings 2024-09-02 14:11:10 -04:00
XtraCube 812cef5f2b fix loadable asset code docs and rework logic slightly 2024-09-02 14:10:44 -04:00
XtraCube 9665188a18 various adjustments to code style 2024-09-02 13:46:10 -04:00
XtraCube cb943c2173 CanKill -> UseVanillaKillButton
ICustomRole changes to clear up confusion
Add KillButtonOutlineColor to ICustomRole
2024-09-02 13:37:45 -04:00
XtraCube dc483adc1c more comments + nullable stuff 2024-09-02 13:04:20 -04:00
XtraCube 3d9bbc0833 comments 2024-09-02 13:01:34 -04:00
XtraCube b032e91e08 using statements 2024-09-02 12:57:32 -04:00
XtraCube 3cada4cb3d fix problem with TimedModifier using RPC on every client, despite being replicated 2024-09-02 12:57:25 -04:00
XtraCube 97ded2fc32 some updates to example mod 2024-09-02 12:53:08 -04:00
XtraCube f207849e5e fix neutral killing issues and rename some properties in ICustomRole to clear confusion 2024-09-02 00:12:50 -04:00
XtraCube f8bb63483f fixing possible issues with ghost roles 2024-09-01 20:54:35 -04:00
XtraCube a3dd4acf43 code document custom murder RPCs 2024-09-01 16:29:42 -04:00
XtraCube f17089f435 split HudManager patches 2024-09-01 16:14:30 -04:00
XtraCube d1c469746e fix poor documentation in ICustomRole 2024-09-01 16:08:18 -04:00
XtraCube b053684235 formatting 2024-09-01 16:08:01 -04:00
XtraCube 0f26cadd9a clean up OptionGroupSingleton.cs 2024-09-01 16:07:36 -04:00
XtraCube a07c332dce add DeathReason to modifier OnDeath method 2024-09-01 16:07:22 -04:00
XtraCube 74ab8c5581 oops 2024-09-01 16:06:41 -04:00
XtraCube aa72770bfc change vent color for custom roles 2024-09-01 16:06:35 -04:00
XtraCube 2b71438cd0 fix button reset after meeting 2024-09-01 15:53:33 -04:00
XtraCube e22032e1fb fix neutral naming from outcast 2024-09-01 15:53:09 -04:00
XtraCube bdb8852347 FIX NUGET CI PRAYING RN 2024-08-31 21:45:01 -04:00
XtraCube 4775bbfeaa precautions for the nuget stuff 2024-08-31 21:42:20 -04:00
XtraCube 0aa164de99 Merge branch 'refs/heads/dev' 2024-08-31 21:39:53 -04:00
XtraCube 5ec91813b7 bump version 2024-08-31 21:35:36 -04:00
XtraCube e2cabc6782 fix skidded CI 2024-08-31 21:35:12 -04:00
XtraCube 126df24a23 HideFromIl2Cpp and slight modification to TimedModifier to use new HudString method 2024-08-31 21:33:32 -04:00
XtraCube 8178967fd8 fix issue #11 2024-08-31 20:43:45 -04:00
XtraCube 0e40526d26 forgor to implement hud string thingy for modifiers 2024-08-31 17:41:12 -04:00
XtraCube 7bb9733513 update modifiers in fixedupdate instead of in add/removemodifier methods 2024-08-31 17:33:03 -04:00
XtraCube 1c97a4d32a try fixing null ref with roletab 2024-08-31 17:32:40 -04:00
XtraCube 1f357b5e08 add hud string method and code docs for modifiers 2024-08-31 16:25:50 -04:00
XtraCube 264defe8bf target should have protected setter, not private 2024-08-31 15:32:45 -04:00
XtraCube c318c447f7 namespace issue 2024-08-31 15:31:50 -04:00
XtraCube 06c59c5103 showcase mira stuff 2024-08-31 15:31:41 -04:00
XtraCube 8fe58ca6ca reset buttons on meeting start 2024-08-31 15:12:39 -04:00
XtraCube 1d92404b0e possible fix to weird errors?? 2024-08-31 15:12:27 -04:00
XtraCube 0429cd8005 remove ModdedStringOption.cs, improve code in Options API 2024-08-31 10:41:16 -04:00
XtraCube dc5bb4177f fix comments 2024-08-31 06:32:54 -04:00
XtraCube 5a95a6b352 finally fix custom colors, stupid among us and no errors for somr reason supe rweird 2024-08-31 00:56:32 -04:00
XtraCube 7999506359 change when colors are registered 2024-08-31 00:29:47 -04:00
XtraCube 0b36939858 fix pls???? 2024-08-31 00:24:21 -04:00
XtraCube 09ce9f7cfb possible fix for getplayermodifiers? 2024-08-31 00:12:12 -04:00
XtraCube aba4b30027 fix getclosestplayer errors 2024-08-31 00:10:04 -04:00
XtraCube 409113e37a WIP code documentation and various fixes 2024-08-30 23:52:43 -04:00
XtraCube a52f46972e make Role Tab optional 2024-08-30 12:28:02 -04:00
XtraCube 9f975c8263 half finished docs for cusotm action button 2024-08-30 11:59:02 -04:00
XtraCube e083c0c420 fix null ref in getclosestplayers 2024-08-30 11:44:15 -04:00
XtraCube 592e636903 document Extensions.cs 2024-08-30 11:25:15 -04:00
XtraCube b139fbe51d Add docs to ICustomRole, remove GetNetData from ICustomRole to prevent overriding it 2024-08-30 09:14:58 -04:00
XtraCube ce87fc4705 fix possible bug related to neutral role ghosts if devs dont specify exactly 2024-08-29 22:03:29 -04:00
XtraCube f23d21d896 remove useless property from ICustomRole 2024-08-29 21:51:28 -04:00
XtraCube 84651b90ea precautions for role configs 2024-08-29 21:36:14 -04:00
XtraCube 1428c629b8 document gamemodes 2024-08-29 20:34:12 -04:00
XtraCube feb73d6b07 document colors 2024-08-29 20:34:06 -04:00
XtraCube 54717c495f rework config definition setup + some docs 2024-08-29 20:16:52 -04:00
XtraCube febfda7d6f sonar analyzer 2024-08-29 20:08:31 -04:00
XtraCube 913377e4df Merge remote-tracking branch 'origin/dev' into dev 2024-08-29 19:48:55 -04:00
XtraCube 86893a1e9e update gitignore 2024-08-29 18:08:26 -04:00
Ang 56c2d9c0df Merge pull request #9 from All-Of-Us-Mods/dev
0.1.3 Changes
2024-08-29 16:51:36 -04:00
ang-xd ab5f997fb6 Bump ver 2024-08-29 16:51:24 -04:00
Ang 869d4970fd Merge pull request #8 from All-Of-Us-Mods/stylecop-and-new-build
Stylecop
2024-08-29 16:47:13 -04:00
ang-xd 2cbbcca161 oops 2024-08-29 16:46:38 -04:00
ang-xd 2f09baa371 Bug fixes and new teleport button 2024-08-29 16:31:07 -04:00
ang-xd acf1d44b52 Changes 2024-08-29 15:47:54 -04:00
ang-xd 03ef684691 New 2024-08-28 20:50:34 -04:00
XtraCube eafc740aca new CI, build, and stylecop skidded from reactor :p 2024-08-28 20:40:56 -04:00
ang-xd 7af85d9fbb Implement custom murders & extension method 2024-08-28 15:18:36 -04:00
Ang bdce8fa37d Update README.md 2024-08-28 15:17:56 -04:00
ang-xd 9fc5044085 Merge branch 'master' into dev 2024-08-28 14:08:12 -04:00
XtraCube 7cb103f318 save config file once when handling netdata 2024-08-28 13:45:32 -04:00
XtraCube dd8d3df2b0 refactor access and management methods for modifiers 2024-08-28 12:39:05 -04:00
XtraCube 19c7e38690 what the freak 2024-08-27 21:56:33 -04:00
XtraCube f1639a784d Merge branch 'refs/heads/dev' 2024-08-27 21:52:41 -04:00
XtraCube 5f1996b457 precautions 2024-08-27 21:49:53 -04:00
XtraCube 33d389e107 fix modifiers logic 2024-08-27 21:46:45 -04:00
XtraCube 176d472cd7 nullable 2024-08-27 21:46:36 -04:00
XtraCube 7a3406e0ae XD 2024-08-27 21:46:26 -04:00
XtraCube 9f92af8958 only show role setting button if there is settings for it 2024-08-27 21:46:21 -04:00
Ang 8d167596d2 Update README.md 2024-08-27 21:29:29 -04:00
XtraCube a98a37bea7 fix modifier manager logic? 2024-08-27 21:14:53 -04:00
ang-xd 4963c80395 Fixes and new stuff 2024-08-27 20:56:53 -04:00
XtraCube 4bef2f838d can use fix 2024-08-27 20:46:15 -04:00
XtraCube 763017b6e2 make GetTarget abstract instead of virtual 2024-08-27 20:44:37 -04:00
XtraCube 16fd8e02aa fix bug with advanced roles settings 2024-08-27 20:44:25 -04:00
XtraCube f187a15f2e more documentaion stuff 2024-08-27 20:23:53 -04:00
XtraCube e211c4c49c rename ResetCooldown to ResetCooldownAndOrEffect, add warning in doc 2024-08-27 20:21:06 -04:00
XtraCube 7f532cd82f Merge remote-tracking branch 'origin/master' 2024-08-27 20:11:43 -04:00
XtraCube 7a0396fe5c Make lobby view pane sync on options change 2024-08-27 20:11:36 -04:00
ang-xd d4955b5183 Merge branch 'master' into dev 2024-08-27 20:10:37 -04:00
ang-xd 0a5c59d9cd somewhat fix notifications on game start 2024-08-27 20:10:01 -04:00
ang-xd 774e1a7a2b Modifiers bug fixed 2024-08-27 19:54:33 -04:00
ang-xd 8e6f75cfbd WIP 2024-08-27 19:43:38 -04:00
XtraCube b36b434a99 oversight in the code 2024-08-27 19:39:36 -04:00
XtraCube 858e518a57 for sake of versioning ig 2024-08-27 19:34:31 -04:00
XtraCube b9734f5a1c forgot to bump version what an idiot 2024-08-27 19:31:42 -04:00
XtraCube 1cb11be9b0 Merge pull request #7 from All-Of-Us-Mods/dev
Button fix, MiraNumberSuffixes, checkmark fix,
2024-08-27 19:24:36 -04:00
XtraCube 6bc6ab7143 fix button issue 2024-08-27 19:22:48 -04:00
ang-xd 05fdf5313d MiraNumberSuffixes, and checkmark fix 2024-08-27 19:04:32 -04:00
XtraCube d54c47c835 oops 2024-08-27 18:24:51 -04:00
XtraCube 5d4f9eb06a Create main.yaml 2024-08-27 18:24:28 -04:00
XtraCube d153f10f0b Create build.cake 2024-08-27 18:23:54 -04:00
XtraCube f8af852286 Update README.md 2024-08-27 18:22:19 -04:00
XtraCube 9fb25542e7 all fixes except TMP mask 2024-08-27 18:12:20 -04:00
ang-xd 8a9300425a Semi broken task scroll 2024-08-27 17:19:50 -04:00
XtraCube 4277193aed we forgot scrolling colors 2024-08-27 16:18:15 -04:00
XtraCube a9015a3535 nugget preparations 2024-08-27 16:07:24 -04:00
XtraCube 67f0513605 fix 2024-08-27 15:56:12 -04:00
XtraCube 9c751bcd39 prep for release 2024-08-27 15:48:19 -04:00
XtraCube 10b8999f3e make colors make sense 2024-08-27 15:38:08 -04:00
XtraCube 76c39d9bdc final touches and fixes 2024-08-27 15:32:26 -04:00
XtraCube 016d21075f add custom color docs to readme 2024-08-27 15:07:20 -04:00
XtraCube 36a419d721 Merge pull request #6 from All-Of-Us-Mods/modifiers
Modifiers
2024-08-27 14:59:53 -04:00
XtraCube 87a1be7410 modifiers README 2024-08-27 14:59:16 -04:00
XtraCube 892c5c7c70 final touches 2024-08-27 14:46:53 -04:00
XtraCube 625cd2ca4b Merge branch 'refs/heads/master' into modifiers
# Conflicts:
#	MiraAPI.Example/Buttons/ExampleButton.cs
#	MiraAPI.Example/ExampleRole.cs
#	MiraAPI/GameOptions/OptionTypes/ModdedOption.cs
#	MiraAPI/Hud/CustomActionButton.cs
#	MiraAPI/MiraApiPlugin.cs
#	MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
#	MiraAPI/Patches/PlayerControlPatches.cs
#	MiraAPI/PluginLoading/MiraPluginManager.cs
#	MiraAPI/Roles/ICustomRole.cs
#	MiraAPI/Utilities/Extensions.cs
2024-08-27 14:43:05 -04:00
XtraCube 39851c6269 hmm 2024-08-27 14:33:33 -04:00
XtraCube 013c94d064 Merge pull request #5 from All-Of-Us-Mods/collapsible-options
Collapsible options, and fixes
2024-08-27 14:30:44 -04:00
XtraCube 2dadf08df4 a todo 2024-08-27 14:30:27 -04:00
XtraCube 74592b2558 oops role ID had issues 2024-08-27 14:29:06 -04:00
XtraCube 157c5af280 more readme 2024-08-27 14:05:04 -04:00
XtraCube 1cc41052e3 Merge branch 'refs/heads/master' into collapsible-options 2024-08-27 13:58:25 -04:00
ang-xd 8a8fb7ced4 Collapsible options, and fixes 2024-08-27 13:57:38 -04:00
XtraCube 99d5efca1a Merge pull request #4 from All-Of-Us-Mods/sequential-role-ids
sequential role IDs
2024-08-27 13:56:32 -04:00
XtraCube 37aee8712e readme update 2024-08-27 13:54:40 -04:00
XtraCube f39580e858 fixes 2024-08-27 13:26:32 -04:00
XtraCube 201826dc62 Merge branch 'refs/heads/master' into sequential-role-ids
# Conflicts:
#	MiraAPI/PluginLoading/MiraPluginInfo.cs
#	MiraAPI/PluginLoading/MiraPluginManager.cs
2024-08-27 13:23:38 -04:00
XtraCube 4cd8aa0bd7 advanced role settings in view tab 2024-08-27 13:18:38 -04:00
XtraCube cd1529b4bf QOL in view tab 2024-08-27 12:51:00 -04:00
XtraCube 564f524dd6 lobby view pane almost done 2024-08-27 12:45:22 -04:00
XtraCube 5e9c592aab prep for view pane 2024-08-27 12:44:53 -04:00
XtraCube d96b146e59 set neutral header color for uniformity 2024-08-27 12:44:41 -04:00
XtraCube a2b1e9ddbf increase contrast on AlternateColors 2024-08-27 12:44:28 -04:00
ang-xd dfa5591188 modifiers UI 2024-08-26 21:28:34 -04:00
ang-xd a88646465b GameModifiers, and fixes 2024-08-26 20:02:05 -04:00
XtraCube f4f2cf9182 braces 2024-08-26 16:27:00 -04:00
XtraCube c77664936f add button location property 2024-08-26 11:17:53 -04:00
XtraCube 55b7174be2 fix palette manager 2024-08-26 11:10:39 -04:00
XtraCube af471f0232 xd 2024-08-26 10:45:42 -04:00
XtraCube e4e3a10ed8 . 2024-08-26 10:41:36 -04:00
XtraCube d0bbb191c5 rename to palette 2024-08-26 10:38:35 -04:00
XtraCube 6de53fb761 custom colors API stuff 2024-08-26 09:57:46 -04:00
XtraCube 0e39612325 add docs to target button 2024-08-26 09:57:35 -04:00
XtraCube b62d1b6565 targeting action button 2024-08-25 21:51:22 -04:00
XtraCube 70320d7c19 fixing a possible version not having commit hash attached to it case 2024-08-25 09:45:57 -04:00
XtraCube 2eb2567db9 update to 2.3.1 and use ReactorCredits 2024-08-24 23:22:21 -04:00
XtraCube 3226d9fea5 small fixes 2024-08-24 16:52:20 -04:00
XtraCube a9ff1c7f63 networking modifiers 2024-08-24 13:36:49 -04:00
ang-xd 9b173a4298 Updates to Modifiers 2024-08-23 20:30:34 -04:00
XtraCube 26284852c9 fix merge issues 2024-08-23 15:48:16 -04:00
XtraCube 140d9ed353 Merge remote-tracking branch 'origin/modifiers' into modifiers
# Conflicts:
#	MiraAPI/Modifiers/BaseModifier.cs
#	MiraAPI/Modifiers/ModifierManager.cs
#	MiraAPI/Utilities/Extensions.cs
2024-08-23 15:45:47 -04:00
XtraCube 81f9fa728b rework how modifiers exist 2024-08-23 15:45:18 -04:00
ang-xd 5c24488049 Idk 2024-08-23 15:18:21 -04:00
XtraCube a0a2e9a6ab sequential role IDs 2024-08-22 18:48:38 -04:00
ang-xd a077cabea1 Modifiers base 2024-08-20 21:42:35 -04:00
294 changed files with 18771 additions and 2124 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
[*.{cs,vb}]
+51
View File
@@ -0,0 +1,51 @@
name: CI
on: ["workflow_dispatch", "push", "pull_request"]
jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/cache@v4
with:
path: |
~/.nuget/packages
~/.cache/bepinex
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Run the Cake script
uses: cake-build/cake-action@v2
with:
verbosity: Diagnostic
- uses: actions/upload-artifact@v4
with:
name: MiraAPI.dll
path: MiraAPI/bin/Release/net6.0/MiraAPI.dll
- uses: actions/upload-artifact@v4
with:
name: AllOfUs.MiraAPI.nupkg
path: MiraAPI/bin/Release/AllOfUs.MiraAPI.*.nupkg
- uses: softprops/action-gh-release@v2
if: github.ref_type == 'tag'
with:
draft: true
files: MiraAPI/bin/Release/net6.0/MiraAPI.dll
- name: Push NuGet package
if: github.ref_type == 'tag'
run: |
dotnet nuget push MiraAPI/bin/Release/AllOfUs.MiraAPI.*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}
+3 -1
View File
@@ -3,5 +3,7 @@
.vs/
obj/
bin/
.qodo/
*.user
*.user
*.lock.json
+14
View File
@@ -0,0 +1,14 @@
<Project>
<ItemGroup>
<PackageReference Include="Reactor" Version="2.3.1" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.735" Private="false" ExcludeAssets="runtime;native" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2025.4.15" PrivateAssets="all" />
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" ExcludeAssets="runtime" />
</ItemGroup>
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
</Target>
</Project>
+45
View File
@@ -0,0 +1,45 @@
<Project>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<DebugType>embedded</DebugType>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<VersionPrefix>0.2.1</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
<Authors>All Of Us, XtraCube, Angxl</Authors>
<Company>All Of Us</Company>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/All-Of-Us-Mods/MiraAPI</RepositoryUrl>
<PackageLicenseExpression>LGPL-2.1-or-later</PackageLicenseExpression>
<!-- SourceLink -->
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'true'">true</ContinuousIntegrationBuild>
</PropertyGroup>
<PropertyGroup>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest</AnalysisLevel>
<AnalysisMode>recommended</AnalysisMode>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.556" PrivateAssets="all" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)\stylecop.json" Link="stylecop.json" Visible="false" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.7.0.110445">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)\stylecop.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
</Project>
-26
View File
@@ -1,26 +0,0 @@
using MiraAPI.Hud;
using MiraAPI.Utilities.Assets;
using Reactor.Utilities;
using UnityEngine;
namespace MiraAPI.Example.Buttons;
[RegisterButton]
public class ExampleButton : CustomActionButton
{
public override string Name => "Example Button";
public override float Cooldown => 5f;
public override float EffectDuration => 0f;
public override int MaxUses => 5;
public override LoadableAsset<Sprite> Sprite { get; } = ExampleAssets.ExampleButton;
protected override void OnClick()
{
Logger<ExamplePlugin>.Info("Example button clicked!");
}
public override bool Enabled(RoleBehaviour role)
{
return true;
}
}
@@ -0,0 +1,48 @@
using MiraAPI.Example.Modifiers.Freezer;
using MiraAPI.Example.Options.Roles;
using MiraAPI.Example.Roles;
using MiraAPI.GameOptions;
using MiraAPI.Hud;
using MiraAPI.Keybinds;
using MiraAPI.Modifiers;
using MiraAPI.Utilities;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Buttons.Freezer;
public class FreezeButton : CustomActionButton<PlayerControl>
{
public override string Name => "Freeze";
public override float Cooldown => OptionGroupSingleton<FreezerRoleSettings>.Instance.FreezeDuration;
public override bool PauseTimerInVent => true;
public override LoadableAsset<Sprite> Sprite => ExampleAssets.ExampleButton;
public override MiraKeybind? Keybind => MiraGlobalKeybinds.PrimaryAbility;
protected override void OnClick()
{
Target?.RpcAddModifier<FreezeModifier>();
}
public override PlayerControl? GetTarget()
{
return PlayerControl.LocalPlayer.GetClosestPlayer(true, Distance);
}
public override void SetOutline(bool active)
{
Target?.cosmetics.SetOutline(active, new Il2CppSystem.Nullable<Color>(Palette.Blue));
}
public override bool IsTargetValid(PlayerControl? target)
{
return true;
}
public override bool Enabled(RoleBehaviour? role)
{
return role is FreezerRole;
}
}
+47
View File
@@ -0,0 +1,47 @@
using MiraAPI.Example.Modifiers;
using MiraAPI.Hud;
using MiraAPI.Keybinds;
using MiraAPI.Modifiers;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Buttons;
public class MeetingButton : CustomActionButton
{
public override string Name => "Call Meeting";
public override float Cooldown => 15;
public override int MaxUses => 3;
public override LoadableAsset<Sprite> Sprite => ExampleAssets.ExampleButton;
public override MiraKeybind? Keybind => MiraGlobalKeybinds.ModifierPrimaryAbility;
public override bool Enabled(RoleBehaviour? role)
{
return PlayerControl.LocalPlayer != null && PlayerControl.LocalPlayer.HasModifier<CaptainModifier>();
}
protected override void OnClick()
{
var bt = ShipStatus.Instance.EmergencyButton;
PlayerControl.LocalPlayer.NetTransform.Halt();
var minigame = Object.Instantiate(bt.MinigamePrefab, Camera.main!.transform, false);
var taskAdderGame = minigame as TaskAdderGame;
if (taskAdderGame != null)
{
taskAdderGame.SafePositionWorld = bt.SafePositionLocal + (Vector2)bt.transform.position;
}
minigame.transform.localPosition = new Vector3(0f, 0f, -50f);
minigame.Begin(null);
if (UsesLeft == 0 && PlayerControl.LocalPlayer.HasModifier<CaptainModifier>())
{
PlayerControl.LocalPlayer.RpcRemoveModifier<CaptainModifier>();
}
}
}
@@ -0,0 +1,27 @@
using MiraAPI.Example.GameOver;
using MiraAPI.Example.Roles;
using MiraAPI.GameEnd;
using MiraAPI.Hud;
using MiraAPI.Keybinds;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Buttons;
public class NeutralKillerButton : CustomActionButton
{
public override string Name => "Win Game";
public override float Cooldown => 0f;
public override LoadableAsset<Sprite> Sprite => ExampleAssets.ExampleButton;
public override MiraKeybind Keybind => ExampleKeybinds.NeutralWinKeybind;
protected override void OnClick()
{
CustomGameOver.Trigger<NeutralKillerGameOver>([PlayerControl.LocalPlayer.Data]);
}
public override bool Enabled(RoleBehaviour? role)
{
return role is NeutralKillerRole;
}
}
@@ -0,0 +1,89 @@
using System.Collections;
using MiraAPI.Example.Options.Roles;
using MiraAPI.Example.Roles;
using MiraAPI.GameOptions;
using MiraAPI.Hud;
using MiraAPI.Keybinds;
using MiraAPI.Utilities.Assets;
using Reactor.Utilities;
using UnityEngine;
namespace MiraAPI.Example.Buttons.Teleporter;
public class TeleportButton : CustomActionButton
{
public override string Name => "Teleport";
public override float Cooldown => OptionGroupSingleton<TeleporterOptions>.Instance.TeleportCooldown.Value;
public override float EffectDuration => OptionGroupSingleton<TeleporterOptions>.Instance.TeleportDuration;
public override int MaxUses => 2;
public override LoadableAsset<Sprite> Sprite => ExampleAssets.TeleportButton;
public override Color TextOutlineColor => new Color32(221, 176, 152, 255);
public static bool IsZoom { get; private set; }
public override MiraKeybind? Keybind => MiraGlobalKeybinds.PrimaryAbility;
public override bool Enabled(RoleBehaviour? role)
{
return role is TeleporterRole;
}
protected override void OnClick()
{
Coroutines.Start(ZoomOutCoroutine());
}
public override void OnEffectEnd()
{
Coroutines.Start(ZoomInCoroutine());
}
protected override void FixedUpdate(PlayerControl playerControl)
{
base.FixedUpdate(playerControl);
if (!EffectActive) return;
if (Input.GetKey(KeyCode.Mouse0))
{
playerControl.NetTransform.RpcSnapTo(Camera.main.ScreenToWorldPoint(Input.mousePosition));
ResetCooldownAndOrEffect();
}
}
private static IEnumerator ZoomOutCoroutine()
{
HudManager.Instance.ShadowQuad.gameObject.SetActive(false);
IsZoom = true;
var zoomDistance = OptionGroupSingleton<TeleporterOptions>.Instance.ZoomDistance;
for (var ft = Camera.main!.orthographicSize; ft < zoomDistance; ft += 0.3f)
{
Camera.main.orthographicSize = MeetingHud.Instance ? 3f : ft;
ResolutionManager.ResolutionChanged.Invoke((float)Screen.width / Screen.height, Screen.width, Screen.height, Screen.fullScreen);
foreach (var cam in Camera.allCameras) cam.orthographicSize = Camera.main.orthographicSize;
yield return null;
}
foreach (var cam in Camera.allCameras) cam.orthographicSize = zoomDistance;
ResolutionManager.ResolutionChanged.Invoke((float)Screen.width / Screen.height, Screen.width, Screen.height, Screen.fullScreen);
}
private static IEnumerator ZoomInCoroutine()
{
for (var ft = Camera.main!.orthographicSize; ft > 3f; ft -= 0.3f)
{
Camera.main.orthographicSize = MeetingHud.Instance ? 3f : ft;
ResolutionManager.ResolutionChanged.Invoke((float)Screen.width / Screen.height, Screen.width, Screen.height, Screen.fullScreen);
foreach (var cam in Camera.allCameras) cam.orthographicSize = Camera.main.orthographicSize;
yield return null;
}
foreach (var cam in Camera.allCameras) cam.orthographicSize = 3f;
HudManager.Instance.ShadowQuad.gameObject.SetActive(true);
IsZoom = false;
ResolutionManager.ResolutionChanged.Invoke((float)Screen.width / Screen.height, Screen.width, Screen.height, Screen.fullScreen);
}
}
+35
View File
@@ -0,0 +1,35 @@
using MiraAPI.Hud;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Buttons;
public class ThinkButton : CustomActionButton
{
public override string Name => "Think";
public override float Cooldown => 15f;
public override float EffectDuration => 10f;
public override int MaxUses => 1;
public override ButtonUsesMode UsesMode => ButtonUsesMode.PerRound;
public override LoadableAsset<Sprite> Sprite => ExampleAssets.ExampleButton;
protected override void OnClick()
{
// This button does absolutely nothing besides changing its text
Button!.OverrideText("Thinking...");
}
public override void OnEffectEnd()
{
Button!.OverrideText("Think");
}
public override bool IsEffectCancellable()
{
return true;
}
public override bool Enabled(RoleBehaviour? role)
{
return role != null && role.IsImpostor;
}
}
+5 -1
View File
@@ -5,5 +5,9 @@ namespace MiraAPI.Example;
public static class ExampleAssets
{
public static LoadableResourceAsset ExampleButton { get; } = new("MiraAPI.Example.Resources.ExampleButton.png");
public static LoadableResourceAsset CallMeetingButton { get; } = new("MiraAPI.Example.Resources.CallMeeting.png");
// Credit to EpicHorrors for the teleport button asset.
public static LoadableResourceAsset TeleportButton { get; } = new("MiraAPI.Example.Resources.TeleportButton.png");
public static LoadableResourceAsset Banner { get; } = new("MiraAPI.Example.Resources.FortniteBanner.jpeg");
}
}
+17
View File
@@ -0,0 +1,17 @@
using MiraAPI.Colors;
using UnityEngine;
namespace MiraAPI.Example;
[RegisterCustomColors]
public static class ExampleColors
{
public static CustomColor Cerulean { get; } = new("Cerulean", new Color(0.0f, 0.48f, 0.65f))
{
ColorBrightness = CustomColorBrightness.Lighter,
};
public static CustomColor Rose { get; } = new("Rose", new Color(0.98f, 0.26f, 0.62f));
public static CustomColor Gold { get; } = new("Gold", new Color(1.0f, 0.84f, 0.0f));
}
+98
View File
@@ -0,0 +1,98 @@
using System.Linq;
using MiraAPI.Events;
using MiraAPI.Events.Mira;
using MiraAPI.Events.Vanilla.Gameplay;
using MiraAPI.Events.Vanilla.Map;
using MiraAPI.Events.Vanilla.Meeting;
using MiraAPI.Events.Vanilla.Meeting.Voting;
using MiraAPI.Events.Vanilla.Player;
using MiraAPI.Example.Buttons.Freezer;
using MiraAPI.Example.Roles;
using MiraAPI.Utilities;
using Reactor.Utilities;
namespace MiraAPI.Example;
public static class ExampleEventHandlers
{
public static void Initialize()
{
// You can register event handlers with the MiraEventManager class.
var handle = MiraEventManager.RegisterEventHandler<BeforeMurderEvent>(@event =>
{
Logger<ExamplePlugin>.Info($"{@event.Source.Data.PlayerName} is about to kill {@event.Target.Data.PlayerName}");
});
MiraEventManager.RegisterEventHandler<AfterMurderEvent>(@event =>
{
Logger<ExamplePlugin>.Info($"{@event.Source.Data.PlayerName} has killed {@event.Target.Data.PlayerName}");
});
MiraEventManager.RegisterEventHandler<CompleteTaskEvent>(@event =>
{
Logger<ExamplePlugin>.Info($"{@event.Player.Data.PlayerName} completed {@event.Task.TaskType.ToString()}");
});
// You can also unregister event handlers using the handle returned from RegisterEventHandler.
MiraEventManager.UnregisterEventHandler(handle);
}
// If you want to add extra votes to a player, do something like this.
[RegisterEvent]
public static void StartMeetingEvent(StartMeetingEvent _)
{
foreach (var plr in PlayerControl.AllPlayerControls.ToArray().Where(player => player.Data.Role is MayorRole))
{
plr.GetVoteData().IncreaseRemainingVotes(1);
}
}
// Example of using the Voting API to make a role similar to the Prosecutor from Town of Us.
[RegisterEvent(15)]
public static void HandleVoteEvent(HandleVoteEvent @event)
{
if (@event.VoteData.Owner.Data.Role is not NeutralKillerRole) return;
@event.VoteData.SetRemainingVotes(0);
for (var i = 0; i < 5; i++)
{
@event.VoteData.VoteForPlayer(@event.TargetId);
}
foreach (var plr in PlayerControl.AllPlayerControls.ToArray().Where(player => player != @event.VoteData.Owner))
{
plr.GetVoteData().Votes.Clear();
plr.GetVoteData().VotesRemaining = 0;
}
@event.Cancel();
}
// Events can be registered using an attribute as well.
[RegisterEvent]
public static void UpdateSystemEventHandler(UpdateSystemEvent @event)
{
Logger<ExamplePlugin>.Error(@event.SystemType.ToString());
}
// Example event handler
[RegisterEvent(1)]
public static void FreezeButtonClickHandler(MiraButtonClickEvent<FreezeButton> @event)
{
Logger<ExamplePlugin>.Warning("Freeze button clicked!");
if (PlayerControl.LocalPlayer.Data.PlayerName != "stupid") return;
@event.Cancel();
@event.Button.SetTimer(15f);
}
// Example event handler
[RegisterEvent]
public static void FreezeButtonCancelledHandler(MiraButtonCancelledEvent<FreezeButton> @event)
{
Logger<ExamplePlugin>.Warning("Freeze button cancelled!");
@event.Button.OverrideName("Freeze Canceled");
}
}
+10
View File
@@ -0,0 +1,10 @@
using MiraAPI.Keybinds;
using Rewired;
namespace MiraAPI.Example;
[RegisterCustomKeybinds]
public static class ExampleKeybinds
{
public static MiraKeybind NeutralWinKeybind { get; } = new("Neutral Win", KeyboardKeyCode.C, [ModifierKey.Shift]);
}
+53
View File
@@ -0,0 +1,53 @@
using BepInEx.Configuration;
using MiraAPI.LocalSettings;
using MiraAPI.LocalSettings.Attributes;
using MiraAPI.Utilities;
using UnityEngine;
namespace MiraAPI.Example;
public class ExampleLocalSettings(ConfigFile config) : LocalSettingsTab(config)
{
public override string TabName => "Mira Example";
protected override bool ShouldCreateLabels => false;
public override LocalSettingTabAppearance TabAppearance => new()
{
ToggleActiveColor = Color.blue,
ToggleInactiveColor = Color.red,
};
[LocalSettingsButton]
public LocalSettingsButton ExampleButton { get; private set; } = new("Example Button", OnExampleButtonClick);
[LocalToggleSetting]
public ConfigEntry<bool> ExampleToggle { get; private set; } = config.Bind("General", "Example Bool", true);
[LocalToggleSetting]
public ConfigEntry<bool> ExampleToggle2 { get; private set; } = config.Bind("General", "Example Bool 2", false);
[LocalSliderSetting(suffixType: MiraNumberSuffixes.Percent, formatString: "0", roundValue: true)]
public ConfigEntry<float> ExampleSlider { get; private set; } = config.Bind("General", "Slider", 50f);
[LocalNumberSetting]
public ConfigEntry<float> ExampleNumber { get; private set; } = config.Bind("General", "Example Number", 4f);
[LocalNumberSetting(min: 0.1f, max: 2.5f, increment: 0.1f, formatString: "0.0", suffixType: MiraNumberSuffixes.Multiplier)]
public ConfigEntry<float> ExampleFloatNumber { get; private set; } = config.Bind("General", "Example Multplier", 1f);
[LocalEnumSetting]
public ConfigEntry<ExampleEnumSetting> ExampleEnum { get; private set; } = config.Bind("General", "Example Enum", ExampleEnumSetting.Fries);
private static void OnExampleButtonClick()
{
LocalSettingsTabSingleton<MiraApiSettings>.Instance.Open();
}
}
public enum ExampleEnumSetting
{
Cheeseburger,
Sandwich,
Fries,
ChickenNuggets,
}
+6 -3
View File
@@ -1,4 +1,5 @@
using BepInEx;
using System.Linq;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
@@ -9,7 +10,7 @@ using Reactor.Networking.Attributes;
namespace MiraAPI.Example;
[BepInAutoPlugin("mira.example", "MiraAPIExample")]
[BepInAutoPlugin("mira.example", "MiraExampleMod")]
[BepInProcess("Among Us.exe")]
[BepInDependency(ReactorPlugin.Id)]
[BepInDependency(MiraApiPlugin.Id)]
@@ -17,9 +18,11 @@ namespace MiraAPI.Example;
public partial class ExamplePlugin : BasePlugin, IMiraPlugin
{
public Harmony Harmony { get; } = new(Id);
public string OptionsTitleText => "Mira API\nExample Mod";
public ConfigFile GetConfigFile() => Config;
public override void Load()
{
ExampleEventHandlers.Initialize();
Harmony.PatchAll();
}
}
}
@@ -0,0 +1,21 @@
using MiraAPI.Example.Roles;
using MiraAPI.GameEnd;
using MiraAPI.Utilities;
using UnityEngine;
namespace MiraAPI.Example.GameOver;
public class NeutralKillerGameOver : CustomGameOver
{
public override bool VerifyCondition(PlayerControl playerControl, NetworkedPlayerInfo[] winners)
{
return winners is [{ Role: NeutralKillerRole }];
}
public override void AfterEndGameSetup(EndGameManager endGameManager)
{
endGameManager.WinText.text = "Outcast Killer Wins!";
endGameManager.WinText.color = Color.magenta;
endGameManager.BackgroundBar.material.SetColor(ShaderID.Color, Color.magenta);
}
}
+6 -26
View File
@@ -1,37 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<DebugType>embedded</DebugType>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix>
<Version>1.0.0</Version>
<Description>Example mod for Mira API</Description>
<Authors>Angxl, XtraCube</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Reactor" Version="2.3.0" />
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.697" Private="false" ExcludeAssets="runtime;native" />
<PackageReference Include="Iced" Version="1.21.0" />
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2024.8.13" PrivateAssets="all" />
<PackageReference Include="BepInEx.AutoPlugin" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" PrivateAssets="all" ExcludeAssets="runtime">
<IncludeAssets>compile; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MiraAPI\MiraAPI.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\ExampleButton.png" />
<EmbeddedResource Include="Resources\FortniteBanner.jpeg" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\**\*.*" />
</ItemGroup>
<Target Name="Copy" AfterTargets="Build" Condition="'$(AmongUs)' != ''">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(AmongUs)/BepInEx/plugins/" UseSymboliclinksIfPossible="true" />
</Target>
<Import Project="..\AmongUs.props" />
</Project>
+27
View File
@@ -0,0 +1,27 @@
using System;
using Il2CppInterop.Runtime.Attributes;
using Reactor.Utilities.Attributes;
using Reactor.Utilities.ImGui;
using UnityEngine;
namespace MiraAPI.Example;
[RegisterInIl2Cpp]
public class MiraDebugWindow(IntPtr cppPtr) : MonoBehaviour(cppPtr)
{
[HideFromIl2Cpp]
public DragWindow DebuggingWindow { get; } = new(
new Rect(10, 10, 0, 0),
"MIRA API DEBUGGING",
() =>
{
})
{
Enabled = true,
};
public void OnGUI()
{
DebuggingWindow.OnGUI();
}
}
-8
View File
@@ -1,8 +0,0 @@
namespace MiraAPI.Example;
public class ModifierExample
{
//name, role specific, etc
// mono behaviour stuff here (ModdedPlayerModifier inherits monobehaviour)
}
@@ -0,0 +1,34 @@
using MiraAPI.Example.Options.Modifiers;
using MiraAPI.GameOptions;
using MiraAPI.Modifiers;
using MiraAPI.Modifiers.Types;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Modifiers;
public class CaptainModifier : GameModifier
{
public override string ModifierName => "Captain";
public override LoadableAsset<Sprite>? ModifierIcon => ExampleAssets.CallMeetingButton;
public override void OnDeath(DeathReason reason)
{
Player.RemoveModifier(this);
}
public override string GetDescription()
{
return $"You can call a meeting from anywhere on the map.";
}
public override int GetAssignmentChance()
{
return (int)OptionGroupSingleton<CaptainModifierSettings>.Instance.Chance;
}
public override int GetAmountPerGame()
{
return (int)OptionGroupSingleton<CaptainModifierSettings>.Instance.Amount;
}
}
@@ -0,0 +1,41 @@
using Il2CppSystem;
using MiraAPI.Example.Roles;
using MiraAPI.Modifiers.Types;
using UnityEngine;
namespace MiraAPI.Example.Modifiers.Freezer;
public class FreezeModifier : TimedModifier
{
public override string ModifierName => "Freezed";
public override bool HideOnUi => false;
public override float Duration => 15f;
public override bool AutoStart => true;
public override bool RemoveOnComplete => true;
public override void OnActivate()
{
if (Player.AmOwner)
{
Player.moveable = false;
}
}
public override void FixedUpdate()
{
base.FixedUpdate();
if (Player.AmOwner || PlayerControl.LocalPlayer.Data.Role is FreezerRole)
{
Player.cosmetics.SetOutline(true, new Nullable<Color>(Palette.LightBlue));
}
}
public override void OnTimerComplete()
{
if (Player.AmOwner)
{
Player.moveable = true;
}
}
}
@@ -0,0 +1,28 @@
using MiraAPI.Modifiers.Types;
namespace MiraAPI.Example.Modifiers;
public class HighPriorityModifier : GameModifier
{
public override string ModifierName => "High Priority";
public override string GetDescription()
{
return "You are high priority! Idrk what this means either tbh...";
}
public override int GetAssignmentChance()
{
return 100;
}
public override int GetAmountPerGame()
{
return 1;
}
public override int Priority()
{
return 100;
}
}
+16 -18
View File
@@ -1,33 +1,31 @@
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
using MiraAPI.Utilities;
using UnityEngine;
namespace MiraAPI.Example.Options;
public class ExampleOptions : AbstractOptionGroup
{
public override string GroupName => "General Group";
public override Color GroupColor => Color.red;
public override string GroupName => "Example Options 1";
public override Color GroupColor => Color.green;
[ModdedToggleOption("Use Thing")]
public bool UseThing { get; set; } = false;
[ModdedToggleOption("Toggle Opt 1")]
public bool ToggleOpt { get; set; } = false;
[ModdedToggleOption("Use another thing")]
public bool UseAnotherThing { get; set; } = true;
[ModdedToggleOption("Toggle Opt 2")]
public bool ToggleOpt2 { get; set; } = true;
[ModdedNumberOption("Sussy level", min: 0, max: 10)]
public float SussyLevel { get; set; } = 4f;
[ModdedNumberOption("Number Opt", min: 0, max: 10, increment: .25f, formatString: "0.00", suffixType: MiraNumberSuffixes.Percent)]
public float NumberOpt { get; set; } = 4f;
[ModdedStringOption("Sus choices", ["hello", "hello 2", "hello 3"])]
public int SusChoices { get; set; } = 2;
[ModdedEnumOption("Enum test", typeof(TestEnum))]
public TestEnum EnumTest { get; set; } = TestEnum.Bye;
[ModdedEnumOption("Best API", typeof(BestApi), ["Mira API", "Mitochondria", "Reactor"])]
public BestApi Opt { get; set; } = BestApi.MiraAPI;
}
public enum TestEnum
public enum BestApi
{
Hello,
Hi,
Bye
}
MiraAPI,
Mitochondria,
Reactor,
}
+23 -17
View File
@@ -1,27 +1,33 @@
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.OptionTypes;
using Reactor.Utilities;
namespace MiraAPI.Example.Options;
public class ExampleOptions2 : AbstractOptionGroup
{
public override string GroupName => "Example 2";
public ModdedToggleOption UseThing { get; } = new("Use Thingy 5", false);
public ModdedToggleOption UseThing2 { get; } = new("Use Thingy 6", false);
public ModdedStringOption Sussy { get; } = new("Sussy", 0, ["Sussy 1", "Sussy 2", "Sussy 3"]);
public ModdedEnumOption SussyEnum { get; } = new("Sussy Enum", 0, typeof(SussyEnum));
public ModdedNumberOption YeezyLevel { get; } = new("Yeezy Level", 50, 0, 100, 25, NumberSuffixes.Multiplier);
public override string GroupName => "Example Options 2";
public override uint GroupPriority => 0; // This group will be displayed first. The default value is uint.MaxValue.
public ModdedPlayerOption PlayerOption2 { get; } = new("YOU MUST CHOSE A PLAYER", false);
public ModdedPlayerOption PlayerOption { get; } = new("Eh whatever");
public ModdedToggleOption ToggleOpt1 { get; } = new("Toggle Option 1", false);
public ModdedToggleOption ToggleOpt2 { get; } = new("Toggle Option 2", false)
{
Visible = () => OptionGroupSingleton<ExampleOptions2>.Instance.ToggleOpt1, // implicit cast from ModdedToggleOption to bool
};
public ModdedEnumOption<TestingData> EnumOpt { get; } = new("Enum Opt", 0)
{
ChangedEvent = x => Logger<ExamplePlugin>.Info($"changed Enum Opt to {x}"),
};
}
public enum SussyEnum
public enum TestingData : ulong
{
Sussy,
Baka,
Imposter,
Kanye
}
Happy,
Sad,
Neutral,
}
@@ -0,0 +1,19 @@
using MiraAPI.Example.Modifiers;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
namespace MiraAPI.Example.Options.Modifiers;
public class CaptainModifierSettings : AbstractOptionGroup<CaptainModifier>
{
public override string GroupName => "Captain Settings";
[ModdedNumberOption("Amount", 0, 5)]
public float Amount { get; set; } = 1;
[ModdedNumberOption("Chance", 0, 100, 10)]
public float Chance { get; set; } = 50;
[ModdedNumberOption("Uses", 1, 5)]
public float NumUses { get; set; } = 3;
}
@@ -0,0 +1,13 @@
using MiraAPI.Example.Modifiers.Freezer;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
namespace MiraAPI.Example.Options.Modifiers;
public class FreezeModifierSettings : AbstractOptionGroup<FreezeModifier>
{
public override string GroupName => "Freeze";
[ModdedToggleOption("Use Color")]
public bool UseColor { get; set; } = true;
}
@@ -0,0 +1,19 @@
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
namespace MiraAPI.Example.Options.Modifiers;
public class GeneralModifierOptions : AbstractOptionGroup
{
public override string GroupName => "General";
public override uint GroupPriority => 0;
public override bool ShowInModifiersMenu => true;
[ModdedToggleOption("Some Boolean Option")]
public bool SomeBooleanOption { get; set; } = true;
[ModdedNumberOption("Number Option", 0, 10, 1)]
public float NumberOption { get; set; } = 5;
}
@@ -1,16 +0,0 @@
using System;
using MiraAPI.Example.Roles;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
namespace MiraAPI.Example.Options.Roles;
public class CustomRole2Settings : AbstractOptionGroup
{
public override string GroupName => "Custom Role";
public override Type AdvancedRole => typeof(CustomRole2);
[ModdedToggleOption("Teleportation ability")] public bool Teleport { get; set; } = true;
}
@@ -1,16 +0,0 @@
using System;
using MiraAPI.Example.Roles;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
namespace MiraAPI.Example.Options.Roles;
public class CustomRoleSettings : AbstractOptionGroup
{
public override string GroupName => "Custom Role";
public override Type AdvancedRole => typeof(CustomRole);
[ModdedNumberOption("Testing level", min: 3, max: 9)] public float TestingLevel { get; set; } = 4;
}
@@ -0,0 +1,17 @@
using MiraAPI.Example.Roles;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
using MiraAPI.Utilities;
namespace MiraAPI.Example.Options.Roles;
public class FreezerRoleSettings : AbstractOptionGroup<FreezerRole>
{
public override string GroupName => "Custom Role";
[ModdedNumberOption("Freeze Duration", 1, 15, 1, MiraNumberSuffixes.Seconds)]
public float FreezeDuration { get; set; } = 5;
[ModdedNumberOption("Freeze Uses", 1, 5)]
public float FreezeUses { get; set; } = 1;
}
@@ -0,0 +1,20 @@
using MiraAPI.Example.Roles;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.Attributes;
using MiraAPI.GameOptions.OptionTypes;
using MiraAPI.Utilities;
namespace MiraAPI.Example.Options.Roles;
public class TeleporterOptions : AbstractOptionGroup<TeleporterRole>
{
public override string GroupName => "Teleporter";
public ModdedNumberOption TeleportCooldown { get; set; } = new("Teleport Cooldown", 10, 5, 60, 2.5f, MiraNumberSuffixes.Seconds);
[ModdedNumberOption("Teleport Duration", 5, 25, 1, MiraNumberSuffixes.Seconds)]
public float TeleportDuration { get; set; } = 10;
[ModdedNumberOption("Zoom Distance", 4, 15)]
public float ZoomDistance { get; set; } = 6;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+78
View File
@@ -0,0 +1,78 @@
using AmongUs.GameOptions;
using MiraAPI.Patches.Stubs;
using MiraAPI.Roles;
using Reactor.Utilities;
using TMPro;
using UnityEngine;
namespace MiraAPI.Example.Roles;
public class ChameloenRole : CrewmateRole, ICustomRole
{
public string RoleName => "Chamelon";
public string RoleLongDescription => "Stay invisible while not moving.";
public string RoleDescription => RoleLongDescription;
public Color RoleColor => Palette.AcceptedGreen;
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
private bool _shouldHide;
public CustomRoleConfiguration Configuration => new(this)
{
OptionsScreenshot = ExampleAssets.Banner,
IntroSound = CustomRoleUtils.GetIntroSound(RoleTypes.Shapeshifter),
};
public override void Initialize(PlayerControl player)
{
Logger<ExamplePlugin>.Info("Initializing ChamelonRole for player: " + player.PlayerId);
RoleBehaviourStubs.Initialize(this, player);
_shouldHide = true;
}
public void FixedUpdate()
{
if (!Player || !_shouldHide)
{
return;
}
if (Player.MyPhysics.Velocity.magnitude > 0)
{
var rend = Player.cosmetics.currentBodySprite.BodySprite;
var tmp = Player.cosmetics.nameText;
tmp.color = Color.Lerp(tmp.color, new Color(tmp.color.r, tmp.color.g, tmp.color.b, 1), Time.deltaTime * 4f);
rend.color = Color.Lerp(rend.color, new Color(1, 1, 1, 1), Time.deltaTime * 4f);
foreach (var cosmetic in Player.cosmetics.transform.GetComponentsInChildren<SpriteRenderer>())
{
cosmetic.color = Color.Lerp(cosmetic.color, new Color(1, 1, 1, 1), Time.deltaTime * 4f);
}
}
else
{
SpriteRenderer rend = Player.cosmetics.currentBodySprite.BodySprite;
TextMeshPro tmp = Player.cosmetics.nameText;
tmp.color = Color.Lerp(tmp.color, new Color(tmp.color.r, tmp.color.g, tmp.color.b, Player.AmOwner ? 0.3f : 0), Time.deltaTime * 4f);
rend.color = Color.Lerp(rend.color, new Color(1, 1, 1, Player.AmOwner ? 0.3f : 0), Time.deltaTime * 4f);
foreach (var cosmetic in Player.cosmetics.transform.GetComponentsInChildren<SpriteRenderer>())
{
cosmetic.color = Color.Lerp(cosmetic.color, new Color(1, 1, 1, Player.AmOwner ? 0.3f : 0), Time.deltaTime * 4f);
}
}
}
public override void Deinitialize(PlayerControl targetPlayer)
{
Logger<ExamplePlugin>.Info("Deinitializing ChamelonRole for player: " + targetPlayer.PlayerId);
RoleBehaviourStubs.Deinitialize(this, targetPlayer);
_shouldHide = false;
foreach (var cosmetic in Player.cosmetics.transform.GetComponentsInChildren<SpriteRenderer>(true))
{
cosmetic.color = Color.white;
}
Player.cosmetics.currentBodySprite.BodySprite.color = Color.white;
Player.cosmetics.nameText.color = Color.white;
}
}
-17
View File
@@ -1,17 +0,0 @@
using MiraAPI.Roles;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Roles;
[RegisterCustomRole]
public class CustomRole : ImpostorRole, ICustomRole
{
public string RoleName => "fortnite killer";
public string RoleLongDescription => "ok so your objective is to eliminate everyone with your fortnite tactical shotgun, good luck";
public string RoleDescription => RoleLongDescription;
public Color RoleColor => Palette.Black;
public ModdedRoleTeams Team => ModdedRoleTeams.Impostor;
public LoadableAsset<Sprite> OptionsScreenshot => ExampleAssets.Banner;
}
-17
View File
@@ -1,17 +0,0 @@
using MiraAPI.Roles;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Roles;
[RegisterCustomRole]
public class CustomRole2 : CrewmateRole, ICustomRole
{
public string RoleName => "fortnite defender";
public string RoleLongDescription => "ok so your objective is to save everyone from the fortnite killer";
public string RoleDescription => RoleLongDescription;
public Color RoleColor => Palette.AcceptedGreen;
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
public LoadableAsset<Sprite> OptionsScreenshot => ExampleAssets.Banner;
}
-17
View File
@@ -1,17 +0,0 @@
using MiraAPI.Roles;
using MiraAPI.Utilities.Assets;
using UnityEngine;
namespace MiraAPI.Example.Roles;
[RegisterCustomRole]
public class CustomRole3 : CrewmateRole, ICustomRole
{
public string RoleName => "fortnite helper";
public string RoleLongDescription => "ok so your objective is to help";
public string RoleDescription => RoleLongDescription;
public Color RoleColor => Palette.Brown;
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
public LoadableAsset<Sprite> OptionsScreenshot => ExampleAssets.Banner;
}
+19
View File
@@ -0,0 +1,19 @@
using MiraAPI.Roles;
using UnityEngine;
namespace MiraAPI.Example.Roles;
public class FreezerRole : ImpostorRole, ICustomRole
{
public string RoleName => "Freezer";
public string RoleLongDescription => "Freeze another player for a duration of time.";
public string RoleDescription => RoleLongDescription;
public Color RoleColor => Palette.Blue;
public ModdedRoleTeams Team => ModdedRoleTeams.Impostor;
public CustomRoleConfiguration Configuration => new CustomRoleConfiguration(this)
{
OptionsScreenshot = ExampleAssets.Banner,
MaxRoleCount = 2,
};
}
+14
View File
@@ -0,0 +1,14 @@
using MiraAPI.Roles;
using UnityEngine;
namespace MiraAPI.Example.Roles;
public class MayorRole : CrewmateRole, ICustomRole
{
public string RoleName => "Mayor";
public string RoleLongDescription => "You get extra votes!";
public string RoleDescription => RoleLongDescription;
public Color RoleColor => new Color32(221, 176, 152, 255);
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
public CustomRoleConfiguration Configuration => new(this);
}
@@ -0,0 +1,39 @@
using MiraAPI.Example.GameOver;
using MiraAPI.GameEnd;
using MiraAPI.Roles;
using UnityEngine;
namespace MiraAPI.Example.Roles;
public class NeutralKillerRole : ImpostorRole, ICustomRole
{
public string RoleName => "Outcast Killer";
public string RoleDescription => "Outcast who can kill.";
public string RoleLongDescription => RoleDescription;
public Color RoleColor => Color.magenta;
public ModdedRoleTeams Team => ModdedRoleTeams.Custom;
public CustomRoleConfiguration Configuration => new(this)
{
UseVanillaKillButton = true,
CanGetKilled = true,
CanUseVent = true,
};
public RoleOptionsGroup RoleOptionsGroup { get; } = new("Outcast", Color.gray);
public TeamIntroConfiguration? IntroConfiguration { get; } = new(
Color.gray,
"OUTCAST",
"You are an Outcast. You do not have a team.");
public override void SpawnTaskHeader(PlayerControl playerControl)
{
// remove existing task header.
}
public override bool DidWin(GameOverReason gameOverReason)
{
return gameOverReason == CustomGameOver.GameOverReason<NeutralKillerGameOver>();
}
}
+26
View File
@@ -0,0 +1,26 @@
using MiraAPI.Roles;
using UnityEngine;
namespace MiraAPI.Example.Roles;
public class TeleporterRole : CrewmateRole, ICustomRole
{
public string RoleName => "Teleporter";
public string RoleLongDescription => "Zoom out and teleport across the map!";
public string RoleDescription => RoleLongDescription;
public Color RoleColor => new Color32(221, 176, 152, 255);
public ModdedRoleTeams Team => ModdedRoleTeams.Crewmate;
public CustomRoleConfiguration Configuration => new CustomRoleConfiguration(this)
{
OptionsScreenshot = ExampleAssets.Banner,
CanModifyChance = false,
DefaultChance = 73,
DefaultRoleCount = 4,
};
public bool CanLocalPlayerSeeRole(PlayerControl player)
{
return true;
}
}
+65
View File
@@ -0,0 +1,65 @@
using MiraAPI.Utilities;
using Reactor.Localization.Utilities;
using UnityEngine;
namespace MiraAPI.Colors;
/// <summary>
/// Represents a custom color with a main color and a shadow color.
/// </summary>
/// <param name="name">The name of the option.</param>
/// <param name="mainColor">The main color.</param>
/// <param name="shadowColor">The shadow color.</param>
public sealed class CustomColor(StringNames name, Color32 mainColor, Color32 shadowColor)
{
/// <summary>
/// Gets or sets the main color.
/// </summary>
public Color32 MainColor { get; set; } = mainColor;
/// <summary>
/// Gets or sets the shadow color.
/// </summary>
public Color32 ShadowColor { get; set; } = shadowColor;
/// <summary>
/// Gets or sets the name of the color.
/// </summary>
public StringNames Name { get; set; } = name;
/// <summary>
/// Gets or sets whether the color is lighter or darker. Can be used to help with colorblind stuff.
/// </summary>
public CustomColorBrightness ColorBrightness { get; set; } = CustomColorBrightness.Darker;
/// <inheritdoc />
public CustomColor(StringNames name, Color32 mainColor) : this(name, mainColor, mainColor.GetShadowColor(60))
{
}
/// <inheritdoc />
public CustomColor(string name, Color32 mainColor) : this(name, mainColor, mainColor.GetShadowColor(60))
{
}
/// <inheritdoc />
public CustomColor(string name, Color32 mainColor, Color32 shadowColor) : this(CustomStringName.CreateAndRegister(name), mainColor, shadowColor)
{
}
}
/// <summary>
/// Can be used to help with colorblind stuff.
/// </summary>
public enum CustomColorBrightness
{
/// <summary>
/// A lighter color.
/// </summary>
Lighter,
/// <summary>
/// A darker color.
/// </summary>
Darker,
}
+32
View File
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
namespace MiraAPI.Colors;
/// <summary>
/// Used to register and track custom colors.
/// </summary>
public static class PaletteManager
{
/// <summary>
/// Gets all registered custom colors.
/// </summary>
public static CustomColor[] RegisteredColors => [.. CustomColors];
internal static readonly List<CustomColor> CustomColors = [];
internal static void RegisterAllColors()
{
var colors = CustomColors.Select(x => x.MainColor).ToArray();
var shadowColors = CustomColors.Select(x => x.ShadowColor).ToArray();
var stringNames = CustomColors.Select(x => x.Name).ToArray();
Palette.PlayerColors = Palette.PlayerColors.ToArray().AddRangeToArray(colors);
Palette.ShadowColors = Palette.ShadowColors.ToArray().AddRangeToArray(shadowColors);
Palette.ColorNames = Palette.ColorNames.ToArray().AddRangeToArray(stringNames);
Palette.TextColors = Palette.TextColors.ToArray().AddRangeToArray(colors);
Palette.TextOutlineColors = Palette.TextOutlineColors.ToArray().AddRangeToArray(shadowColors);
}
}
@@ -0,0 +1,9 @@
using System;
namespace MiraAPI.Colors;
/// <summary>
/// Used to mark a class for custom colors registration.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class RegisterCustomColorsAttribute : Attribute;
@@ -0,0 +1,44 @@
using MiraAPI.Hud;
namespace MiraAPI.Events.Mira;
/// <summary>
/// Invoked when a Mira Button click is cancelled. Do not use for vanilla buttons.
/// </summary>
/// <typeparam name="T">The Mira Button type.</typeparam>
public sealed class MiraButtonCancelledEvent<T> : MiraEvent where T : CustomActionButton
{
/// <summary>
/// Gets Mira Button whose click was cancelled.
/// </summary>
public T Button { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MiraButtonCancelledEvent{T}"/> class.
/// </summary>
/// <param name="button">The Mira Button whose click was cancelled.</param>
public MiraButtonCancelledEvent(T button)
{
Button = button;
}
}
/// <summary>
/// Invoked when a Mira Button click is cancelled. Do not use for vanilla buttons.
/// </summary>
public sealed class MiraButtonCancelledEvent : MiraEvent
{
/// <summary>
/// Gets Mira Button whose click was cancelled.
/// </summary>
public CustomActionButton Button { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MiraButtonCancelledEvent"/> class.
/// </summary>
/// <param name="button">The Mira Button whose click was cancelled.</param>
public MiraButtonCancelledEvent(CustomActionButton button)
{
Button = button;
}
}
@@ -0,0 +1,51 @@
using MiraAPI.Hud;
namespace MiraAPI.Events.Mira;
/// <summary>
/// Button click event for Mira Buttons only. Do not use for vanilla buttons.
/// </summary>
/// <typeparam name="T">The Mira Button type.</typeparam>
public sealed class MiraButtonClickEvent<T> : MiraCancelableEvent where T : CustomActionButton
{
/// <summary>
/// Gets Mira Button that was clicked.
/// </summary>
public T Button { get; }
/// <summary>
/// Gets the generic click event that is invoked before this button-specific event.
/// </summary>
public MiraButtonClickEvent GenericClickEvent { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MiraButtonClickEvent{T}"/> class.
/// </summary>
/// <param name="button">The Mira Button that was clicked.</param>
/// <param name="genericClickEvent">The generic click event invoked before button-specific events.</param>
public MiraButtonClickEvent(T button, MiraButtonClickEvent genericClickEvent)
{
GenericClickEvent = genericClickEvent;
Button = button;
}
}
/// <summary>
/// Button click event for Mira Buttons only. Do not use for vanilla buttons.
/// </summary>
public sealed class MiraButtonClickEvent : MiraCancelableEvent
{
/// <summary>
/// Gets Mira Button that was clicked.
/// </summary>
public CustomActionButton Button { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MiraButtonClickEvent"/> class.
/// </summary>
/// <param name="button">The Mira Button that was clicked.</param>
public MiraButtonClickEvent(CustomActionButton button)
{
Button = button;
}
}
+28
View File
@@ -0,0 +1,28 @@
namespace MiraAPI.Events;
/// <summary>
/// Abstract class for Mira Events that can be cancelled.
/// </summary>
public abstract class MiraCancelableEvent : MiraEvent
{
/// <summary>
/// Gets a value indicating whether the event is cancelled.
/// </summary>
public bool IsCancelled { get; private set; }
/// <summary>
/// Cancels the event.
/// </summary>
public void Cancel()
{
IsCancelled = true;
}
/// <summary>
/// Uncancels the event.
/// </summary>
public void UnCancel()
{
IsCancelled = false;
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace MiraAPI.Events;
/// <summary>
/// Abstract class for Mira Events.
/// </summary>
public abstract class MiraEvent;
+22
View File
@@ -0,0 +1,22 @@
using System;
namespace MiraAPI.Events;
/// <summary>
/// Event handle to use when unregistering an event.
/// </summary>
public class MiraEventHandle
{
/// <summary>
/// Gets the type of event.
/// </summary>
public Type EventType { get; }
internal MiraEventWrapper EventWrapper { get; }
internal MiraEventHandle(Type type, MiraEventWrapper eventWrapper)
{
EventType = type;
EventWrapper = eventWrapper;
}
}
+152
View File
@@ -0,0 +1,152 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Reactor.Utilities;
namespace MiraAPI.Events;
/// <summary>
/// Mira Event manager.
/// </summary>
public static class MiraEventManager
{
private static readonly Dictionary<Type, List<MiraEventWrapper>> EventWrappers = [];
/// <summary>
/// Invoke an event.
/// </summary>
/// <param name="eventInstance">The event instance.</param>
/// <typeparam name="T">Type of Event.</typeparam>
/// <returns>If there was an event handler invoked for this event, return true. Otherwise, return false.</returns>
public static bool InvokeEvent<T>(T eventInstance) where T : MiraEvent
{
EventWrappers.TryGetValue(typeof(T), out var handlers);
if (handlers == null || handlers.Count == 0)
{
return false;
}
foreach (var handler in handlers)
{
try
{
((Action<T>)handler.EventHandler).Invoke(eventInstance);
}
catch (Exception ex)
{
Logger<MiraApiPlugin>.Error($"Error invoking event handler for {typeof(T).Name}: {ex.ToString()}");
}
}
return true;
}
/// <summary>
/// Invoke an event and use a specific type to find the handlers.
/// </summary>
/// <param name="eventInstance">The event instance.</param>
/// <param name="type">The type to use for handler lookup.</param>
/// <returns>If there was an event handler invoked for this event, return true. Otherwise, return false.</returns>
public static bool InvokeEvent(MiraEvent eventInstance, Type type)
{
EventWrappers.TryGetValue(type, out var handlers);
if (handlers == null || handlers.Count == 0)
{
return false;
}
foreach (var handler in handlers)
{
try
{
handler.EventHandler.DynamicInvoke(eventInstance);
}
catch (Exception ex)
{
Logger<MiraApiPlugin>.Error($"Error invoking event handler for {type.Name}: {ex.ToString()}");
}
}
return true;
}
/// <summary>
/// Register an event.
/// </summary>
/// <param name="type">The type of event.</param>
/// <param name="methodInfo">The MethodInfo of the event handler.</param>
/// <param name="priority">The priority of the event handler. Lower values are called first.</param>
/// <returns>An event handle to use when unregistering the event.</returns>
public static MiraEventHandle RegisterEventHandler(Type type, MethodInfo methodInfo, int priority = 0)
{
if (!type.IsSubclassOf(typeof(MiraEvent)))
{
throw new InvalidOperationException($"Type must be a subclass of MiraEvent: {type.FullName}");
}
EventWrappers.TryAdd(type, []);
var handlers = EventWrappers[type];
var @delegate = Delegate.CreateDelegate(typeof(Action<>).MakeGenericType(type), methodInfo);
var eventWrapper = new MiraEventWrapper(@delegate, priority);
var index = handlers.BinarySearch(eventWrapper, Comparer<MiraEventWrapper>.Create((a, b) => a.Priority.CompareTo(b.Priority)));
if (index < 0)
{
index = ~index;
}
handlers.Insert(index, eventWrapper);
return new MiraEventHandle(type, eventWrapper);
}
/// <summary>
/// Register an event.
/// </summary>
/// <param name="handler">The callback method/handler for the event.</param>
/// <param name="priority">The priority of the event handler. Lower values are called first.</param>
/// <typeparam name="T">Type of event.</typeparam>
/// <returns>An event handle to use when unregistering the event.</returns>
public static MiraEventHandle RegisterEventHandler<T>(Action<T> handler, int priority = 0) where T : MiraEvent
{
EventWrappers.TryAdd(typeof(T), []);
var handlers = EventWrappers[typeof(T)];
var eventWrapper = new MiraEventWrapper(handler, priority);
var index = handlers.BinarySearch(eventWrapper, Comparer<MiraEventWrapper>.Create((a, b) => a.Priority.CompareTo(b.Priority)));
if (index < 0)
{
index = ~index;
}
handlers.Insert(index, eventWrapper);
return new MiraEventHandle(typeof(T), eventWrapper);
}
/// <summary>
/// Unregister an event using the event handle.
/// </summary>
/// <param name="eventHandle">A handle to the event.</param>
/// <returns>True if the event was unregistered successfully, false otherwise.</returns>
public static bool UnregisterEventHandler(MiraEventHandle eventHandle)
{
if (!EventWrappers.TryGetValue(eventHandle.EventType, out var handlers))
{
return false;
}
if (!handlers.Remove(eventHandle.EventWrapper))
{
return false;
}
if (handlers.Count == 0)
{
EventWrappers.Remove(eventHandle.EventType);
}
return true;
}
}
+30
View File
@@ -0,0 +1,30 @@
using System;
namespace MiraAPI.Events;
/// <summary>
/// Wrapper for event handlers.
/// </summary>
public class MiraEventWrapper
{
/// <summary>
/// Gets the event handler delegate.
/// </summary>
public Delegate EventHandler { get; }
/// <summary>
/// Gets the priority of the handler. Lower values are called first.
/// </summary>
public int Priority { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MiraEventWrapper"/> class.
/// </summary>
/// <param name="eventHandler">The action for the event handler.</param>
/// <param name="priority">The priority of the handler.</param>
public MiraEventWrapper(Delegate eventHandler, int priority)
{
EventHandler = eventHandler;
Priority = priority;
}
}
+24
View File
@@ -0,0 +1,24 @@
using System;
namespace MiraAPI.Events;
/// <summary>
/// Register an event.
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class RegisterEventAttribute : Attribute
{
/// <summary>
/// Gets the priority of the event. Lower values are called first.
/// </summary>
public int Priority { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RegisterEventAttribute"/> class.
/// </summary>
/// <param name="priority">The priority of the event. Lower values are called first.</param>
public RegisterEventAttribute(int priority = 0)
{
Priority = priority;
}
}
@@ -0,0 +1,35 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// Event that is invoked after a player is murdered. Only called after a successful murder. This event is not cancelable.
/// </summary>
public class AfterMurderEvent : MiraEvent
{
/// <summary>
/// Gets the player that killed the target.
/// </summary>
public PlayerControl Source { get; }
/// <summary>
/// Gets the player that was killed.
/// </summary>
public PlayerControl Target { get; }
/// <summary>
/// Gets the player's body, if it exists.
/// </summary>
public DeadBody? DeadBody { get; }
/// <summary>
/// Initializes a new instance of the <see cref="AfterMurderEvent"/> class.
/// </summary>
/// <param name="source">The killer.</param>
/// <param name="target">The killed player.</param>
/// <param name="deadBody">The player's vody, if it exists.</param>
public AfterMurderEvent(PlayerControl source, PlayerControl target, DeadBody? deadBody)
{
Source = source;
Target = target;
DeadBody = deadBody;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// Invoked before RpcEndGame is called, allowing cancellation of the game end entirely.
/// </summary>
public class BeforeGameEndEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the reason for the game end.
/// </summary>
public GameOverReason Reason { get; }
/// <summary>
/// Initializes a new instance of the <see cref="BeforeGameEndEvent"/> class.
/// </summary>
/// <param name="reason">The reason for the game end.</param>
public BeforeGameEndEvent(GameOverReason reason)
{
Reason = reason;
}
}
@@ -0,0 +1,28 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// Event that is invoked before a player is murdered. This event is cancelable.
/// </summary>
public sealed class BeforeMurderEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the player that is killing the target.
/// </summary>
public PlayerControl Source { get; }
/// <summary>
/// Gets the player that is being killed.
/// </summary>
public PlayerControl Target { get; }
/// <summary>
/// Initializes a new instance of the <see cref="BeforeMurderEvent"/> class.
/// </summary>
/// <param name="source">The player that is killing the target.</param>
/// <param name="target">The player that is being killed.</param>
public BeforeMurderEvent(PlayerControl source, PlayerControl target)
{
Source = source;
Target = target;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// Event invoked on IntroCutscene.OnDestroy and ExileController.WrapUp to determine if it should run the round event or not.
/// </summary>
public class BeforeRoundStartEvent : MiraCancelableEvent
{
/// <summary>
/// Gets a value indicating whether the event was triggered by the IntroCutscene or ExileController.
/// </summary>
public bool TriggeredByIntro { get; }
/// <summary>
/// Initializes a new instance of the <see cref="BeforeRoundStartEvent"/> class.
/// </summary>
/// <param name="triggeredByIntro">Whether the event was triggered by the intro or not.</param>
public BeforeRoundStartEvent(bool triggeredByIntro)
{
TriggeredByIntro = triggeredByIntro;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// The event that is invoked when the end game screen is shown. Non cancelable.
/// </summary>
public class GameEndEvent : MiraEvent
{
/// <summary>
/// Gets the instance of the EndGameManager.
/// </summary>
public EndGameManager EndGameManager { get; }
/// <summary>
/// Initializes a new instance of the <see cref="GameEndEvent"/> class.
/// </summary>
/// <param name="manager">The instance of the EndGameManager.</param>
public GameEndEvent(EndGameManager manager)
{
EndGameManager = manager;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// The event that is invoked when the intro cutscene is shown. Non cancelable.
/// </summary>
public class IntroBeginEvent : MiraEvent
{
/// <summary>
/// Gets the instance of the IntroCutscene.
/// </summary>
public IntroCutscene IntroCutscene { get; }
/// <summary>
/// Initializes a new instance of the <see cref="IntroBeginEvent"/> class.
/// </summary>
/// <param name="introCutscene">The intro cutscene.</param>
public IntroBeginEvent(IntroCutscene introCutscene)
{
IntroCutscene = introCutscene;
}
}
@@ -0,0 +1,12 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// The event that is invoked when the intro cutscene has finished playing.
/// </summary>
public class IntroEndEvent(IntroCutscene introCutscene) : MiraEvent
{
/// <summary>
/// Gets the instance of the IntroCutscene.
/// </summary>
public IntroCutscene IntroCutscene { get; } = introCutscene;
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// The event that is invoked when the player's role is shown on the intro cutscene. Non cancelable.
/// </summary>
public class IntroRoleRevealEvent : MiraEvent
{
/// <summary>
/// Gets the instance of the IntroCutscene.
/// </summary>
public IntroCutscene IntroCutscene { get; }
/// <summary>
/// Initializes a new instance of the <see cref="IntroRoleRevealEvent"/> class.
/// </summary>
/// <param name="introCutscene">The intro cutscene.</param>
public IntroRoleRevealEvent(IntroCutscene introCutscene)
{
IntroCutscene = introCutscene;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// Start Round event, invoked on IntroCutscene.OnDestroy and ExileController.WrapUp if the event isn't cancelled.
/// </summary>
public class RoundStartEvent : MiraEvent
{
/// <summary>
/// Gets a value indicating whether the event was triggered by the IntroCutscene or ExileController.
/// </summary>
public bool TriggeredByIntro { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RoundStartEvent"/> class.
/// </summary>
/// <param name="triggeredByIntro">Whether the event was triggered by the intro or not.</param>
public RoundStartEvent(bool triggeredByIntro)
{
TriggeredByIntro = triggeredByIntro;
}
}
@@ -0,0 +1,30 @@
using AmongUs.GameOptions;
namespace MiraAPI.Events.Vanilla.Gameplay;
/// <summary>
/// Event that is invoked after a player's role is set. This event is not cancelable.
/// </summary>
public class SetRoleEvent : MiraEvent
{
/// <summary>
/// Gets the player whos role was changed.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Gets the role that the player was set to.
/// </summary>
public RoleTypes Role { get; }
/// <summary>
/// Initializes a new instance of the <see cref="SetRoleEvent"/> class.
/// </summary>
/// <param name="player">The player.</param>
/// <param name="role">The new role.</param>
public SetRoleEvent(PlayerControl player, RoleTypes role)
{
Player = player;
Role = role;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Map;
/// <summary>
/// Event fired when a player closes the doors in a room.
/// </summary>
public class CloseDoorsEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the room that the doors were closed in.
/// </summary>
public SystemTypes Room { get; }
/// <summary>
/// Initializes a new instance of the <see cref="CloseDoorsEvent"/> class.
/// </summary>
/// <param name="room">The room that was closed.</param>
public CloseDoorsEvent(SystemTypes room)
{
Room = room;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Map;
/// <summary>
/// Sabotage from Vanilla Among Us.
/// </summary>
public class PlayerOpenSabotageEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the MapBehaviour.
/// </summary>
public MapBehaviour MapBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="PlayerOpenSabotageEvent"/> class.
/// </summary>
/// <param name="mapBehaviour">The MapBehaviour.</param>
public PlayerOpenSabotageEvent(MapBehaviour mapBehaviour)
{
MapBehaviour = mapBehaviour;
}
}
@@ -0,0 +1,35 @@
namespace MiraAPI.Events.Vanilla.Map;
/// <summary>
/// Cancelable event that is invoked before a system is updated. Usually used for sabotage events.
/// </summary>
public class UpdateSystemEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the type of system that will be updated.
/// </summary>
public SystemTypes SystemType { get; }
/// <summary>
/// Gets the player that is updating the system.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Gets the byte amount the system is being updated by.
/// </summary>
public byte Amount { get; }
/// <summary>
/// Initializes a new instance of the <see cref="UpdateSystemEvent"/> class.
/// </summary>
/// <param name="systemType">The SystemType being updated.</param>
/// <param name="player">The player that is updating the system.</param>
/// <param name="amount">Amount to update System to.</param>
public UpdateSystemEvent(SystemTypes systemType, PlayerControl player, byte amount)
{
SystemType = systemType;
Player = player;
Amount = amount;
}
}
@@ -0,0 +1,21 @@
namespace MiraAPI.Events.Vanilla.Meeting;
/// <summary>
/// The event that is invoked when a player is ejected. Non-cancelable.
/// </summary>
public class EjectionEvent : MiraEvent
{
/// <summary>
/// Gets the instance of the ExileController.
/// </summary>
public ExileController ExileController { get; }
/// <summary>
/// Initializes a new instance of the <see cref="EjectionEvent"/> class.
/// </summary>
/// <param name="controller">The exile controller.</param>
public EjectionEvent(ExileController controller)
{
ExileController = controller;
}
}
@@ -0,0 +1,12 @@
namespace MiraAPI.Events.Vanilla.Meeting;
/// <summary>
/// The event that is invoked when the meeting has ended.
/// </summary>
public class EndMeetingEvent(MeetingHud meetingHud) : MiraEvent
{
/// <summary>
/// Gets the MeetingHud instance.
/// </summary>
public MeetingHud MeetingHud { get; } = meetingHud;
}
@@ -0,0 +1,36 @@
namespace MiraAPI.Events.Vanilla.Meeting;
/// <summary>
/// The event that is invoked when a body is reported.
/// This is invoked in CmdReportBody.
/// </summary>
public class ReportBodyEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the player that is reporting the body.
/// </summary>
public PlayerControl Reporter { get; }
/// <summary>
/// Gets the player that is being reported. Will be null for emergency meeting.
/// </summary>
public NetworkedPlayerInfo? Target { get; }
/// <summary>
/// Gets the body that is being reported. Will be null for emergency meeting.
/// </summary>
public DeadBody? Body { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ReportBodyEvent"/> class.
/// </summary>
/// <param name="reporter">The player who reported the body.</param>
/// <param name="target">The player being reported.</param>
/// <param name="body">The body being reported.</param>
public ReportBodyEvent(PlayerControl reporter, NetworkedPlayerInfo? target, DeadBody? body)
{
Reporter = reporter;
Target = target;
Body = body;
}
}
@@ -0,0 +1,22 @@
namespace MiraAPI.Events.Vanilla.Meeting;
/// <summary>
/// The event that is invoked when a meeting is called. This event is not cancelable.
/// This event is called after Mira resets votes, so if you plan on adding votes to a specific player, do it with this event.
/// </summary>
public class StartMeetingEvent : MiraEvent
{
/// <summary>
/// Gets the MeetingHud instance.
/// </summary>
public MeetingHud MeetingHud { get; }
/// <summary>
/// Initializes a new instance of the <see cref="StartMeetingEvent"/> class.
/// </summary>
/// <param name="meetingHud">The MeetingHud instance.</param>
public StartMeetingEvent(MeetingHud meetingHud)
{
MeetingHud = meetingHud;
}
}
@@ -0,0 +1,30 @@
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// Event that is invoked after the local player successfully votes a player or skips. This event is not cancelable.
/// </summary>
public class AfterVoteEvent : MiraEvent
{
/// <summary>
/// Gets the instance of the voter's vote data.
/// </summary>
public PlayerVoteArea VoteArea { get; }
/// <summary>
/// Gets the player who voted.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Initializes a new instance of the <see cref="AfterVoteEvent"/> class.
/// </summary>
/// <param name="playerVoteArea">The player vote area that was voted on.</param>
/// <param name="voter">The player who voted.</param>
public AfterVoteEvent(PlayerVoteArea playerVoteArea, PlayerControl voter)
{
VoteArea = playerVoteArea;
Player = voter;
}
}
@@ -0,0 +1,30 @@
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// Event that is invoked before the local player confirms a vote on a player or when skipping. This event is cancelable.
/// </summary>
public class BeforeVoteEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the instance of the voter's vote data.
/// </summary>
public PlayerVoteArea VoteArea { get; }
/// <summary>
/// Gets the player who voted.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Initializes a new instance of the <see cref="BeforeVoteEvent"/> class.
/// </summary>
/// <param name="playerVoteArea">The player vote area that was voted on.</param>
/// <param name="voter">The player who voted.</param>
public BeforeVoteEvent(PlayerVoteArea playerVoteArea, PlayerControl voter)
{
VoteArea = playerVoteArea;
Player = voter;
}
}
@@ -0,0 +1,26 @@
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// Checks if voting is complete. If canceled, the default end voting logic will be skipped.
/// </summary>
public class CheckForEndVotingEvent : MiraCancelableEvent
{
/// <summary>
/// Gets a value indicating whether default voting logic determines that voting is complete.
/// </summary>
public bool IsVotingComplete { get; }
/// <summary>
/// Gets or sets a value indicating whether the voting should be forced to end, regardless of the default logic.
/// </summary>
public bool ForceEndVoting { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="CheckForEndVotingEvent"/> class.
/// </summary>
/// <param name="isVotingComplete">>True if voting is complete, false otherwise.</param>
public CheckForEndVotingEvent(bool isVotingComplete)
{
IsVotingComplete = isVotingComplete;
}
}
@@ -0,0 +1,44 @@
using System;
using MiraAPI.Utilities;
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// Invoked before the dummy selects their vote. If canceled, the dummy won't vote.
/// </summary>
public class DummyVoteEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the dummy that needs to vote.
/// </summary>
public DummyBehaviour Dummy { get; }
/// <summary>
/// Gets the instance of the dummy's vote data.
/// </summary>
public PlayerVoteData VoteData { get; }
/// <summary>
/// Gets or sets a value indicating whether the dummy can vote to skip the meeting.
/// </summary>
public bool CanSkip { get; set; }
/// <summary>
/// Gets or sets a predicate for validating whether the dummy can vote on a player.
/// By default, excludes dead and disconnected players.
/// </summary>
public Predicate<PlayerControl> PlayerIsValid { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="DummyVoteEvent"/> class.
/// </summary>
/// <param name="dummy">The voting dummy.</param>
public DummyVoteEvent(DummyBehaviour dummy)
{
Dummy = dummy;
VoteData = dummy.myPlayer.GetVoteData();
CanSkip = true;
PlayerIsValid = x => !x.Data.IsDead && !x.Data.Disconnected;
}
}
@@ -0,0 +1,50 @@
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// The event that is invoked when Mira handles a vote. This is invoked before Mira's behaviour, so be cautious.
/// If you intend on adding custom vote behaviour, cancel the event and do so.
/// If you are NOT canceling the event, keep in mind that Mira automatically removes a vote and adds the suspect to the VotedPlayers list after this event is invoked.
/// </summary>
public class HandleVoteEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the instance of the voter's vote data.
/// </summary>
public PlayerVoteData VoteData { get; }
/// <summary>
/// Gets the player who voted.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Gets the player id of the target.
/// </summary>
public byte TargetId { get; }
/// <summary>
/// Gets a value indicating whether to prevent the vote from commencing.
/// </summary>
public bool PreventVote { get; }
/// <summary>
/// Gets the player info of the target.
/// </summary>
public NetworkedPlayerInfo TargetPlayerInfo { get; }
/// <summary>
/// Initializes a new instance of the <see cref="HandleVoteEvent"/> class.
/// </summary>
/// <param name="playerVoteData">The voter's data.</param>
/// <param name="targetId">The target's playerId.</param>
public HandleVoteEvent(PlayerVoteData playerVoteData, byte targetId)
{
VoteData = playerVoteData;
Player = playerVoteData.Owner;
TargetId = targetId;
PreventVote = false;
TargetPlayerInfo = GameData.Instance.GetPlayerById(targetId);
}
}
@@ -0,0 +1,43 @@
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// The event that is invoked when the player tries to select another player to vote.
/// </summary>
public class MeetingSelectEvent : MiraEvent
{
/// <summary>
/// Gets the instance of the voter's vote data.
/// </summary>
public PlayerVoteData VoteData { get; }
/// <summary>
/// Gets the player id of the target.
/// </summary>
public int TargetId { get; }
/// <summary>
/// Gets the player info of the target.
/// </summary>
public NetworkedPlayerInfo TargetPlayerInfo { get; }
/// <summary>
/// Gets or sets a value indicating whether the player is allowed to select the target.
/// </summary>
public bool AllowSelect { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MeetingSelectEvent"/> class.
/// </summary>
/// <param name="playerVoteData">The voter's data.</param>
/// <param name="targetId">The target's playerId.</param>
/// <param name="allowSelect">>Whether the player is allowed to select the target.</param>
public MeetingSelectEvent(PlayerVoteData playerVoteData, int targetId, bool allowSelect)
{
VoteData = playerVoteData;
TargetId = targetId;
TargetPlayerInfo = GameData.Instance.GetPlayerById((byte)targetId);
AllowSelect = allowSelect;
}
}
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// Called in VotingUtils.HandlePopulateResults.
/// Cancelling is NOT advised but if you do plan on cancelling, please ensure you account for displaying ALL player's votes.
/// </summary>
public class PopulateResultsEvent : MiraCancelableEvent
{
/// <summary>
/// Gets a list of networked votes.
/// </summary>
public List<CustomVote> Votes { get; }
/// <summary>
/// Initializes a new instance of the <see cref="PopulateResultsEvent"/> class.
/// </summary>
/// <param name="votes">The list of votes.</param>
public PopulateResultsEvent(List<CustomVote> votes)
{
Votes = votes;
}
}
@@ -0,0 +1,48 @@
using System.Collections.Generic;
using System.Linq;
using MiraAPI.Voting;
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// Ran after calculating votes and before displaying the results. Only ran on the host.
/// </summary>
/// <remarks>
/// Initializes a new instance of the <see cref="ProcessVotesEvent"/> class.
/// </remarks>
/// <param name="votes">>The list of votes that are being processed.</param>
/// <param name="exiledPlayer">The player to be exiled. Will be null if no player is to be exiled.</param>
public class ProcessVotesEvent(List<CustomVote> votes, NetworkedPlayerInfo? exiledPlayer = null) : MiraEvent
{
private readonly List<CustomVote> _originalVotes = [.. votes];
private NetworkedPlayerInfo? _exiledPlayer = exiledPlayer;
/// <summary>
/// Gets a value indicating whether the exiled player has been modified by the event.
/// </summary>
public bool ExiledPlayerModified { get; private set; }
/// <summary>
/// Gets a value indicating whether the votes have been modified by the event.
/// </summary>
public bool VotesModified => !Votes.SequenceEqual(_originalVotes);
/// <summary>
/// Gets the list of votes that are being processed.
/// </summary>
public List<CustomVote> Votes { get; } = votes;
/// <summary>
/// Gets or sets the player to be exiled. Will be null if no player is to be exiled.
/// </summary>
public NetworkedPlayerInfo? ExiledPlayer
{
get => _exiledPlayer;
set
{
_exiledPlayer = value;
ExiledPlayerModified = true;
}
}
}
@@ -0,0 +1,13 @@
namespace MiraAPI.Events.Vanilla.Meeting.Voting;
/// <summary>
/// The event that is invoked when the voting phase of a meeting is complete.
/// </summary>
/// <param name="meetingHud">The MeetingHud instance.</param>
public class VotingCompleteEvent(MeetingHud meetingHud) : MiraEvent
{
/// <summary>
/// Gets the MeetingHud instance.
/// </summary>
public MeetingHud MeetingHud { get; } = meetingHud;
}
@@ -0,0 +1,28 @@
namespace MiraAPI.Events.Vanilla.Player;
/// <summary>
/// The event that is invoked when a player completes a task. Non cancelable.
/// </summary>
public class CompleteTaskEvent : MiraEvent
{
/// <summary>
/// Gets the instance of the <see cref="PlayerControl"/>.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Gets the instance of the <see cref="PlayerTask"/> that the player completed.
/// </summary>
public PlayerTask Task { get; }
/// <summary>
/// Initializes a new instance of the <see cref="CompleteTaskEvent"/> class.
/// </summary>
/// <param name="player">The player who completed the task.</param>
/// <param name="task">The task that the player completed.</param>
public CompleteTaskEvent(PlayerControl player, PlayerTask task)
{
Player = player;
Task = task;
}
}
@@ -0,0 +1,35 @@
namespace MiraAPI.Events.Vanilla.Player;
/// <summary>
/// Event that is invoked when a player dies. Non cancelable.
/// </summary>
public class PlayerDeathEvent : MiraEvent
{
/// <summary>
/// Gets the player who died.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Gets the reason the player died.
/// </summary>
public DeathReason DeathReason { get; }
/// <summary>
/// Gets the dead body associated with the player, if any.
/// </summary>
public DeadBody? DeadBody { get; }
/// <summary>
/// Initializes a new instance of the <see cref="PlayerDeathEvent"/> class.
/// </summary>
/// <param name="player">The player who died.</param>
/// <param name="reason">The reason the player died.</param>
/// <param name="deadBody">The player's body, if it exists.</param>
public PlayerDeathEvent(PlayerControl player, DeathReason reason, DeadBody? deadBody)
{
Player = player;
DeathReason = reason;
DeadBody = deadBody;
}
}
@@ -0,0 +1,23 @@
using InnerNet;
namespace MiraAPI.Events.Vanilla.Player;
/// <summary>
/// Event that is invoked when a player joins the lobby. Non cancelable.
/// </summary>
public class PlayerJoinEvent : MiraEvent
{
/// <summary>
/// Gets the player who joined.
/// </summary>
public ClientData ClientData { get; }
/// <summary>
/// Initializes a new instance of the <see cref="PlayerJoinEvent"/> class.
/// </summary>
/// <param name="data">The data of the player who joined.</param>
public PlayerJoinEvent(ClientData data)
{
ClientData = data;
}
}
@@ -0,0 +1,30 @@
using InnerNet;
namespace MiraAPI.Events.Vanilla.Player;
/// <summary>
/// Event that is invoked when a player leaves the game. Non cancelable.
/// </summary>
public class PlayerLeaveEvent : MiraEvent
{
/// <summary>
/// Gets the player who left.
/// </summary>
public ClientData ClientData { get; }
/// <summary>
/// Gets the reason why the player left.
/// </summary>
public DisconnectReasons Reason { get; }
/// <summary>
/// Initializes a new instance of the <see cref="PlayerLeaveEvent"/> class.
/// </summary>
/// <param name="data">The data of the player who left.</param>
/// <param name="reason">The reason why the player left.</param>
public PlayerLeaveEvent(ClientData data, DisconnectReasons reason)
{
ClientData = data;
Reason = reason;
}
}
@@ -0,0 +1,28 @@
namespace MiraAPI.Events.Vanilla.Usables;
/// <summary>
/// Event that is invoked when a player enters a vent. This event is cancelable.
/// </summary>
public class EnterVentEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the player that is entering the vent.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Gets the vent that the player is entering.
/// </summary>
public Vent? Vent { get; }
/// <summary>
/// Initializes a new instance of the <see cref="EnterVentEvent"/> class.
/// </summary>
/// <param name="player">The player that is entering the vent.</param>
/// <param name="vent">The vent being entered.</param>
public EnterVentEvent(PlayerControl player, Vent? vent)
{
Player = player;
Vent = vent;
}
}
@@ -0,0 +1,28 @@
namespace MiraAPI.Events.Vanilla.Usables;
/// <summary>
/// Event that is invoked when a player exits a vent. This event is cancelable.
/// </summary>
public class ExitVentEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the player that is exiting the vent.
/// </summary>
public PlayerControl Player { get; }
/// <summary>
/// Gets the vent that the player is exiting.
/// </summary>
public Vent? Vent { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ExitVentEvent"/> class.
/// </summary>
/// <param name="player">The player who is exiting the vent.</param>
/// <param name="vent">The vent being exited from.</param>
public ExitVentEvent(PlayerControl player, Vent? vent)
{
Player = player;
Vent = vent;
}
}
@@ -0,0 +1,15 @@
namespace MiraAPI.Events.Vanilla.Usables;
/// <summary>
/// Event for if a <see cref="PlayerControl"/> can use an <see cref="IUsable"/> from Vanilla Among Us. Will always be ran locally.
/// </summary>
public class PlayerCanUseEvent : PlayerUseEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="PlayerCanUseEvent"/> class.
/// </summary>
/// <param name="usable">The IUsable.</param>
public PlayerCanUseEvent(IUsable usable) : base(usable)
{
}
}
@@ -0,0 +1,34 @@
namespace MiraAPI.Events.Vanilla.Usables;
/// <summary>
/// Event for <see cref="PlayerControl"/> using a <see cref="IUsable"/> from Vanilla Among Us. Will always be ran locally.
/// </summary>
public class PlayerUseEvent : MiraCancelableEvent
{
/// <summary>
/// Gets the instance of <see cref="IUsable"/> that was used.
/// </summary>
public IUsable Usable { get; }
/// <summary>
/// Gets a value indicating whether the IUsable is a <see cref="Console"/>, <see cref="MapConsole"/>, or <see cref="SystemConsole"/>.
/// </summary>
public bool IsPrimaryConsole { get; }
/// <summary>
/// Gets a value indicating whether the IUsable is a <see cref="Vent"/>.
/// </summary>
public bool IsVent { get; }
/// <summary>
/// Initializes a new instance of the <see cref="PlayerUseEvent"/> class.
/// </summary>
/// <param name="usable">The IUsable.</param>
public PlayerUseEvent(IUsable usable)
{
Usable = usable;
IsPrimaryConsole = usable.TryCast<Console>() || usable.TryCast<SystemConsole>() || usable.TryCast<MapConsole>();
IsVent = usable.TryCast<Vent>();
}
}
+78
View File
@@ -0,0 +1,78 @@
using System.Collections.Generic;
using MiraAPI.Networking;
using Reactor.Networking.Rpc;
namespace MiraAPI.GameEnd;
/// <summary>
/// Custom Game Over.
/// </summary>
public abstract class CustomGameOver
{
/// <summary>
/// Gets the current CustomGameOver.
/// </summary>
public static CustomGameOver? Instance { get; internal set; }
/// <summary>
/// Verifies if the condition for this CustomGameOver is met.
/// </summary>
/// <param name="playerControl">The PlayerControl that requested the Game Over.</param>
/// <param name="winners">The collection of winners.</param>
/// <returns>True if the condition is met, otherwise false.</returns>
public virtual bool VerifyCondition(PlayerControl playerControl, NetworkedPlayerInfo[] winners)
{
return true;
}
/// <summary>
/// Runs before the base game calls EndGameManager.SetEverythingUp.
/// </summary>
/// <param name="endGameManager">The EndGameManager instance.</param>
/// <returns>Return True to use the run the original method, return False to skip it.</returns>
public virtual bool BeforeEndGameSetup(EndGameManager endGameManager)
{
return true;
}
/// <summary>
/// Runs after the base game calls EndGameManager.SetEverythingUp.
/// </summary>
/// <param name="endGameManager">The EndGameManager instance.</param>
public virtual void AfterEndGameSetup(EndGameManager endGameManager)
{
}
/// <summary>
/// Get the GameOverReason associated with this CustomGameOver.
/// </summary>
/// <typeparam name="T">Type of the custom game over.</typeparam>
/// <returns>The GameOverReason associated with the custom game over.</returns>
public static GameOverReason GameOverReason<T>() where T : CustomGameOver
{
return (GameOverReason)GameOverManager.GetGameOverId<T>();
}
/// <summary>
/// Send a custom game over.
/// </summary>
/// <param name="winners">A collection of winners.</param>
/// <typeparam name="T">Type of the custom game over.</typeparam>
public static void Trigger<T>(IEnumerable<NetworkedPlayerInfo> winners) where T : CustomGameOver
{
var reason = GameOverManager.GetGameOverId<T>();
var data = new GameOverData(reason, [.. winners]);
Rpc<CustomGameOverRpc>.Instance.Send(PlayerControl.LocalPlayer, data, true);
}
/// <summary>
/// Implicitly convert a CustomGameOver to a GameOverReason.
/// </summary>
/// <param name="gameOver">The CustomGameOver instance.</param>
/// <returns>The GameOverReason associated with the CustomGameOver.</returns>
public static implicit operator GameOverReason(CustomGameOver gameOver)
{
return (GameOverReason)GameOverManager.GetGameOverId(gameOver.GetType());
}
}
+10
View File
@@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace MiraAPI.GameEnd;
/// <summary>
/// Data for a game over.
/// </summary>
/// <param name="Reason">Reason for the game over.</param>
/// <param name="Winners">A collection of winners.</param>
public record struct GameOverData(int Reason, List<NetworkedPlayerInfo> Winners);
+90
View File
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Reactor.Utilities;
namespace MiraAPI.GameEnd;
/// <summary>
/// Manage custom game overs.
/// </summary>
public static class GameOverManager
{
private static readonly Dictionary<Type, int> GameOverIds = [];
private static readonly Dictionary<int, Type> GameOverTypes = [];
private static int _nextId = Enum.GetNames<GameOverReason>().Length;
/// <summary>
/// Register a custom game over.
/// </summary>
/// <param name="gameOverType">Type of the custom game over.</param>
/// <exception cref="ArgumentException">Thrown when the type is not a subclass of CustomGameOver, is abstract, or does not have a parameterless constructor.</exception>
/// <returns>>True if the game over was registered successfully, false otherwise.</returns>
public static bool RegisterGameOver(Type gameOverType)
{
if (!typeof(CustomGameOver).IsAssignableFrom(gameOverType))
{
return false;
}
if (gameOverType.IsAbstract)
{
Logger<MiraApiPlugin>.Error("The type must not be abstract.");
return false;
}
if (gameOverType.GetConstructor(Type.EmptyTypes) == null)
{
Logger<MiraApiPlugin>.Error("The type must have a parameterless constructor.");
return false;
}
GameOverIds.Add(gameOverType, _nextId);
GameOverTypes.Add(_nextId, gameOverType);
_nextId++;
return true;
}
/// <summary>
/// Create an instance of a custom game over.
/// </summary>
/// <param name="id">ID of the custom game over.</param>
/// <param name="customGameOver">The created instance of the custom game over.</param>
/// <returns>An instance of the custom game over.</returns>
public static bool TryGetGameOver(int id, [NotNullWhen(true)] out CustomGameOver? customGameOver)
{
if (GameOverTypes.TryGetValue(id, out var gameOverType))
{
customGameOver = Activator.CreateInstance(gameOverType) as CustomGameOver;
return customGameOver != null;
}
customGameOver = null;
return false;
}
/// <summary>
/// Get the ID of a custom game over.
/// </summary>
/// <typeparam name="T">Type of the custom game over.</typeparam>
/// <returns>The ID of the custom game over.</returns>
public static int GetGameOverId<T>() where T : CustomGameOver
{
return GetGameOverId(typeof(T));
}
/// <summary>
/// Get the ID of a custom game over.
/// </summary>
/// <param name="gameOverType">Type of the custom game over.</param>
/// <returns>The ID of the custom game over.</returns>
/// <exception cref="ArgumentException">Thrown when the type is not registered.</exception>
public static int GetGameOverId(Type gameOverType)
{
if (GameOverIds.TryGetValue(gameOverType, out var id))
return id;
throw new ArgumentException($"{gameOverType.FullName} is not a registered custom game over!");
}
}
+2
View File
@@ -0,0 +1,2 @@
[*.cs]
dotnet_diagnostic.CS1591.severity = none
+66 -50
View File
@@ -3,74 +3,82 @@
namespace MiraAPI.GameModes;
/// <summary>
/// Base class for custom gamemodes
/// Base class for custom gamemodes.
/// </summary>
public abstract class CustomGameMode
{
/// <summary>
/// Game mode name
/// Gets the game mode name.
/// </summary>
public abstract string Name { get; }
/// <summary>
/// Game mode description
/// Gets the game mode description.
/// </summary>
public abstract string Description { get; }
/// <summary>
/// Game mode ID
/// Gets the game mode ID.
/// </summary>
public abstract int Id { get; }
/// <summary>
/// Called when Intro Cutscene is destroyed
/// Called when Intro Cutscene is destroyed.
/// </summary>
public virtual void Initialize() { }
public virtual void Initialize()
{
}
/// <summary>
/// Called on HudManager.Start()
/// Called on HudManager.Start().
/// </summary>
/// <param name="instance">Instance of HudManager</param>
public virtual void HudStart(HudManager instance) { }
/// <param name="instance">Instance of HudManager.</param>
public virtual void HudStart(HudManager instance)
{
}
/// <summary>
/// Called every frame on HudManager.Update()
/// Called every frame on HudManager.Update().
/// </summary>
/// <param name="instance">Instance of HudManager</param>
public virtual void HudUpdate(HudManager instance) { }
/// <param name="instance">Instance of HudManager.</param>
public virtual void HudUpdate(HudManager instance)
{
}
/// <summary>
/// Called when a player is killed
/// Called when a player is killed.
/// </summary>
/// <param name="player">PlayerControl that was killed</param>
public virtual void OnDeath(PlayerControl player) { }
/// <param name="player">PlayerControl that was killed.</param>
public virtual void OnDeath(PlayerControl player)
{
}
/// <summary>
/// Calculate Game End logic
/// Calculate Game End logic.
/// </summary>
/// <param name="runOriginal">Should original game end logic be used</param>
/// <param name="instance">Instance of LogicGameFlowNormal</param>
/// <param name="runOriginal">Should original game end logic be used.</param>
/// <param name="instance">Instance of LogicGameFlowNormal.</param>
public virtual void CheckGameEnd(out bool runOriginal, LogicGameFlowNormal instance)
{
runOriginal = true;
}
/// <summary>
/// Custom role assignment
/// Custom role assignment.
/// </summary>
/// <param name="runOriginal">Should original role assignment be used</param>
/// <param name="instance">Instance of LogicRoleSelection</param>
/// <param name="runOriginal">Should original role assignment be used.</param>
/// <param name="instance">Instance of LogicRoleSelection.</param>
public virtual void AssignRoles(out bool runOriginal, LogicRoleSelectionNormal instance)
{
runOriginal = true;
}
/// <summary>
/// Custom murder logic
/// Custom murder logic.
/// </summary>
/// <param name="runOriginal">Should original murder logic be used</param>
/// <param name="result">Result of custom murder logic</param>
/// <param name="target">Target player for murder</param>
/// <param name="runOriginal">Should the original murder logic be used.</param>
/// <param name="result">Result of custom murder logic.</param>
/// <param name="target">Target player for murder.</param>
public virtual void CanKill(out bool runOriginal, out bool result, PlayerControl target)
{
result = false;
@@ -78,61 +86,69 @@ public abstract class CustomGameMode
}
/// <summary>
/// Should Roles Settings be available when this gamemode is selected?
/// Should Roles Settings be available when this gamemode is selected.
/// </summary>
public virtual bool CanAccessRolesTab() => true;
/// <returns>True if Role Settings are enabled in this game mode.</returns>
public virtual bool AreRoleSettingsEnabled() => true;
/// <summary>
/// Should Game Settings be available when this gamemode is selected?
/// Should Game Settings be available when this gamemode is selected.
/// </summary>
public virtual bool CanAccessSettingsTab() => true;
/// <returns>True if Game Settings are enabled in this mode.</returns>
public virtual bool AreGameSettingsEnabled() => true;
/// <summary>
/// Custom winner selection
/// Custom winner selection.
/// </summary>
/// <returns>List of winners</returns>
public virtual List<NetworkedPlayerInfo> CalculateWinners() => null;
/// <returns>List of winners or null.</returns>
public virtual List<NetworkedPlayerInfo>? CalculateWinners() => null;
/// <summary>
/// Show gamemode in Intro Cutscene
/// Show gamemode in Intro Cutscene.
/// </summary>
public virtual bool ShowCustomRoleScreen() => false;
/// <returns>True if the game mode should be shown in the intro cutscene.</returns>
public virtual bool ShowGameModeIntroCutscene() => false;
/// <summary>
/// Can Admin be used in this gamemode
/// Can Admin be used in this gamemode.
/// </summary>
/// <param name="console">Admin Console</param>
/// <param name="console">Admin Console.</param>
/// <returns>True if Admin console is enabled.</returns>
public virtual bool CanUseMapConsole(MapConsole console) => true;
/// <summary>
/// Can a body be reported in this gamemode
/// Can a body be reported in this gamemode.
/// </summary>
/// <param name="body">Target body for reporting</param>
/// <param name="body">Target body for reporting.</param>
/// <returns>True if dead bodies can be reported.</returns>
public virtual bool CanReport(DeadBody body) => true;
/// <summary>
/// Can system consoles be used in this gamemode
/// Can system consoles be used in this gamemode.
/// </summary>
/// <param name="console">System Console</param>
/// <param name="console">System Console.</param>
/// <returns>True if system consoles are enabled in this mode.</returns>
public virtual bool CanUseSystemConsole(SystemConsole console) => true;
/// <summary>
/// Can tasks be interacted with in this gamemode
/// Can tasks be interacted with in this gamemode.
/// </summary>
/// <param name="console">Task console</param>
public virtual bool CanUseConsole(Console console) => true;
/// <param name="console">Task console.</param>
/// <returns>True if tasks are enabled in this mode.</returns>
public virtual bool CanUseTasks(Console console) => true;
/// <summary>
/// Should the sabotage map be used when attempting to open sabotage overlay
/// Should the sabotage map be used when attempting to open sabotage overlay.
/// </summary>
/// <param name="map">MapBehaviour object</param>
/// <param name="map">MapBehaviour object.</param>
/// <returns>True if the sabotage map should be shown.</returns>
public virtual bool ShouldShowSabotageMap(MapBehaviour map) => true;
/// <summary>
/// Can a player vent in this gamemode
/// Can a player vent in this gamemode.
/// </summary>
/// <param name="vent">Target vent</param>
/// <param name="playerInfo">Player attempting to vent</param>
/// <param name="vent">Target vent.</param>
/// <param name="playerInfo">Player attempting to vent.</param>
/// <returns>True if venting is enabled in this mode.</returns>
public virtual bool CanVent(Vent vent, NetworkedPlayerInfo playerInfo) => true;
}
}
+13 -14
View File
@@ -1,20 +1,19 @@
#nullable enable
using Reactor.Utilities;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Reactor.Utilities;
namespace MiraAPI.GameModes;
/// <summary>
/// Manages custom gamemodes
/// Manages custom gamemodes.
/// </summary>
public static class CustomGameModeManager
{
/// <summary>
/// List of registered gamemodes
/// List of registered gamemodes.
/// </summary>
public static readonly Dictionary<int, CustomGameMode> GameModes = [];
internal static readonly Dictionary<int, CustomGameMode> GameModes = [];
public static bool IsDefault()
{
@@ -22,14 +21,14 @@ public static class CustomGameModeManager
}
/// <summary>
/// Current gamemode
/// Gets the current gamemode.
/// </summary>
public static CustomGameMode? ActiveMode = new DefaultMode();
public static CustomGameMode? ActiveMode { get; internal set; } = new DefaultMode();
/// <summary>
/// Set current gamemode
/// Set current gamemode.
/// </summary>
/// <param name="id">gamemode ID</param>
/// <param name="id">gamemode ID.</param>
public static void SetGameMode(int id)
{
if (GameModes.TryGetValue(id, out var gameMode))
@@ -42,9 +41,9 @@ public static class CustomGameModeManager
}
/// <summary>
/// Register gamemode from type
/// Register gamemode from type.
/// </summary>
/// <param name="gameModeType">Type of gamemode class, should inherit from <see cref="CustomGameMode"/></param>
/// <param name="gameModeType">Type of gamemode class, should inherit from <see cref="CustomGameMode"/>.</param>
internal static void RegisterGameMode(Type gameModeType)
{
if (!typeof(CustomGameMode).IsAssignableFrom(gameModeType))
@@ -60,7 +59,7 @@ public static class CustomGameModeManager
Logger<MiraApiPlugin>.Error($"Failed to create instance of {gameModeType.Name}");
return;
}
if (GameModes.Any(x => x.Key == gameMode.Id))
{
Logger<MiraApiPlugin>.Error($"ID for gamemode {gameMode.Name} already exists!");
@@ -69,4 +68,4 @@ public static class CustomGameModeManager
GameModes.Add(gameMode.Id, gameMode);
}
}
}
+1 -2
View File
@@ -1,9 +1,8 @@
namespace MiraAPI.GameModes;
[RegisterGameMode]
public class DefaultMode : CustomGameMode
{
public override string Name => "Default";
public override string Description => "Default Among Us GameMode";
public override int Id => 0;
}
}
@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace MiraAPI.GameModes;
[AttributeUsage(AttributeTargets.Class)]
public class RegisterGameModeAttribute : Attribute
{
private static readonly HashSet<Assembly> RegisteredAssemblies = [];
internal static void Register(Assembly assembly)
{
if (!RegisteredAssemblies.Add(assembly))
{
return;
}
foreach (var type in assembly.GetTypes())
{
var attribute = type.GetCustomAttribute<RegisterGameModeAttribute>();
if (attribute != null)
{
CustomGameModeManager.RegisterGameMode(type);
}
}
}
}
+47 -12
View File
@@ -1,30 +1,65 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
namespace MiraAPI.GameOptions;
/// <summary>
/// Base class for option groups. An option group is a collection of options that are displayed together in the options menu.
/// </summary>
public abstract class AbstractOptionGroup
{
public List<IModdedOption> Options { get; } = [];
internal List<IModdedOption> Options { get; } = [];
/// <summary>
/// The name of the group. Visible in options menu.
/// Gets a list of the options which are a part of this group.
/// </summary>
public ReadOnlyCollection<IModdedOption> Children => new(Options);
/// <summary>
/// Gets the name of the group. Visible in options menu.
/// </summary>
public abstract string GroupName { get; }
/// <summary>
/// A function that returns whether the group should be visible or not.
/// Gets the Optionable type of the group.
/// </summary>
public virtual Type? OptionableType => null;
/// <summary>
/// Gets a value indicating whether the group should be shown in the modifiers menu.
/// </summary>
// TODO: make this not a boolean
public virtual bool ShowInModifiersMenu => false;
/// <summary>
/// Gets the function that determines whether the group should be visible or not.
/// </summary>
public virtual Func<bool> GroupVisible => () => true;
/// <summary>
/// The group color. This is used to color the group in the options menu.
/// Gets the group color. This is used to color the group in the options menu.
/// </summary>
public virtual Color GroupColor => Color.clear;
public virtual Color GroupColor => MiraApiPlugin.DefaultHeaderColor;
/// <summary>
/// The role the group is associated with. This is used for the advanced role options menu.
/// Gets the group priority. This is used to determine the order in which groups are displayed in the options menu.
/// Zero is the highest priority, and the default value is the max uint value.
/// </summary>
public virtual Type AdvancedRole => null;
}
public virtual uint GroupPriority => uint.MaxValue;
internal bool AllOptionsHidden { get; set; }
internal CategoryHeaderMasked? Header { get; set; }
}
/// <summary>
/// Base class for option groups. An option group is a collection of options that are displayed together in the options menu.
/// </summary>
/// <typeparam name="T">The type of the optionable that this group contains.</typeparam>
public abstract class AbstractOptionGroup<T> : AbstractOptionGroup where T : IOptionable
{
/// <inheritdoc />
public override Type OptionableType => typeof(T);
}
@@ -1,27 +1,34 @@
using MiraAPI.GameOptions.OptionTypes;
using System;
using System;
using System.Reflection;
using MiraAPI.GameOptions.OptionTypes;
namespace MiraAPI.GameOptions.Attributes;
public class ModdedEnumOptionAttribute(string title, Type enumType, Type roleType = null)
: ModdedOptionAttribute(title, roleType)
/// <summary>
/// Attribute for creating an enum option.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedEnumOptionAttribute(string title, Type enumType, string[]? values = null)
: ModdedOptionAttribute(title)
{
internal override IModdedOption CreateOption(object value, PropertyInfo property)
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
var opt = new ModdedEnumOption(Title, (int)value, enumType, RoleType);
var opt = new ModdedEnumOption(Title, (int)(value ?? 0), enumType, values);
return opt;
}
/// <inheritdoc />
public override void SetValue(object value)
{
ModdedEnumOption opt = HolderOption as ModdedEnumOption;
opt.SetValue((int)value);
var opt = HolderOption as ModdedEnumOption;
opt?.SetValue((int)value);
}
/// <inheritdoc />
public override object GetValue()
{
ModdedEnumOption opt = HolderOption as ModdedEnumOption;
return Enum.ToObject(enumType, opt.Value);
return HolderOption is ModdedEnumOption opt
? Enum.ToObject(enumType, opt.Value)
: throw new InvalidOperationException($"HolderOption for option \"{Title}\" with EnumType ${enumType.FullName} is not a ModdedEnumOption");
}
}
}
@@ -1,34 +1,43 @@
using MiraAPI.GameOptions.OptionTypes;
using System;
using System;
using System.Reflection;
using MiraAPI.GameOptions.OptionTypes;
using MiraAPI.Utilities;
namespace MiraAPI.GameOptions.Attributes;
/// <summary>
/// A number option attribute for the modded options system.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedNumberOptionAttribute(
string title,
float min,
float max,
float increment = 1,
NumberSuffixes suffixType = NumberSuffixes.None,
bool zeroInfinity = false,
Type roleType = null)
: ModdedOptionAttribute(title, roleType)
MiraNumberSuffixes suffixType = MiraNumberSuffixes.None,
string? formatString = null,
bool zeroInfinity = false)
: ModdedOptionAttribute(title)
{
internal override IModdedOption CreateOption(object value, PropertyInfo property)
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
var toggleOpt = new ModdedNumberOption(Title, (float)value, min, max, increment, suffixType, zeroInfinity, RoleType);
return toggleOpt;
return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, formatString, zeroInfinity);
}
/// <inheritdoc />
public override void SetValue(object value)
{
ModdedNumberOption toggleOpt = HolderOption as ModdedNumberOption;
toggleOpt.SetValue((float)value);
var opt = HolderOption as ModdedNumberOption;
opt?.SetValue((float)value);
}
/// <inheritdoc />
public override object GetValue()
{
ModdedNumberOption toggleOpt = HolderOption as ModdedNumberOption;
return toggleOpt.Value;
if (HolderOption is ModdedNumberOption opt)
{
return opt.Value;
}
throw new InvalidOperationException($"HolderOption for option \"{Title}\" is not a ModdedNumberOption");
}
}
}
@@ -3,18 +3,37 @@ using System.Reflection;
namespace MiraAPI.GameOptions.Attributes;
/// <summary>
/// Represents an attribute that is used to define a modded option.
/// </summary>
/// <param name="title">The option title.</param>
/// <param name="roleType">Optional parameter to specify a role Type.</param>
[AttributeUsage(AttributeTargets.Property)]
public abstract class ModdedOptionAttribute(string title, Type roleType = null) : Attribute
public abstract class ModdedOptionAttribute(string title, Type? roleType = null) : Attribute
{
public IModdedOption HolderOption { get; set; }
public string Title { get; private set; } = title;
protected Type RoleType { get; private set; } = roleType;
internal IModdedOption? HolderOption { get; set; }
public abstract void SetValue(object val);
/// <summary>
/// Gets the title of the option.
/// </summary>
public string Title { get; private set; } = title;
/// <summary>
/// Gets the role type of the option.
/// </summary>
protected Type? RoleType { get; private set; } = roleType;
/// <summary>
/// Sets the value of the option.
/// </summary>
/// <param name="value">The new value as an object.</param>
public abstract void SetValue(object value);
/// <summary>
/// Gets the value of the option.
/// </summary>
/// <returns>The value of the option as an object.</returns>
public abstract object GetValue();
internal abstract IModdedOption CreateOption(object value, PropertyInfo property);
}
internal abstract IModdedOption? CreateOption(object? value, PropertyInfo property);
}
Loaded 100 of 294 files, more files were not shown because too many files have changed in this diff. Show more